AI 的记忆问题,不是忘记,是过时

给 Agent 加记忆,直觉是记得越多越好。但 Claude Code 和 Codex 自带的记忆,都在限制自己记什么、算不算数。顺着这些设计看,记忆真正的难点不是遗忘,而是过时。

给 Agent 加记忆,直觉是让它记得越多越好。

但是 Claude Code 的官方文档介绍自动记忆,花了不少篇幅讲哪些不记:能从代码里推出来的不记,架构、文件路径、修过的 bug 都不记;CLAUDE.md 里写过的也不记。OpenAI 的 Codex 也有类似的记忆功能,它的文档给记忆的定位是:只是一个辅助回忆的层,必须一直遵守的规则不能只靠它,要写进 AGENTS.md 或进仓库的文档。

两套记忆系统,都在限制自己记什么、算不算数。它们防的是什么?

01|失忆已经不是主要问题

模型本身没有跨会话的记忆。每个新会话都从空的上下文开始,上一次你纠正过的错、讲清楚的约定,到了下一次都不存在。早期用编程 Agent,常碰到这种事:昨天刚说过「legacy/ 目录别动」,今天新开一个会话,它又顺手改了里面的文件。

现在这种事少见了,主要靠三样东西:

  • 规则文件每次自动加载。CLAUDE.md、AGENTS.md、Cursor Rules 这类文件在会话开始时被读进来,约定写一次,以后每次都在。
  • 工具自带记忆。Claude Code 的 auto memory 会把你的纠正和偏好记成笔记,每条一个文件,再由一个索引文件在下次会话开头加载。Codex 打开记忆功能后,会在对话闲置一段时间后,把有用的内容整理成本地记忆文件。
  • 模型会自己读环境。看到 pnpm-lock.yaml 就知道用 pnpm,看到 .nvmrc 就知道 Node 版本。很多以前得靠人说的事,仓库里本来就写着。

02|记得住之后,问题变成过时

设想一个很普通的场景。

上个月,项目的登录用的是 session。这个月,登录模块整个重写,换成了 JWT。

如果记忆里有一条「登录用 session」,这句话并没有记错,它如实记录了上个月的事,只是已经不能指导今天的工作了。

一条记忆可以完全属实,却仍然是错误答案。

如果记忆只往里添,情况还会更糟。session 方案用了大半年,围绕它的讨论、改动、踩坑留下了很多条记录;JWT 方案才上线几周,只有几条。新会话里一出现和登录有关的问题,按相关度捞上来的大部分会是旧的。系统分得清新旧,架不住旧的数量多。

相似度能回答「这条和问题像不像」,回答不了「这条现在还算不算数」。

03|自带记忆在防什么

回头看 Claude Code 和 Codex 的记忆设计,几条限制都对着过时。

代码里有的,不记。 Claude Code 的文档写明,能从代码库推出来的东西不记,比如架构、文件路径、修过的 bug;CLAUDE.md 里已经写了的也不记。「登录用 JWT」写在代码里,记忆里就不该再有一份。两份记录迟早会分叉,代码改了,记忆不会跟着改。不记,就没有第二个会过时的副本。

还在进行的,不记。 Codex 会跳过正在进行或很短的会话,等对话闲置够久才生成记忆,文档给的理由是避免总结还没做完的工作。做到一半的结论最容易过时,干脆不让它进来。

索引有上限,过时的要清。 Claude Code 每次只加载记忆索引的前 200 行或 25KB。索引快到上限时,它会提醒模型精简:一条一行,细节挪进单独的文件,合并或删掉过时的条目。容量有限,记忆就不能只往里添。

纠正要附上原因。 翻开 Claude Code 写下的 feedback 类记忆,正文下面通常跟着两行:为什么(Why),以及怎么用(How to apply)。原因写在旁边,将来读到这条的模型就能判断:当初的理由还在不在?理由不在了,规则也就可以不守了。

这几条放在一起看,自带记忆一直在缩小自己的范围。它只收代码、git、文档、对话都装不下的东西,是个兜底的地方。

04|它管不到的地方

这套设计处理掉了大部分看得见的过时,剩下的是没有信号的那部分。

不记代码里有的,只能防住代码里有的。 一个文件还在不在,一查就知道;「legacy/ 目录别动」还算不算数,代码里没有答案。可记忆里留下来的,恰恰就是这类代码里看不出来的东西,它们过时了,没有东西能拿来核对。

