如果你在构建 Agent,一定想过这个问题:怎么让 Agent 跨会话记住用户的偏好、项目的背景、之前犯过的错误?大部分人的做法是搞一个文件,把所有「需要记住的东西」往里塞。文件越来越大,token 成本越来越高,而且大部分内容跟当前对话根本没关系。Claude Code 的记忆系统给出了一个反直觉的设计原则:工程量最大的部分不是「怎么存」,也不是「怎么取」,而是「什么该存、什么不该存」。
一、核心哲学:记忆是代码的补集
这套记忆系统的设计哲学可以用一句话概括:
记忆是代码的补集。
听起来简单,但这是整个设计里最有启发性的原则。具体来说:
| 维度 | 代码/工具擅长 | 记忆系统擅长 |
|---|---|---|
| 时效性 | 实时查询、权威来源 | 跨会话沉淀、经验积累 |
| 可变性 | 随代码更新自动失效 | 需要主动维护、可能过时 |
| 粒度 | 精确到函数/文件 | 模糊的意图、偏好、上下文 |
该存的:全部是「关于人和上下文」的信息——人的偏好、纠正、动机、外部资源指针。这些藏在代码之外,不查记忆就无从得知。
不该存的:全部是「关于代码和项目状态」的信息——代码是实时的、可查的、权威的。代码能回答的问题,不要让记忆来回答。
这个分界线一旦清晰,你会发现很多之前觉得「应该记住」的东西,其实根本不该存。
二、四种该存的记忆
2.1 用户记忆:记用户是谁
用户记忆记录的是用户的角色、技术背景、工作习惯、知识水平。
好的例子:
「这个用户是数据科学家,目前在做日志系统的调研。」
「这个用户写了十年 Go,但第一次碰 React。」
这类记忆的设计意图是让 Agent 能调整沟通方式和工作策略。面对一个资深后端工程师,Agent 不需要解释基础概念,可以直接用技术术语;面对一个初学者,Agent 需要更耐心地铺垫背景。
关键约束:记忆的目的是「怎么更好地帮这个人」,不是「给这个人画像」。不要记录对用户的负面评价,也不要记录跟工作无关的个人信息。
1 | ❌ 不要记:「这个用户脾气不好,经常发火」 |
2.2 反馈记忆:记纠正和肯定
这是四种记忆里设计最精细的一种。源码里对它有三个关键要求。
要求一:规则 + 原因 + 适用场景
每条反馈记忆必须包含三个部分:
1 | 规则是什么 → Why → 什么时候该应用 |
举个实际例子。用户说:
「测试不要 mock 数据库,上个季度我们就是因为 mock 测试通过了但生产环境迁移失败才出的事故。」
如果只记「不要 mock 数据库」,Agent 在所有测试里都不敢 mock,包括那些跟数据库迁移完全无关的单元测试。
但如果它知道原因是「mock 和生产环境行为不一致导致迁移失败」,它就能判断:集成测试不该 mock,但纯逻辑的单元测试 mock 是没问题的。
记原因,是为了让 Agent 能在新场景下做判断,而不是机械地执行规则。
要求二:不要只记纠正,也要记肯定
源码注释里说得很直白:
如果你只记录用户说「不要这样做」的时刻,它只知道什么是错的,不知道什么是对的。时间长了,它会回避一切不确定的做法,变得畏手畏脚。
但肯定信号比纠正信号更难捕捉。用户说「不要这样做」很明显,但用户说「对,就是这样」或者默默接受了一个不寻常的方案,需要主动注意这些肯定信号。
例子:
用户说:「对,这次用一个大 PR 是对的,拆开反而是无意义的工作量。」
这条记忆的价值是:下次遇到类似的重构场景,Agent 知道这个用户倾向于合并提交,而不是拆成很多小 PR。这不是纠正,是一个被验证过的判断。
要求三:区分个人偏好和项目规范
「不要在回复末尾加总结」→ 个人偏好,只对这个用户有效
「集成测试必须用真实数据库」→ 项目规范,对所有协作者有效
源码里用 scope 来区分这两种。个人偏好存在私有目录,项目规范存在团队共享目录。
2.3 项目记忆:记正在发生什么
项目记忆记录的是当前项目里正在发生的事:谁在做什么、为什么要做、截止日期是什么。
例子:
「本周四之后冻结所有非关键合并,移动端团队要切发布分支。」
「正在重写认证中间件,原因是法务团队指出旧的 token 存储方式不符合合规要求,所以做决策的时候要优先考虑合规性而不是技术优雅。」
关键规则:相对日期必须转换成绝对日期
用户说「周四冻结」,记忆里存的是具体的年月日,比如「2026-03-07」。
为什么?因为记忆是跨会话的。如果存「周四」,下周再看这条记忆就不知道是哪个周四了。
另一个特点:衰减得很快
一个月前的项目状态大概率已经过时了。所以源码要求项目记忆必须记录「为什么」。即使事实过时了,背后的动机仍然有参考价值。
1 | 事实过时:「正在重写认证中间件」→ 可能已经写完了 |
2.4 引用记忆:记外部资源在哪里
引用记忆记录的是外部资源的位置:bug 在哪个系统里追踪、监控面板的地址是什么、设计文档在哪个平台。
例子:
「流水线相关的 bug 都在 Linear 的 INGEST 项目里追踪。」
「API 延迟的监控面板在 grafana.internal/d/api-latency,值班的时候看这个。」
这是四种里最简单的,但也是最实用的。它本质上是一个「去哪里找信息」的索引。
三、五种不该存的东西
这部分才是整个设计里最有启发性的。很多人做记忆系统的第一件事,就是把不该存的东西全存了。
3.1 代码模式、架构、文件路径、项目结构
这是最反直觉的。很多人觉得 Agent 应该记住「项目用了什么框架、目录怎么组织、哪个文件负责什么」。
Claude Code 说:不要存这些。
为什么?因为这些信息可以直接从代码里读出来。Agent 随时可以通过读代码和搜索来获取当前的项目结构。
把这些存进记忆有两个问题:
1 | 问题一:浪费空间 |
背后的原则:如果一个信息可以从当前项目状态推导出来,就不要存进记忆。记忆只存那些「看代码看不出来」的东西。
3.2 版本管理历史
谁改了什么、最近的提交记录——这些用版本管理工具查就行了。
Git 是实时的、权威的,不需要记忆来存一份可能过时的副本。
3.3 调试方案和修复方法
修复已经在代码里了,提交信息里有上下文。存「怎么修的」没有意义,因为代码本身就是最好的参考。
3.4 配置文件里已经写过的东西
如果你的项目里有 CLAUDE.md 或其他配置文件已经定义了编码规范,记忆系统不需要再存一份。
重复存储不仅浪费空间,还会在两份内容不一致的时候制造混乱。
1 | 配置文件说:「使用 pnpm」 |
3.5 临时性的任务细节
当前正在做什么、对话里的中间状态——这些是短期的,属于当前会话的上下文,不该进入长期记忆。
四、一条特别重要的规则
即使用户明确要求你记住某些东西,如果它属于上面五类,也不该记。
例子:
用户:「记住这周的 PR 列表」
Agent 不应该直接存 PR 列表,而应该反问:
「这些 PR 里有什么让你意外的或者不明显的?那个部分才值得记。」
活动日志不是记忆,从活动中提炼出的洞察才是。
用户要求存不该存的内容时,正确的做法是提炼价值点。PR 列表本身不该存,但如果某个 PR 的处理方式让用户觉得「这样做是对的」,那个判断才值得存成反馈记忆。
五、信息来源决策树
把上面的原则整理成一个判断流程:
1 | 这条信息能从代码/工具实时获取吗? |
六、实践中的常见错误
错误一:把记忆当成项目文档
1 | ❌ 存储:「src/auth 目录负责认证逻辑,包含 middleware.ts 和 token.ts」 |
错误二:把记忆当成聊天记录
1 | ❌ 存储:「用户昨天问怎么配置 Redis,我回答了...」 |
错误三:记了规则但没记原因
1 | ❌ 存储:「不要用 forEach」 |
错误四:只记纠正不记肯定
1 | ❌ 只存:「不要在回复末尾加总结」 |
七、记忆系统的质量检验清单
在写入一条记忆之前,问自己这些问题:
1 | □ 是否存了代码可查的内容?→ 删除或反问用户 |
八、总结
Claude Code 记忆系统的核心设计可以概括为一句话:少而精。
记忆的价值不在于数量,而在于每条记忆都能在关键时刻减少认知负担。
如果你在给自己的 Agent 做记忆系统,这个分类框架可以直接拿来用:
四种该存:
- 用户是谁(角色、背景、习惯)
- 用户纠正和肯定过什么(含规则、原因、适用场景)
- 项目背后的动机和时间线(相对日期→绝对日期)
- 外部资源在哪里(索引而非内容)
五种不该存:
- 代码能告诉你的一切
- 版本历史能告诉你的一切
- 提交记录能告诉你的一切
- 配置文件已经说过的一切
- 临时性的中间状态
这样做的好处是:你的记忆文件会非常精简,每一条都是高价值的、代码里找不到的信息。模型每次加载记忆的时候,看到的全是有用的东西,没有噪声。
相关文章:
- Memory 系统:跨会话持久化知识库 — Claude Code 记忆系统的技术实现细节
- Claude Code 源码深度解析系列 — 更多 Claude Code 架构分析