压缩不是备份,是有损摘要:什么活得下来,什么会被丢掉

上下文压缩看起来像给对话做了个存档,其实是有损摘要。哪些信息能活过一次压缩、哪些会被静默丢弃,有一份完整的官方规则表。这篇把它逐条讲清楚,然后落成一套能直接抄的工程规范——核心结论是:把规则放在对的地方,比反复叮嘱模型有用。

会话跑了两小时,agent 一直很稳。你让它遵守的那条约束——「不要动 migrations 目录」,你在开头说过一次,它也确实没碰过。 然后它触发了自动压缩。压缩完成后,它开始改 migrations 目录里的文件。 你翻记录想找原因,发现终端里只有一行「Conversation compacted」,没有任何细节告诉你那条约束去哪了。

这个问题被问过太多次,以至于它已经成了一种民间玄学:有人说要反复强调,有人说要写进 system prompt,有人说压缩之后要重述一遍。

其实都不用猜。Anthropic 有一条完整的规则表,明确列了压缩之后哪些东西会被从磁盘重新注入、哪些会被摘要掉、哪些只剩一个路径引用。这篇就把它逐条摊开,然后落成工程规范。

先把上一篇的前提说清楚:压缩这件事本身是什么、协议层怎么设计的,在《compact 进协议了》里。这篇只回答一个更接地气的问题——压完之后,我的东西还在不在。

一、压缩到底做了什么

一句话:把对话历史换成一份摘要。

不是归档,不是快照,不是「压缩包可以解压回来」。原来的消息被摘要取代,从此不再存在于上下文里。按官方文档的说法,你会丢失「完整的工具输出和中间推理过程」——逐字的对话被摘要取代。

所以「压缩是不是可靠」这个问题问错了。正确的问题是:我不希望被压掉的东西,现在放在哪里?

二、官方那张表格:什么活下来

这张表是整件事的核心,逐条列了压缩之后各机制的存续情况。

内容压缩后会怎样
系统提示词、输出风格保留,继续生效
项目根 CLAUDE.md 和无作用域规则从磁盘重新注入
自动记忆(Auto memory / MEMORY.md)从磁盘重新注入,上限为前 200 行或 25KB,先到者为准
Plan 模式下 Claude 写的计划从磁盘重新注入
环境信息保留
Claude 读过或编辑过的文件重新读取最多 5 个,按最近修改优先
已调用 Skill 的主体重新注入,但每个 skill 上限 5,000 token、总计上限 25,000 token,超出时最旧的先被丢弃
后台命令、后台 subagent继续运行;Claude Code 会提醒 Claude 哪些还在跑,避免重复启动
匹配 compact 源的 SessionStart hooksClaude Code 会运行它们,输出加入压缩后的上下文
带 paths: frontmatter 的规则❌ 被摘要掉,直到 Claude 读到匹配的文件才重新加载
子目录里的嵌套 CLAUDE.md❌ 同上,读到该目录文件时才重载
Skill 描述列表❌ 不重新注入(只有你实际调用过的 skill 主体才会回来)
早期由 hooks 添加的上下文❌ 与对话其余部分一起被摘要
Agent SDK 用户会收到一条 subtype: "compact_boundary" 的系统消息,这是程序化感知压缩发生的唯一官方接口

三、真正会丢的是这四类东西

把上表里打叉的部分拎出来,会丢的就是这四类。它们有个共同点——都不是「对话内容」,而是「配置和产物」。

