MemoryLake
返回全部文章
Tutorial2026 年 8 月 7 日·11 分钟阅读

为什么 Claude Code 会遗忘你的修正——以及如何解决它(2026 年)

“不对——运行那个之前一定要先 `cd backend/`。”它道了歉,正确地执行了,然后你继续。两个会话之后,它又从仓库根目录运行了相同的命令,构建静默无操作(no-op),而你已经是第五次输入相同的修正了。

直接的答案是:有两种不同的失败披着同一件外衣,它们需要不同的解决方法。大多数情况下,修正从未被写入任何持久的地方——你是在一个已经结束的对话中说出它的,所以它消失了。但有时它确实被写下来了,却仍然没有被执行,这是一个独立的问题:存储并不等于遵守。解决第一个问题很简单。解决第二个问题意味着要让重要的修正要么通过机械方式强制执行,要么在适用的那一刻保持简短且可检索——而不仅仅是存在于一个不断增长的文件中的某个地方。

本文将区分这两者,结合一个真实的报告案例来说明为什么这种区分至关重要,并坦诚地说明记忆层对哪些修正有所帮助,对哪些没有帮助。

为什么 Claude Code 会遗忘你的修正

修正通常从未被写下来

在聊天中输入的修正属于对话上下文。它塑造了该会话的其余部分,然后会话就结束了。Claude Code 会从你的文件(CLAUDE.md、仓库,或者你指向的任何内容)开始下一个会话——而你的修正并不在其中。

这是大多数情况,而且很寻常。这感觉就像遗忘了某个教训,因为你曾把它当作教学来体验。从机制上讲,什么都没有被保存。这与 Claude Code 在没有项目上下文的情况下启动每个会话背后的差距是一样的——该工具在设计上是无状态的,只有文件能连接不同的会话。

写下来并不等于被执行

以下是改变建议的部分,而且这是有文档记录的,而非道听途说。

2026 年 3 月 22 日,anthropics/claude-code 仓库中提交了一个名为 “Claude repeatedly fails to apply its own memory/feedback — same mistakes recur across sessions”(Claude 反复无法应用其自身的记忆/反馈——相同的错误在不同会话中重复出现)的 Issue。报告者的描述非常精准:“Claude Code 的记忆系统正确地存储了反馈和规则,但模型始终无法应用它们。尽管记忆文件已被多次更新(针对同一问题更新了 5 次以上),但同一类错误在不同会话中依然重复出现。”

他们的例子是每个人都能认出来的:

  • 记忆中写着在运行后端命令之前,始终 `cd` 到 `backend/`,以及在 `vite build` 之前始终 `cd` 到 `frontend/`。但命令仍然在错误的目录中运行,导致构建失败或静默无操作。
  • 记忆中写着在 `App.jsx` 更改后始终重新构建 `dist`,以及始终将 `public/` 文件复制到 `dist/`。但这些步骤被跳过了,提供的是过时的 bundle。
  • 记忆中写着未提交的更改在同步时会丢失。但文件仍然在没有提交的情况下被临时复制到生产环境,并且更改在下一次同步时被静默还原。
  • 上一个会话中的一个修复——将 marmot.svg 替换为 marmot.png——从未被提交,被还原了,不得不再次要求修复。

报告者的总结是值得记住的一句话:“记忆系统捕获了知识,但无法可靠地影响行为。” 他们称之为 Claude Code CLI(使用 Opus 4.6 和基于文件的记忆)上的“阿尔茨海默症问题”。

有两点需要明确。该 Issue 被关闭为“不计划解决”(not planned),因此这是一个用户报告,而不是被承认的缺陷。它证明了对于显而易见的结论来说有些棘手的事情:在这种情况下,添加更多存储空间是无济于事的。规则已经被存储了。整整五次。

漫长的会话会埋没你在开始时设定的规则

还有第三种机制,看起来像是在抗拒,其实不然。在漫长的会话中,早期的指令可能会脱离可靠的获取范围——对此进行过阐述的从业者将其描述得非常精准:模型并不是在忽略你在会话开头说的话,而是它已经无法清晰地看到它以进行检索。你一小时前给出的修正技术上存在于对话中,但实际上已经消失了。

这就是为什么同一个修正可以维持 20 分钟,却在第 90 分钟时烟消云散的原因,也是知识文件在会话变长时被挤出上下文背后的机制。

没有触发条件的修正只是琐碎的杂事

大多数修正是条件性的:部署时、运行后端命令之前、如果你修改了 App.jsx。写入一个不断增长的指令文件中,该条件作为模型必须注意到的散文体存在。并没有一种机制能在命令即将运行的那一刻,将“始终先 cd”浮现出来。

因此,失败不仅在于规则是否存在。而在于规则存在于一个与需要它的时刻毫无关联的地方。

人们尝试过的方法

将其添加到 `CLAUDE.md`。 这是正确的第一步,而且对于稳定、无条件的约定确实有效。它的局限性就是上面提到的那些:文件会增长,它是被整体加载的,埋在第 180 行的一行内容会与所有其他内容竞争注意力。#37314 报告就是这种方法的极端表现。

