跳到主要内容

Coding Agent 的记忆应该保存什么?

使用 Coding Agent 的时间长了,你会遇到一个很具体的烦恼:换一个工具,或者关掉会话重新开,就得重新解释一遍项目背景。你告诉 Claude Code "我们用 pnpm,不用 npm",告诉 Codex "这个目录下不要动测试文件",然后在 Antigravity 里又把同样的规则说了一遍。有时候你建了一个规则文件,几个月之后打开,发现里面有三条早就不适用的约束、两个已经改了名字的分支,以及一段当时用来调试某个 bug 的临时记录——全部都在。

这个状态的根本问题不是"记得太少",而是什么都混在一起了。


先回答那个问题

Coding Agent 的记忆应该保存什么? 答案不是"尽量多",也不是"只要稳定的东西"。

它需要保存四类彼此分离的信息,每一类的写入者、有效范围、载入方式和失效规则都不一样:

  1. 长期项目规则 ——包管理器、构建命令、代码规范、架构约束,保存在版本控制里,手动维护,每次会话自动加载。
  2. 当前任务状态 ——目标、负责人、阻塞、当前假设、下一步动作,任务存在期间有效,任务关闭时清理或归档。
  3. 按需检索的历史 ——过去的调试记录、决策理由,可能在未来某个时刻有用,但不应该每次都自动塞进上下文。
  4. 应该过期的临时上下文 ——探索性 Prompt、失败假设、原始日志、临时讨论脚手架,任务结束后应该自然消亡。

这四类信息需要不同的存储策略。如果你把它们全部放进同一个文件,或者不加区分地让 Agent 写入记忆,你得到的不是一个记性更好的 Agent,而是一个被杂音干扰的 Agent。


用一个具体任务来把这四层讲清楚

假设你正在修复一次登录回归问题。用户反映登录后会话偶发失效,复现率不高,但已经有若干条 issue 跟踪了。这是一个真实仓库里很常见的任务类型——影响面不小,但定位过程会产生大量探索性工作。

我们逐层来看这四类记忆在这个任务里的样子。


第一层:长期项目规则

这一层是 Agent 工作的基础设施约束,不因任务而变。

在登录回归这个任务里,长期规则包括:

  • 这个仓库用 pnpm,不用 npm
  • 认证模块在 packages/auth/,不要在其他地方引入 session 逻辑
  • 不要修改 *.test.ts 里的测试用例本身,只允许新增
  • CI 用 pnpm run test:unit 验证

谁可以写入? 人类开发者。这类规则涉及整个项目的约定,不应该由 Agent 自动修改,因为它们通常需要团队共识。

有效范围? 整个仓库,或者特定目录。Claude Code 的文档区分了两种机制:开发者手动维护的 CLAUDE.md,以及 Claude 可以写入的 auto memory。对于长期项目规则,CLAUDE.md 是更合适的位置——你希望它在版本控制里,可以被 review,可以和代码一起演进。OpenAI Codex 使用 AGENTS.md,支持从全局到项目路径的分层作用域,道理相同:不同目录可以有不同的指令层级,越靠近具体路径的规则优先级越高。

是每次自动载入,还是按需检索? 自动载入。这一层的价值就在于稳定性——你不应该每次会话都手动告知 Agent 这些基础约束。

什么事件会更新或让它失效? 技术栈迁移、架构重构、规范变更。更新行为应该是明确的人工决策,而不是 Agent 的自发写入。

最大的失败模式? 规则过时但没有人清理。六个月前加的"不要用 Lodash,我们正在迁移",迁移完成后这条规则留在文件里,Agent 就会一直遵守一条已经不需要的约束。规则腐化(rule rot)是这一层最常见的问题:文件越来越长,但没有人定期审计哪些条目已经失效。


第二层:当前任务状态

这一层记录的是"现在这个任务在什么状态"。

对于登录回归这个任务,任务状态可能是:

