Claude Code 上下文管理与压缩机制详解
Claude Code 的上下文压缩不是单一策略,而是一套从最轻到最重的 5 环节组合拳。核心思路:能省事搞定,就绝不费劲。
背景:问题在哪?
- 默认上下文窗口:20 万 TOKEN
- 每轮发给模型的不只是当前消息,还有:系统说明、工具说明书、项目记忆文件、全部聊天记录
- 真实场景:几十轮对话下来,读文件/跑命令的结果能吃掉十几万 TOKEN
- 模型回答也要占地方,实际给聊天记录的只有 ~18 万
- 必须压缩
5 个核心压缩环节
按从省事(不计费、有损小)到费劲(计费、有损大)的顺序每次执行。
环节 1:工具结果预算
处理单条消息内容超限的情况。
- 从同一条消息中找到最大的文件/结果,把完整内容挪到硬盘,消息里只留缩略版开头
- 模型真要完整内容时再去读
- 决策冻结:某个结果第一次处理后(缩略版或完整版),之后都按此处理。——因为旧消息一个字都不能动,才能命中服务端缓存
环节 2:历史裁剪
把整轮对话整体删除。
- 适用:完全无用的轮次(如试错路径:给错路径→不对→再给→还不对)
- 铲完后计算腾出的空间,告知后续环节,避免误触发最重的完整压缩
环节 3:微压缩
专门清理读命令、跑命令、搜索、改文件产生的旧结果。
- 不处理:用户提问、模型思考/回复、用户反馈(这些不会变)
- 两条分支:
| 条件 | 做法 |
|---|---|
| 缓存还热(一直在聊) | 发编辑指令给服务端,指定从缓存里抹掉某些旧文件结果。消息内容一个字没改,缓存全命中 |
| 缓存已凉(离开很久) | 直接换占位符:“已清除”。留最近 5 条,最早的全替换 |
环节 4:上下文折叠
把旧的对话片段折叠成摘要存着,但按阶段保留关键上下文。
- 例:重构订单模块,翻文件阶段(~800行)压成摘要,但设计阶段和写代码阶段保留原文
- 折叠后腾出的空间够多,最重的完整压缩就不用执行了
环节 5:完整压缩
最重的一步,走完整流程:
生成总结 — 巧妙设计
- 分身 Agent:派一个分身去做总结
- 伪装请求:分身故意把请求内容伪装成跟主对话一模一样,只在最后偷偷加一句”请给我总结”
- 因为前面内容相同,缓存命中,大部分走缓存读取,节省一次完整计费
- 副作用控制:分身带了全套工具,可能手痒调用
- 只给一次机会,调工具就失败
- 提示词开头和结尾都放强硬指令:“只准说话不准动工具”
- 万一失败了,退回普通方式直接发(更贵但保证拿到结果)
九段式总结结构
| 段 | 内容 |
|---|---|
| 1 | 最初要干嘛(开头) |
| 2 | 用到的技术 |
| 3 | 动过的文件和代码 |
| 4 | 踩了什么坑、怎么填的 |
| 5 | 用户每句话的意思 |
| 6 | 还有哪些没做完 |
| 7 | 现在在做什么 |
| 8 | 下一步(一字不差引用用户原话) |
| 9 | 其他关键信息 |
第 8 段特别要求一字不差引用原话,防止模型在总结途中篡改用户意图。
重建现场
总结拿到后,系统需要恢复工作状态:
- 重新读取最近改动过的 最多 5 个文件的最新内容
- 还原计划、用过的技能
- 重新声明全套工具
- 拼接:分界标记 + 总结 + 新内容
- 如果是自动触发,还会偷偷加一句:“直接接着干,别打招呼、别复述,就当刚才啥都没发生过”
会话记忆 — 把压缩拆成日常笔记
在完整压缩启动前,先试一条更省事的办法:
- 会话提取器:后台一直运行,每有新内容就派个分身,把新增的要点记到笔记文件里
- 增量累积:每次只记上次到现在新增的小段,很便宜,在聊天间隙偷偷干
- 压缩时直接拿来用:省掉从头读几十万 TOKEN 的大工程,压缩瞬间完成
本质:把一次压缩大工作,拆成聊天间隙一次次小笔记,提前做完。
安全机制
- 自动压缩连续失败 3 次 → 本场对话不再自动尝试
- 曾出现过单场对话连续失败 3000+ 次的极端案例
关键设计哲学
| 角度 | 省事(优先) | 费劲(兜底) |
|---|---|---|
| 是否计费 | 本地操作,不计费 | 调模型,多计费 |
| 是否丢信息 | 轻损(文件挪硬盘,可恢复) | 重损(对话→总结,细节丢失) |