Memory 系统:CLAUDE.md + auto memory
原文:https://code.claude.com/docs/en/memory 官方定位:Each Claude Code session begins with a fresh context window. Two mechanisms carry knowledge across sessions: CLAUDE.md files (you write) + Auto memory (Claude writes itself). 要求:auto memory 需要 v2.1.59+;
/memory命令在所有现代版本可用
🔥 影响力卡片
| 维度 | 数据 |
|---|---|
| 两条互补系统 | CLAUDE.md(你写,给指令)+ Auto memory(Claude 自己写,记 pattern) |
| CLAUDE.md 5 个 scope | managed policy / project / project-.claude/CLAUDE.md / user(~/.claude/CLAUDE.md)/ local(CLAUDE.local.md,gitignored) |
| Auto memory 存哪 | ~/.claude/projects/<project-hash>/memory/MEMORY.md + 主题文件 |
| MEMORY.md 加载阈值 | 前 200 行 / 25KB(超出不进 context — 主题文件按需加载) |
| CLAUDE.md 加载阈值 | 全文加载(无阈值,但建议 ≤200 行) |
.claude/rules/ 高级 | 支持 paths: glob 限定何时加载 — 大型项目省 context |
| 兼容 AGENTS.md | @AGENTS.md import 或 symlink — Cursor/Windsurf 用户无需重写 |
| 典型 auto memory 沉淀量 | 几个月使用后,项目 memory 目录通常会有 5-10 个 feedback/project/reference 文件,均积累自历史 chat |
🎯 为什么必读
1. Memory 是 Claude Code 跟 ChatGPT/Copilot 最显著的差别。
ChatGPT 的 “Memory” 是黑盒。Claude Code 的 memory 是纯磁盘文件(markdown),你能 read / edit / delete / version control。完全透明。
2. 用过几个月的项目,auto memory 已经在悄悄重度积累。
打开任意一个常用项目的 memory 目录,通常长这样:
~/.claude/projects/<this-project>/memory/
├── MEMORY.md
├── feedback_<topic-1>.md
├── feedback_<topic-2>.md
├── feedback_<topic-3>.md
├── reference_<external-system>.md
└── project_<initiative>.md
这些都是 Claude 自动沉淀的 — 每次你纠正 / 表扬 / 给反馈,Claude 自己决定要不要写进来。
3. 跟 .claude/rules/ 的 paths: 字段一起,实现了真正的”按需加载”知识库。
CLAUDE.md 是”启动时全加载”。.claude/rules/<topic>.md 加 paths: ["src/api/**"] 后,只有你改 src/api/ 下的文件时它才进 context。
4. 跟 skill / hook / subagent memory 联动
| 机制 | 加载时机 | 存哪 |
|---|---|---|
| CLAUDE.md | session 启动 | ./CLAUDE.md |
| Auto memory | session 启动 + 期间动态 | ~/.claude/projects/.../memory/ |
.claude/rules/*.md | 启动 + 路径匹配时 | .claude/rules/ |
| Skill body | skill 触发时 | plugin / .claude/skills/ |
| Subagent memory | subagent 启动时 | ~/.claude/agent-memory/<agent>/ |
全部用 markdown 文件。
一句话总结
Memory = 一组磁盘上的 markdown 文件**,Claude 启动时读相关的、运行时按需读其他、auto memory 还会自己写。你写 CLAUDE.md 给指令,Claude 写 auto memory 学 pattern;两条都进每个 session 的 context。**
💎 金句墙
★ “CLAUDE.md content is delivered as a user message after the system prompt, not as part of the system prompt itself. Claude reads it and tries to follow it, but there’s no guarantee of strict compliance.” “CLAUDE.md 是作为系统提示之后的 user message 发给 Claude — 它会读、会尽量遵循,但不保证严格执行。” —— 🟢 重要事实 — Memory 不是配置,是上下文。要硬执行用 Hook
★ “Each project gets its own memory directory at
~/.claude/projects/<project>/memory/. The<project>path is derived from the git repository, so all worktrees and subdirectories within the same repo share one auto memory directory.” “每个项目独立 memory 目录,基于 git repo 派生,所有 worktree / 子目录共享同一份 auto memory。” —— 🟢 这就是为什么 background session 用 worktree 跑时,记忆不会分裂
★ “Auto memory is machine-local.” “Auto memory 是本机限定的。” —— 🟢 跨机器不同步。要团队共享,只能写进 CLAUDE.md 并 git commit
📋 核心精读
1. CLAUDE.md 5 个加载位置 + 优先级
| 优先级 | 路径 | 范围 |
|---|---|---|
| 最高 | /Library/Application Support/ClaudeCode/CLAUDE.md(macOS)等 managed 路径 | 整个机器,IT 推 |
| 项目 | ./CLAUDE.md 或 ./.claude/CLAUDE.md | 项目所有人(进 git) |
| 个人 | ~/.claude/CLAUDE.md | 你所有项目 |
| 本地 | ./CLAUDE.local.md | 你 + 当前项目(gitignored) |
叠加规则:不是覆盖,是合并 — 全部都加载,顺序从 root 往下,内层在外层之后(后写优先生效)。
一个典型的独立开发者配置:
~/.claude/CLAUDE.md ← 全局个人偏好(协作风格、技术纪律、隐私红线)
+
项目根目录 ./CLAUDE.md 或 ./.claude/CLAUDE.md(可选)
+
./CLAUDE.local.md(可选,本地未提交的临时说明)
→ 只有全局 CLAUDE.md 时,所有项目共享同一份指令。加上项目 CLAUDE.md,就能对单仓库做特化覆盖。
2. 目录树向上 walk — 多层叠加
~/code/monorepo/projects/my-feature/ ← 当前 cwd
├── CLAUDE.md (如果有 → 加载)
~/code/monorepo/projects/
├── CLAUDE.md (如果有 → 加载,放在上面那个之前)
~/code/monorepo/
├── CLAUDE.md (如果有 → 加载,再前面)
~/code/
├── CLAUDE.md (如果有 → 加载,再前面)
...
~/
└── .claude/CLAUDE.md ← user 全局
实际上 Claude 走整个路径树,一路找 CLAUDE.md + CLAUDE.local.md。子目录下的不在启动时全加载,而是 Claude 读那个子目录文件时才会加载。
→ 给 monorepo 用户准备的:不会一次塞整个仓库的 CLAUDE.md 进 context。
3. AGENTS.md 兼容性
如果你的 repo 已经用 AGENTS.md(Cursor / Windsurf / Aider 等都用这个文件名):
# CLAUDE.md(根目录)
@AGENTS.md
## Claude Code 专属
Use plan mode for changes under `src/billing/`.
或者 symlink:
ln -s AGENTS.md CLAUDE.md
→ 一份指令,所有 AI 工具共享。/init 命令在已有 AGENTS.md 时会自动 reads 并合并。
4. .claude/rules/ + paths: glob — 高级用法(很多人不知道)
my-project/
├── .claude/
│ ├── CLAUDE.md
│ └── rules/
│ ├── code-style.md # 总是加载(没 paths)
│ ├── api.md # 只在改 src/api/ 时加载
│ └── frontend.md # 只在改 src/components/ 时加载
api.md frontmatter:
---
paths:
- "src/api/**/*.ts"
- "src/api/**/*.tsx"
---
# API conventions
All endpoints must include input validation.
Use the standard error response format.
没 paths 字段的 rules = 无条件加载(跟 CLAUDE.md 一样,启动时进 context)
有 paths 字段的 = 只在 Claude 读匹配文件时加载
支持的 glob:
| 模式 | 匹配 |
|---|---|
**/*.ts | 所有 ts 文件 |
src/**/* | src/ 下任何文件 |
*.md | 项目根的 markdown |
src/components/*.tsx | 特定目录的 React 组件 |
src/**/*.{ts,tsx} | brace 扩展 |
monorepo 场景:多 demo / 多子项目的 monorepo 仓库可以建:
~/code/my-monorepo/
├── CLAUDE.md ← 总览:仓库定位 + 共性约束
├── .claude/
│ └── rules/
│ ├── frontend-projects.md paths: "projects/*-web/**"
│ ├── content-projects.md paths: "projects/*-curation/**"
│ └── api-projects.md paths: "projects/*-api/**"
切到不同子项目时,Claude 只加载相关的 rules,不会一次塞整个仓库的指令进 context。
5. Auto memory — Claude 替你做笔记
触发条件:
- 你纠正 Claude(“不,这里应该用 X 而不是 Y”)
- 你确认非显然做法(“是的就这样做,继续这种风格”)
- 你告诉它记下来(“以后这种情况都用 X”)
Claude 决定要不要写:
- 信息对未来有用 → 写
- 信息仅当前 session 有用 → 不写
存储:
~/.claude/projects/<project-hash>/memory/
├── MEMORY.md ← 索引,启动时加载前 200 行
├── feedback_<topic>.md ← 反馈类
├── project_<name>.md ← 项目状态类
├── reference_<system>.md ← 外部引用类
├── user_<aspect>.md ← 用户身份类
└── ... ← Claude 自己起名
<project-hash> 是基于 git repo 派生的 — 同一仓库的所有 worktree / 子目录共享一份 memory。
只 MEMORY.md 是启动加载(前 200 行)。其他主题文件是 Claude 运行时按需 Read 的。所以你可以放心写长。
6. 一个常见的 auto memory 形态
用过几个月的内容创作型项目里,memory 目录可能长这样:
- feedback_<workflow-discipline>.md ← 反复出现的工作流纠错
- feedback_<tool-pitfall>.md ← 某个工具的反直觉行为
- feedback_<quality-bar>.md ← 内容质量标准
- project_<long-running-effort>.md ← 跨 session 的长项目
- reference_<external-pipeline>.md ← 外部系统位置
典型分布观察:
- 文件类型偏 feedback(纠错记忆比内容标签更值钱)
- 没有 user_* 类(关于个人角色的) — 当 CLAUDE.md 已覆盖角色描述时,Claude 不会另外写
- 当前进行中的项目通常还没有
project_*文件 — Claude 写得相对保守,要等积累到某个临界点才决定是否沉淀
7. /memory 命令 — 实时查看 + 编辑
> /memory
# 列出所有当前 session 加载的 CLAUDE.md / CLAUDE.local.md / rules / auto memory
# 选一个文件 → 打开编辑器
# 也能 toggle auto memory on/off
告诉 Claude 记:
> always use pnpm, not npm
# → Claude 自动写到 auto memory(具体哪个文件 Claude 决定)
> add this to CLAUDE.md instead
# → 写到 CLAUDE.md
8. CLAUDE.md 怎么写才好(摘自 best practices)
# Project: My Demo App
## Build
- Run `bun dev` for local development
- Run `bun test` before committing
## Style
- Use 2-space indentation
- Functional React components, no classes
- Tabs in Python, spaces in TypeScript
## Architecture
- API handlers in `src/api/`
- Components in `src/components/`
- Hooks in `src/hooks/`
## Don't
- Don't run `git push` without explicit instruction
- Don't add new dependencies without asking
关键纪律:
- ≤ 200 行(超过会降低 adherence)
- 具体(“2-space indentation” 比 “format code properly” 强)
- 可验证(“Run
npm testbefore committing” 比 “Test your changes” 强) - 不矛盾(两条规则相互打架时 Claude 任选一个)
9. 跟 Compact 的关系(必懂)
session context 满了 → /compact 自动压缩对话。此时:
| 类型 | 是否幸存 |
|---|---|
| 项目根 CLAUDE.md | ✅ 重新从磁盘读,重新注入 |
| 嵌套子目录 CLAUDE.md | ❌ 不自动重读 — 下次 Claude 读那个子目录文件时才回来 |
| Auto memory MEMORY.md | ✅ 同 CLAUDE.md |
| 调用过的 skill | ✅ 每个 skill 保前 5000 tokens,总预算 25k |
| 对话历史 | ❌ 压缩成 summary |
意味着:如果你在 chat 里随口说”以后这个项目用 pnpm”,这个指令会在 compact 后消失(它没进任何持久化文件)。要持久化:让 Claude 写进 CLAUDE.md 或让 auto memory 接管。
10. InstructionsLoaded Hook — 调试用
如果你怀疑某个 CLAUDE.md / rule 没被加载,装这个 hook:
{
"hooks": {
"InstructionsLoaded": [
{
"hooks": [
{
"type": "command",
"command": "jq -r '.file_path' >> ~/claude-loaded.log"
}
]
}
]
}
}
每次 CLAUDE.md / rule 加载都会写一行日志,你能看到加了什么、什么时候加的、为什么加的(load_reason: session_start / nested_traversal / path_glob_match / include / compact)。
11. autoMemoryDirectory 自定义 auto memory 存哪
只能在 ~/.claude/settings.json 设(防止恶意 cloned repo 改这个):
{
"autoMemoryDirectory": "~/my-special-memory-place"
}
实际用例:
- 想把 memory 进 git(同步多机)→ 设到你某个私有 repo 里
- 想隔离 work / personal 项目的 memory → 用不同的
CLAUDE_CONFIG_DIR(更彻底)
🟢 译者总评
1. Memory 系统的设计核心:不强制,但赋能
“Claude reads it and tries to follow it, but there’s no guarantee of strict compliance.”
这跟 Cursor 的 .cursorrules(强制行为)/ Aider 的 system prompt 完全不同。Claude 故意把 memory 做成”context 一部分”而不是”硬约束”。好处:你可以更松地写,不用怕一条不严格的规则把 Claude 卡死。代价:复杂规则可能被忽略。
要硬执行 → 用 Hook(本系列 06-hooks.md)。
2. Auto memory 已经在跑了,但可以更系统化:
a. 主动告诉 Claude 沉淀什么
session 里直接说:
> 把"我所有 demo 项目都放 ~/code/<name>/,
> 这是个 monorepo,每个项目独立 git history 不开"记到 memory
b. 自己 /memory 一次,清理冗余
打开 /memory 看一遍每个 auto memory 文件 — Claude 写的是不是还对?有没有冲突?有没有过期?
c. 升级到 .claude/rules/ + paths:
如果某些指令只跟某类项目相关,把它们从全局 CLAUDE.md 拎出来,放 .claude/rules/,加 paths: 缩限。
3. 关于”AI 记忆”哲学
Claude Code 的 memory 设计跟 ChatGPT 的截然不同:
| ChatGPT Memory | Claude Code Memory | |
|---|---|---|
| 存哪 | OpenAI 服务器 | 你机器(~/.claude/) |
| 看得见 | 在 settings 看 | 直接 markdown 文件 |
| 改得了 | 删除某条 | 任意编辑 |
| Git track | 不行 | CLAUDE.md 可以;auto memory 不进 git |
| 跨工具 | 不能 | AGENTS.md 通用 |
Anthropic 的赌注:开发者要透明可控的 memory,而不是”AI 自己学就好”。这种设计跟 plugin、skills、hooks 一脉相承 — 一切都是磁盘上的 markdown 或 JSON。
4. 警惕的反模式
- ❌ CLAUDE.md 写得跟 manual 一样长 → 200 行硬约束记着
- ❌ 多个 CLAUDE.md 指令打架 → Claude 任选一个,行为不可预期
- ❌ 把 secrets / API key 写进 CLAUDE.md → 会进 git 暴露
- ❌ 用 auto memory 当 todo list → 它不是任务管理,是知识沉淀
- ❌ 期望 Claude 在 strict mode 跑 → memory 不是硬约束,要硬约束用 hook
🔗 延伸阅读
- 同系列:
05-skills-system.md(skill 跟 memory 互补 — memory 是上下文,skill 是流程)、06-hooks.md(InstructionsLoaded hook + 硬约束)、08-subagents.md(subagent 自己的持久化 memory) - 官方:
/en/context-window— 看 CLAUDE.md / memory 加载占 context 多少 - 官方:
/en/debug-your-config— 排查”指令为什么没生效” - 工具书:
/en/settings—autoMemoryEnabled/autoMemoryDirectory/claudeMd/claudeMdExcludes
🔗 调研来源(可校验)
- 主原文:
https://code.claude.com/docs/en/memory - user CLAUDE.md 位置:
~/.claude/CLAUDE.md - auto memory 目录:
~/.claude/projects/<project-hash>/memory/(<project-hash>由 cwd 派生) - v2.1.59 引入 auto memory 的版本约束:本文档明确
- 跟 AGENTS.md 兼容:文档专门列了
@AGENTS.mdimport 和 symlink 两种方式