上下文管理实战:/compact、/clear 的时机与上下文经济学
把上下文当成仓库库容
做过仓储管理的都知道:仓库满了不是想办法堆更高,而是判断哪些货该清、哪些该存、哪些根本不该进库。上下文管理的思维完全一样——它不是"越大越好",而是"进什么、留什么、什么时候清"的决策艺术。
先复习一遍基础账本。上下文窗口里装着:系统指令、CLAUDE.md、自动记忆、对话历史、读过的文件内容、命令输出、已加载的技能。满了之后 Claude Code 自动压缩:先清旧工具输出,再把对话总结成摘要,你的原始需求和关键代码会保留,但早期的详细指令可能丢。
# 看当前的账单:谁占了多少
/context
# 带焦点的手动压缩
/compact 重点保留支付接口的重构方案和已确认的边界条件
# 换任务就清场
/clear
/compact:什么时候手动压
自动压缩的水位你管不着细节,但你可以抢在它前面。这三个时机值得手动压:
- 大任务开跑前。刚收完上一个任务,准备开始大的新任务,先
/compact 带焦点,把上一个任务压缩成几行结论,给新任务腾出干净空间; - 感觉它开始"忘事"。比如引用了你半小时前说的约束却记错细节——大概率压缩水位已过,早压早保真;
- 刚做完一堆探索。读了十几个文件、跑了一堆命令之后,这些"过程数据"的价值已经兑现完了,压掉不心疼。
压缩时带焦点指令是核心技巧,等于告诉它:"总结时保住这几件事。"不带焦点的压缩等于让一个实习生凭感觉整理你的会议纪要——重要结论可能被当成"细节"省略掉。
另外两个进阶玩法:/rewind 菜单里可以对部分对话做摘要(Summarize from here / Summarize up to here),不用整场压缩;/autocompact 500k 这类命令可以调整自动压缩的触发水位。
压缩机制深度拆解
既然压缩如此重要,值得知道它到底动了什么。压缩的工作方式是:把整段对话历史交给模型总结成结构化摘要,替换掉原始内容。不同内容的命运差异很大,我把官方对照表浓缩成三句话:
压缩后自动回来的(从磁盘重注入):项目根的 CLAUDE.md、自动记忆、系统提示与输出样式、计划模式写的计划文件。这些你完全不用操心。
压缩后按需回来的:子目录的 CLAUDE.md、带 paths 的规则——等 Claude 再碰到相关文件时重新加载。损失半拍,不丢功能。
压缩后真丢的:对话里只说过的指令(没进文件的)、大部分文件原文(最多重读五个最近修改的)、超长技能正文(有截断上限)。这一栏才是你需要经营的地方。
由此得出一个反直觉的结论:压缩不是要避免的灾难,而是要主动利用的工具。老手会在任务交接点上主动 /compact,用焦点指令把"值得留的"点名保留,而不是让自动压缩在随机的时刻做随机质量的总结。
大窗口模型与压缩水位
如果你的工作流天然需要塞很多内容(比如整个微服务联调),还有一条路:部分模型支持 1M token 的扩展上下文窗口,可在模型配置里选带 [1m] 标记的变体。窗口大了不等于不用管——压缩机制在更大窗口下工作方式相同,只是触发更晚。日常单任务场景,普通窗口加勤 /clear 通常比大窗口更省钱,因为上下文内容在每轮对话里都要被反复计价。
自动压缩的触发水位也可以调:/autocompact 500k 把触发点设在你指定的 token 数,/autocompact auto 恢复模型默认。想压得更早、留更多余量,就把数字调小。
/clear:什么时候清场
/clear 比 /compact 更彻底——对话直接归零(旧会话仍保存,可 /resume 找回)。判断标准就一条:新任务和旧对话还有没有关系。
| 情形 | 动作 |
|---|---|
| 修完 bug,开始写新功能 | /clear |
| 同一个 bug 的第二轮修复 | 别 clear,上下文还有用 |
| 讨论完方案,开始按方案实施 | 视情况:方案在计划文件里就 clear |
| 探索完代码库,开始改代码 | /compact,保住探索结论 |
| 切到完全无关的另一个仓库任务 | /clear,没悬念 |
新手最常见的问题恰恰相反——舍不得 clear。一个会话从早聊到晚,什么都塞在里面,结果后半程 Claude 的每一步都拖着前半程的包袱:慢、贵、而且容易混淆不同任务的上下文。会话不是续命池,是弹药匣,打完就换。
省上下文的五个工程手段
命令之外,还有结构性的省法。这五招是重度用户和普通用户的真正分水岭:
1. 文件内容是大头,用子代理消化。 让 Claude"用子代理调研 X",它会在自己的独立上下文里读文件,只把结论带回主会话。大文件深读、代码库广撒网,都该这么干。
2. 命令输出别直灌。 测试跑出几千行日志,让它重定向到文件,只读失败部分。tail -200 app.log 也要好过 cat app.log。
3. @ 引用有上限。 @src/utils/auth.js 这种引用会把文件内容直接带进对话(默认上限 25,000 token),大文件别 @,让它自己按需读。
4. CLAUDE.md 用路径规则瘦身。 上一章讲过 paths 作用域——不需要每会话都在场的指令别放全局。
5. 描述任务时给路径。 "退款逻辑在 src/payments/refund/"一句省它十次搜索。
一个真实工作日的上下文流水账
09:30 claude 启动,/init(若还没建过)
09:35 任务A:修购物车数量更新的 bug
10:40 修完。/compact 保留修法结论 → /clear
10:45 任务B:给订单模块写测试(子代理先调研现有测试风格)
12:00 写完,跑测试通过。/clear
13:30 任务C:大重构——结账流程
13:35 /plan 规划,批准后执行(计划文件压缩后自动重注入)
15:20 中途 /context 看了一眼:文件读取占 40%,让后续阅读走子代理
16:00 全部测试通过,/diff、/code-review,提交
注意每个任务的会话边界清清楚楚。一天下来上下文始终"轻装上阵",这也是同样的套餐额度,有人一天干三件事、有人干十件事的原因。
隐性消耗:三类容易被忽略的开销
前两节讲的是显性大户,还有三类隐性消耗,新手几乎都会中招:
第一类:重复携带的文件内容。 你让它读一个文件,内容进了对话就一直在。之后哪怕你们聊的是别的事,这段内容每轮都被捎带着。所以"读大文件"这个动作要有目的性——不确定值不值得读,先让它只读结构(函数签名、目录树)。
第二类:失败尝试的尸骸。 一次跑挂的测试、一段被否定的方案,都会留在历史里反复消耗。错误教训有价值,但 tenth 次重复携带就纯粹是浪费。失败多的时候主动压缩一次,告诉它"保留失败原因结论,过程细节可以丢"。
第三类:粘贴的巨块内容。 直接把两千行日志贴进输入框,是上下文管理的自杀行为。正确做法:落盘成文件,给 Claude 路径,让它按需读取需要的段落。
一个高效上下文的配置基线
把上下文管理落到配置层面,这份基线可以直接抄进新项目:
{
"cleanupPeriodDays": 30,
"env": {}
}
配套的目录约定:
.claude/
├── CLAUDE.md # 200 行以内的项目核心约定
├── rules/
│ ├── api.md # 带 paths 的接口规范,改 API 时才加载
│ └── migration.md # 带 paths 的迁移规范
└── skills/ # 流程类知识放这里,按需加载
上下文成本在三个载体间的分配逻辑是:每会话必须知道的进 CLAUDE.md;特定场景才需要的进带 paths 的 rules;多步骤流程进 skills。三层各司其职,/context 里看到的"内存文件"区块就会保持苗条。
另外记住 MCP 工具定义默认是延迟加载的(tool search 机制)——只有名字和说明占上下文,具体定义在 Claude 实际用到某个工具时才载入。所以装一堆 MCP 服务器不再像早期那样暴涨上下文,但用不上的服务器还是建议关掉。
排障速查
| 症状 | 诊断 | 处方 |
|---|---|---|
/context 显示爆仓 |
文件读太多 / 对话太长 | 压缩或清场,后续改用子代理 |
| 压缩后指令失效 | 指令只在对话里说过 | 移入 CLAUDE.md |
| 压缩后立刻又满 | 单文件或单输出太大 | 拆任务或子代理处理 |
| 新会话上下文就很高 | CLAUDE.md / 记忆 / 插件太多 | /context 逐项瘦身后重开会话 |
关于压缩后什么会保留、什么会丢,官方在上下文窗口文档里有完整的对照表。心法只有一句:上下文是你唯一需要主动经营的资源,别的都有默认值管着。
本章由 WorkBuddy 原创整理,事实性内容参考 Claude Code 官方文档。
