Skip to content
预计 1 分钟右侧目录可快速定位

Context 什么时候该压缩、什么不能丢:Compaction、Trigger 与 Fidelity ​

前置:Tool 如何撑爆 Context:Definition Cost 与 Result Management
核心问题:Context 快满时,哪些内容可以压缩、哪些事实绝不能丢,怎样证明 compaction 没把任务语义悄悄改掉?

在 70% 先清理旧 Tool Result,85% 才做结构化 compaction;进入新里程碑时也可主动 checkpoint/reset。用户要求“绝不提交代码”应存入 protected constraints;即使历史压缩多次也必须保持,不能因 summary 漂移丢失。

Context Compaction ​

Compaction 不是“把聊天摘要一下”,而是把已经消费过的 working context 转成下一轮仍能继续工作的更小状态表示。

至少要保留:当前目标/约束、已完成进度、关键失败、尚未解决的问题,以及可重新读取的 artifact/tool-result reference。大量旧对话措辞、重复日志和已失效中间推理可以丢掉。

判断是否成功的标准不是“token 变少了”,而是 compaction 后 Agent 继续执行时不会忘记重要事实或把已经失败的路径重新走一遍。

Compaction Trigger Policy ​

不要等到 Provider 报 context overflow 才开始压缩。更好的 trigger 是提前观察:

text
token high-water mark
+ turn 数持续增长
+ tool result 快速膨胀
+ 任务阶段切换

例如 128K window 不应该用到 127K 才 compaction,因为还要给下一轮 Tool schema、retrieval 和模型输出留空间。

触发也不能过早:每几轮都做有损 summary,会让信息经过多次压缩后逐渐漂移。实际系统通常设置 high-water mark,再在阶段边界优先压缩。

Protected State ​

Protected State 是 compaction 不得自由丢弃的 durable facts,例如 objective、constraints、decisions、completed/pending、failed attempts、artifact refs。结构化字段比一段自由摘要更可验证。

它应由结构化字段保护,而非依赖 summarizer 自觉。

Compaction Drift / Information Loss ​

重复 summary-of-summary 会放大小遗漏。减轻方法包括结构化 compaction、保留原始 artifact/provenance、必要时 re-ground authoritative source。

尤其 negative knowledge、精确参数、边界条件最容易丢。应保留 source refs,并周期性从权威原文 re-ground。

Failure Modes ​

只在 Context 即将溢出时才触发 Compaction ​

症状: token ratio 已接近硬上限仍继续追加大 Tool Result。

为什么危险: 没有空间进行温和压缩或保留 output reserve,下一次 call 直接 overflow。

处理: 设置 soft/hard watermark,并结合 task phase、tool result size、turn count 提前触发。

Compaction 把关键约束和未决状态一起摘要掉 ​

症状: 用户目标、审批要求、失败尝试只存在自由文本 summary。

为什么危险: 多次 summary-of-summary 后关键约束永久丢失,后续模型可能重复错误或越权。

处理: 目标、constraints、decisions、pending approvals 等结构化 protected state 独立保存并在 compaction 后校验。

Summary-of-summary 累积语义漂移 ​

症状: 每次 compaction 都只读取上一次 summary,不再保留 provenance 或原始 artifact reference。

为什么危险: 小遗漏被后续 summary 放大,最终任务状态与真实历史偏离。

处理: 保留原始 transcript/artifact refs,结构化 summary,并定期 re-ground 到权威来源。

如何验证 ​

Case断言
只在 Context 即将溢出时才触发 Compaction模拟 token 逐步增长,断言 soft limit 触发清理/compaction,hard limit 前仍留安全余量。
Compaction 把关键约束和未决状态一起摘要掉连续多次 compaction,断言 protected fields 完整且与原始事实一致。
Summary-of-summary 累积语义漂移长程 eval 多次 compaction,检查 critical fact recall、constraint preservation 与 drift rate。

Codex 源码对照:Context Projection + Compaction Lifecycle ​