目标:定位会话偶发失效的根本原因并修复
负责人:有光
当前假设:JWT 刷新逻辑中存在竞争条件
阻塞:需要在 staging 环境复现,暂时无法访问 staging DB 日志
下一步动作:在本地 mock 中模拟并发刷新请求
完成证据:复现率降到零,相关集成测试通过

谁可以写入? Agent 和人类都可以,但人类应该有明确的编辑权限。Agent 可以在推进任务时更新"当前假设"和"下一步动作",人类负责确认"阻塞"和"完成证据"。

有效范围? 当前任务。这不是整个仓库的规则,而是这一次工作的状态快照。

是每次自动载入,还是按需检索? 在任务活跃期间,每次载入当前任务状态是合理的。但"当前任务"不等于"所有历史任务"——你不需要把三个月前修复的另一个 bug 的状态也带进来。

什么事件会更新或让它失效? 任务关闭。任务完成时,状态要么归档进可检索历史,要么删除。继续挂在那里只会制造噪声。

最大的失败模式? 任务状态和长期规则混在同一个文件里。当你把"当前假设:JWT 刷新逻辑有竞争条件"写进 CLAUDE.md,任务结束后你可能忘记删,Agent 下一次工作时会把它当成长期约束来遵守。

Beads 这个项目将自己描述为面向 Coding Agent 的依赖图任务系统和结构化持久记忆,它的设计思路在这一层很直观:把任务、阻塞和依赖关系结构化保存,而不是散落在自由格式的文本里。这是值得参考的方向,但我没有独立验证它的具体能力,也不在这里给所有读者推荐固定的工具组合。


第三层:按需检索的历史

历史不应该自动载入,但应该能被找到。

在登录回归这个任务里,你可能想起六个月前有人调查过类似的会话问题,当时留下了一段调试记录,最后是在 Redis 客户端的连接池配置里找到了问题。那次调试记录对现在可能有用——但只是"可能",而且只在你意识到相关性、主动去找的时候才有价值。

如果你让 Agent 每次都自动加载所有历史调试记录,上下文窗口会被大量不相关的信息占满,真正有用的信号会被稀释。

谁可以写入? Agent 运行过程中产生,人类可以标记哪些值得保留。

有效范围? 项目级,可以跨任务检索,但不按任务自动关联。

是每次自动载入,还是按需检索? 按需检索。你需要时才去找它,而不是它每次都出现在你面前。

什么事件会更新或让它失效? 技术栈大幅变化后,旧的调试记录可能整体失效,但这需要人工判断,很难完全自动化。

最大的失败模式? 没有索引,或者索引没有被维护。历史变成了一个你知道"里面有东西"但找不到的黑盒。

deja-vu 这个项目将自己描述为对历史 Agent 会话建立本地索引,通过 CLI 或 MCP 按需召回。这个设计直接对应了这一层的需求:不把历史塞进当前上下文,而是在需要时主动检索。我没有独立验证它的隐私保护、脱敏或安全性声明,引用它只是作为这种设计方向的一个例子。


第四层:应该过期的临时上下文

这一层是最容易被忽视的,也是最容易污染其他层的。

在登录回归调试过程中,你可能:

  • 把一段原始错误日志粘贴给 Agent,让它分析
  • 让 Agent 列出五种可能的原因,然后逐一排除
  • 临时告诉 Agent "先不管测试,只关注复现路径"
  • 记下一个当时觉得有用但最后证明是错误的假设

这些信息在对话进行时有价值,任务结束之后没有价值。如果它们被写进了某个持久存储,就会成为未来工作的噪声。

谁可以写入? 主要是对话本身。

有效范围? 单次任务,甚至单次会话。

是每次自动载入,还是按需检索? 都不是。它应该自然消亡——随着会话结束而结束。

什么事件会更新或让它失效? 任务关闭,或者会话结束。

最大的失败模式? 把临时信息误写进长期存储。Agent 有时候会主动写入记忆,如果你没有明确告诉它哪些信息可以持久化,它可能把"当前复现路径是在 Safari 下登录后立即刷新"这样的临时上下文写进 CLAUDE.md——而这个条件可能在修复完成后完全不再成立。

