上下文工程:长项目里怎么管 token、防漂移
- 理解"上下文漂移"和"token 撑爆"的根本机制,不再把 AI 犯错归因于模型水平
- 掌握至少 5 种管 token 的实战手段,能在长项目里主动控制上下文窗口
- 用防漂移策略(CLAUDE.md、阶段性复述、plan 锁定)让 AI 在整个项目周期里记住关键约定
- 能按"长项目上下文管理 checklist"独立排查"AI 忘事、胡说、报 token 超限"这几类问题
项目刚开始的时候,AI 又快又准,感觉非常好用。然后项目渐渐大了——文件多了、需求迭代了、你们聊了几百条消息——某一天你发现:它开始"忘记"你们早先说好的东西,改出来的代码和项目规范越来越不搭,有时候直接绕开你们谈好的架构决策,甚至出现同一个问题反复犯的情况。
这不是 AI 变笨了。这是你的上下文没管好。
漂移和 token 爆炸:为什么会发生
要搞清楚机制,才能对症下药。
AI 编程工具(无论是 Claude Code 还是其他工具)的工作方式是:每次回复前,把"上下文窗口"里的内容全部喂给模型,然后生成下一条回复。上下文窗口就像一张纸,你和 AI 的所有对话、系统提示、它读进来的文件,都写在这张纸上。
问题是这张纸有大小上限——这就是"token 上下文窗口"。超过上限,要么报错,要么工具自动把早期的内容截掉。
漂移发生在截掉之前:窗口虽然没超限,但随着对话积累,早期的关键约定(你们谈好的架构原则、技术栈决策、代码风格要求)被后续大量内容"稀释"了——它们还在窗口里,但离得越来越远,模型对它们的"注意力"越来越低。你会看到两种症状:
- 忘记早期约定:它用了你们说好不用的库,或者用 JS 写了本来说好用 TS 的文件。
- 越聊越偏:需求理解开始和你的实际意图偏离,每条回复都在"纠偏"上浪费精力。
token 爆炸则是更直接的问题:会话越来越长,上下文窗口被大量中间结果、重复解释、无关消息填满,最终要么报"context length exceeded",要么工具自动截断,导致 AI 突然"失忆"——它不知道发生了什么。
明白了机制,解法就清楚了:要么缩小窗口、要么把关键信息从"对话"搬到"持久存储"。
管 token 的实战手段
1. 及时 /clear,重开一个干净会话
这是最直接的手段。Claude Code 的 /clear 命令会清空当前会话的上下文,回到一张白纸。
什么时候 /clear:
- 一个子任务完成了(比如改完一个模块、解决了一个 bug),进入下一个不相关的任务之前。
- 感觉 AI 开始绕弯子、复述大量无关信息。
- 对话长度已经超过 50-100 轮(经验值,视任务复杂度调整)。
很多人舍不得 /clear,觉得"这些对话里有用的东西"。但大多数时候那些"有用的东西"应该被写成文档或规则文件(见下文),而不是靠对话历史传递。
2. 用子代理隔离上下文
Claude Code 支持启动子代理(subagent)来处理相对独立的任务。子代理有自己独立的上下文窗口,任务完成后上下文自动释放,不会污染主会话。
适合用子代理的场景:
- 一次性的分析任务("帮我分析这个文件里有没有 SQL 注入风险")。
- 大量文件读取(让子代理读完汇总结果,而不是把几十个文件内容全堆进主会话)。
- 并行的独立子任务(同时让多个子代理处理不同模块,主会话只汇总结果)。
口诀:独立任务交给子代理,主会话留给决策和协调。
3. 把稳定知识沉淀到规则文件
这是最容易被忽视、但效益最高的手段。
你们在对话里谈好的"这个项目用 Tailwind 不用 styled-components"、"数据库操作必须走 repository 层"、"错误信息统一用中文"——这些是稳定的约定,不应该每次开新会话都重新交代。
把它们写进 CLAUDE.md(项目记忆文件)。Claude Code 每次启动都会自动读取项目根目录的 CLAUDE.md,相当于"永久上下文"。
稳定知识 → CLAUDE.md,对话上下文里就可以不重复了,窗口节省出来放真正动态的内容。
4. 分段任务,不要一次喂太多
一次性给 AI "帮我把整个订单模块重构成微服务架构,同时把接口文档也更新一下,顺便把旧的单元测试都改过来" —— 这种任务不是不能做,但它会让上下文膨胀得很快,而且出错了很难定位。
更好的方式:把大任务拆成有顺序的子任务,每个子任务完成后确认、提 commit,再开下一个。这样每段对话的上下文是干净的,出问题也知道是哪一步出的。
5. 压缩历史,主动清理无用轮次
如果你不想 /clear 掉整个会话,可以让 AI 帮你做一次"总结提炼":
> 把我们这段对话里所有的关键决策和还没解决的问题列出来
把输出的内容复制出来,/clear 掉当前会话,然后用这份提炼过的摘要重新开始对话。这样新会话的起点是"精华"而不是"流水账"。
防漂移实战手段
管 token 是"硬控制",防漂移是"软控制"——让 AI 在整个项目周期里始终记得"我们要做什么、怎么做"。
1. 关键约定写进 CLAUDE.md,不靠记忆
每次你们在对话里达成一个影响整个项目的决策,立刻把它沉淀进 CLAUDE.md:
## 技术约定
- 状态管理用 Zustand,禁用 Redux
- API 请求统一走 src/lib/api.ts,不允许在组件里直接 fetch
- 所有错误日志必须包含 traceId
## 代码风格
- 函数命名用动词开头:getUser / fetchOrder / validateInput
- 禁止 any 类型,需要泛型时明确写出类型参数
关于 CLAUDE.md 的写法和结构,4.2 节有详细说明。
2. 阶段性复述目标
在一个长任务的中途(比如改了 5-6 个文件之后),主动让 AI 复述一下它的理解:
> 到目前为止,我们这个功能的目标是什么,还有哪些步骤没做?
如果它的复述和你的预期有出入,现在纠偏比等到最后发现整体跑偏成本低得多。这就像长途开车每隔一段确认一下方向,而不是到了终点才发现走错了。
3. 用 plan 锁定方案,实施前先确认
SDD(规范驱动开发) 的核心思路:在动手写代码前,先让 AI 生成详细的实施计划,你确认计划没问题再执行。
> 先给我一个实施方案,不要直接动手,我确认后再执行
plan 本身就是一份"对齐文档"——AI 写下来,你读一遍,有分歧就在这里消除,而不是实施到一半才发现方向不对。这不只是防漂移,也是防止 AI 擅自做"超出需求"的改动。
和 3.1"喂上下文"的区别
3.1 节讲的是"怎么把上下文喂准"——在单次对话里,如何把背景、约束、格式要求清楚地传达给 AI,让第一条回复就对准目标。
本节讲的是长期管理:当你和 AI 合作的时间跨度是"一个功能迭代"或"几周的项目"时,如何保证上下文不膨胀、不漂移、不丢失关键信息。
两者不矛盾,是不同粒度的问题:3.1 是"怎么开好一局",本节是"怎么赢下整盘棋"。
长项目上下文管理 Checklist
每次开始一个需要多天持续开发的任务时,过一遍这个清单:
项目启动前
- CLAUDE.md 里有没有记录这个项目的技术栈、代码规范、关键约定
- 这次任务的目标是否清晰写成了一段 spec 或 plan
- 如果是接着上次的进度,新会话开始时是否用摘要重建了上下文
开发过程中
- 每个子任务完成后是否提了 commit(便于上下文清理)
- 上下文窗口是否开始臃肿(感受标志:AI 的回复开始大量复述历史、绕弯子)
- 是否有新的技术决策需要沉淀进 CLAUDE.md
- 有没有"顺手"让 AI 帮你把中途达成的约定补充进规则文件
感觉漂了的时候
- 让 AI 复述一下当前任务目标和进度
- 确认复述和自己的理解是否一致,不一致立刻纠偏
- 如果已经严重跑偏,考虑 /clear + 摘要重建,比继续纠偏更高效
任务收尾时
- 把这次任务新增的约定同步进 CLAUDE.md
- 检查一遍 CLAUDE.md 是否有过时的内容需要更新或删除
故障排查表
| 症状 | 根本原因 | 处理方法 |
|---|---|---|
| 它忘了早先约定的架构规范 | 关键约定只存在对话里,窗口积累后被稀释 | 把约定写进 CLAUDE.md,每次启动自动生效 |
| token 超限报错 / 上下文截断 | 会话过长、大量文件内容堆进了主会话 | /clear 重开,用摘要重建上下文;大文件读取改用子代理 |
| 它改的代码和项目风格越来越不搭 | 漂移:窗口里的规范信息被后续内容稀释 | 阶段性复述 + CLAUDE.md 补齐遗漏约定 |
| 一个功能改了很久,越改越复杂 | 没有 plan 阶段,边改边想,目标发散 | 下次先 plan 再实施;当前先复述目标重新对齐 |
| 子任务完成后开始下一个,AI 带着前任务的"残留想法" | 没有及时 /clear 隔离上下文 | 子任务完成提 commit 后 /clear,新任务从干净状态开始 |
常见问题
Q:CLAUDE.md 能写多长,会不会反而浪费 token?
CLAUDE.md 的内容会在每次启动时加入上下文,所以不建议把它写成流水账。原则是:只写稳定的、全局生效的约定,越精炼越好。临时性的任务说明不要放进去,放进去反而是噪声。一般几十到两百行以内就足够覆盖大多数项目需求。
Q:/clear 之后,我们谈好的东西就真的全消失了吗?
如果你没有把关键约定写进 CLAUDE.md 或者其他持久化的地方,那就真的消失了。这就是为什么强调"稳定知识沉淀到规则文件"——对话是临时的,文件是持久的。
Q:怎么判断"现在该 /clear 了"?
几个信号:AI 开始大段复述你们说过的话;它的回复变长了但信息量没增加;你感觉每次对话都要花时间"重新对齐"。出现这些信号,基本上就是到该 /clear 的时候了。另一个硬指标:任务有了自然的完成节点(一个功能做完、一个 bug 修完),节点之间 /clear 是好习惯。
Q:子代理和直接开新会话有什么区别?
开新会话是你手动换一个上下文;子代理是 Claude Code 自动管理的隔离环境,任务完成后上下文自动回收。子代理更适合在一个大任务里处理独立的子问题,不需要你手动切换。两者都是隔离上下文的手段,场景不同选不同的方式。
Q:plan 锁定方案和直接让 AI 动手有什么实质区别?
直接动手的话,AI 在"一边思考一边执行",中途可能悄悄改了你没注意到的东西。先出 plan 的话,所有要做的事提前摆在你面前,你有一次完整的确认机会。对于会修改多个文件、影响范围不确定的任务,先 plan 能大幅降低"改完才发现跑偏"的概率。
👉 看看我们的 AI 编程实战体系课,或逛 AI 编程教程大全 把基本功打扎实。