更强硬地重复修正。 全大写、“IMPORTANT:”、“NEVER”。效果微乎其微,而且无法扩展——一旦有六个规则在“大喊大叫”,就没有一个能得到强调。

在两次失败的修正后使用 `/clear`。 经验丰富的用户推荐的一种真实技巧:如果尝试两次后修正仍未生效,请清除会话,而不是积累一个充满失败的上下文。有效且直接——但你也会丢掉该会话中所有有用的内容。

使用 `/compact` 保持会话敏锐。 通过压缩对话来帮助解决长会话机制,以便模型可以继续。不过,压缩在定义上是有损的,因此它也可能是丢掉你修正的罪魁祸首。

将修正转化为代码。 被低估了,对于特定类别的修正,这简直就是正确的答案——下文将对此进行详细介绍。

一个供你复制粘贴的运行笔记文件。 有效是因为它是外部且持久的,但你成了检索系统,需要在每个会话中决定哪些修正是相关的并将其粘贴进去。

解决方法:让修正在关键时刻可被检索

首先将你的修正分成两堆。这是产生差异的关键步骤。

第一堆:可以机械化的修正。 “始终先 cdbackend/。”“修改 App.jsx 后始终重新构建 dist。”“部署前先提交。”GitHub Issue 中的每个例子都在这一堆中——对于这些,坦诚的建议不是使用记忆层。而是一个为你执行 cd 的 npm 脚本、一个重新构建的 Makefile 目标、一个 pre-commit 钩子、一个在未提交部署时报错的 CI 检查。一个智能体无法违反的规则,胜过一个它应该记住的规则,而且它也能保护未来的你。如果你从本文中只学到一件事,那就是这一点。

第二堆:无法机械化的修正。 “我们在适配器层中允许该模式,因为上游在失败时返回 200。”“客户在 3 月份拒绝了模态框方案。”“不要重构遗留的导入器,它将在第四季度被替换。”没有脚本可以强制执行判断。这些是需要写在持久地方、保持简短并在相关时浮现的内容——这也是外部记忆层发挥真正作用的地方:修正存在于任何单个会话之外,它在主题被提起时被检索,而不是在每次请求时都被加载,并且它保持足够简短,能够真正竞争注意力。

MemoryLake 就是为第二堆设计的——一个你的智能体可以通过 MCP 或 API 读取的存储库,保存你的工作所产生的决策和约束,而不是将它们累积在每周都在变长的指令文件中。

这个界限需要说清楚,因为 #37314 正是证明这一点的案例:记忆层并不保证模型会遵守。 智能体是否根据它读取的内容采取行动是模型行为,没有任何存储系统能控制这一点。改变的是可用性和形式——约束在相关的时刻是存在、最新且简短的,而不是完全缺失或埋在第 180 行。这是一个真正的改进,但不是保证。任何告诉你其他情况的人都在推销。

步骤 1:创建 API 密钥

生成密钥并在大约 30 秒内发出你的第一次请求。将其保存在你的环境变量或机密管理器中,而不是保存在你可能提交的配置文件中。

创建 MemoryLake API 密钥
创建 MemoryLake API 密钥

步骤 2:上传你的第一批记忆

放入保存你第二堆修正的文档、图像和文件:带有原因的决策文档、架构说明、“我们尝试过这个但失败了,因为……”的记录。上传源文件,而不是整洁的摘要——修正背后的原因通常是在摘要中被省略的部分,而原因正是阻止其被重新争论的关键。

上传你的第一批记忆到 MemoryLake
上传你的第一批记忆到 MemoryLake

步骤 3:连接你的 AI 和智能体

让 Claude、Codex、OpenClaw 和其他 AI 智能体通过 MCP 或 API 访问记忆。Claude Code 支持 MCP 服务器,因此这是一个配置项。然后,你的其他智能体也可以读取相同的存储库,这很重要,因为当你切换工具时,修正并不会失效。

通过 MCP 连接你的 AI 和智能体
通过 MCP 连接你的 AI 和智能体

这在实践中改变了什么

最直接的变化是你的 CLAUDE.md 不再增长。可机械化的规则变成了脚本和钩子;基于判断的修正移到了存储库中。剩下的是一个简短的现行规则文件,模型实际上可以关注它——这是解决注意力问题的方法,而不是绕过它的权宜之计。

第二个变化是,第五次重复不复存在。不是因为模型变得更听话了,而是因为这两类问题现在由适合它们的机制来处理:构建顺序的错误不可能发生,而判断性的决策是可检索的,而不是靠记忆的。

第三个变化是,修正以你可以审计的形式跨越了会话边界。当出现问题时,你只需编辑一条记录,而不是寻找你在哪里写过它——而且你可以看到修正是否曾被捕获,这通常就是答案。

而且它们在工具更迭中存活了下来。“不要重构遗留的导入器”在 Cursor 和 Codex 中同样适用。保存在 CLAUDE.md 中,它只是一个 Claude Code 的事实;保存在共享存储库中,它就是一个项目的事实——这也是为 Claude Code 添加记忆层往往比你本季度使用的任何智能体都更长寿的原因。

