Feisky 让 AI 成为你的第二大脑

Claude Code

Claude Code 作者亲授:百万 token 上下文的正确用法

题记:本文基于 Claude Code 作者 Thariq 昨晚发布的长文《Using Claude Code: Session Management & 1M Context》编译整理,结合评论区的精华问答和个人使用经验,帮中文读者快速掌握上下文管理的核心策略。

Claude Code 升级到 100 万 token 上下文之后,我以为终于可以放飞自我了,一个 Session 从头用到尾,再也不用担心上下文不够用。

结果用了一段时间发现,情况没那么简单。上下文确实够大了,但有时候聊着聊着,Claude Code 的回答质量明显下滑,响应速度变慢不说,前面读过的文件细节开始记不清,甚至会重复做已经做过的事情。更让人困惑的是,有时候 compact 一下反而把关键信息给丢了。

这种体验应该不只我一个人有。昨晚 Claude Code 的作者 Thariq 专门写了一篇长文,系统讲了上下文管理这件事。

这里面有些东西是我之前没想清楚的,特别是 Rewind 和 Compact 的使用策略。再加上评论区 Thariq 亲自回复了不少细节,值得好好聊聊。

上下文腐烂:不是越多越好

上下文窗口越大,模型表现越好?不一定。

上下文窗口结构

Thariq 用了一个很形象的说法叫上下文腐烂。随着上下文增长,模型的注意力被分散到更多 token 上,老旧的、跟当前任务无关的内容开始干扰判断。100 万 token 的窗口,实际上在 30 万到 40 万 token 左右就可能开始出现性能下降。当然,Thariq 也强调这个数字跟任务类型强相关,不是一条硬线。

评论区有人分享了一个挺有意思的观察:同一个 Session 里始终聚焦一个主题深挖,即使对话很长,质量下降也不明显。但频繁跳转不同主题,腐烂来得很快。

这跟我自己的体感也吻合。做一个功能从头做到尾,体验挺好。做完功能接着改 bug、写文档、调配置?Claude Code 就开始犯迷糊了。

100 万上下文不是让你往里塞 100 万 token。它给你的是更大的操作空间,让你能跑更长的自主任务,但上下文质量仍然需要主动管理。

上下文腐烂与 Compact 过程

每一轮对话都是一个决策点

Thariq 文章里最让我觉得有启发的,是这个框架:Claude Code 每完成一轮操作后,你面前其实有五条路可以走。

最自然的当然是继续对话,在当前 Session 里接着发下一条消息。大多数人都是这么用的,包括我自己。

但继续对话意味着什么?所有之前的工具调用结果、读过的文件内容、尝试过的方案,全都留在上下文里。有用的,没用的,一锅炖。积累到一定程度,上下文就开始腐烂了。

另外四条路各有各的用法,下面逐个拆开聊。

/rewind(或者连按两次 Esc)可以回退到之前的某条消息,从那个点重新开始。回退点之后的所有消息都会被丢弃。这适合“试了一条路发现走不通”的场景。

/clear 是彻底开一个新 Session。你需要自己把关键上下文写下来带到新会话里,比如“我们在重构 auth 中间件,约束是 X,相关文件是 A 和 B,已经排除了 Y 方案”。费点功夫,但新 Session 的上下文完全由你决定。

/compact 让 Claude Code 总结当前对话,然后用总结替换掉原始对话历史。你不用动手写任何东西,但总结的质量取决于 Claude Code 自己的判断。

还有 Subagent,也就是让 Claude Code 起一个子 Agent 来处理下一段工作。子 Agent 有自己独立的上下文窗口,做完之后只把最终结果返回给主 Session。中间产生的大量工具调用和文件读取不会污染主上下文。

五种上下文管理策略对比

这五个选项不是互斥的,更像是一个工具箱。关键在于判断什么时候该用哪个。

新 Session 还是继续?

Thariq 给了一条简单的判断原则:新任务,新 Session。

但实际操作中有灰色地带。比如你刚实现完一个功能,接下来要给它写文档。按说是不同任务,应该新开 Session。但如果新开,Claude Code 得重新读一遍你刚写的那些文件,既慢又费 token。

Thariq 的建议是,这种情况可以继续用当前 Session。写文档对上下文的“智力要求”没那么高,多一些历史上下文的干扰问题不大,换来的是不用重新读文件的效率提升。

所以这儿不是看任务是否相关,而是看新任务对上下文质量的敏感度。调试、重构,这类需要精确理解代码逻辑的活儿,上下文干净很重要,值得新开。写文档、加注释?继续用就行。

不过话说回来,什么时候该新开 Session 只是上下文管理的一部分。更关键的问题是:方案试错了怎么办?

Rewind:最被低估的上下文管理操作

如果只能从这篇文章里记住一个技巧,Thariq 说应该是 Rewind。

场景是这样的:Claude Code 读了五个文件,试了一个方案,结果不行。这时候很多人的本能反应是继续发消息说“那个方案不行,试试 X 吧”。

问题在于,这条纠正消息虽然给了新方向,但之前那次失败尝试的所有中间过程,读文件的结果、错误的代码、报错信息,全都还留在上下文里。Claude Code 的注意力不得不穿越这些无用信息来理解你的新指令。

纠正 vs Rewind 对比

更好的做法是 Rewind 到 Claude Code 读完文件之后、开始尝试方案之前的那个点,然后重新给指令:“不要用方案 A,foo 模块没有暴露那个接口,直接用方案 B。”

失败的尝试从上下文里彻底消失了。Claude Code 拿到的是一个干净的起点,加上你从失败中提炼出的经验。

