跳转到内容

上下文工程

官方 best-practices 反复强调一句话:

Context is the most important resource.

不是模型、不是订阅档位——是上下文。这一篇把上下文当作一种工程对象来对待:它怎么退化、怎么管理、怎么监控、怎么扩容。社区作者 Eyad 把这套思路叫「上下文工程」。

如果 上下文管理 那篇是「操作手册」,这一篇就是「设计原理」——告诉你每条命令背后为什么这么用。

先把比喻立住:上下文 = 短期记忆

人脑的短期记忆容量极小——一串电话号码转头就忘,得靠笔记。Claude 的上下文窗口大得多(约 200K token),但本质一样:它是 Claude 此刻能「看见」的一切。读过的文件、跑过的命令、刚才的对话——全在这块短期记忆里。

塞满了会怎样?它会变笨。前面读过的代码它记不清了,刚定的方案它忘了,问它「你刚才说的那个函数叫啥」它会答错。这不是模型变弱了,是短期记忆溢出,信息被挤出去了。

社区作者 Eyad 在进阶系列里给了一个被广泛引用的经验数字:

上下文用到 45% 左右,性能开始退化。

注意——不是 95% 才退化,是 45%。95% 是 auto-compact 触发的红线,但红线之前很久,退化已经悄悄开始了。

这意味着什么?你不能等到 auto-compact 触发才管上下文。那时候 Claude 已经「笨」了半个会话了。高手的做法是:在 45% 之前主动管理,把上下文压力分摊出去。

怎么知道现在到几个 percent?看 /stats

/stats 显示当前会话的 token 使用情况——消耗了多少、还剩多少、auto-compact 触发过几次。

/stats

高手用 /stats 做的是反向优化策略

  • 看到某类操作特别烧 token?下次少做。
  • 看到 auto-compact 频繁触发?说明任务太大该拆。
  • 看到上下文消耗速度异常?检查是不是有冗余信息在反复传。

定期看一眼 /stats,能发现很多「原来这一步这么贵」的盲点。这是从「凭感觉用」走向「数据驱动用」的关键一步。

/compact 把当前对话压缩成一份摘要,保留关键信息、丢掉过程噪音。

裸用:

/compact

高阶用法是指定聚焦点

/compact 保留 test 输出和已改动的代码细节,丢掉探索过程的中间讨论

加一句 instructions,压缩就有的放矢——你告诉它「这些必须留,那些可以丢」,而不是赌它自己猜对。

更彻底的做法:把这种聚焦提示写进 CLAUDE.md,让每次 compact 都自动带上:

# Summary descriptions
When using compact, focus on test output and code changes.

这样 auto-compact 触发时,它都会默认保留测试输出和代码改动——你最在乎的两类信息。官方 best-practices 也是这么建议的。

/compact 是压缩,/clear推倒重来——把上下文归零,从白纸开始。

什么时候用 /clear

  • 一个任务做完了,要开下一个不相关的活。
  • 上下文已经被污染——聊歪了、信息乱了。
  • 想换完全不同的方向。
/clear

区别:compact 是「浓缩保留」,clear 是「清空重来」。任务之间用 clear,任务之内用 compact

Claude Code 有个保护机制:上下文用到 95% 时,auto-compact 自动触发,避免直接撞墙。

这个机制可以在 /config 里切换:

/config

一般保持开启就好——它是你的安全网。但记住:95% 触发已经太晚了(45% 就开始退化),auto-compact 是兜底,不是策略。主动管理才是策略。

上下文工程有一条容易被忽略的大腿:Skills 的渐进式披露

Skill 启动时只加载约 100 token 的元信息(名字 + 简介)——告诉 Claude「我有这个能力」。只有当 Claude 判断这个 Skill 匹配当前任务时,才加载完整的 Skill 内容(可能几千 token)。

这意味着 20 个 Skill 同时挂在项目里,启动成本只有约 2000 token,而不是 20 个完整 Skill 的总和。没被用到的 Skill 不占上下文——这就是渐进式披露的妙处。

这也是为什么 Skill 比把所有规则塞进 CLAUDE.md 强——CLAUDE.md 每次都全量加载,Skill 按需加载。详见 Skills 深入

另一条大腿:子代理的独立上下文

派一个子代理干活,它在独立上下文里跑——读多少文件、跑多少命令,都不污染主会话。干完之后只把摘要交回来,主会话只多了一份几百 token 的总结。

> 派 Explore 子代理通读 @src/ 目录,给我一份模块依赖图。
(子代理读了一万行代码,主会话只多了一份摘要)

这就是把上下文压力分流出去。重活脏活甩给子代理,主会话只装「决策」不装「过程」。

适合甩给子代理的活:通读代码库、跑全套测试并总结、审查一大片 diff。共同特征是「读很多、跑很久、但结论很简单」。详见 Subagents 深入

最后一条、也是最朴素的一条:任务太大就拆

一个会话塞不下的大重构,拆成多个会话——每个会话一个子目标,做完 compact 或 clear,再开下一个。这比硬塞进一个会话、靠 auto-compact 反复救场要稳得多。

参考 会话管理 的「一个功能一个会话」——本质就是把上下文压力分摊到多个会话里,每个会话的上下文都留有余量。

custom status line:实时监控上下文

Section titled “custom status line:实时监控上下文”

官方提供了 custom status line 能力,让你在状态栏里实时看到上下文使用情况——比如当前 token 数、剩余百分比、auto-compact 触发次数。

挂在状态栏,你不用主动跑 /stats,眼睛余光就能看到上下文水位——到 40% 就该考虑 compact 或甩子代理了,别等到 95%。

详见 状态栏 Status Line 和官方的 interactive context window walkthrough(交互式上下文窗口教程)——后者会带你一步步走完一遍「上下文怎么从空到满、什么时候该操作」的全流程。

把所有策略串起来看:

策略 何时用 解决什么
/compact [instructions] 任务内压缩 释放空间,保留关键信息
/clear 任务间清空 切换任务不串味
/stats 定期查看 反向优化策略
auto-compact 95% 兜底 防止撞墙
CLAUDE.md compact 聚焦提示 配一次 自动压缩有方向
Skills 渐进式披露 挂多个 Skill 启动成本低
Subagents 独立上下文 重活甩出去 主会话不被污染
拆分任务 大任务 分摊上下文压力
custom status line 实时监控 眼睛余光看水位

核心心法就一句:主动管理,不要等 auto-compact 救场。45% 就开始退化,95% 才触发——中间这 50 个百分点的性能损失,全靠你的主动管理避免。

会担心这些 compact、命令处理额外烧钱?官方和社区都测算过:背景 token(conversation summarization、command processing)通常每会话不到 $0.04

也就是说,compact 一次、清空一次、跑几个斜杠命令,这点开销相对于写代码本身几乎可以忽略。别为了省这点 token 而不去管理上下文——不管理导致上下文退化造成的损失,是这点 token 的几十倍。

上下文是 Claude 的「短期记忆」,是最重要的资源。Eyad 经验 45% 左右开始退化(远早于 95% auto-compact)。/compact 带聚焦点、/clear 任务间清空、/stats 反向优化、Skills 渐进式披露、Subagents 独立上下文、custom status line 实时监控、拆分任务分摊压力——主动管理,不要等 auto-compact 救场。背景 token 每会话不到 $0.04。


下一步,去看 常见反模式与避坑——上下文工程管不好会变成什么样,提前打预防针。🚀