让修正持久生效的最佳实践

机械化任何可以机械化的内容

在写下修正之前,先问问脚本、钩子或 CI 检查是否可以让它无法出错。如果是,那就这样做。上面报告案例中的每个例子都是可以机械化的,而报告者更新了五次记忆,却没有添加一行 npm 脚本。这不是对他们的批评——这是整个工作流设置的陷阱,因为编写规则感觉就像编写代码一样。

写下触发条件,而不仅仅是指令

“数据库列使用 snake_case”很无力。“在 db/migrations/ 中添加迁移时,列名使用 snake_case——ORM 映射假定如此”给模型提供了一个可以识别的条件和一个不进行二次猜测的原因。指明触发条件的修正比仅陈述偏好的修正更容易存活。

特意保持始终加载的文件简短

CLAUDE.md 中的每一行都会在每个任务中加载,因此每一行都会在每次请求中消耗你的成本,并与所有其他行竞争注意力。将其视为稀缺资源:仅保留现行规则,上限设定为你自己愿意重新阅读的长度。其他所有内容都属于检索。一个 300 行的指令文件并不会比一个 60 行的文件有效五倍——而且长会话的注意力问题只会让情况变得更糟,而不是更好。

在两次失败的修正后停止并改变方法

如果一个修正尝试了两次都没有生效,第三次重复也解决不了问题。要么将其机械化,要么将其移入简短的可检索记录中,或者清除会话并重新开始。在一个已经充斥着该修正失败记录的上下文中重复修正,是所有可行选择中效果最差的一个。

在继续之前提交修复

该 Issue 中的 marmot.svg 案例值得深入思考:修正确实被应用了,但由于从未被提交而丢失了。有些“它忘了”实际上是“它从未在任何地方持久化”,这包括 git。

结论

Claude Code 遗忘你的修正有两个不同的原因,而且解决方法不能混用。通常,修正从未被写入任何持久的地方,因此无从记忆。有时——正如 2026 年 3 月关于 claude-code 仓库的一份报告所记录的那样,针对同一问题更新了五次或更多次记忆文件,报告者得出结论,记忆系统“捕获了知识,但无法可靠地影响行为”——它被写下来了,但仍然没有发生。

所以把它们分开。机械化脚本或钩子可以强制执行的内容,因为一个无法被违反的规则胜过一个必须被记住的规则。将基于判断的修正放入一个保持简短、最新且在适用时刻可检索的存储库中,并保持你始终加载的指令文件足够小,以便模型实际上可以关注它。这种结合可以处理这两种失败模式。单靠其中任何一种都无法做到。

常见问题

这是 Claude Code 的 Bug 吗?

并非官方承认的 Bug。2026 年 3 月 22 日描述记忆已存储但未应用的 Issue 被关闭为“不计划解决”(not planned),因此请将其视为一份记录详尽的用户报告,而非已确认的缺陷。无论如何,它是关于该失败模式的有用证据,也是将存储和遵守视为两个独立问题的原因。

记忆层会让 Claude Code 真正遵循我的修正吗?

单靠它自己是不行的,这是坦诚的局限性。模型是否根据它读取的内容采取行动是模型行为;没有任何存储层能控制它。记忆层改变的是,修正存在于会话之外、保持最新、简短,并在相关时被检索——而不是缺失或埋在长文件中。这有明显的帮助。但这不是保证,对于任何关键的事情,你需要的是强制执行,而不是记忆。

为什么同一个修正在一段时间内有效,然后就失效了?

漫长的会话。随着上下文的增长,会话早期的指令可能会变得无法可靠检索——它并没有被忽略,而是超出了有效的获取范围。这就是为什么 /compact/clear 都有帮助,以及为什么将重要的修正移出对话并放入文件或存储库中,比把它们说得天花乱坠更持久的原因。

我应该把每个修正都放进 CLAUDE.md 中吗?

把你的现行规则放进去,并保持简短。CLAUDE.md 会在每个任务中加载,因此每一行都会在每次请求中消耗你的成本,并与所有其他行竞争注意力。条件性和情境性的修正作为检索记录效果更好;可机械化的修正作为脚本和钩子效果更好。一个 300 行的指令文件并不会比一个 60 行的文件有效五倍。

这与 Claude 遗忘我的约定有什么不同?

约定是你曾作为一般偏好陈述过一次的事情——团队约定问题(house-conventions problem)是指它们根本不存在。而修正是响应性的、具体的:你看到了错误的输出并修复了它。这种区别很重要,因为修正几乎总是带有触发条件和原因,而当修正被扁平化为偏好时,这两者都会被丢弃。

这会发生在其他编程智能体上吗?

是的——这是结构性的,而非特定于厂商。每个读取指令文件并全新启动会话的智能体都有相同的两种失败模式,这就是为什么关于 ChatGPT 重新提出你已经拒绝的想法会出现同样抱怨的原因。这也是为什么将修正保留在特定于工具的文件中意味着,无论你下一步转向哪个智能体,都必须重新教一遍的原因。