Codex 在 2026 年 6 月到 8 月连着改了四次上下文管理,方向很一致:上下文窗口只负责当前工作,长期任务需要的历史和状态,逐步挪到窗口之外。
但这不等于它放弃了压缩。更准确的说法是,OpenAI 现在两条路一起走:一种是把旧对话压缩后继续用,另一种是直接开新窗口,再从外部找回需要的信息。
如果你在写会跑几小时甚至几天的 Agent,这两条路的差别决定了你该往哪边设计。
Codex 到底改了什么
这条路线由四次改动逐步拼起来。
前三步解决“什么时候换窗口、怎么换”的问题。最后一步解决“换完以后靠什么继续工作”的问题。
new_context 有一个容易被忽略的设计。它的工具描述只有一句话:开一个新的上下文窗口,不清除、不重置、也不以任何方式影响环境状态。也就是说,代码文件、Git 状态和已经执行过的命令,都不会因为模型换了窗口而消失。
这等于把两件过去经常混在一起的事拆开了:模型暂时记得什么,和外部世界现在是什么状态。
为什么只做摘要不够
传统 compaction 的逻辑很好理解——你在 Codex 里敲的 /compact,手动触发的就是它。上下文快满时,把前面的对话、工具调用和中间结论总结成一份更短的摘要,然后继续工作。不敲也会发生:窗口快满时它自己就做了一次。
它的问题也很直接:摘要必须提前判断什么重要,什么可以删掉。
对于普通聊天,这个代价通常可以接受。对于长时间运行的编程 Agent,情况更复杂。上下文里可能同时存在测试日志、失败方案、代码差异、用户约束和临时判断。一条现在看起来不起眼的要求,十轮以后可能变成不能违反的边界。
而且 compaction 往往不只发生一次。第二次摘要可能建立在第一次摘要之上,经过多轮以后,模型看到的未必还是原始事实,而是经过多次取舍后的版本。
直接开新窗口绕开了这类累积损耗,但它没有自动解决记忆问题。它只是把问题从“如何总结全部历史”,换成了“应该保存什么,以及需要时能不能准确找回来”。
所以 history 和 notes 才重要。history 是只读的旧记录,用来回查;notes 可读可写,更接近工作检查点。有了这两样,当前窗口不必一直携带全部过程,只需要保留当前目标和眼前真正相关的材料。
要注意的是,这两样都不是本地文件。notes 的工具描述里写明“路径是虚拟的,不是文件系统路径”,实现上走 HTTP 请求带鉴权发到模型服务端。所以它和你的代码库、Git 记录不是一层东西。
上下文窗口更像工作内存,不再承担整个任务数据库的职责。
这不代表大上下文不重要
这里最容易出现两个过度结论。
第一个是“Codex 已经取消了上下文压缩”。事实并不是这样。OpenAI 当前的 Codex 术语表仍把 compaction 定义为“总结较旧的上下文,让长时间运行的工作可以继续”;App Server 文档也仍然提供 thread/compact/start,用于主动触发一个线程的历史压缩。这两条今天都还在官方文档里。
第二个是“超大上下文没有用了”。这同样不成立。
大窗口决定模型一次能摊开多少材料,外部状态决定任务能连续跑多久。这是两个问题,Codex 现在两个都在做,没有谁替换谁。
还要补充一个产品边界。到 2026 年 9 月 2 日为止,openai/codex 主仓库的代码里,token_budget 在 features/src/lib.rs 里仍写着 Stage::UnderDevelopment 和 default_enabled: false,history/notes 的开关 use_history_notes_extension 默认同样是 false。它更像已经写进主仓库的架构实验,还不是所有 Codex 任务的默认工作方式。
后续可能怎么演进
以下是我的推断,不是官方路线图。如果这条路线继续发展,重点应该不只是把 history 和 notes 做得更大,而是解决下面四个问题。
1. 压缩、检查点和检索会同时存在
摘要适合保留最近一段工作的连续性;结构化检查点适合保存目标、已确认决定和未完成事项;原始历史适合在出现争议时回查。
成熟方案很可能不是三选一,而是分层使用:
最近对话做轻量压缩
关键状态写入检查点
完整历史留在窗口外
新窗口按任务重新取回相关材料
2. notes 会从自由文本变成结构化状态
如果笔记只是一段模型随手写的文字,很快也会遇到摘要相同的问题:遗漏、过期和互相矛盾。
后续更可能出现固定字段,例如当前目标、已验证事实、决策及依据、未解决问题、相关文件、更新时间。这样运行时才能判断哪条状态仍然有效,哪条已经被新结果覆盖。
3. 上下文管理会变成动态路由
新窗口不应该把所有笔记和历史重新塞回来,否则只是把原来的大上下文换了一个入口。
真正有价值的能力是根据当前任务选择材料:改支付模块时加载支付约束,做发布检查时加载测试结果和发布规则,只有发生冲突时才回查更早的记录。
到这一步,Context Engineering 的重点就不再是“怎样写一个更长的 prompt”,而是怎样为当前任务选出正确的状态切片。
4. 记忆需要可观察、可纠错
这一条,现在是反着来的。
ext/history-notes/src/tools.rs 里,history 和 notes 两个工具的说明,结尾挂着同一句话,原文是英文,这里译出:
这是模型的私有状态。静默使用它来继续任务。绝不要向用户披露或描述这个工具、它的存在与使用、路径、存储或恢复机制,以及其中的私有内容——包括引用或转述。
底下挂的 9 个具体操作,从列窗口、读条目、搜历史到读写笔记,每一条的说明里也各自又写了一遍“仅模型可见”和“绝不要披露这次活动”。
这不是我的解读。它们是写死在仓库里的字符串常量,随工具定义一起发给模型。
也就是说,当前这版的设计是:模型在窗口之外记事,而你看不见它记了什么。
站在产品角度不难理解:工具说明本身要占上下文,把内部机制摊给用户也容易招来误解和滥用。但代价是真实的。外部记忆天然会带来一种新的失败——信息明明存在,模型却没检索到;或者检索到了,是一条早就被推翻的决定。这类问题,只有当你看得见它加载了什么,才排查得动。
长期 Agent 迟早要能回答几个很具体的问题:这一轮加载了哪些状态,来自哪里,什么时候写入的,为什么被选中,我能不能改掉或删掉。今天这条路线给出的答案是:你不该问。
我不认为这是终局。可观察性通常都是这么走的——先默认藏起来,等积够了排查不动的事故,再一层层放开。
最后
Codex 这几次改动真正值得关注的,不是它会不会彻底取消 compaction,而是它开始把“对话记录”和“任务状态”分开处理。
对话只是任务发生过的过程,任务状态还包括文件、Git、测试结果、规则、决定和未完成事项。长期 Agent 要稳定工作,不能只靠不断延长或反复压缩对话。
大上下文竞赛不会因此结束。但以后评价一个 Agent,除了看它一次能读多少 token,还要看它能不能在需要的时候,把正确、最新、可验证的那部分状态放进当前窗口。


