所属层级:第四层「Anthropic 在做什么」
建议前读:07. QueryEngine 与上下文 或 17. 系统提示词与模型决策
建议后读:21. 记忆系统
Anthropic 为什么把上下文治理做成一整套持续运行机制,而不是只在窗口满了以后做一次摘要?
Claude Code 的 compact 系统不是辅助功能,而是长期工程会话的生存机制;它的目标是让 agent 能持续工作,同时尽量不丢掉工程语义。
这一章解释 Claude Code 长会话为什么不会无限膨胀:什么时候触发 auto compact,microcompact 清什么,session memory compact 和传统 compact 各自负责什么。
- Anthropic 把上下文当成稀缺资源,而不是免费黑板。
- compact 不是单一路径,而是多层机制协同。
- 工具结果、历史消息、session memory 和附件会被区别对待。
- 上下文治理的目标不是“压缩成短摘要”,而是“继续工作而不失真”。
如果 agent 要长期做工程任务,它迟早会遇到两个问题:
- token 会不够
- 旧上下文虽然昂贵,但又不能随便丢
Claude Code 的 compact 设计明显是在解决这个矛盾:既要持续省上下文,又不能破坏 tool 调用、plan 信息、skills、session memory 这些真正还在起作用的材料。
Claude Code 不是只在超长上下文时做一次“总结旧消息”。当前快照里至少有四层治理:
- token 阈值驱动的 auto compact
- 对工具结果做局部清理的 microcompact
- 使用 session memory 的替代式 compact
- compact 后的 post-compact cleanup 与附件重建
Anthropic 明显把上下文压缩设计成持续运行时算法,而不是一条兜底命令。
- 自动 compact:src/services/compact/autoCompact.ts
- 传统 compact 主逻辑:src/services/compact/compact.ts
- microcompact:src/services/compact/microCompact.ts
- session memory compact:src/services/compact/sessionMemoryCompact.ts
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"]
src/services/compact/autoCompact.ts 里:
- 先按模型 context window 计算有效窗口
- 预留摘要输出 token
- 再减去 buffer,得到
autoCompactThreshold
同一文件还明确区分:
- warning threshold
- error threshold
- blocking limit
- manual compact buffer
这说明 compact 不是“超过上限再抢救”,而是带预警、阻塞和回旋空间的阈值系统。
shouldAutoCompact() 中有多种 guard:
session_memory/compactquery source 不再递归 compactmarble_origami这类 context collapse 相关 source 会跳过- 某些 reactive compact / context collapse 开启时主动让位
这体现出 Anthropic 对“多个上下文治理机制互相踩踏”的防范意识。
src/services/compact/microCompact.ts 定义了 COMPACTABLE_TOOLS,包括:
Read- shell 工具
GrepGlobWebSearchWebFetchEditWrite
其目标不是总结历史,而是删除或替换这些工具产生的高 token 成本内容,例如旧 tool result。这里的治理更像“局部垃圾回收”。
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 的重点是“保留工程语义 + 替换旧上下文”,而不只是把历史砍掉。
src/services/compact/compact.ts 负责更完整的总结流程,里面能确认:
- 会先 strip image / document 等不必要内容
- 可在 prompt-too-long 时通过
truncateHeadForPTLRetry()丢弃最旧 API round - 会在 compact 后重建 plan attachment、plan mode attachment、skill attachment 等
这意味着 compact 后的历史不是“只剩一段总结”,而是“总结 + 必要附件 + 保留段”。
无论是传统 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 则保证压缩后仍可继续执行。