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

2026-06-09 21:09:39 1130阅读 0评论 SEO资讯
  • 内容介绍
  • 文章标签
  • 相关推荐
问题描述: 深入浅出 Claude Code(一):从源码理解 CLAUDE.md,重写你的配置 开发调优
新一期来啦: 大多数人写 CLAUDE.md 的方式是:随便写几条规则,感觉效果不明显,然后放弃。 你不知道这些文字在 Claude 眼里长什么样、被放在哪里、和其他指令的优先级关系是什么。 今天我来带各位佬友们剖析一下 claudecode 的底层逻辑 全网统一小恐龙头像,在别的地方看到的家人们点点赞 1. CLAUDE.md 不在 System Prompt 里 这是最大的认知误…

上一篇我们重写了 CLAUDE.md,但这只是表层。今天这篇,我们将顺着代码的调用栈,扒开 Claude Code 的记忆系统,看看你的指令在底层究竟被赋予了什么级别的权重。

你让 Claude Code "记住"的东西,下次对话它可能完全不记得。或者记得,但不照做。

其实不是功能坏了——是你不清楚这些 memory 在系统里是怎么流动的。存在哪、怎么加载、权重多高、什么格式才有效,搞清楚这条链路,memory 才能真正起作用。

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


1. Memory 存在哪

所有 memory 文件存储在本地文件系统,按项目隔离:

~/.claude/projects/{sanitized-project-path}/memory/ ├── MEMORY.md ← 索引文件 ├── user_profile.md ← topic 文件 ├── feedback_no_summary.md ├── project_deadline.md └── reference_linear.md

{sanitized-project-path} 是你项目根目录的路径哈希。不同项目的 memory 互不干扰。

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

这些就是普通的 markdown 文件,你可以直接用编辑器打开改。


2. 它怎么被加载到模型的

这是整篇最关键的一点。

Claude Code 的输入结构分两层:system promptuser message。Memory 和 CLAUDE.md 分别在这两层里:

System Prompt(优先级更高): 位置 1-9:静态指令(身份、工具使用规范、语气等) 位置 10:会话指导 位置 11:★ Memory 系统指令 + MEMORY.md 索引内容 位置 12-18:环境信息、MCP 指令等 User Message(优先级更低): 第一条:★ CLAUDE.md 内容(包在 <system-reminder> 里,带降权提示) 第二条:你的第一句话 后续:对话历史

两个关键差异:

Memory 在 system prompt 里,没有降权。 模型被直接告知"你有一个持久化的记忆系统,直接用"。

CLAUDE.md 在 user message 里,带降权。 注入时附带一句 this context may or may not be relevant to your tasks,显式告诉模型这些内容可能不相关。

同一条指令,放在 memory 里比放在 CLAUDE.md 里更容易被遵守。这不是玄学,是注入位置和降权声明的直接影响。


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

很多人往 MEMORY.md 里堆大段内容。问题是它有硬截断:

MAX_ENTRYPOINT_LINES = 200 // 超过 200 行,后面的直接丢弃 MAX_ENTRYPOINT_BYTES = 25_000 // 超过 25KB,在最近的换行处截断

截断后末尾追加一条警告,超出部分永久丢失(本次加载)。

MEMORY.md 的正确用法是当索引——每条一行,指向 topic 文件:

- [用户画像](user_profile.md) — 高级 Go 开发者,偏好简洁代码 - [不要总结](feedback_no_summary.md) — 回答结束不要总结做了什么 - [发布冻结](project_release_freeze.md) — 4月3日前不合并非关键 PR

每行控制在 150 字符以内。详细内容写在各自的 topic 文件里——topic 文件没有行数限制。

system prompt 中只注入 MEMORY.md 的内容和 Memory 系统的使用指令。topic 文件只在模型主动用 Read 工具读取时才会被看到。所以 MEMORY.md 索引条目的描述要写得足够清晰——模型根据这一行描述来判断要不要去读 topic 文件。


4. 四种类型:按对行为的影响排序

Memory 文件用 frontmatter 声明类型。四种类型中,对 Claude 行为影响最大的排在前面:

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