Thariq 还提到一个配套功能叫“summarize from here”,可以让 Claude Code 在回退前先总结它学到了什么,生成一条交接消息。有点像给过去的自己写一封信:“方案 A 走不通,foo 模块的接口不对,直接走方案 B。”然后 Rewind,把这封信贴到新的起点。

这里有个大家比较关心的问题:Rewind 之后,会不会导致 prompt cache miss?毕竟上下文变了,缓存可能失效,那延迟和成本都会上去。Thariq 直接回复说不会,Rewind 之后仍然是 cache hit。

这意味着 Rewind 几乎没有额外代价。免费的上下文清理,不用白不用。

Compact 用不好,问题出在哪

很多人用 /compact 的体验是玄学。有时候压缩完一切正常,有时候关键信息莫名其妙地丢了。

Thariq 解释了 bad compact 的根本原因:模型无法预测你接下来要做什么

举个例子,你花了很长时间在 debug 一个问题,中间偶然看到 bar.ts 里有个 warning。debug 结束后自动触发了 compact,Claude Code 总结了整个 debug 过程,但那个顺带看到的 warning 被判定为不重要,从总结里丢掉了。然后你下一条消息说“修一下 bar.ts 里那个 warning”,Claude Code 就懵了,因为它的上下文里已经没有这个信息了。

更糟糕的是,compact 触发的时机往往是在上下文快满的时候,恰恰是上下文腐烂最严重、模型最不清醒的时刻。也就是说,模型在最笨的时候,被要求做一个关键的总结决策,能够稳定才怪。

Compact vs Clear 对比

不过 100 万上下文带来了一个好处:你有更多的时间窗口来主动 compact,不用等到快满了才被动触发。

这里有一个很多人不知道的技巧:/compact 可以带参数。比如 /compact focus on the auth refactor, drop the test debugging,直接告诉 Claude Code 重点保留什么、可以丢掉什么。

总之,Compact 的正确用法不是等它自动触发,而是在阶段性工作完成后,带着明确的指令主动执行。

Compact 解决的是上下文太长怎么瘦身的问题。但还有一种情况:你明确知道接下来一段工作会产生大量中间输出,而你只要最终结论。这时候该怎么办?

用 Subagent 管理上下文

大多数教程把 Subagent 当并行执行或者任务委派来讲。Thariq 提了一个不同的角度:Subagent 本质上是一种上下文管理工具。

判断标准就一句话:你需要的是中间过程,还是最终结论?

如果你让 Claude Code 在另一个代码库里调研 auth 的实现方式,中间它可能读了二十个文件、试了好几种搜索,产生了大量的工具调用输出。但你真正需要的只是一份总结:“他们用了 JWT + refresh token,关键逻辑在 auth/middleware.ts 里,token 过期时间是 24 小时。”

Subagent 上下文隔离

如果这些中间过程留在主 Session 里,就是纯粹的上下文污染。用 Subagent 来做,中间过程封装在子 Agent 的独立上下文里,主 Session 只拿到最终的总结。

Thariq 给了几个典型场景。比如让 Subagent 根据 spec 文件验证你的实现是否符合要求,只返回“通过/不通过”和问题列表。或者让 Subagent 去读另一个代码库,总结 auth 是怎么实现的,然后你在主 Session 里按总结来写自己的。还有让 Subagent 根据 git 变更写文档,写完直接交付,中间读了多少文件、改了几版,主 Session 完全不需要知道。

共同特点就一个:中间过程产出量大,最终需要的信息量小。

Subagent 默认继承主 Agent 的模型,但你可以在 Agent tool 参数里用 model 字段覆盖,比如主任务跑 Opus,Subagent 用 Haiku 来省钱。不过实际用下来我发现一个有点尴尬的地方:Claude Code 自己就很爱起 Explore agent 来搜索代码,然后又提示你 subagent 使用量过高。自己制造开销自己报警,这个体验还有优化空间。

写在最后

看完 Thariq 这篇文章,最大的感受是:上下文管理这件事,其实跟程序员管理内存没什么本质区别。

100 万 token 像是一台内存超大的工作站。内存大了,能同时打开更多文件、跑更长的任务,但不管内存多大,working set 永远应该保持精简。

从 Claude Code 目前的工具链来看,Rewind 处理回退,Compact 处理压缩,Subagent 处理隔离,Auto Memory 处理跨 Session 的持久化,四件套基本覆盖了上下文管理的主要场景。Thariq 在文章最后也说了,未来 Claude Code 会更主动地帮你管理上下文,但现在这个阶段,理解这些机制比等待自动化更实际。

一个表格总结:

场景建议操作原因
同一个任务,上下文还有用继续对话窗口里的信息还在发挥作用,不用花代价重建
Claude Code 走错了方向/rewind(双击 Esc)保留有用的文件读取,丢掉失败的尝试,带着经验重新来
任务进行中,但堆了一堆过时的调试/探索记录/compact <提示>省事,Claude Code 自己决定保留什么。需要的话用提示引导
要开始一个全新的任务/clear零腐烂,你完全控制带什么进新 Session
下一步会产生大量中间输出,但你只需要结论(代码库搜索、验证、写文档)Subagent中间的工具调用噪音留在子 Agent 里,只有结果返回主 Session

养成 Rewind 的习惯,主动 /compact 带参数,中间过程多的任务扔给 Subagent。这三个动作做到位,大多数上下文问题就解决了。


相关资源


欢迎长按下面的二维码关注 Feisky 公众号,了解更多云原生和 AI 知识。

Feisky 公众号二维码

相关文章

目录

本页目录