Claude Code 每开一个新会话,上下文窗口都是一张白纸——它不会自动记得你上次纠正过什么、这个项目用什么构建命令。要让知识跨会话留下来,靠两套互补的机制:
- CLAUDE.md:你手写的持久指令,Claude 每次会话开头都读。
- 自动记忆(auto memory):Claude 自己写的笔记,根据你的纠正和偏好,它觉得"以后用得上"就记下来。
这篇把这两套机制讲透:各自该装什么、放在哪、怎么加载、怎么拆分管理、怎么排查不生效的问题。
一、先分清:CLAUDE.md vs 自动记忆
两者都在每次会话开始时载入,而且 Claude 都把它们当作上下文(context),不是强制配置——也就是说,它们是"指引",Claude 会尽量遵守但不保证 100%。要硬性拦截某个动作,得用 PreToolUse hook,那才是强制层。
| CLAUDE.md | 自动记忆 | |
|---|---|---|
| 谁写 | 你 | Claude |
| 内容 | 指令、规则 | 学到的经验、模式 |
| 作用域 | 项目 / 用户 / 组织 | 按仓库,worktree 间共享 |
| 载入 | 每次会话 | 每次会话(前 200 行 / 25KB) |
| 适合 | 编码规范、工作流、架构 | 构建命令、调试心得、它发现的你的偏好 |
一句话:想主动"指挥"Claude 的行为,写 CLAUDE.md;想让它"从你的纠正里自己学",开自动记忆。
二、CLAUDE.md:你手写的持久指令
什么时候该往里加东西
把 CLAUDE.md 当成"否则你就得反复重新解释"的那些东西的归处。出现这些信号就该加:
- Claude 第二次犯同一个错;
- code review 抓到一个它本该知道的本仓库惯例;
- 你这次会话又敲了上次敲过的那句纠正/澄清;
- 一个新同事需要同样的背景才能上手。
只放"每次会话都该记得"的事实:构建命令、约定、项目结构、“永远做 X"的规则。如果某条是多步流程、或只跟代码库某一部分有关,就别塞 CLAUDE.md——挪去 skill 或带路径作用域的 rule。
放在哪:四个作用域
CLAUDE.md 可以放在多个位置,作用域不同。下表按加载顺序(从最宽到最具体)排列——越具体的越后读、优先级越高:
| 作用域 | 位置 | 共享给谁 |
|---|---|---|
| 受管策略(组织级) | 系统级目录(见表下) | 全组织(IT/DevOps 下发,个人无法排除) |
| 用户级 | ~/.claude/CLAUDE.md |
只有你,所有项目 |
| 项目级 | ./CLAUDE.md 或 ./.claude/CLAUDE.md |
团队(随版本控制共享) |
| 本地级 | ./CLAUDE.local.md |
只有你,当前项目 |
受管策略的系统级路径按操作系统区分:
- macOS:
/Library/Application Support/ClaudeCode/CLAUDE.md - Linux / WSL:
/etc/claude-code/CLAUDE.md - Windows:
C:\Program Files\ClaudeCode\CLAUDE.md
本地级的 CLAUDE.local.md 记得加进 .gitignore,免得跟着提交。
工作目录及其上层的 CLAUDE.md / CLAUDE.local.md 在启动时全量加载;子目录里的则按需加载——当 Claude 读到那个子目录的文件时才载入。
小技巧:跑
/init能自动生成一份起步 CLAUDE.md——Claude 分析你的代码库,把发现的构建命令、测试方式、项目约定写进去。已有 CLAUDE.md 时它会建议改进而不是覆盖。
写出"管用"的指令
CLAUDE.md 每次会话都进上下文、占 token,而且是"指引"不是"强制”,所以怎么写直接影响遵守程度:
- 篇幅:单个文件控制在 200 行内。太长既费上下文又降低遵守率。要长就用路径作用域 rule 拆分。
- 结构:用 markdown 标题和列表分组。Claude 和人一样扫结构,有组织的段落比密密麻麻的大段好读。
- 具体:写到能验证的程度。
- ✅ “用 2 空格缩进” ❌ “格式化好代码”
- ✅ “提交前跑
npm test” ❌ “测试你的改动” - ✅ “API handler 放在
src/api/handlers/” ❌ “文件组织好”
- 一致:两条规则互相矛盾时,Claude 可能随机选一条。定期清理过期/冲突的指令。
用 @import 引入其它文件
CLAUDE.md 可以用 @path/to/import 语法引入别的文件,被引入的内容在启动时展开并一起进上下文。相对路径相对于"引用它的文件"解析(不是工作目录),最多递归 4 层。
See @README for project overview and @package.json for available npm commands.
# Additional Instructions
- git workflow @docs/git-instructions.md
注意:@import 只是组织手段,不省上下文——被引入的文件照样在启动时全量载入。真正想省上下文,用下面的路径作用域 rule。
跨 worktree 的个人偏好:gitignore 的 CLAUDE.local.md 只存在于你创建它的那个 worktree。想跨 worktree 共享,改成从家目录引入:
@~/.claude/my-project-instructions.md。
已经有 AGENTS.md 怎么办
Claude Code 只读 CLAUDE.md,不读 AGENTS.md。如果你的仓库已经为别的 agent 用了 AGENTS.md,建一个 CLAUDE.md 把它引进来,两边就共用同一份、不重复:
@AGENTS.md
## Claude Code
Use plan mode for changes under `src/billing/`.
不需要加 Claude 专属内容的话,软链也行:ln -s AGENTS.md CLAUDE.md(Windows 建软链需要管理员/开发者模式,建议改用 @AGENTS.md 引入)。
多个 CLAUDE.md 怎么叠加
Claude Code 从当前工作目录向上逐级找 CLAUDE.md 和 CLAUDE.local.md,全部拼接进上下文(不是互相覆盖)。顺序是从文件系统根往下到工作目录——也就是越靠近你启动位置的越后读;同一目录内 CLAUDE.local.md 排在 CLAUDE.md 之后。
两个细节很实用:
- 块级 HTML 注释(
<!-- 维护者备注 -->)会在注入上下文前被剥掉,所以可以用它给人留备注而不浪费 token(代码块内的注释保留)。 - monorepo 里别的团队的 CLAUDE.md 被误读时,用
claudeMdExcludes按路径/glob 跳过。
三、用 .claude/rules/ 拆分大项目
项目一大,所有规则堆在一个 CLAUDE.md 就难维护了。.claude/rules/ 让你把指令拆成多个主题文件,而且能按文件路径作用域加载——只在 Claude 处理匹配文件时才进上下文,省噪音省空间。
your-project/.claude/
├── CLAUDE.md # 主项目指令
└── rules/
├── code-style.md # 代码风格
├── testing.md # 测试约定
└── security.md # 安全要求
rules/ 下所有 .md 递归发现,可以放 frontend/ backend/ 子目录。没有 paths: 的 rule 开局加载,优先级和 .claude/CLAUDE.md 相同。
路径作用域 rule:省上下文的关键
给 rule 加 YAML frontmatter 的 paths 字段,它就只在 Claude 读到匹配文件时才触发:
---
paths:
- "src/api/**/*.ts"
---
# API Development Rules
- 所有 API 端点必须做输入校验
- 用统一的错误响应格式
- 带上 OpenAPI 文档注释
glob 写法:
| 模式 | 匹配 |
|---|---|
**/*.ts |
任意目录下所有 TS 文件 |
src/**/* |
src/ 下所有文件 |
*.md |
项目根的 markdown |
src/components/*.tsx |
指定目录的 React 组件 |
也支持多个模式 + 花括号展开:"src/**/*.{ts,tsx}"。
跨项目共享 rule 可以用软链:
ln -s ~/shared-claude-rules .claude/rules/shared。个人级 rule 放~/.claude/rules/,对所有项目生效,且优先级低于项目级。
四、自动记忆:Claude 自己记笔记
自动记忆(auto memory)让 Claude 不用你写就跨会话积累知识:构建命令、调试心得、架构笔记、代码风格偏好、工作习惯。它不是每次都记,而是判断"这条信息以后会不会有用"再决定。
需要 Claude Code v2.1.59+,
claude --version查看。
开关
默认开启。会话里跑 /memory 用开关切换,或在项目设置里 "autoMemoryEnabled": false,或环境变量 CLAUDE_CODE_DISABLE_AUTO_MEMORY=1。
存在哪
每个项目一个目录:~/.claude/projects/<project>/memory/。<project> 由 git 仓库路径推导,所以同一仓库的所有 worktree 和子目录共享一份。
~/.claude/projects/<project>/memory/
├── MEMORY.md # 简洁索引,每次会话载入
├── debugging.md # 调试模式的详细笔记
├── api-conventions.md # API 设计决策
└── ... # Claude 创建的其它主题文件
MEMORY.md 是整个目录的索引。它每次会话载入前 200 行(或 25KB,先到为准);超出部分不载入。Claude 通过把详细内容挪进主题文件来保持 MEMORY.md 精简,主题文件(如 debugging.md)不在启动时载入,而是 Claude 需要时按需读取。
这是机器本地的,不跨机器/云环境共享。界面上出现 “Writing memory” / “Recalled memory” 就是它在读写这个目录。
审阅与编辑
自动记忆全是纯 markdown,随时可读可改可删。跑 /memory 就能浏览并打开这些文件。当你对 Claude 说"以后一律用 pnpm 不用 npm"或"记住 API 测试需要本地 Redis",它就存进自动记忆;想存进 CLAUDE.md 则直接说"把这条加进 CLAUDE.md"。
五、指令不被遵守?排查清单
Claude 没按我的 CLAUDE.md 来
CLAUDE.md 是作为系统提示之后的一条用户消息送进去的,不是系统提示本身——Claude 会读会尽量照做,但不保证严格遵守,尤其指令含糊或冲突时。排查:
- 跑
/memory确认文件确实被加载了(没列出来就是 Claude 根本看不到); - 确认这个 CLAUDE.md 在会被加载的位置;
- 把指令写更具体(“用 2 空格缩进” 胜过 “格式化好”);
- 找冲突指令——多个文件对同一行为给了不同说法,Claude 会随机选。
如果某条必须在特定时机执行(每次提交前、每次编辑后),写成 hook,那是按生命周期事件确定性执行的,不受 Claude"决定"影响。
不知道自动记忆存了啥
/memory → 选自动记忆文件夹,全是 markdown,随便读/改/删。
CLAUDE.md 太大了
超 200 行会费上下文、降遵守率。用路径作用域 rule 让指令只在处理匹配文件时载入,或直接精简。注意 @import 帮组织但不省上下文(引入的文件照样开局全载)。
/compact 后指令好像丢了
项目根的 CLAUDE.md 能扛过压缩——/compact 后 Claude 会从磁盘重新读、重新注入。但子目录里嵌套的 CLAUDE.md 不会自动重注入,要等下次 Claude 读到那个子目录的文件才重载。所以:只在对话里说过的指令、或还没重载的嵌套 CLAUDE.md,压缩后可能"消失"——把只在对话里说过的指令写进 CLAUDE.md 就能持久。
小结
把 Claude Code 的记忆体系记成两条线:
- 你写的(CLAUDE.md):四个作用域(组织 > 用户 > 项目 > 本地),向上逐级全量拼接;大项目用
.claude/rules/+paths:作用域拆分省上下文;@import只帮组织不省 token;只读 CLAUDE.md 不读 AGENTS.md(用@AGENTS.md桥接)。 - Claude 写的(自动记忆):默认开,存
~/.claude/projects/<project>/memory/,MEMORY.md当索引每次载入前 200 行,详细内容拆主题文件按需读;纯 markdown 可随时审阅。
最后记牢那条边界:CLAUDE.md 和自动记忆都是"指引"不是"强制"。要硬规则,用 hooks 和 permissions。
关于
关注我获取更多资讯