Skip to content

Latest commit

 

History

History
164 lines (110 loc) · 6.83 KB

File metadata and controls

164 lines (110 loc) · 6.83 KB

19. 上下文压缩与历史治理

所属层级:第四层「Anthropic 在做什么」

建议前读:07. QueryEngine 与上下文17. 系统提示词与模型决策

建议后读:21. 记忆系统

研究问题

Anthropic 为什么把上下文治理做成一整套持续运行机制,而不是只在窗口满了以后做一次摘要?

一句话结论

Claude Code 的 compact 系统不是辅助功能,而是长期工程会话的生存机制;它的目标是让 agent 能持续工作,同时尽量不丢掉工程语义。

这篇讲什么

这一章解释 Claude Code 长会话为什么不会无限膨胀:什么时候触发 auto compact,microcompact 清什么,session memory compact 和传统 compact 各自负责什么。

如果你不看源码,只看这一章,应该记住什么

  • Anthropic 把上下文当成稀缺资源,而不是免费黑板。
  • compact 不是单一路径,而是多层机制协同。
  • 工具结果、历史消息、session memory 和附件会被区别对待。
  • 上下文治理的目标不是“压缩成短摘要”,而是“继续工作而不失真”。

Anthropic 的设计目标

如果 agent 要长期做工程任务,它迟早会遇到两个问题:

  • token 会不够
  • 旧上下文虽然昂贵,但又不能随便丢

Claude Code 的 compact 设计明显是在解决这个矛盾:既要持续省上下文,又不能破坏 tool 调用、plan 信息、skills、session memory 这些真正还在起作用的材料。

先给结论

Claude Code 不是只在超长上下文时做一次“总结旧消息”。当前快照里至少有四层治理:

  • token 阈值驱动的 auto compact
  • 对工具结果做局部清理的 microcompact
  • 使用 session memory 的替代式 compact
  • compact 后的 post-compact cleanup 与附件重建

Anthropic 明显把上下文压缩设计成持续运行时算法,而不是一条兜底命令。

源码依据

Mermaid 图:上下文压缩流程图

flowchart TD
    A["新一轮 query 前"] --> B["统计 token 使用"]
    B --> C{"是否超 autoCompactThreshold"}
    C -- 否 --> D["仅做 microcompact / 保持原历史"]
    C -- 是 --> E{"能否用 session memory compact"}
    E -- 能 --> F["生成 compact boundary + summary"]
    E -- 不能 --> G["compactConversation"]
    G --> H["必要时 prompt-too-long 重试 / 截断头部"]
    F --> I["postCompactCleanup"]
    H --> I
    I --> J["重建 plan / skills / file attachments"]
Loading

auto compact 如何判断触发

src/services/compact/autoCompact.ts 里:

  • 先按模型 context window 计算有效窗口
  • 预留摘要输出 token
  • 再减去 buffer,得到 autoCompactThreshold

同一文件还明确区分:

  • warning threshold
  • error threshold
  • blocking limit
  • manual compact buffer

这说明 compact 不是“超过上限再抢救”,而是带预警、阻塞和回旋空间的阈值系统。

auto compact 还会主动避开某些模式

shouldAutoCompact() 中有多种 guard:

  • session_memory / compact query source 不再递归 compact
  • marble_origami 这类 context collapse 相关 source 会跳过
  • 某些 reactive compact / context collapse 开启时主动让位

这体现出 Anthropic 对“多个上下文治理机制互相踩踏”的防范意识。

microcompact 清的不是消息,而是高成本工具结果

src/services/compact/microCompact.ts 定义了 COMPACTABLE_TOOLS,包括:

  • Read
  • shell 工具
  • Grep
  • Glob
  • WebSearch
  • WebFetch
  • Edit
  • Write

其目标不是总结历史,而是删除或替换这些工具产生的高 token 成本内容,例如旧 tool result。这里的治理更像“局部垃圾回收”。

session memory compact 解决什么问题

src/services/compact/sessionMemoryCompact.ts 明确:

  • 先检查 feature gate
  • 等待 session memory extraction 完成
  • 如果有 lastSummarizedMessageId,只保留之后的消息
  • resumed session 时,即使不知道明确边界,也可把 session memory 作为摘要源

它还会保证:

  • 不拆开 tool_use / tool_result
  • 保留最少 token 和最少文本消息数
  • 生成 compact boundary message

这说明 session memory compact 的重点是“保留工程语义 + 替换旧上下文”,而不只是把历史砍掉。

传统 compact 的职责

src/services/compact/compact.ts 负责更完整的总结流程,里面能确认:

  • 会先 strip image / document 等不必要内容
  • 可在 prompt-too-long 时通过 truncateHeadForPTLRetry() 丢弃最旧 API round
  • 会在 compact 后重建 plan attachment、plan mode attachment、skill attachment 等

这意味着 compact 后的历史不是“只剩一段总结”,而是“总结 + 必要附件 + 保留段”。

为什么 post-compact cleanup 很重要

无论是传统 compact 还是 session memory compact,最终都不是单纯返回 summary,而是要经过 post-compact cleanup,把运行时需要重新注入的状态接回去。否则上下文虽然省了 token,但 agent 会失去当前工作面。

这里体现出的设计哲学

如果和前面的 Agent 理念章节对照,这里能看到 Anthropic 对上下文治理的几条硬约束:

  • 先做局部清理,再做全局 compact。
  • 尽量避免不同治理机制互相冲突。
  • 压缩时必须维护 API 级别不变量,例如 tool_use/tool_result 配对。
  • compact 结果要能继续工作,而不是只可供人类阅读。

这一章的工作结论

Claude Code 的长会话管理依赖一套多层压缩系统:microcompact 清理高成本局部内容,auto compact 管阈值,session memory compact 与传统 compact 负责摘要替换,post-compact cleanup 则保证压缩后仍可继续执行。

延伸阅读