Codex auto compact(自动上下文压缩)是 OpenAI Codex 在会话 token 逼近上限时自动触发的历史摘要机制,桌面端与 CLI 共用同一套 codex-rs 内核。2026 年 7 月以来 openai/codex 仓库已积累二十余个相关未关
|
Codex auto compact(自动上下文压缩)是 OpenAI Codex 在会话 token 逼近上限时自动触发的历史摘要机制,桌面端与 CLI 共用同一套 codex-rs 内核。2026 年 7 月以来 openai/codex 仓库已积累二十余个相关未关闭 issue,症状集中在压缩卡住无法取消、压缩完成后上下文仍有约 80% 被占用、以及压缩后对话历史从界面消失。根因是一处基数错配:压缩阈值按原始窗口的 90% 计算,可用窗口却只有原始窗口的 95%,压缩因而发生在可用窗口约 94.7% 处,且该阈值只能调低不能调高。OpenAI 已于 2026 年 8 月转向 token budget 方案,改用开新窗口配合持久化历史与笔记工具。 桌面端用户实际遇到的是哪几类问题Codex 桌面端的自动压缩问题不是单一 bug,而是四条独立的故障链,在 openai/codex 仓库中均处于未关闭状态。
第四类最容易被误判为「数据丢了」。issue #41954 的报告者导出了原始 rollout 文件,发现历史 API 返回的条目形如 {"type":"userMessage","text":""}。 而完整原文仍保存在 compacted.payload.replacement_history 字段里——数据没丢,是渲染层没有正确回填被压缩窗口的内容。 还有一类间接症状:issue #39767(2026-08-20)分析了一份长会话 rollout,发现 GPT-5.6 的历史推理内容被重复计数了一次,在该会话的 76 次自动压缩中,76 次全部是误触发——按正确计数方式,一次都不该触发。 自动压缩到底在什么时候触发自动压缩的阈值是模型原始上下文窗口的 90%,而不是可用窗口的 90%。 这一点在 codex-rs 的模型元数据实现里写得很直白:
同一个文件里,「可用窗口」用的是另一个字段:
注释写明这个百分比是「为系统提示词、工具开销和模型输出预留余量之后,可用于输入的上下文窗口比例」。两者基数不同,叠加后的结果就是 issue #40095(2026-08-22)实测到的数字:
也就是说,压缩实际发生在可用窗口的约 94.7% 处,此时只剩约 13,600 token 余量。而压缩动作本身要携带待摘要的历史、压缩提示词和模型输出,这点余量经常不够——这就是压缩卡住和压缩失败的直接来源。 为什么调大 model_auto_compact_token_limit 没用model_auto_compact_token_limit 只能把阈值调低,调高会被静默忽略。 上面那段源码的关键在 std::cmp::min:配置值与「原始窗口 90%」取较小者。字段注释也确认了这一行为——省略时由 context_window 推导出 90%,提供时会被钳制到 90% 上限。 网上流传的「把这个值调大就不会频繁压缩」的说法在当前实现下不成立。同理,官方配置参考中并没有提供关闭自动压缩的开关,阈值、作用域和压缩提示词是仅有的三类旋钮。 压缩完为什么还是 80% 满,以及 42GB 的磁盘去哪了压缩会把被替换掉的完整历史重新写回会话记录,这既撑大了新窗口,也撑爆了磁盘。 issue #35032 描述的循环是:压缩 → 恢复时接近满载 → 跑几次工具调用 → 再次压缩。报告者指出问题在于 replacement history 未做去重和裁剪,仍然携带了不再需要的原始工具输出。 磁盘侧的表现更直观。issue #41806(2026-08-31,macOS)统计了自己的 ~/.codex 目录:
根因被归结为两点:压缩时把完整 replacement_history 重新嵌进 rollout JSONL,以及归档会话从不清理、不压缩、不裁剪。 反复压缩还有一层成本代价:每一轮压缩都要把历史重新送进模型做摘要,这部分 token 不产生任何有效产出。长 Agent 任务的费用难以预估,很大一部分就来自这类不可见的重算——按额度包预付的接入形式在这类场景下用量上限在调用前即已确定,例如七牛云 Token Plan 采用的就是这种计费方式。
config.toml 里真正可调的旋钮Codex 桌面端与 CLI 共享 ~/.codex/config.toml。与压缩直接相关的配置项如下(字段名与官方配置参考一致):
把阈值调低,是当前唯一能给压缩动作留出足够操作余量的办法。以 272,000 窗口为例,配置成可用窗口的 85% 左右比较稳妥:
body_after_prefix 的意义是:阈值只计算压缩窗口前缀之后新增的部分,而不是整个活动上下文。对于已经压缩过一次、前缀本身就很大的长会话,这个选项能显著减少「刚压缩完就又到阈值」的情况。 此外还有两个生命周期钩子事件 PreCompact 和 PostCompact,可以在压缩前后执行命令或 MCP 工具,支持 async(默认 false)和 additionalContextLimit(默认 2500)等参数。 常见用法是在 PreCompact 里把当前任务的验收标准、待办清单写进一个外部文件,压缩后再读回来,避免关键状态被摘要掉。 OpenAI 的答案:token budget 正在取代压缩Codex 团队的方向不是修好压缩,而是在长任务中不再压缩——改为直接开启新的上下文窗口,靠历史与笔记工具跨窗口恢复状态。 codex-rs/core/src/compact_token_budget.rs 里的实现注释说明了这一点:
函数体里也确实没有任何摘要请求,核心只有一句 sess.start_new_context_window(step_context, world_state)。压缩钩子和事件被保留,是为了不破坏客户端兼容性。 配套能力来自 PR #39827,标题为「Add history and notes tools for token-budget sessions」,已于 2026 年 8 月 21 日合并。它为 token budget 会话新增了两组直连模型的工具:
PR 描述明确写道,这是为了让 token budget 会话「能够跨上下文窗口切换恢复此前的对话上下文并保留工作状态」。 内核里还内置了一条提醒模板,会在窗口即将耗尽时告知模型接下来会发生什么:
这套机制目前仍在功能开关后面,相关配置位于 features.token_budget 命名空间下:
长任务现在该怎么配在 token budget 模式全量放开之前,可按以下顺序处理:
常见问题Codex 桌面端能彻底关闭自动压缩吗? 为什么我把 model_auto_compact_token_limit 调大了却没有生效? 压缩后界面里消失的对话内容还能找回来吗? total 和 body_after_prefix 这两个作用域该选哪个? token budget 模式现在能用吗? 小结Codex 桌面端自动压缩的核心问题不在压缩算法本身,而在触发时机:阈值按原始窗口的 90% 计算,可用窗口又只有原始窗口的 95%,两个百分比基数不一致,使压缩发生在可用空间几乎耗尽的位置。 叠加 replacement history 未裁剪导致的新窗口高占用,就形成了反复压缩、额度浪费和会话文件膨胀的连锁反应。 据 openai/codex 仓库的公开 issue 与源码,OpenAI 已在 2026 年 8 月转向 token budget 方案,用开新窗口配合持久化的历史与笔记工具替代摘要式压缩。 本文所述行为基于 openai/codex 仓库截至 2026 年 9 月 3 日的主干代码(CLI 最新发布版本 rust-v0.153.0)与官方配置参考,功能开关状态和默认值随版本变动较快,建议在实际配置前对照当前版本的配置文档核实字段名与默认值。 |
2026-07-02
2026-06-24
2026-06-01
2026-06-27
2026-06-02