写代码的人对内存溢出都不陌生——程序直接崩给你看,干脆利落。上下文溢出就没这么痛快了。Claude Code 不会报错,也不会提醒你「上下文快满了」,它只是默默地开始给你越来越差的结果。回答变得啰嗦、跑偏、丢失之前说好的约束条件。你可能还在纳闷「怎么突然变笨了」,其实是上下文被撑满了。
我第一次踩这个坑是在做一个比较复杂的重构。前面十几轮对话都很顺畅,突然 Claude 开始重复之前已经讨论过的方案,还把我明确否掉的写法又拿出来了。当时百思不得其解,后来才意识到是上下文窗口的锅。
理解上下文最好的方式,是把它当成一种货币。你的上下文窗口总量是固定的,每一条消息、每一次文件读取都在花这笔「预算」。关键问题是:你花的每一分上下文,都带来了等价的收益吗?
最常见的浪费是什么?读取一个 500 行的文件,但你真正需要的只有其中 20 行。花了 500 行的成本,只得到 20 行的收益。乘以一次对话中反复出现的类似操作,浪费的上下文量是很可观的。
踩坑多了之后,我总结了五种最常见的上下文污染方式。如果你用 Claude Code 时偶尔觉得它「不太对劲」,大概率是踩中了其中一种。
历史堆积是最隐蔽的一种。对话进行了十五轮,前面那些已经不相关的讨论还占着空间。Claude 不得不在一大堆过时信息中寻找跟当前问题有关的内容,准确率自然下降。
过度读取很好理解——「帮我看一下整个 src 目录」。你觉得给 Claude 越多信息越好,实际上大量无关文件只会分散它的注意力。
重复信息经常出现在长对话中。同一个文件在不同轮次被读取了三次,每次都占一份上下文空间。
错误残留是调试过程中的常见问题。你尝试了好几种失败的方案,这些失败代码和报错信息都还留在上下文里,干扰 Claude 对正确方向的判断。
指令模糊则是间接污染——一个含糊的 prompt 往往引来一个冗长的回复,而冗长的回复又占据大量上下文,挤压后续有用信息的空间。
程序员管理内存有一套成熟的思路,同样的思路可以直接搬过来用。
惰性加载:需要什么才读什么,别一上来就把整个目录灌进去。你可以先告诉 Claude 你要做什么,让它告诉你需要看哪些文件,然后再针对性地读取。
及时释放:一件事做完了就开新对话。旧对话里的上下文会被释放,新对话从一个干净的状态开始。
按需引用:别说「看一下 auth 模块」,而是说「看 src/auth/service.ts 的第 45-80 行」。精确到文件名、行号甚至函数名,Claude 只需要读取真正相关的部分。
压缩存储:对话进行了一阵子之后,用 /compact 让 Claude 压缩历史信息。相当于做了一次垃圾回收,把过时信息清理掉。
我的经验是,把一次对话想象成一次函数调用:有明确的输入,有处理过程,有输出。做完一件事就 return,不要让状态无限累积。这个心智模型能帮你自然而然地避开大部分上下文问题。
每周更新 Claude Code 实战技巧、工具对比、行业动态。回复「模板」获取 CLAUDE.md 模板合集。