Claude Code 的源码被公开后,有人直奔最有趣的部分——记忆系统本身。

记忆架构:Markdown 文件的 v1 设计

Claude Code 把记忆存成明文 Markdown 文件,路径是 ~/.claude/projects/<项目名>/memory/。每个项目一个文件夹,每次对话结束后可写文件,文件在会话之间持久化。这就是整个持久化模型。

根目录有一个 MEMORY.md 索引文件。每次新会话开始时,Claude 读取这个索引,了解存在哪些记忆。正是这里埋着 Anthropic 从未公开的硬性限制。

两道硬限制,静默失效

MEMORY.md 在源码里硬编码了两道限制:

200 行上限。 索引超过 200 行时,系统静默截断。它会在被截断内容后面追加一条警告,但这条警告只有在手动翻文件时才能看到。Claude 在对话里看到的是干净的 system prompt,根本不知道索引被切过。

25KB 上限。 单独一个字节数限制,处理每行特别长的边缘情况。

失败模式是静默的。你刚写到第 201 行,最旧的记忆从索引底部掉落。Claude 下次新会话时完全不知道那些记忆存在过。它不会报错,不会告诉你,只是忘了。

记忆被区分为四种明确类型:

  • User memories:记录你是谁——角色、专业领域、偏好、沟通方式。仅本人可见。
  • Feedback memories:记录你给过的指导——修正、验证过的方法、需要停止做的事。
  • Project memories:记录代码库里正在发生的事——截止日期、决策、从代码本身推导不出的架构上下文。
  • Reference memories:存储指向外部系统的指针——bug 追踪在哪里、该关注哪个 Slack 频道。

源码里写得很明确:如果一个信息能通过 grep 或 git 从当前代码库推导出来,就不应该被存为记忆。

每次对话的检索:Sonnet 侧调用,5 文件上限

每次对话中,Claude Code 会单独调用一次 Claude Sonnet,只为了弄清楚哪些记忆文件与当前查询相关。

流程是:扫描所有记忆文件,提取文件名和描述,发送这个清单给 Sonnet,让它选出最相关的文件。每次最多返回 5 个文件。

这是一个语义相关步骤,但它的依据只是文件名和一句话描述。不是 embeddings,不是向量搜索,只是一个语言模型在读列表然后做判断。

还有一个 memoryFreshnessText() 函数,对超过一天的旧记忆生成"过时警告"。警告内容是:"此记忆是 X 天前的快照。记忆是时间点观察,不是实时状态。关于代码行为或 file:line 引用的声明可能已过时。"

这条警告直接加在记忆内容前面,Claude 看到时就知道这条记忆可能是错的。但从外部没有办法知道具体哪条记忆触发了这个警告。

会话结束后有一个 extract-memories agent 在后台运行——回顾刚才发生了什么,自动提炼记忆。这意味着有两样东西在同时往记忆目录写东西:主 agent 在会话中写,后台提取器在会话结束后写。

那个让系统崩溃的场景

你用 Claude Code 在一个真实项目上工作了三个月。它已经学会了:

  • 你的偏好和工作方式
  • 1 月做出的架构决策
  • 那个不稳定的 endpoint 在测试时不应该被信任
  • 你的团队对 hotfix 跳过 PR review

然后你写到了第 201 条。

索引静默截断。最旧的记忆从底部掉落。Claude 下次新会话时,满眼是干净的上下文,根本不知道那些记忆存在过。

接下来发生的是:

  • Claude 写了一个测试,命中那个不稳定的 endpoint
  • Claude 再次问你关于 PR review 政策的问题
  • Claude 反驳你们几个月前共同同意的架构

它不是在幻觉。它没坏。它只是忘了。而且它没有办法告诉你它忘了。

Freshness warnings 让这更糟——它们只对被加载的记忆触发。如果一条记忆在截断中丢失了,它根本不会被加载。没有警告,没有信号。Claude 不知道自己不知道。

mem0 的修复方案

mem0 是一个专门为生产级 AI agent 设计的记忆层。它用向量存储替代扁平 Markdown 文件。记忆被 embedding,检索是语义搜索。没有索引文件可以截断,没有 200 行上限,没有 5 文件限制,没有静默截断。6 个月前的记忆如果与当前工作相关,就会浮出来。

mem0 的 Claude Code 插件安装方式是:

/plugin marketplace add mem0ai/mem0
/plugin install mem0@mem0-plugins

安装之后,语义搜索、跨会话召回和完整的记忆管理都启用:add_memory、search_memories、update_memory、delete_memory。