要回答的问题 ​

Runtime 中的 source-of-truth state 怎样变成一次真正发给模型的 context?Compaction 是只在 Turn 开始前发生,还是也会在同一个 Codex Turn 的 continuation 中发生?

精确定位 ​

Tag: rust-v0.150.1

File:

Symbols:

  • ContextManager::for_prompt(...)
  • ContextManager::for_prompt_annotated(...)
  • context_window_token_status(...)
  • run_turn(...)
  • run_pre_sampling_compact(...)
  • run_auto_compact(...)
  • CompactTask::run(...)

最小调用链 ​

Context projection:

text
SessionState.history: ContextManager
→ record context / world-state updates
→ clone_history()
→ ContextManager::for_prompt(input_modalities)
→ normalize / filter model-visible history
→ sampling_request_input
→ run_sampling_request(...)

Pre-turn protection:

text
run_turn(...)
→ run_pre_sampling_compact(...)
→ context_window_token_status(...)
→ token_limit_reached?
→ run_auto_compact(..., CompactionPhase::PreTurn)
→ sampling

Mid-turn continuation protection:

text
sampling + tool/response completion
→ context_window_token_status(...)
→ needs_follow_up
→ threshold / new-context-window request
→ should_roll_over
→ run_auto_compact(..., CompactionPhase::MidTurn)
→ continue
→ next sampling

Observable Fact ​

ContextManager::for_prompt() 明确是“准备发送给模型的 history”:它会 normalize history,并根据 model input modalities 去掉或转换不适合发送的内容。因此 stored history 与 model-visible request projection 不是同一个对象。

context_window_token_status() 由 Runtime 计算 active context usage、auto-compact scope、full context hard cap 和 token_limit_reached。run_turn() 在第一次正常 sampling 前调用 run_pre_sampling_compact();在 sampling 完成后又重新计算 token status,如果仍需 follow-up 且需要 rollover,则以 CompactionPhase::MidTurn 执行 auto compact 后 continue 到下一次 sampling。

Design Inference ​

两个 invariant:

  1. Source-of-truth state ≠ model context projection:Runtime 可以持有比模型输入更多、更权威的状态;每次 request 应从 source state 构造受预算/能力约束的 projection。
  2. Compaction trigger belongs to Runtime policy:Runtime 应根据 token/context status 与 continuation need 决定何时 compact,而不是让模型自由声称“我已经压缩过上下文”。

Codex-specific Trade-off ​

Codex rust-v0.150.1 使用 ContextManager、AutoCompactTokenLimitScope、CompactionPhase::PreTurn/MidTurn,并根据 provider capability 选择 local/remote compact。这些命名、阈值策略和 provider 分支属于 Codex 当前实现。

Shadow Harness Delta ​

  1. 把 ContextSnapshot 明确建模为从 Run/Session source state 派生的 request projection,不能当唯一真实状态库。
  2. Context Assembly 增加 build_projection(source_state, model_capabilities, budget) 边界,并记录 projection manifest/hash。
  3. Compaction state machine 增加两类入口:pre_request protection 与 mid-run continuation protection。
  4. 测试至少覆盖:连续两次 tool continuation 跨过阈值后,compact 后仍能继续下一次 sampling;protected constraints / pending action / artifact reference 不能丢。

不要过度推导 ​

Runtime 触发了 compact 不等于 summary 一定语义无损。这些文件能证明 trigger、phase 和 continuation control 在 Runtime;不能证明任何 summarizer 都满足 Fidelity,也不能证明 compact 后所有业务约束天然保真。

完整映射见 OpenAI Codex Source Map。

自测 ​

  1. Compaction 后“必须兼容 Python 3.12”这条约束消失了。这个错误说明 protected state 或 fidelity check 哪一环失效?
  2. 为什么等到 hard context limit 才开始压缩太晚?你会用什么 soft trigger,并怎样验证多次 compaction 后语义没有漂移?

Sources ​

AI Engineering · Agent · Harness · Backend Systems