Claude Code 记忆系统详解:Markdown、Auto Memory 与向量检索怎么选
新开一个会话,Agent 却知道项目的测试命令、代码风格、哪些目录不能碰——这不是模型「记住」了上次聊天,而是外部文件和加载逻辑在起作用。本文拆解 Claude Code 的记忆分层:规则与经验各放哪里、记忆如何与上下文协同、以及记忆越积越多之后怎么治理。
为什么记忆必须外置
先明确一个前提:LLM 在两次请求之间不保存任何状态。每轮调用时,客户端把系统提示、历史对话、工具结果和新问题拼在一起发给模型;下一轮还能「想起来」,只是应用层又把相关内容带了回来。
普通聊天不太暴露这个问题,Agent 场景就不一样了:读文件、跑命令、调工具,每一步都在消耗上下文,窗口很快被临时材料占满,长期规则反而淹没其中。所以跨会话的知识必须外置成文件,并回答四个问题:什么值得长期保存?存到哪里、谁看得见?启动时加载多少、任务中怎么补?过期或冲突的记忆如何发现和清理?
规则与经验:两类记忆的分工
Claude Code 的长期上下文先分两类:人写给 Agent 的规则和 Agent 自己攒下的经验。
| 机制 | 谁写 | 适合存什么 | 加载方式 |
|---|---|---|---|
CLAUDE.md |
人 | 稳定规则、项目约定、协作流程 | 每次会话加载 |
.claude/rules/ |
人 | 只在某类文件或目录下生效的条件规则 | 读取匹配文件时按需加载 |
| Auto Memory | Agent | 工作中发现的偏好、命令、排坑经验 | 启动时加载索引,正文按需读 |
规则文件:确定性与可审查
CLAUDE.md 是会话开始前的工作说明书:编码规范、常用命令、目录约束、不要碰的区域。它按层级组织——组织级、用户级(~/.claude/CLAUDE.md)、项目级、本地级、子目录级。范围越大的越先加载,各层是叠加关系而非覆盖;子目录级文件要等读到对应目录的文件时才补进来。几点要注意:
CLAUDE.md以 user message 形式注入,本质是提示而非强制约束;真正要硬拦的行为(禁止危险命令、提交前跑检查)应交给 Hooks、权限配置或 CI。- 每份文件建议控制在 200 行以内,写得太长模型反而只记住一部分。
@path/to/file引入外部文件不会省 Token——被引用的内容照样在启动时展开进上下文。
只在特定路径下才有意义的规则(比如前端规则只在 src/**/*.tsx 生效),适合放进 .claude/rules/ 并通过 frontmatter 里的 paths 控制触发范围,避免每次会话都背着无关规则。
--- |
Auto Memory:经验的索引式存储
Auto Memory 记录 Agent 在工作中发现的构建命令、调试经验、用户偏好和反复出现的坑。它按 Git 仓库存储在 ~/.claude/projects/<project>/memory/,目录里 MEMORY.md 是入口索引,细节放在各自的 topic file 中。会话启动时只加载索引的前 200 行或 25KB,哪个先到就停;需要细节时再打开对应文件。/memory 可以查看和编辑。
这个结构和 Skills 的渐进式披露是同一思路:先让模型知道「有什么」,别把「全部内容」一次性塞进窗口。想关掉它,可以在配置里设 "autoMemoryEnabled": false 或设置对应的环境变量。
多代理场景下还有 Subagent Memory:记忆主体换成某个子代理,按 user、project、local 三种 scope 存到不同的 agent-memory 目录,用来沉淀专用 worker(如只负责数据库迁移的代理)的长期经验。注意它和 Agent Teams 不是一回事——后者解决多个会话之间的任务分工与通信,不等于共享长期记忆。
记忆与上下文的协同
记忆系统的设计核心是和上下文窗口打配合,而不是替代它:
- 索引常驻,正文按需:索引文件短小、每轮加载;具体经验在任务相关时才读入。索引别写成小作文,只负责告诉 Agent「有哪些记忆、该打开哪个文件」。
- 只记源码推不出来的东西:用户偏好、项目特有约定、某次技术决策的原因、踩过的坑,值得记;目录结构、函数签名、依赖版本、提交历史,都能从仓库直接查到,重复记录只会抬高固定开销。
- 读回记忆要分信任等级:用户长期偏好可以优先采用,但本轮明确指令永远优先级更高;历史决策原因只能参考,它解释的是当时为什么这么选;文件路径、模块位置这类会变的事实只能当线索,用之前必须回到当前代码库核对——「按记忆找方向,按现状做决定」。
记忆膨胀的治理
一条记忆写进去,成本就不只是几十个 Token:它每轮都可能被加载,还需要被复查、更新或删除;没人管时,Agent 可能拿着过期前提继续做决定。「记错」比「忘记」更糟糕。
治理从写入端开始。写入前先问三个问题:下次做决定会不会用到?是不是用户明确确认过(而非 Agent 自己猜的)?过期了有没有人能发现?答不上来就让它留在当前会话。真正写入时也别只记一句结论,至少带上原因和适用范围:
--- |
只写「别用 H2」,Agent 容易机械执行;补上原因和边界,它遇到边缘场景才有机会做对取舍。时间表达也要落成绝对日期——「月底前别动订单模块」应写成「2026-06-30 前不修改订单模块」,否则隔几天再读就失了效。
运维侧的配套动作:记忆变更走 review;按季度审计过期条目;密钥、凭证这类敏感信息永不写入;定期用 /memory 看看实际记了什么。
至于向量检索类方案(如 memsearch 这类外置记忆库),适合多工具、多成员、长周期共享记忆的团队,代价是索引、嵌入模型、权限都要有人维护。记忆只有几十条时,文件索引完全够用,别为了用而用。
小结
- 模型不保存跨会话状态,记忆 = 外部文件 + 加载规则;规则(
CLAUDE.md、.claude/rules/)由人维护求确定性,经验(Auto Memory)由 Agent 记录但需人审查。 - 记忆与上下文协同的要点是索引常驻、正文按需、只记源码推不出的内容;读回时区分信任等级,可变事实先核对再用。
- 治理的核心是克制写入:写清原因、边界和绝对时间,定期审计清理,敏感信息绝不入库。
- 规模没到之前,Markdown 文件索引胜过向量库;让 Agent「记住一切」没有意义,更可靠的是让它知道下一步该去哪里核对。

