使用 Agentic Coding 工具写代码的人,应该都见过同一个现象:项目根目录下的CLAUDE.md一直在变长。一开始它可能只有十几行,写着项目命令和基本规范;跑了两三周之后,它膨胀到几百行,再往后每次打开都能看到新追加的“关键说明”。这不是文档自律问题,而是 Agentic Coding 里一种非常典型的“灾难性记住”(Catastrophic Remembering):Agent 为了不忘记任何东西,把几乎所有信息都写进长期记忆,结果记忆本身成了新的负担。
这篇文章先解释CLAUDE.md为什么会无节制膨胀,再拆开“Catastrophic Remembering”是怎么发生的,最后给一套可以落地的维护流程和排查顺序。不管你是个人项目使用者,还是准备在团队里推行 Agent 编码,这套思路都适用。
1. 先搞清楚 CLAUDE.md 变大,到底说明发生了什么
1.1 它其实是 Agent 的“项目级永久记忆”
在 Agentic Coding 工作流里,CLAUDE.md通常放在项目根目录,作用是给 Agent 提供长期、稳定的项目背景。它可以包含启动命令、测试命令、代码风格、目录结构、已知问题、架构决策等信息。和普通聊天窗口里的短期上下文不同,它更像一份每轮任务开始前都会重新加载的“入职手册”。
这个文件的价值在于:它让 Agent 在下一次任务里不用重新摸索一遍项目。没有它,Agent 每次都要从零理解代码库;有了它,Agent 可以更快地进入状态,也更容易遵循项目约定。
但问题恰恰出在这里。因为它的更新成本很低,很多人在跑任务时看到 Agent 报错、又自己修好,就顺手把整个修复过程写进CLAUDE.md,希望“下次别再犯”。这种想法本身没问题,问题是写多了以后,文件会变成一个大杂烩。
1.2 “灾难性记住”不是记性好,而是优先级坏了
“灾难性记住”这个词,可以对照机器学习里的“灾难性遗忘”来理解。
灾难性遗忘是说模型学了新任务后,把旧任务忘了。Catastrophic Remembering 则是反过来的现象:Agent 对过去的每条信息都保留,旧规则和新规则同时存在,信息之间互相冲突,最终导致它在关键决策上变得不稳定。它不是“记得不够”,而是“记得太杂、太满、没有优先级”。
CLAUDE.md里的信息最终会被 Agent 作为上下文读取。文件越长,每次任务携带的固定上下文就越长,留给真正代码分析的 token 空间就越少。更麻烦的是,当文件里出现互相矛盾的描述时,Agent 可能选择最新一条,也可能选择表达更详细的一条,行为就变得难以预测。
我见过一个典型场景:CLAUDE.md里前 20 行写“所有新功能都要跑完整测试”,后面 300 行记录了一次临时调试时用过的“跳过测试直接验证”的快捷方式。结果 Agent 在正式任务里有时会跳过测试,理由就是“根据 CLAUDE.md 的备注”。这就是灾难性记住的典型表现:旧信息没有淘汰,临时方法被当成了长期规则。
所以,CLAUDE.md越长,并不代表 Agent 越懂项目。很多时候它只代表项目里发生过很多事,但那些事没有经过整理。
2. CLAUDE.md 持续膨胀的三个来源
2.1 Agent 把每一次工具执行结果都当成了经验
Agent 编码过程中会大量执行命令、读日志、看报错、修文件。有些工具会把这些过程中的“发现”自动追加到记忆文件里,或者由使用者手动补充。
最常见的追加内容是这类:
- 某次启动报错,原因是环境变量没配。
- 某次测试失败,原因是端口被占用。
- 某次构建失败,原因是缓存过期。
- 某次调用接口返回 500,原因是服务没启动。
这些信息在发生当下是有价值的。但如果每次都原样写进CLAUDE.md,文件就会被大量“一次性日志”填满。真正稳定的规则,比如“测试前先启动 mock 服务”,反而被淹没在大量偶然信息里。
这里需要区分两个概念:经验和日志。经验是经过抽象之后仍然成立的规则;日志是某个时间点的过程记录。CLAUDE.md应该收录经验,而不是日志。
2.2 项目规范、历史决定、临时排查混杂在一起
很多项目的CLAUDE.md不是一开始就设计好的,而是靠不断追加长出来的。
前几行可能是“项目简介”,接着是一段“依赖安装说明”,再后面是“测试命令”,然后是某次重构后的“新目录说明”,中间还夹着“如果遇到 xx 问题,试一下 xx”。这种没有分区的文件,Agent 读起来很吃力,人也很难维护。
更严重的是,旧规范可能已经失效,但没人删除。比如项目从 Webpack 迁移到 Vite 之后,CLAUDE.md里还留着“启动前先清理 webpack 缓存”的说明。Agent 每次都会读到它,但这条信息已经没有任何意义,甚至可能诱导 Agent 去做多余操作。
历史决定不是不能记录,而是应该放在独立的决策记录里,不要让长期规范文档承载所有历史。
2.3 缺少删除机制,只增不减
CLAUDE.md膨胀的另一个原因是:几乎没有人为它设置“保质期”。
日常开发中,代码有 code review,依赖有升级检查,唯独记忆文件很少有人主动清理。新增一条很容易,删除一条却需要判断“它还有没有用”。因为判断难,很多人干脆全留着。
结果就是,文件只会单向增长。今天加一条“注意端口”,明天加一条“注意权限”,后天加一条“注意超时时间”,一个月以后 Agent 每次启动都要读一份庞大的规则清单。真正好用的记忆文件,不是只增不减,而是要像代码一样有迭代、有废弃、有清理。
注意:如果你的
CLAUDE.md已经连续几周只增不减,那它大概率已经从“项目记忆”变成了“项目日记”。
3. 好用的 CLAUDE.md,应该先有分类和分层
3.1 推荐结构:稳定区、动态区、变更记录
解决膨胀,第一步不是删内容,而是给内容分区。把不同稳定性的信息放在不同区块,Agent 读取时会更清楚优先级,人维护时也更容易找到问题。
一个建议的最小结构长这样:
# 项目记忆 ## 1. 项目一句话简介 这里写清楚项目是什么、给谁用、技术栈大概有哪些。 ## 2. 高频命令 所有新成员和 Agent 都需要频繁使用的命令: - 安装依赖:pnpm install - 启动开发:pnpm dev - 运行测试:pnpm test - 代码检查:pnpm lint ## 3. 长期规范 这些规则要求 Agent 每次任务都必须遵守: - 修改接口时同步更新 openapi.yaml - 提交前必须跑通 lint 和 test - 新增依赖需要先确认是否已有替代方案 ## 4. 已知问题和规避方式 只写那些真实出现过、且未来很可能再遇到的问题: - 本地端口 5173 可能被占用,启动前检查 - 旧的构建缓存可能干扰产物,必要时执行 pnpm build:clean ## 5. 变更记录 记录这个文件本身的重要变更,方便回溯。 - 2025-06-01:新增已知问题中端口占用检查规则 - 2025-05-28:删除 Vite 迁移前的 webpack 缓存说明这个结构的关键不是格式好看,而是把稳定信息和临时信息隔开。
稳定区负责约束 Agent 的长期行为,动态区负责处理可能变化的信息,变更记录负责追溯文件自己怎么长大的。这样,即使文件变长,Agent 也能快速识别哪部分更重要。
3.2 区分“约定”和“过程信息”
CLAUDE.md里只有一部分内容值得长期保留。可以用一个简单的表来判断:
| 内容类型 | 例子 | 是否适合写入 CLAUDE.md |
|---|---|---|
| 长期约定 | 测试命令、代码风格、提交规范 | 适合 |
| 架构决策 | 为什么选择某个方案、目录结构 | 适合,但要简洁 |
| 可复现的坑 | 某个端口冲突、某个已知依赖问题 | 适合,写规避方法 |
| 临时报错 | 这次启动遇到某行报错,重启后好了 | 不适合 |
| 调试日志 | 具体堆栈信息、当前环境变量内容 | 不适合 |
| 个人偏好 | “我喜欢用双引号”“我讨厌长函数名” | 可以写,但要压缩成规则 |
| 历史未决问题 | 某个模块可能有问题,但还没查 | 不建议,容易污染判断 |
判断标准很简单:这条信息能不能指导 Agent 的下一次行为?如果能,写成规则;如果不能,只是某次过程记录,就不要写进长期记忆。
4. 给记忆增补加道工序:新增前问三个问题
4.1 这条规则未来是否稳定?
很多内容当时看起来很重要,过几天就会失效。
比如“当前接口需要先登录才能访问”,这个状态可能很快变化。再比如“某次构建失败是因为 npm 源不稳定”,这是一个偶然事件,不是一个持续规则。写入之前先问:下个月再跑任务时,这条信息还成立吗?如果不确定,就不要写进去。
真正值得写的,是那种你已经踩过两次以上、并且换一个开发者也大概率会踩的坑。一次性的意外,不需要 Agent 永久记住。
4.2 是否已经被旧条目覆盖?
CLAUDE.md膨胀的一个根源是:规则更新时没有同步删旧规则,而是把新规则追加在后面。
举例来说,项目原本规定“测试文件放在 tests 目录”,后来重构为“使用 colocated 测试,测试文件放在源码目录下”。如果只追加新规则,不删除旧规则,Agent 每次读取都会遇到两套标准。它可能会按旧规则做事,也可能会按新规则做事,完全看上下文里谁更突出。
所以,追加之前应该先搜一遍文件里有没有类似表述。如果有,就改成覆盖更新:
<!-- 旧 --> 测试文件放在 tests 目录下 <!-- 新 --> 测试文件与被测文件放在同一目录,命名以 .test.ts 结尾覆盖不是简单删除,而是把旧规则替换成新规则,或者标注“已废弃”。这样文件长度不会无意义增长,Agent 的判断也会更一致。
4.3 如果不记录,最坏后果是什么?
这个问题能过滤掉大量“不写不踏实”的内容。
如果一条信息不记录,最坏后果是 Agent 下次多花 5 分钟排查,那可以接受。如果最坏后果是 Agent 会改坏生产配置、破坏接口协议、误删数据,那就必须记录,而且要放在醒目的位置。
优先级可以参考这个顺序:
- 影响数据安全、生产环境、回滚能力的规则:必须写,放在最前面。
- 影响团队协作和代码质量的规范:应该写。
- 影响单次调试效率的提示:选择性写。
- 只对某个历史版本有用的信息:不要写。
这样整理之后,CLAUDE.md的每一行都有明确责任,而不是靠数量堆出来的安全感。
4.4 自动追加能开,但一定要加一道 review
现在不少 Agentic Coding 工具支持自动把“学到的经验”写进记忆文件。这个功能方便,但如果不加审查,很容易让文件失控。
我建议的做法是:先把自动追加关掉,或者至少设置成“生成建议、人工确认”。跑完一轮任务之后,检查 Agent 准备追加的内容,问问自己:它刚才遇到的问题,是不是真实、稳定、可复现?如果是,再把精简后的版本手动写入。
如果你用的工具不支持关闭自动追加,那就在每次任务结束后主动看一遍CLAUDE.md的 diff。不要等项目变得非常卡顿、或者 Agent 频繁做出错误决定时才想起来检查。
建议:把
CLAUDE.md当成代码来管理。任何写入都要经过思考,任何改动都要能回溯。
5. 当 CLAUDE.md 已经膨胀到影响任务,怎么排查
5.1 先判断现象是“大文件”还是“失效记忆”
不是所有长文件都需要立即清理。先判断真正的问题是什么。
可能出现的现象:
- Agent 每次启动任务时行为不一致,同样的请求第一天能完成,第二天就不行。
- Agent 频繁在旧规则和新规则之间摇摆,代码风格一时一变。
- Agent 在处理代码时总是先花大量时间“复述记忆”,而不是直接进入任务。
- 每次调用费用涨了很多,因为固定上下文太长。
- 让 Agent 做一个小改动,它却搬出很多无关的旧规范来阻挠。
如果只是文件大,但 Agent 当前任务表现稳定,可以暂时不处理,放在下一次维护窗口里清理。如果已经出现行为不一致,就要立刻检查。
5.2 从文件历史里找出增长源头
如果项目用 Git 管理,可以直接看这个文件的变更历史:
git log --oneline -- CLAUDE.md这条命令可以列出CLAUDE.md的所有提交记录。然后再看最近几次改动具体加了什么:
git diff HEAD~5 -- CLAUDE.md对比之后,通常能很快找出增长最快的来源。我见过很多情况,最近两周的提交里只有两三条是真正值得记录的规则,其他都是临时调试信息的堆叠。
如果没有用 Git 管理,就想办法建立一个“维护基线”:先按照前面提到的结构整理一版,然后在这个基础上做后续变更。每一次变更都手动记录日期和原因,避免再次失控。
5.3 按优先级压缩,不要一次性全删
清理CLAUDE.md时最忌讳的是“一键清空”。清空之后,Agent 确实不会再被旧规则干扰,但它也可能忘记很多关键约束。
更稳妥的做法是按优先级分几步走:
- 保留最稳定、最影响安全的规则:部署命令、测试命令、数据操作规范。
- 合并重复规则:把多个位置出现的同类型说明合并成一条。
- 把历史决策移到独立文档:比如
docs/decisions/或docs/architecture.md。 - 删除一次性日志:比如“某次端口冲突”“某次缓存异常”。
- 在文件顶部加一句“只保留当前仍然有效的规则”,提示 Agent 不要恢复旧内容。
压缩完成后,用一两个典型任务做验证。比如找代理之前经常出错的核心流程,跑一遍看行为是否恢复正常。
5.4 常见误判:以为是模型不行,其实是记忆污染
排查 Agentic Coding 问题时,很容易把锅甩给模型能力。实际上,很多异常不是模型不够聪明,而是CLAUDE.md给了太多互相矛盾的引导。
看到 Agent 做错事,先不要急着换一个更大的模型或加大推理参数。先看它启动时读到了什么记忆,再判断这个错误是“理解不了”还是“被错误规则误导”。很多时候,删掉一条已经过时的旧规则,比增加任何提示词都管用。
6. 让 CLAUDE.md 停在“够用”,而不是“变得更多”
6.1 好用的标准,从“记住了多少”改成“少踩坑多少次”
“好用的 CLAUDE.md”不是一个越长越好的文档,也不是一个内容越全越好的项目手册。它的核心价值应该放在两个指标上:
- Agent 是否在重复犯同一个错误。
- Agent 是否能在更少的信息干扰下完成任务。
如果文件越来越长,但 Agent 仍然反复踩同一个坑,那说明它只是记得多,不是记得准。真正有效的记忆,应该能够减少重复劳动,而不是每次任务开始都要先消化一堆互相打架的规则。
6.2 不同项目规模下的维护节奏
个人项目、团队项目、长时间运行的 Agent 任务,维护节奏可以不一样。
- 个人项目:可以按周或按功能迭代来维护。每次项目结构有大的变更时,顺便看一眼
CLAUDE.md是否需要更新。 - 团队项目:把
CLAUDE.md的变更纳入 code review 流程。任何对项目规范的修改,都要有明确的理由和影响说明。 - 持续很久的 Agent 自动化任务:建议在任务配置里固定使用一个精简的规则集,不让运行过程中的临时发现自动污染主记忆文件。
这里的核心不是追求“完美维护”,而是让维护变成习惯。一个好的信号是:当你因为某个问题修改CLAUDE.md时,你知道为什么改,也知道旧内容会不会被新内容覆盖。
6.3 最后留几个我自己排查时优先会看的点
如果你现在正被CLAUDE.md膨胀困扰,我建议从下面几个方向入手:
- 先列出最近 10 次提交,看看有多少条是真正稳定的规则。
- 搜索文件里有没有重复出现的主题词,比如“端口”“缓存”“登录”“权限”。
- 检查顶部 30 行,看它们是不是文件里最重要、最该被 Agent 优先遵守的信息。
- 看看 Agent 在处理问题时,是否频繁引用文件后半段中的临时备注。
- 如果文件中出现过期技术栈、已经删除的目录、废弃命令,立即删除。
最危险的不是 Agent 忘记某个细节,而是它把一整份堆满规则、矛盾百出的记忆当作最高准则。与其让它什么都记住却无法一致地执行,不如给它一份精简、稳定、当前仍然有效的记忆。
CLAUDE.md的真正价值,不在于它记录了多少历史,而在于它能让 Agent 在下一次任务里少走多少弯路。