← 返回信息流
Agent SkillLINUX DO · Claude·2026/4/1

Claude Code MEMORY.md源码解构:上下文注入链路

原标题:深入浅出 Claude Code(二):从源码解构 MEMORY.md,重塑你的上下文注入链路

速览

Claude Code 的记忆系统通过 MEMORY.md 文件作为索引,存储在本地文件系统中。MEMORY.md 被注入到系统提示(system prompt)中,没有降权,而 CLAUDE.md 被注入到用户消息(user message)中并带有降权提示,因此相同指令放在 memory 中更容易被遵守。MEMORY.md 有行数(200行)和大小(25KB)限制,正确用法是作为索引,每条指向一个 topic 文件,详细内容写在 topic 文件中。Memory 文件分为四种类型:feedback(行为修正,影响最大)、user(用户画像)、project(项目背景)、reference(外部指针),其中 feedback 应同时记录成功和失败案例,并包含 Why 和 How to apply 以保证模型能灵活判断。

AI 深度解读

背景

Claude Code 是 Anthropic 推出的命令行 AI 编程助手,它通过注入系统指令和用户消息来与模型交互。许多用户在使用 Claude Code 时,发现其“记忆”功能(Memory)表现不稳定:有时让模型记住的事情,下次对话它完全不记得,或者记得但不去执行。这并非功能缺陷,而是用户不清楚 Memory 在底层如何流动、存储、加载以及权重分配。本文基于 Claude Code 源码,深入解构其记忆系统,揭示 MEMORY.md 的真正角色,并给出如何高效利用 Memory 和 CLAUDE.md 的实践指南。

核心内容

1. Memory 的存储位置

所有 Memory 文件存储在本地文件系统,按项目隔离,路径为 ~/.claude/projects/{sanitized-project-path}/memory/。其中 {sanitized-project-path} 是项目根目录的路径哈希。该目录下包含多个 markdown 文件,核心是 MEMORY.md(索引文件),以及各种 topic 文件(如 user_profile.mdfeedback_no_summary.md 等)。不同项目的 memory 互不干扰,用户可以直接用编辑器打开修改。

2. Memory 如何被加载到模型