“你做错了 X,以后这样做"或"你做对了 Y,继续保持”。

源码对 feedback 的特别说明:

Record from failure AND success: if you only save corrections, you will avoid past mistakes but drift away from approaches the user has already validated, and may grow overly cautious.

只记纠正不记确认,模型会越来越保守。好的 feedback 两种都要记。

格式要求三行结构——规则、原因、适用场景:

--- name: no-extra-changes description: 只改用户要求的部分,不要顺便改其他代码 type: feedback --- 只改用户要求改的部分。不要加注释、加类型标注、重构周围代码。 **Why:** 之前"顺手"改动多次引入新问题,用户需要精确控制变更范围。 **How to apply:** 所有代码修改操作。

为什么要 Why 和 How to apply?源码注释说得很直白:

Include why so you can judge edge cases later.

没有 Why,模型只会机械执行规则。有了 Why,遇到边缘情况模型能自己判断该不该打破规则。

user(用户画像)—— 影响中等

关于你是谁的信息。模型据此调整沟通方式。

--- name: user-profile description: 高级 Go 开发者,新接触 React,偏好简洁 type: user --- 用户是高级 Go 开发者,10 年经验。刚开始接触项目的 React 前端部分。 偏好简洁代码,不喜欢过度抽象。用中文交流。

project(项目背景)—— 影响中等

不能从代码和 git 历史推导出来的项目信息。

--- name: release-freeze description: 4月3日起冻结非关键合并,移动端切 release 分支 type: project --- 4月3日起冻结非关键 merge,移动端团队切 release 分支。 **Why:** 移动端发版需要稳定的代码基线。 **How to apply:** 4月3日后不建议合并非关键 PR。

注意一个源码里的要求:相对日期必须转为绝对日期。“周四"要写成"2026-04-03”——memory 跨会话,下周再看"周四"就不知道指哪天了。

reference(外部指针)—— 影响最小

指向外部系统的指针,告诉模型哪里能找到信息。

--- name: bug-tracker description: pipeline bug 在 Linear 的 INGEST 项目追踪 type: reference --- Pipeline 相关的 bug 在 Linear 项目 "INGEST" 中追踪。


5. 什么不该存

源码里硬编码了一个排除清单:

✗ 代码模式、架构、文件路径 —— 读代码就能知道 ✗ Git 历史、谁改了什么 —— git log / git blame 是权威来源 ✗ 调试方案和修复步骤 —— 修复已经在代码里 ✗ CLAUDE.md 里已经有的 —— 重复无意义 ✗ 临时任务进度、当前对话上下文 —— 用 task 系统,不是 memory

还有一条值得单独说:

If they ask you to save a PR list or activity summary, ask what was surprising or non-obvious about it — that is the part worth keeping.

即使你说"记住这个 PR 列表",模型应该追问"这里面什么是让你意外的?"——保存那个意外的部分,而不是一整个列表。能从 git log 还原的信息不值得占 memory 的空间。


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 里提到了某个文件路径 → 先检查文件是否还存在 如果 memory 里提到了某个函数名 → 先 grep 确认 "memory 说 X 存在" ≠ "X 现在存在"

所以 memory 里不要写"函数 handleAuth 在 main.go 第 42 行"——文件一改就过时。写"项目用中间件模式处理认证,入口在 main.go"这种不依赖行号的描述。


7. 你没说"记住",它也会自动存

除了你主动说"记住这个",Claude Code 还有一个后台提取机制。

模型完成回答后,如果满足以下条件,会自动启动一个后台 agent 扫描对话内容、提取值得保存的信息:

1.本轮主 agent 没有手动写过 memory

2.extractMemories feature flag 启用

3.auto memory 开启

所以你的 memory 目录里可能有你没主动要求保存的文件——那是后台 agent 提取的。


8. Compact 后 Memory 重新加载

执行 /compact/clear 时,Memory 的缓存会被完全清除:

function runPostCompactCleanup(): void { resetGetMemoryFilesCache('compact') // Memory 文件缓存清除 clearSystemPromptSections() // 包括 memory section }

下一轮对话时 MEMORY.md 被重新读取。

这意味着:如果你在对话中途手动编辑了 memory 文件(比如用编辑器加了一条 feedback),执行 /compact 后修改立即生效。不需要重启。


9. Memory 和 CLAUDE.md 怎么配合

不要重复——源码明确禁止把 CLAUDE.md 里已有的内容存到 memory。

正确的配合方式:

CLAUDE.md 存规则,Memory 存对规则的强化和例外。

比如 CLAUDE.md 写了"commit message 用中文",但模型老是忘。不要在 memory 里再写一遍"commit message 用中文"。写一条 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 的权重,而不是重复内容。feedback 在 system prompt 里(高权重),CLAUDE.md 在 user message 里(低权重),两层叠加比写两遍同一句话有效得多。


10. 安全边界

Memory 目录路径不能通过项目级 settings.json 设置:

// SECURITY: projectSettings is intentionally excluded — a malicious repo // could otherwise set autoMemoryDirectory: "~/.ssh" and gain silent // write access to sensitive directories

防止恶意仓库把 memory 目录指向 ~/.ssh 然后让 AI 往里写文件。只有用户级和管理员级配置可以改路径。

但 memory 文件的内容没有任何校验——你写什么进去就注入什么到 system prompt。这是设计意图:文件在你本地磁盘上,你有完全控制权。

网友解答:
--【壹】--:

已学习,棒棒哒


--【贰】--:

学习学习


--【叁】--:

感谢各位支持


--【肆】--:

感谢分享,前来学习


--【伍】--:

ok,就当下期预告


--【陆】--:

wo03ne?


--【柒】--:

前排学习,感谢佬


--【捌】--:

学习学习


--【玖】--:

学习学习


--【拾】--:

学习一波,加个书签


--【拾壹】--:

前排学习


--【拾贰】--:

学习学习


--【拾叁】--:

type一共有几种类型?


--【拾肆】--:

不错,看完了,第三章呢


--【拾伍】--:

写subagent,agent协作


--【拾陆】--:

向大佬学习


--【拾柒】--:

假装学会了


--【拾捌】--:

点个赞,有时间好好看一下


--【拾玖】--:

第三章不知道写什么了

问题描述: 深入浅出 Claude Code(一):从源码理解 CLAUDE.md,重写你的配置 开发调优
新一期来啦: 大多数人写 CLAUDE.md 的方式是:随便写几条规则,感觉效果不明显,然后放弃。 你不知道这些文字在 Claude 眼里长什么样、被放在哪里、和其他指令的优先级关系是什么。 今天我来带各位佬友们剖析一下 claudecode 的底层逻辑 全网统一小恐龙头像,在别的地方看到的家人们点点赞 1. CLAUDE.md 不在 System Prompt 里 这是最大的认知误…

上一篇我们重写了 CLAUDE.md,但这只是表层。今天这篇,我们将顺着代码的调用栈,扒开 Claude Code 的记忆系统,看看你的指令在底层究竟被赋予了什么级别的权重。

你让 Claude Code "记住"的东西,下次对话它可能完全不记得。或者记得,但不照做。

其实不是功能坏了——是你不清楚这些 memory 在系统里是怎么流动的。存在哪、怎么加载、权重多高、什么格式才有效,搞清楚这条链路,memory 才能真正起作用。

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


1. Memory 存在哪

所有 memory 文件存储在本地文件系统,按项目隔离:

~/.claude/projects/{sanitized-project-path}/memory/ ├── MEMORY.md ← 索引文件 ├── user_profile.md ← topic 文件 ├── feedback_no_summary.md ├── project_deadline.md └── reference_linear.md

{sanitized-project-path} 是你项目根目录的路径哈希。不同项目的 memory 互不干扰。

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

这些就是普通的 markdown 文件,你可以直接用编辑器打开改。


2. 它怎么被加载到模型的

这是整篇最关键的一点。

Claude Code 的输入结构分两层:system promptuser message。Memory 和 CLAUDE.md 分别在这两层里:

System Prompt(优先级更高): 位置 1-9:静态指令(身份、工具使用规范、语气等) 位置 10:会话指导 位置 11:★ Memory 系统指令 + MEMORY.md 索引内容 位置 12-18:环境信息、MCP 指令等 User Message(优先级更低): 第一条:★ CLAUDE.md 内容(包在 <system-reminder> 里,带降权提示) 第二条:你的第一句话 后续:对话历史

两个关键差异:

Memory 在 system prompt 里,没有降权。 模型被直接告知"你有一个持久化的记忆系统,直接用"。

CLAUDE.md 在 user message 里,带降权。 注入时附带一句 this context may or may not be relevant to your tasks,显式告诉模型这些内容可能不相关。

同一条指令,放在 memory 里比放在 CLAUDE.md 里更容易被遵守。这不是玄学,是注入位置和降权声明的直接影响。


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

很多人往 MEMORY.md 里堆大段内容。问题是它有硬截断:

MAX_ENTRYPOINT_LINES = 200 // 超过 200 行,后面的直接丢弃 MAX_ENTRYPOINT_BYTES = 25_000 // 超过 25KB,在最近的换行处截断

截断后末尾追加一条警告,超出部分永久丢失(本次加载)。

MEMORY.md 的正确用法是当索引——每条一行,指向 topic 文件:

- [用户画像](user_profile.md) — 高级 Go 开发者,偏好简洁代码 - [不要总结](feedback_no_summary.md) — 回答结束不要总结做了什么 - [发布冻结](project_release_freeze.md) — 4月3日前不合并非关键 PR

每行控制在 150 字符以内。详细内容写在各自的 topic 文件里——topic 文件没有行数限制。

system prompt 中只注入 MEMORY.md 的内容和 Memory 系统的使用指令。topic 文件只在模型主动用 Read 工具读取时才会被看到。所以 MEMORY.md 索引条目的描述要写得足够清晰——模型根据这一行描述来判断要不要去读 topic 文件。


4. 四种类型:按对行为的影响排序

Memory 文件用 frontmatter 声明类型。四种类型中,对 Claude 行为影响最大的排在前面:

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

“你做错了 X,以后这样做"或"你做对了 Y,继续保持”。

源码对 feedback 的特别说明:

Record from failure AND success: if you only save corrections, you will avoid past mistakes but drift away from approaches the user has already validated, and may grow overly cautious.

只记纠正不记确认,模型会越来越保守。好的 feedback 两种都要记。

格式要求三行结构——规则、原因、适用场景:

--- name: no-extra-changes description: 只改用户要求的部分,不要顺便改其他代码 type: feedback --- 只改用户要求改的部分。不要加注释、加类型标注、重构周围代码。 **Why:** 之前"顺手"改动多次引入新问题,用户需要精确控制变更范围。 **How to apply:** 所有代码修改操作。

为什么要 Why 和 How to apply?源码注释说得很直白:

Include why so you can judge edge cases later.

没有 Why,模型只会机械执行规则。有了 Why,遇到边缘情况模型能自己判断该不该打破规则。

user(用户画像)—— 影响中等

关于你是谁的信息。模型据此调整沟通方式。

--- name: user-profile description: 高级 Go 开发者,新接触 React,偏好简洁 type: user --- 用户是高级 Go 开发者,10 年经验。刚开始接触项目的 React 前端部分。 偏好简洁代码,不喜欢过度抽象。用中文交流。

project(项目背景)—— 影响中等

不能从代码和 git 历史推导出来的项目信息。

--- name: release-freeze description: 4月3日起冻结非关键合并,移动端切 release 分支 type: project --- 4月3日起冻结非关键 merge,移动端团队切 release 分支。 **Why:** 移动端发版需要稳定的代码基线。 **How to apply:** 4月3日后不建议合并非关键 PR。

注意一个源码里的要求:相对日期必须转为绝对日期。“周四"要写成"2026-04-03”——memory 跨会话,下周再看"周四"就不知道指哪天了。

reference(外部指针)—— 影响最小

指向外部系统的指针,告诉模型哪里能找到信息。

--- name: bug-tracker description: pipeline bug 在 Linear 的 INGEST 项目追踪 type: reference --- Pipeline 相关的 bug 在 Linear 项目 "INGEST" 中追踪。


5. 什么不该存

源码里硬编码了一个排除清单:

✗ 代码模式、架构、文件路径 —— 读代码就能知道 ✗ Git 历史、谁改了什么 —— git log / git blame 是权威来源 ✗ 调试方案和修复步骤 —— 修复已经在代码里 ✗ CLAUDE.md 里已经有的 —— 重复无意义 ✗ 临时任务进度、当前对话上下文 —— 用 task 系统,不是 memory

还有一条值得单独说:

If they ask you to save a PR list or activity summary, ask what was surprising or non-obvious about it — that is the part worth keeping.

即使你说"记住这个 PR 列表",模型应该追问"这里面什么是让你意外的?"——保存那个意外的部分,而不是一整个列表。能从 git log 还原的信息不值得占 memory 的空间。


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 里提到了某个文件路径 → 先检查文件是否还存在 如果 memory 里提到了某个函数名 → 先 grep 确认 "memory 说 X 存在" ≠ "X 现在存在"

所以 memory 里不要写"函数 handleAuth 在 main.go 第 42 行"——文件一改就过时。写"项目用中间件模式处理认证,入口在 main.go"这种不依赖行号的描述。


7. 你没说"记住",它也会自动存

除了你主动说"记住这个",Claude Code 还有一个后台提取机制。

模型完成回答后,如果满足以下条件,会自动启动一个后台 agent 扫描对话内容、提取值得保存的信息:

1.本轮主 agent 没有手动写过 memory

2.extractMemories feature flag 启用

3.auto memory 开启

所以你的 memory 目录里可能有你没主动要求保存的文件——那是后台 agent 提取的。


8. Compact 后 Memory 重新加载

执行 /compact/clear 时,Memory 的缓存会被完全清除:

function runPostCompactCleanup(): void { resetGetMemoryFilesCache('compact') // Memory 文件缓存清除 clearSystemPromptSections() // 包括 memory section }

下一轮对话时 MEMORY.md 被重新读取。

这意味着:如果你在对话中途手动编辑了 memory 文件(比如用编辑器加了一条 feedback),执行 /compact 后修改立即生效。不需要重启。


9. Memory 和 CLAUDE.md 怎么配合

不要重复——源码明确禁止把 CLAUDE.md 里已有的内容存到 memory。

正确的配合方式:

CLAUDE.md 存规则,Memory 存对规则的强化和例外。

比如 CLAUDE.md 写了"commit message 用中文",但模型老是忘。不要在 memory 里再写一遍"commit message 用中文"。写一条 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 的权重,而不是重复内容。feedback 在 system prompt 里(高权重),CLAUDE.md 在 user message 里(低权重),两层叠加比写两遍同一句话有效得多。


10. 安全边界

Memory 目录路径不能通过项目级 settings.json 设置:

// SECURITY: projectSettings is intentionally excluded — a malicious repo // could otherwise set autoMemoryDirectory: "~/.ssh" and gain silent // write access to sensitive directories

防止恶意仓库把 memory 目录指向 ~/.ssh 然后让 AI 往里写文件。只有用户级和管理员级配置可以改路径。

但 memory 文件的内容没有任何校验——你写什么进去就注入什么到 system prompt。这是设计意图:文件在你本地磁盘上,你有完全控制权。

网友解答:
--【壹】--:

已学习,棒棒哒


--【贰】--:

学习学习


--【叁】--:

感谢各位支持


--【肆】--:

感谢分享,前来学习


--【伍】--:

ok,就当下期预告


--【陆】--:

wo03ne?


--【柒】--:

前排学习,感谢佬


--【捌】--:

学习学习


--【玖】--:

学习学习


--【拾】--:

学习一波,加个书签


--【拾壹】--:

前排学习


--【拾贰】--:

学习学习


--【拾叁】--:

type一共有几种类型?


--【拾肆】--:

不错,看完了,第三章呢


--【拾伍】--:

写subagent,agent协作


--【拾陆】--:

向大佬学习


--【拾柒】--:

假装学会了


--【拾捌】--:

点个赞,有时间好好看一下


--【拾玖】--:

第三章不知道写什么了