Codex Compact 机制详解:本地压缩、远程压缩与会话续接
机制优先地拆解 Codex compact:覆盖手动与自动触发、provider 如何决定 remote/local compact、local compact 如何重写历史、remote /responses/compact 为什么返回加密 compaction_summary,以及 compact 后初始上下文与技…
Codex Compact 机制详解:本地压缩、远程压缩与会话续接 Code Version: 基于 openai/codex commit 19702e190ebf16f789617ca5f16bfc373c238fe7。 讨论范围: 只覆盖 Codex 的 compact 逻辑,包括 manual /compact、auto compact、local compact、remote compact,以及 compact 后的会话恢复。1. 为什么 Codex 需要 compact Codex 的问题不是“聊天记录太长不好看”,而是线程历史会不断膨胀,最终逼近模型的上下文窗口。 一旦历史过长,系统会面临两个直接问题:新一轮请求可能在发送前就已经接近或超过上下文上限。多工具、多轮推理线程里,大量旧消息会持续挤占最新问题的可见预算。 所以 compact 的目标不是简单“删旧消息”,而是把线程状态压缩成一个更短、但仍然可继续执行的历史表示。 💡 Key Point Codex 里的 compact 本质上是“历史重写”。 它不是给用户生成一段摘要就结束,而是会真正替换会话历史,并把替换后的历史持久化下来。2. 入口在哪里:手动 compact 和自动 compact Compact 有两条入口:手动触发和自动触发。2.1 手动 /compact 当用户手动执行 compact 时,handlers::compact(...) 会创建一个新的 turn,把 compact prompt 作为合成的 UserInput,然后派发 CompactTask,见 codex.rs。 任务真正执行时,会在 tasks/compact.rs 里根据 provider 做一次分流:provider.is_openai() 为真,走 remote compact否则走 local compact 对应判断函数在 compact.rs。2.2 自动 compact 正常对话时,compact 也可能自动发生,而且有两种时机。 第一种发生在本轮真正采样之前。run_turn(...) 会先调用 run_pre_sampling_compact(...),见 codex.rs 和 codex.rs。 它会在两种情况下触发:当前累计 token 已经达到 auto_compact_token_limit线程准备从一个更大上下文窗口的模型切换到一个更小窗口的模型,而且当前历史对新模型来说已经太大 后一种专门走 maybe_run_previous_model_inline_compact(...),见 codex.rs。 第二种发生在本轮采样之后。如果这一轮还需要 follow-up,而且累计 token 已经触发阈值,Codex 会在当前 turn 中途执行 compact,再继续后续推理,见 codex.rs。 这时会使用 InitialContextInjection::BeforeLastUserMessage,而不是普通的 DoNotInject。这是 local/remote 两条路径都共享的重要约束,定义在 compact.rs。2.3 一个总流程图flowchart TD A["用户发起 /compact 或正常对话"] --> B{"manual 还是 auto"} B -->|"manual"| C["spawn CompactTask"] B -->|"auto pre-turn"| D["run_pre_sampling_compact"] B -->|"auto mid-turn"| E["run_auto_compact"] C --> F{"provider.is_openai()"} D --> F E --> F F -->|"yes"| G["remote compact"] F -->|"no"| H["local compact"] G --> I["replace_compacted_history"] H --> I I --> J["recompute_token_usage + persist rollout"] 3. 分流标准其实很简单:看 provider,不看“是不是登录态” 这一点最容易被误解。 Codex 是否走 remote compact,不是看“现在是不是 ChatGPT 登录态”,而是看 provider 是否被识别为 OpenAI provider。判断逻辑只有一行,见 compact.rs。 ModelProviderInfo::is_openai() 的实现也很直接,就是 provider 名字是否为 openai,见 model_provider_info.rs。 真正和 auth…
正在初始化 WebAssembly 引擎…
首次编译原生模块可能需要数秒
就绪后,页面交互将以接近原生的速度运行