Claude Code 的输入结构分为两层:System Prompt(优先级更高)和 User Message(优先级更低)。

  • System Prompt(高优先级):

    • 位置 1-9:静态指令(身份、工具使用规范、语气等)
    • 位置 10:会话指导
    • 位置 11:★ Memory 系统指令 + MEMORY.md 索引内容
    • 位置 12-18:环境信息、MCP 指令等
  • User Message(低优先级):

    • 第一条:★ CLAUDE.md 内容(包在 <system-reminder> 标签内,带有降权提示 this context may or may not be relevant to your tasks
    • 第二条:用户的第一句话
    • 后续:对话历史

关键差异:

  • Memory 位于 system prompt 中,没有降权,模型被直接告知“你有一个持久化的记忆系统,直接用”。
  • CLAUDE.md 位于 user message 中,带有降权提示,显式告诉模型这些内容可能不相关。

因此,同一条指令放在 memory 里比放在 CLAUDE.md 里更容易被遵守。

3. MEMORY.md 是索引,不是记事本

MEMORY.md 有硬截断限制:

  • MAX_ENTRYPOINT_LINES = 200(超过 200 行,后面的直接丢弃)
  • MAX_ENTRYPOINT_BYTES = 25,000(超过 25KB,在最近的换行处截断)
  • 截断后末尾追加一条警告,超出部分永久丢失(本次加载)。

正确用法是作为索引,每条一行,指向 topic 文件,例如:

- [用户画像](user_profile.md) — 高级 Go 开发者,偏好简洁代码
- [不要总结](feedback_no_summary.md) — 回答结束不要总结做了什么

每行控制在 150 字符以内。详细内容写在各自的 topic 文件中,topic 文件没有行数限制。System prompt 中只注入 MEMORY.md 的内容和 Memory 系统的使用指令。topic 文件只在模型主动用 Read 工具读取时才会被看到,因此 MEMORY.md 索引条目的描述要足够清晰,模型根据这一行描述来判断是否要去读 topic 文件。

4. 四种 Memory 类型及对行为的影响(按影响排序)

Memory 文件用 frontmatter 声明类型,四种类型从高到低影响排序:

  1. feedback(行为修正) —— 影响最大

    • 格式:--- name: no-extra-changes description: 只改用户要求的部分... type: feedback --- 后跟规则、原因(Why)、适用场景(How to apply)。
    • 源码特别说明:不能只记录失败纠正,还要记录成功确认。如果只保存纠正,模型会越来越保守;好的 feedback 需要两者都记。
    • 为什么需要 Why 和 How to apply?因为有了 Why,模型遇到边缘情况能自己判断是否该打破规则。
  2. user(用户画像) —— 影响中等

    • 记录关于用户身份、偏好、经验等信息,模型据此调整沟通方式。
  3. project(项目背景) —— 影响中等

    • 记录不能从代码和 git 历史推导出的项目信息,如发布计划、团队分工等。
    • 注意:相对日期必须转为绝对日期(如“周四”应写成“2026-04-03”),因为 memory 跨会话。
  4. reference(外部指针) —— 影响最小

    • 指向外部系统的指针,告诉模型哪里能找到信息,如 bug tracker 链接。

5. 什么不该存进 Memory

源码硬编码排除清单:

  • 代码模式、架构、文件路径(读代码即可知道)
  • Git 历史、谁改了什么(git log 是权威)
  • 调试方案和修复步骤(修复已在代码中)
  • CLAUDE.md 中已有的内容(重复无意义)
  • 临时任务进度、当前对话上下文(应使用 task 系统)

特别提示:如果用户要求保存 PR 列表或活动摘要,模型应追问“这里面什么是让你意外的?”,只保存意外或非显而易见的部分,而不是整个列表。

6. 陈旧机制:老 memory 会被警告

模型读取 memory 文件时,系统根据文件修改时间附加陈旧提醒(源码 memdir/memoryAge.ts):

  • 今天/昨天 → 无警告
  • 2 天以上 → 警告“This memory is N days old. Memories are point-in-time observations, not live state — verify against current code before asserting as fact.”

此外,如果 memory 中提到了某个文件路径,模型应先检查文件是否存在;如果提到了函数名,应先 grep 确认。memory 不应写依赖行号的信息,如“函数 handleAuth 在 main.go 第 42 行”,因为文件一改就过时。应写“项目用中间件模式处理认证,入口在 main.go”这种不依赖行号的描述。

7. 自动记忆:你没说“记住”,它也会自动存

除了用户主动说“记住这个”,Claude Code 还有一个后台提取机制。模型完成回答后,如果满足以下条件,会自动启动一个后台 agent 扫描对话内容、提取值得保存的信息:

  1. 本轮主 agent 没有手动写过 memory
  2. extractMemories feature flag 启用
  3. auto memory 开启

因此,用户 memory 目录中可能出现没有主动要求保存的文件。

8. Compact 后 Memory 重新加载

执行 /compact/clear 时,Memory 的缓存会被完全清除(函数 runPostCompactCleanup 中调用了 resetGetMemoryFilesCache('compact')clearSystemPromptSections())。下一轮对话时 MEMORY.md 被重新读取。这意味着如果在对话中途手动编辑了 memory 文件,执行 /compact 后修改立即生效,无需重启。

9. Memory 和 CLAUDE.md 如何配合

不要重复内容。CLAUDE.md 存规则,Memory 存规则的强化和例外。例如,CLAUDE.md 写了“commit message 用中文”,但模型老是忘。不应在 memory 再写一遍,而应写一条 feedback:

---
name: enforce-chinese-commit
description: 强调 commit message 必须中文,之前多次忘记
type: feedback
---
CLAUDE.md 中的"commit message 用中文"规则必须严格遵守。
**Why:** 之前多次输出英文 commit message,用户每次都要手动改。
**How to apply:** 每次 git commit 前检查 message 是否为中文。

用 feedback 来加强 CLAUDE.md 的权重

查看原文 →linux.do