第一类:带 paths: 的模块级规则。 这是最反直觉的一条。很多人把规则按目录拆开写,paths: src/api/** 一个文件、paths: services/** 一个文件,以为这样加载更精准。结果是:它们在触发文件被读取时进入消息历史,压缩时就跟着被摘要掉了。官方给的建议很直接——想跨压缩活下来,去掉 paths: frontmatter,或者移到项目根 CLAUDE.md。

第二类:超过 5,000 token 的文件正文。 压缩后 Claude Code 会重读最多 5 个最近改动过的文件,但文件超过 5,000 token 时,回来的是路径引用而不是内容——界面上显示为 Referenced file 而不是 Read。所以「agent 明明读过这个文件,怎么又不知道了」的答案通常是:它读是读过,但文件太大,压缩后只剩一个指针。

第三类:Skill 主体被截断,而且截的是尾巴。 Skill 正文会重新注入,但有大技能时会截断以适配上限——截断保留文件开头。这条的工程含义非常具体:最重要的指令必须写在 SKILL.md 顶部。写在末尾的操作步骤、边界情况说明,一旦技能超过 5,000 token,就可能在压缩后消失。而且总预算 25,000 token 用完时,最旧的 skill 先被丢——一个会话里调了很多技能的话,最早那个已经不在了。

第四类:Skill 描述列表。 和其他启动内容不一样,这个列表压缩后不会重新注入。只有你真正调用过的技能,其主体才会被保留。所以「我配了二十个技能,它怎么都不用」——如果会话中途压过一次,它可能已经看不到那张技能清单了。

四、结论:位置比措辞重要

把上面这些串起来,会得到一条很实用的判断法:

能不能活过一次压缩,取决于信息放在哪,而不是你怎么措辞。

  • 写进项目根 CLAUDE.md → 每次重新注入,稳定活下来
  • 写进子目录规则文件 / 带 paths: 的规则 → 会被摘要掉
  • 说在对话里 → 会被摘要掉(而且是不可控地、有损地)
  • 写进磁盘上的文件,让 agent 需要时自己去读 → 不受压缩影响

这也解释了官方文档里那句看着像偏好的建议——「把持久规则放在 CLAUDE.md 里」——其实不是偏好,是架构约束。项目根 CLAUDE.md 是唯一保证每次都在的入口。

五、四条能直接抄的工程规范

1. 持久规则收敛到项目根 CLAUDE.md 单一入口。 别按目录拆。想在组织层面固化,就写进组织级 CLAUDE.md。这条听起来粗暴,但它是唯一可验证的承诺:其他位置你都得问「它还在不在上下文里」。

2. 在 CLAUDE.md 里加一段 Compact instructions。 这是主动引导摘要的办法。官方示例:

# Compact instructions
When you are using compact, please focus on test output and code changes

有个细节值得知道:这一段的小标题不是魔法字符串,叫什么名字都行,压缩器是按意图匹配的。也就是说你可以把「压缩时必须保留的东西」写成一段正常的中文说明,它会生效。这一条是把摘要的主导权从「让自动流程猜」拿回到自己手里。

3. 用 PreCompact hook 把完整转录归档下来。 压缩发生前会触发这个 hook,而且它带一个 trigger 字段告诉你是手动还是自动触发的。既然摘要必然有损,那就在压缩前把原始转录存一份——出了问题至少能查。这比事后猜「它为什么忘了」便宜得多。

4. 主动压缩,别等自动。 官方建议在开始一段漫长的新任务前,自己跑一次带焦点的压缩:

/compact focus on the auth bug fix

摘要会保留你指定的内容,而不是让自动流程去判断什么重要。同理,如果只是要丢掉一段跑偏的历史,用 /rewind 选中某条消息,然后选「Summarize from here」或「Summarize up to here」——这能让你只压一半。官方对「回退 + 摘要」这个组合的定位写得很妙:它相当于给上一个版本的自己留一条交接信息,把「这条路试过了不行」的经验递下去。

六、还有一件比压缩更早发生的事

最后说一个前提性的问题:等压缩触发的时候,往往已经晚了。

接下来这句需要标注来源——来自中文社区和第三方博客的实操反馈,不是官方结论:上下文占用到 20%–40% 的时候,输出质量就已经开始下滑,只是不明显。如果模型在压缩前就已经在退化,压缩并不会把质量救回来。

社区把这一组症状叫 context rot(上下文腐坏):重复犯同一个错、忘记早前定下的架构决策、反复重读同一个文件、回复变慢、旧信息权重过高、早期指令被忽略。这些症状出现的阈值,明显早于上下文窗口被填满。

所以真正的上下文卫生,不是「压缩之后怎么补救」,而是三件事:

  • 一个任务一个会话。 拿同一个会话先写认证系统再重构数据库层,上下文会互相污染。做完一件事就 /clear,CLAUDE.md 还在,项目背景没丢。
  • 把计划写进磁盘文件。 让 agent 把进度写进 plan.md 这类真实文件,明天回来让它读文件接着干——这比指望会话历史活下来可靠得多。
  • 大范围调研甩给 subagent。 subagent 有独立的上下文窗口,只把结果带回来。主会话的 token 预算省下来了,也就没那么容易触发压缩。官方在讲上下文管理时专门把这条列为推荐做法。

用 /context 定期看一眼当前占用,比等到质量掉下去再回头找原因,成本低得多。

七、和专栏前文的呼应

上一篇《compact 进协议了》讲的是协议层:压缩怎么变成一个可配置、可观测的 API 能力,以及那个会让你成本账算错的 usage.iterations 陷阱。

这篇讲的是同一件事的另一面——不管协议层做得多好,摘要依然是有损的。协议能帮你控制「什么时候压、压多少、钱花在哪」,但控制不了「哪条信息会消失」。后者只能靠你把信息放到对的位置上解决。

这也接着 harness 系列那条线。那几篇一直说「壳比模型值钱」——决定体验的是模型外面那层。上下文管理恰好是这层壳里最不显眼、但最容易出事的部分:权限、沙箱出问题你能立刻看到,上下文悄悄丢掉一条约束,你可能三天后才发现。

模型在变强,能替你兜住的东西在变多。但「什么信息必须活下来、把它放在哪」这件事,暂时还没有模型能替你决定。


信息源:Anthropic 官方文档《Explore the context window》(含「What survives compaction」规则表、v2.1.198 起的摘要继承 extended thinking 配置说明)、《Manage costs effectively》(Compact instructions 与自定义压缩指令)、《How the agent loop works》(PreCompact hook、compact_boundary 消息)、Claude Code 官方博客《Using Claude Code: session management and 1M context》(compact 与 clear 的分工、rewind-summarize 的定位)。第六章「20%–40% 即开始质量下滑」及 context rot 症状描述来自第三方社区实操反馈,非官方结论,请按此成色参考。