这也是 Anthropic 文档里对 auto memory 需要谨慎的地方:它是 Claude 可以自主写入的机制,但你需要知道它在写什么,而不是让它无限积累。


记忆保留矩阵

层次示例内容写入者自动载入失效触发主要风险
长期项目规则包管理器、构建命令、架构约束人类技术栈变更(人工决定)规则腐化,过时约束堆积
当前任务状态目标、阻塞、假设、下一步动作人类 + Agent✓(活跃任务)任务关闭任务内容混入长期规则
按需检索的历史过去调试记录、决策理由Agent 产出,人工标记✗(主动检索)技术栈大幅变更无索引或索引失维护
临时上下文原始日志、失败假设、探索 Prompt对话产生会话结束误写入持久存储

多 Agent 场景让这个问题更明显

在 Claude Code、Codex 和 Antigravity 之间切换工作时,我意识到"记忆"从来就不是一个统一的概念,而是之前我假装它是统一的。

每个工具有自己的会话边界。Anthropic 的文档说明得很清楚:每个 Claude Code 会话都从新的上下文窗口开始。这意味着你在上一次会话里和 Agent 谈过的所有事情,在下一次会话里都不存在——除非它被写进了 CLAUDE.md 或者 auto memory。

这个事实本身不是问题,问题是开发者的应对策略:把所有东西都写进一个记忆文件,然后期待 Agent 下次能从里面找到相关信息。结果就是那个文件越来越长,包含越来越多不同类型、不同新鲜度的内容,混合在一起,没有人知道哪些还有效,哪些已经过时。

不同工具换了一个新的视角来切入同一个问题:CLAUDE.mdAGENTS.md 的分层作用域设计,其实已经暗示了"范围越窄的规则应该越具体"这个方向。把全局约束放在全局文件里,把目录级别的特殊要求放在更接近那个目录的文件里——这是在空间维度上分层。但时间维度的分层还需要你自己来设计:哪些信息是永久的,哪些是临时的,哪些是需要时才召回的。


四层之外的一个元问题

设计记忆层次之后,还有一个问题需要回答:Agent 应该知道自己的记忆是怎么组织的吗?

我认为答案是"应该",而且越明确越好。在长期项目规则文件的开头写清楚:这个文件只放稳定的长期约束,任务状态放在哪里,历史检索用什么方式。这相当于给 Agent 一个记忆的元描述。

没有这个元描述,Agent 默认会把你给它的任何信息都当成潜在的长期约束来对待。有了它,Agent 对"什么应该被记住"有了更准确的理解,也更不容易把临时信息误写进错误的位置。

这不是一个复杂的操作。在 CLAUDE.md 的最开头加几行:

# 记忆架构说明
这个文件只包含长期项目规则。
当前任务状态请参考任务跟踪工具或 TASK.md。
历史调试记录需要时通过检索获取,不在此文件中保留。

这几行字会让 Agent 对文件的性质有更准确的预期,也会让你在审计时更容易发现越界的内容。


你现在可以做一件事

打开你项目的 CLAUDE.md(或者 AGENTS.md,或者你当前 Agent 工具使用的规则文件),对里面的每一个条目问三个问题:

  1. 这条信息是什么类型的? 是长期规则、任务状态、历史记录,还是临时上下文?
  2. 它现在还有效吗? 如果它涉及的技术、约定或任务已经结束,标记它或删除它。
  3. 它应该在这里吗? 如果它是任务状态或临时上下文,把它移出这个文件,或者直接删除。

这个审计不需要很长时间。通常几分钟就能找到几条过时的规则和几条混进来的任务信息。删掉它们之后,Agent 从这个文件里读到的每一条规则都是真实有效的,它就更容易信任这些规则,也更不容易被矛盾信息迷惑。

记忆不是越多越好。有效的记忆是在对的时间、对的范围内出现的对的信息——其余的,应该让它自然消失。


相关阅读


参考来源

注:本文的"长期规则、任务状态、可检索历史、临时上下文"四层模型是作者的综合判断,不是上述任何工具或文档的官方分类。