一句话版本:CLAUDE.md 常驻上下文,所以「短而具体」远比「大而全」有效;只对部分文件生效的约定,拆进带 paths: 的 rules 文件,按需载入。
为什么这天学这个
D1 里我们看到,Claude Code 的每一轮 agentic loop 都从同一个上下文出发,而 CLAUDE.md 是这个上下文里「每个会话都在场」的固定部分——会话启动时载入,之后每一轮都带着它。D2 又算过账:常驻上下文的每一行都在持续消耗 token。把这两件事连起来,就得到本课的核心问题:这份「永远在场」的文件,该放在哪、写什么、怎么在变长之后拆分。
本课也为后面铺路:D7 的 Skills 是「按需载入」的另一半——CLAUDE.md 和不带 paths: 的规则常驻上下文,Skills 只在被调用时载入,分清这两类是搭配置体系的基础。而 D8 的 Hooks 解决 CLAUDE.md 管不住的事:CLAUDE.md 是建议,Hooks 才是强制。
概念讲清楚
CLAUDE.md 是什么:你写的持久指令
官方每个 Claude Code 会话都从空白上下文开始,跨会话携带知识的机制有两套:CLAUDE.md(你写的指令)和 auto memory(Claude 自己记的笔记)。两者都在每个会话开始时载入。本课聚焦前者;auto memory 只需先知道三点:默认开启、存在 ~/.claude/projects/<project>/memory/、每次会话只载入其索引 MEMORY.md 的前 200 行或 25KB。
官方关键定位:这两套记忆都是「上下文」,不是「强制配置」。Claude 会读并尽力遵循,但没有硬约束——想无论如何拦下某个动作,要用 PreToolUse hook(D8 展开)。指令写得越具体、越简洁,遵循得越稳定。
四个层级,一个拼接顺序
官方CLAUDE.md 可以放在四种位置,作用域从宽到窄。载入时按「从宽到窄」的顺序拼接进上下文,所以项目指令出现在用户指令之后;官方对全局 CLAUDE.md 的说明也写明:两者同时在场,指令冲突时项目级优先。
| 层级 | 位置 | 给谁用 | 是否入库 |
|---|---|---|---|
| 组织策略 | macOS /Library/Application Support/ClaudeCode/CLAUDE.md(Linux/WSL 与 Windows 另有对应路径) | 全组织,由 IT 统一下发,个人无法排除 | 由 IT 管理 |
| 用户级 | ~/.claude/CLAUDE.md | 你自己,所有项目 | 否 |
| 项目级 | ./CLAUDE.md 或 ./.claude/CLAUDE.md | 团队,随源码共享 | 是,进 git |
| 本地项目 | ./CLAUDE.local.md | 你自己,仅本项目 | 否,加进 .gitignore |
加载规则:向上全载,向下按需
官方启动时,Claude Code 从当前工作目录一路向上走到文件系统根,沿途每一层目录的 CLAUDE.md 和 CLAUDE.local.md 全部载入。所有文件是拼接进上下文,不互相覆盖:目录树上层的在前、越接近工作目录的越靠后;同一目录内 CLAUDE.local.md 排在 CLAUDE.md 之后。子目录方向则相反:工作目录之下的 CLAUDE.md 不在启动时载入,等 Claude 实际读到那个目录里的文件时才按需带入。
官方几条容易错过的细节:CLAUDE.md 里的块级 HTML 注释(<!-- … -->)在注入上下文前会被剥离,可以拿来写给人看的维护备注,不花 token;文件里可以用 @path/to/import 语法引入其他文件,被引入的文件在启动时一并展开载入(相对路径相对于所在文件,最多递归 4 层,写在反引号里则不触发);项目文件里指向工作目录之外的 import,首次会弹确认框。另外 Claude Code 只读 CLAUDE.md、不读 AGENTS.md——已有 AGENTS.md 的仓库,官方建议在 CLAUDE.md 里写一行 @AGENTS.md 引入,或直接建符号链接。
该写什么,不该写什么
官方判断标准就一句:对每一行问「删掉它,Claude 会因此犯错吗?」不会就删。官方给出的取舍对照:
| 该写 | 不该写 |
|---|---|
| Claude 猜不出来的构建/测试/部署命令 | 读代码就能推断的内容(目录结构、依赖清单) |
| 与默认不同的代码风格规则 | 语言通用惯例(Claude 本来就会) |
| 测试跑法与首选 test runner | 详细 API 文档(放链接即可) |
| 分支命名、PR 约定等仓库礼仪 | 频繁变化的信息 |
| 项目特有的架构决策 | 长篇解释和教程 |
| 环境怪癖(必需的环境变量) | 逐文件的代码库描述 |
| 常见坑与非直觉行为 | 「写干净代码」这类不可验证的空话 |
官方体量目标:单个 CLAUDE.md 控制在 200 行以内。超长文件仍会整份载入,但会挤占上下文并降低遵循度。写法上三条原则:具体可验证(「用 2 空格缩进」优于「格式要规范」)、结构化(标题加列表,别写成大段落)、无冲突(两条规则打架时,Claude 可能任选一条执行)。拆分时注意:@import 只解决组织问题,被引入的文件启动时照样载入,不省上下文;真正省上下文的是下面的 path-scoped rules。
rules:把指令拆成多文件,按路径生效
官方项目大了以后,把指令拆进 .claude/rules/ 目录:每个 .md 文件讲一个主题(如 testing.md、api-design.md),子目录也会被递归发现。不带 paths: frontmatter 的规则在启动时载入,优先级与 .claude/CLAUDE.md 相同;带 paths: 的规则只在 Claude 读到匹配 glob 的文件时才载入:
---
paths:
- "src/api/**/*.ts"
---
# API Development Rules
- All API endpoints must include input validation
- Use the standard error response format
官方glob 支持多模式与花括号展开(如 src/**/*.{ts,tsx})。个人通用的约定可以放 ~/.claude/rules/,对所有项目生效,且先于项目规则载入(项目规则优先);.claude/rules/ 还支持符号链接,方便多个仓库共享同一套规则。monorepo 里如果上层目录混进了别的团队的 CLAUDE.md,可用 claudeMdExcludes 设置按路径排除(组织策略层的除外)。注意:rules 和 CLAUDE.md 同一性质,都是 Claude「读到的建议」,不是强制配置。
常见误区:「写了不听」
官方误区:以为 CLAUDE.md 是配置文件,写进去就必然生效。实际上它以用户消息的形式排在系统提示词之后进入上下文,Claude 会读、会尽力遵循,但没有强制力。官方给出的排查顺序:先跑 /context 看 Memory files 列表确认文件真的载入了(不在列表里,Claude 根本看不见);再检查文件位置是否在会被加载的层级;然后把指令改具体;最后排查多个文件之间的指令冲突。
本站观点实践里「写了不听」最常见的原因是文件太长:重要规则被淹没在噪音里——官方最佳实践原文即警告「臃肿的 CLAUDE.md 会让 Claude 忽略你真正的指令」。/doctor 能对入库的 CLAUDE.md 提出裁剪建议(需 v2.1.206+)。完整的排查与瘦身步骤,见 Tip:CLAUDE.md 写了不听,多半是太长。另外记住分工:凡是「必须在某个时点发生」的动作(比如每次 commit 前跑 lint),别写在 CLAUDE.md 里祈祷,写成 Hook(D8)。
当天能做完的实操
- 项目还没有 CLAUDE.md 的,在会话里跑
/init。预期:Claude 分析代码库后生成一份含构建命令、测试方式与项目约定的 CLAUDE.md;若已存在,则是提出改进建议而非覆盖。已有 CLAUDE.md 的直接进下一步。 - 跑
/context,在 Memory files 列表里确认你的 CLAUDE.md(以及 CLAUDE.local.md、rules)确实载入了。预期:能看到文件清单;某个文件不在,说明位置放错了层级。 - 用下面的 prompt 让 Claude 审计你的 CLAUDE.md,对照上面的取舍表瘦身:
请审计本项目的 CLAUDE.md(如有 .claude/rules/ 一并审):
1. 列出 Claude 读代码就能自己推断的内容(目录结构、依赖清单、架构综述),建议删除;
2. 列出含糊到无法验证执行的指令(如「保持代码整洁」),各给一条具体、可验证的改写;
3. 列出互相矛盾或重复的指令;
4. 只对部分目录或文件类型生效的指令,建议移入 .claude/rules/ 并给出 paths: 的 glob。
先输出审计报告,待我确认后再修改文件。
- 亲手建一条 path-scoped rule:
mkdir -p .claude/rules,新建.claude/rules/testing.md,内容参照下面(glob 按你的项目改)。然后开新会话,先跑/context确认它不在启动载入清单里(带 paths 的规则按需载入),再让 Claude 读一个匹配的测试文件并复述当前生效的测试约定。预期:规则内容在读到匹配文件后才出现在 Claude 的表述里。--- paths: - "**/*.test.ts" - "**/*.test.tsx" --- # Testing Rules - 测试命名用「should [预期结果] when [条件]」 - mock 外部依赖,不 mock 内部模块 - (可选)跑
/memory浏览各层记忆文件的位置,顺便打开 auto memory 目录,看看 Claude 已经为这个项目自己记了什么。
验收标准
- 能不看图讲出 CLAUDE.md 的四个层级与拼接顺序,并说清哪些在启动时载入、哪些按需载入。
- 能说出至少三类「不该写进 CLAUDE.md」的内容,并用 D2 的上下文成本解释为什么。
- 项目里有一份 200 行以内、通过第 3 步审计的 CLAUDE.md,外加至少一条带
paths:的规则文件且验证过其按需载入。 - 自测题:monorepo 根目录和你负责的子包里各有一份 CLAUDE.md,你在子包目录启动 Claude Code,哪些会载入、顺序如何?(答案:两份都在启动时载入,根目录的在前、子包的在后;子包之下更深子目录里的 CLAUDE.md 则要等 Claude 读到该目录的文件时才按需载入。)