04:Memory System:Claude Code 如何把经验变成可召回知识
上一篇把 Prompt System 理解成 Claude Code 的行为协议装配层。
04:Memory System:Claude Code 如何把经验变成可召回知识
上一篇把 Prompt System 理解成 Claude Code 的行为协议装配层。
提示词系统解决的是“本轮 agent 应该按什么身份、规则和工具契约行动”。但长期协作里还有另一个问题:有些信息反复出现,用户不想每次都重新解释,agent 也不该每次都重新踩坑。
这就进入 Memory System:
Claude Code 如何判断什么值得被记住,并在后续任务里把它重新召回?
这篇拆的是一条信息管道:一条信息从当前会话出现,到成为可复用记忆,再到下一次进入模型上下文,中间到底发生了什么。

这篇文章要拆的主线:什么值得被记住
这一篇回答的问题是:
Claude Code 如何把一次任务里的经验,筛选成后续任务可召回的项目知识、用户偏好、调试经验和会话状态?
这里的关键词是“筛选”。
一次会话会产生很多信息:用户要求、工具结果、报错日志、文件改动、计划变化、测试结论、临时限制、用户纠正。它们都可能有用,但生命周期完全不同。
有些信息只对当前任务有用,比如“这次先别跑全量测试”。
有些信息适合变成项目规则,比如“这个仓库使用 pnpm”。
有些信息适合变成调试经验,比如“构建报错经常来自 frontmatter 字段”。
有些信息应该交给运行时硬边界,比如“禁止读取密钥文件”。
所以记忆系统的核心不是“全都记住”,而是判断:
这条信息应该留在哪一层,什么时候再拿出来?
这就是 memory router 的问题。
记忆系统解决的工程问题:把经验变成可召回知识
长任务和长期协作里,最烦人的成本往往来自重复补背景:同样的命令、同样的偏好、同样的环境坑,隔几天又要解释一遍。
比如:
- 用户每次都要提醒“这个项目用 pnpm”。
- agent 每次都要重新找构建命令。
- 某个本地服务没启动导致测试失败,下一次又踩一遍。
- 写同一系列文章时,口吻、引用方式、章节边界反复被纠正。
- 恢复一个旧任务时,前面做过什么、还剩什么已经散在聊天历史里。
记忆系统要减少这些重复摩擦。
它的价值不是让模型拥有神秘的长期大脑,而是把有复用价值的信息文件化、索引化,再在合适时机重新装进上下文。
用一句话概括:
Memory System 把一次任务里的可复用经验,变成后续任务可以召回的外部知识。
这个定义也把它和 Prompt System 分开了。提示词系统负责本轮行为协议;记忆系统负责跨会话保存可复用信息。至于每一轮到底加载哪些记忆、放到上下文哪里,第 05 篇上下文管理再展开。
记忆不是一个文件,而是几层状态
Claude Code 的记忆更像几层不同生命周期的信息,而不是单独一个“memory 文件”。
可以先看一张地图:
| 信息层 | 主要内容 | 生命周期 | 适合解决什么问题 |
|---|---|---|---|
| session transcript | 本次会话消息、工具调用、结果、任务状态 | 当前 session 或恢复同一 session | 继续之前那件事 |
CLAUDE.md / rules | 人维护的项目规则、命令、约定 | 项目长期存在 | 团队共享和版本管理 |
MEMORY.md index | auto memory 的入口索引 | 本机项目长期存在 | 快速告诉 agent 有哪些可查记忆 |
| topic files | 调试经验、偏好、项目细节等专题记忆 | 按需读取 | 需要细节时再展开 |
| team memory | 团队共享的长期知识 | 团队范围 | 多人、多环境共享经验 |
| runtime policy | settings、permissions、hooks | 长期硬约束 | 动作许可、拦截、审计 |
这里最容易混的是 CLAUDE.md 和 auto memory。
CLAUDE.md 更适合放人明确维护的项目规则,比如常用命令、目录约定、生成文件规则。它适合被团队 review,也适合随仓库版本变化。
auto memory 更像 Claude 从使用过程中提取的笔记。它可能来自用户纠正、偏好、调试经验和项目模式,通常更偏个人或本机项目上下文。
runtime policy 又是另一层。settings、permissions、hooks 可以跨会话生效,但它们不是“给模型读的软知识”,而是运行时硬约束。比如禁止读密钥文件,更适合放到权限规则里,而不是只写成记忆。
这样分层以后,记忆系统就不再是“往哪里写一段话”,而是“这段信息属于哪种状态”。
MEMORY.md:索引,而不是仓库全集
auto memory 里最值得注意的是 MEMORY.md。
它不是把所有长期经验都塞进去的大文件,更像一个入口索引。启动时,Claude Code 会加载有限的 MEMORY.md 内容,让模型知道有哪些主题值得查。更细的内容会拆到 topic files,需要时再读。
Mem0 的分析提到,MEMORY.md 有前 200 行或 25KB 这类加载限制,详细记忆会按主题拆到其他文件;Claude 后续可以再读取相关 topic files。[2]
这说明 memory 的设计很克制:
启动时先给索引,需要细节时再读正文。
这个设计和上下文管理的思路是一致的。启动时把所有记忆全量塞进去,成本高,噪声也大。索引短一点,topic files 分开,agent 才能按任务需要取信息。
这也带来一个要求:索引要写得像索引。
好的 MEMORY.md 应该让 agent 一眼知道:
- 有哪些主题文件。
- 每个主题大概解决什么问题。
- 哪些记忆最近更新。
- 哪些信息可能过期,需要复核。
如果索引只是堆很多散句,Claude 可能知道“有很多记忆”,却不知道该打开哪一份。Milvus 对 memory 限制的讨论也提醒了一点:长期项目里,记忆会积累,索引上限、召回方式和旧信息污染都会变成问题。[4]
所以 memory 的第一条工程原则是:
记忆要能被找到,比记忆多更重要。
记忆如何写入:从用户纠正到后台提取
记忆写入大概有几条路径。
第一种是用户显式要求。
用户说“记住,这个项目以后都用 pnpm”,这类信息适合进入长期记忆。用户说“把这条写进项目规则”,那更适合进入 CLAUDE.md 或 rules。
第二种是用户反复纠正。
如果用户多次纠正“写这个系列时中文为主”“少用反驳式表达”“不要写硬核源码逐行解读”,系统就可以判断这里有稳定偏好。稳定偏好适合沉淀,临时限制则留在当前任务里。
第三种是人主动维护项目规则。
团队可以手动更新 CLAUDE.md、rules 或项目文档。这类写入更适合团队共享,也更适合代码 review。项目命令、目录约定、生成文件规则,通常应该走这条路。
第四种是后台提取。
Mem0 和 win4r 的分析都提到,Claude Code 的 memory 并不只是手写文件,还涉及从会话中提取候选经验的机制。[2],[3]
这类后台提取的价值是省心:用户纠正过的偏好、项目里的反复坑、调试经验,可以被整理成未来可读的 markdown。
但它也需要审计。
一次临时要求可能会被误判成长期偏好。比如“这次先别跑全量测试”可能只是当前任务为了节省时间;如果写成长期记忆,后面每次验证都可能变弱。
所以自动写入要配一个出口:用户能看到、能改、能删。/memory 或文件层面的审计入口,正是这类系统能长期使用的关键。
记忆如何召回:启动加载、按需读取、恢复会话
写入只是前半段,召回才决定记忆能不能帮上忙。
记忆召回可以分成三种场景。
-
新 session 启动。 启动时加载稳定记忆和索引,比如人维护的项目说明、规则,以及 auto memory 的入口索引。它们给模型一个默认背景。
-
按需读取细节。 当任务触发某个主题,Claude 可以再读 topic files。比如构建失败时读取调试经验,写博客时读取写作偏好,改 API 时读取接口约定。
-
恢复同一会话。 恢复 session 时带回 transcript,这是“继续之前那件事”。它和长期项目记忆不同,更多是当前任务的历史状态。
这三种召回经常被混在一起。
比如 session transcript 里有一个临时计划,它可以帮助恢复当前任务,但不应该自动变成项目长期规则。CLAUDE.md 里的测试命令适合每次新会话都加载。topic memory 里的某个调试经验,只在相关任务里读取就够了。
所以召回的核心是时机:
新会话给稳定背景,当前任务读相关细节,恢复会话带回工作现场。
05 上下文管理会继续讲:这些召回来的东西进入上下文以后,还要面对顺序、长度、压缩和污染问题。
记忆应该按用途分层:偏好、约定、经验、交接
为了避免文章滑进源码字段,我更愿意按用途给记忆分层。
| 用途 | 例子 | 更适合放哪里 |
|---|---|---|
| 用户偏好 | 喜欢先给结论、中文为主、少写反驳句 | auto memory 或用户级规则 |
| 项目约定 | 使用 pnpm、目录结构、生成文件不要手改 | CLAUDE.md / rules |
| 调试经验 | 构建失败常见原因、本地服务依赖、测试坑 | topic memory |
| 任务交接 | 已改文件、未跑验证、下一步计划 | session transcript、notes、compact summary |
| 硬边界 | 禁读密钥、危险命令审批、工具审计 | settings、permissions、hooks |
这个分类更贴近日常工程。
它也能帮助判断一条信息的归宿。
“这个系列文章主要用中文写”是用户偏好和项目约定的混合,如果只对这个博客系列生效,可以写进项目写作规则或改造计划。
“本轮先不跑构建”是任务交接,不适合长期记忆。
“构建报错经常来自 frontmatter 字段缺失”是调试经验,适合进 topic memory。
“不要读取 .env”是硬边界,适合权限配置。
这就是记忆路由。
对我写 Agent 的启发:设计 memory router
如果自己写一个 coding agent,我会先设计 memory router,而不是先设计 memory database。
数据库只是存储。真正决定效果的是路由。
我会把流程拆成六步:
-
捕获。
从用户纠正、工具结果、失败日志、文件改动、总结里收集候选记忆。 -
分类。
判断它是用户偏好、项目约定、调试经验、任务交接,还是运行时硬边界。 -
写入。
不同类型写到不同位置:rules、topic memory、session notes、permissions、hooks。 -
召回。
新会话加载稳定索引,当前任务按需读细节,恢复会话带回 transcript。 -
审计。
用户能看到记忆来源、更新时间、适用范围和当前内容。 -
遗忘。
过期、错误、临时信息要能删除或降级。
每条 memory candidate 都要问几个问题:
- 它从哪里来?
- 作用域是用户、项目、目录、任务,还是团队?
- 有效期大概多久?
- 应该写到哪里?
- 什么时候召回?
- 谁能审计和修改?
这套问题比“存进向量库还是 markdown”更基础。
Claude Code 给我的启发是:记忆系统不一定一开始就很复杂,但它必须可见、可分层、可修剪。否则 agent 记得越多,越容易带着错误背景行动。
参考资料
Claude Code 记忆系统
[1] How Claude remembers your project - Claude Code Docs
本文主要参考它关于 CLAUDE.md、auto memory、MEMORY.md、topic files、加载顺序和 /memory 审计入口的说明。
[2] How Memory Works in Claude Code - Mem0
本文主要参考它关于 MEMORY.md 索引、200 行 / 25KB 上限、topic files、freshness warning 和后台提取机制的分析。
[3] Claude Code 记忆系统深度分析 - win4r/cc-notebook
本文主要参考它关于 session memory、persistent memory、team memory 的分层分析。
[4] Claude Code Memory System Explained: 4 Layers, 5 Limits, and a Fix - Milvus
本文主要参考它关于 memory 限制、召回失败、索引上限和长期污染风险的讨论。
[5] Claude Code Source Leak: The Three-Layer Memory Architecture - MindStudio
本文主要参考它从 builder 视角对三层记忆架构的总结。
下一篇:Context Management
这一篇先把 Memory System 理解成 Claude Code 的记忆路由系统。
核心结论是:
记忆系统的关键不是记得越多,而是把信息写到合适的层,并在合适时机召回。
但记忆被保存以后,还有一个问题:每一轮模型调用时,到底加载哪些记忆、工具结果和项目材料?它们进入上下文后怎么排序、压缩、隔离?
所以下一篇继续追的问题是:
Claude Code 如何管理进入模型上下文的信息,让 agent 看见关键东西,同时控制噪声?