没人通知的失效,没人处理。 记忆的更新要靠对话触发:你说了「登录改成 JWT 了」,它才会去改那一条。可现实里很多过时根本没人说出来。同事提交了一次重构,你 git pull 下来;依赖升级了。没有一句话告诉记忆「这条作废了」,它就不会动。一次改动还经常连带作废一片,「登出时要清 session cookie」和「登录改用 JWT」说法不像,却一起失效了。

读它的模型变了。 Claude Code 的作者 Boris Cherny 在今年 YC 的 Startup School 上给过一个建议:只是使用 Claude Code、不做 Agent 产品的人,每六个月把 CLAUDE.md、skills、hooks 都删掉,看看模型自己会怎么做。他提到 Opus 5 发布后,团队删掉了 Claude Code 大约 80% 的系统提示词,很多指令是为了纠正老模型的毛病写的,新模型不再需要。记忆里那些纠正也一样:你当初纠正的是旧模型的习惯,换了模型,这条可能已经从必要变成噪音。项目一行没改,规则也会过时。

它只在你一个人的机器上。 Claude Code 的记忆在 ~/.claude/projects/ 下,Codex 的在 ~/.codex/memories/ 下,都是本机文件,不进 git,没有 diff,同事看不到。它记错了、记偏了,你不去翻那个目录就不会知道。如果一条团队约定只存在某个人的记忆里,同事的 Agent 根本不知道有这回事。Codex 的文档也是这个意思。

最后这一点,是项目文档和记忆最根本的区别。文档的优势在位置:它和代码放在同一个仓库里,代码改了,同一次提交里就能改它;每一次改动都会留下一个看得见的 diff,会被人 review。Claude Code 的官方文档也建议定期检查 CLAUDE.md 和规则文件,删掉过时或互相冲突的指令,并且提供了 /doctor prompt-audit 命令,用来找出为旧模型写的指令、指向不存在的文件的引用,以及互相矛盾的规则。

文档也会过时。但它过时的时候,人看得见,也改得了。

05|按失效方式决定放在哪

这两套设计已经暗示了一种分工:一条信息放在哪,取决于它会怎么失效。

历史:永不过期。 上次的 bug 怎么解决的,当初为什么没选 Redis,某个方案讨论过哪些替代。这类信息的价值在于保留,旧的不该删。它最好的去处是 git 历史、PR 和设计记录,这也是 Claude Code 不把修过的 bug 记进记忆的原因。这一层是线索,不是规范。

当前状态:被取代时过期。 当前技术栈、当前架构、哪个目录不能动、提交信息用什么格式。这类问题只有一个正确答案,而且答案会变。属于整个团队的,写进仓库里的 CLAUDE.md、AGENTS.md,跟代码一起改、一起 review;只属于你个人的偏好,比如「以后都用 pnpm」,才交给记忆,而且要能被下一条偏好直接覆盖。

任务状态:任务结束就过期。 当前做到哪一步、待办清单、这次调试的临时结论。这类信息既不该进历史,也不该写进文档,留在对话和任务清单里就够了。Codex 不总结还没做完的会话,防的就是它。否则文档和记忆里会堆满「正在改 xx」「暂时先这样」之类的半截话,几周后没人知道它们还算不算数。

写入时,可以先问一句:这条信息会被什么取代?

  • 不会被取代,放进历史;
  • 下一次改动时会被取代,放进当前状态;
  • 任务结束就没用了,留在任务里。

这个问题在写下的那一刻最容易回答,因为那时候你知道它是什么。等到几百条记录混在一起、再靠相似度捞出来,同样的问题就只能交给模型去猜。

结尾

我们一直把 AI 的遗忘当成缺陷,所以第一反应是给它更多记忆。

可认真设计过的记忆系统给的答案正好反过来:少记,把为什么记清楚,能交给代码、git 和文档的都不放进记忆。

Agent 已经记得住了,麻烦在于记住的东西会过时。记忆库再大也解决不了这个,得先想清楚每条信息该放在哪里,什么时候该忘掉。

关于

关注我获取更多资讯

月球基地博客公众号二维码,扫码关注获取更多 AI 与编程资讯
📢 公众号
月球基地博客作者个人微信二维码,扫码交流 AI 与编程话题
💬 个人号
使用 Hugo 构建
主题 Stack 由 Jimmy 设计