一句话总结
CLAUDE.md 是一个纯 Markdown 指令文件,Claude Code 每次 session 开始时都会完整加载,/compact 之后还会重新读一遍。项目级文件放在 ./CLAUDE.md(或 ./.claude/CLAUDE.md),提交进仓库,控制在 200 行以内。重点写五件事:构建/测试/lint 命令、约定、禁碰路径、项目结构、“永远要做 X” 的规则。先用 /init 生成初稿再打磨。截至 2026 年 6 月,Claude Code 还会维护自动记忆(它自己写的笔记),所以不用再手写一切——而老的 #”加入记忆”快捷写法已经取消了。
CLAUDE.md 到底是什么
它不是给人看的 README。按官方 Claude Code 记忆文档的说法,CLAUDE.md 的内容是作为系统 prompt 之后的一条 user message 投进去的,然后在每次 session 开始时加载进上下文窗口。所以它是持久上下文,不是强制配置:Claude 会读、会尽量遵守,但没有硬性保证。指令越具体、越精简,遵守得越稳。
下面所有规则都由这一条事实推导出来。因为它和你真正的对话争抢 token,又因为模糊的句子会被略读,目标就是一份简短的、具体可验证的规则文件——不是一篇 wiki。
这篇给在真项目里跑 Claude Code、反复遇到同样摩擦的工程师看:它忽略你的 import 顺序、改你说过不许碰的文件、跑错测试命令、把本该遵循的写法重写掉。
两套记忆系统(2026 年 6 月)
Claude Code 现在有两套互补的记忆机制,每次对话开始时都会加载。分清谁是谁,才知道哪些该你手写。
| CLAUDE.md 文件 | 自动记忆 | |
|---|---|---|
| 谁写 | 你 | Claude |
| 内容 | 指令和规则 | Claude 自己发现的经验 |
| 范围 | 项目 / 用户 / 组织 | 按 git 仓库 |
| 加载 | 每次 session 完整加载 | 每次加载 MEMORY.md 前 200 行 / 25 KB |
| 适合 | 标准、流程、架构 | 构建命令、调试心得、它学到的偏好 |
自动记忆需要 Claude Code v2.1.59 及以上(用 claude --version 查),默认开启。它存在 ~/.claude/projects/<project>/memory/,按 git 仓库归类,所以同一仓库的所有 worktree 共享一份。界面上出现 “Writing memory” 或 “Recalled memory” 时,那是自动记忆,不是你的 CLAUDE.md。用 /memory 浏览或关闭,或设 CLAUDE_CODE_DISABLE_AUTO_MEMORY=1。
实际结论:别把 CLAUDE.md 的行数花在 Claude 跑一次就能学会的东西上。把文件留给那些它每次都会重新推导或弄错的东西。
文件放哪(以及加载顺序)
CLAUDE.md 可以存在多个层级。它们是拼接,不是覆盖,按下面这个顺序加载——最宽的最先,所以最具体的指令最后读、平局时它赢:
| 层级 | 位置 | 提交进仓库? |
|---|---|---|
| 组织托管策略 | macOS /Library/Application Support/ClaudeCode/CLAUDE.md;Linux/WSL /etc/claude-code/CLAUDE.md;Windows C:\Program Files\ClaudeCode\CLAUDE.md | 由 IT/MDM 下发 |
| 用户(个人) | ~/.claude/CLAUDE.md | 不提交(在你机器上) |
| 项目(团队) | ./CLAUDE.md 或 ./.claude/CLAUDE.md | 提交,走版本控制 |
| 本地(私有) | ./CLAUDE.local.md | 不提交——加进 .gitignore |
Claude 从你的工作目录沿目录树往上爬,把一路上找到的每个 CLAUDE.md 和 CLAUDE.local.md 在启动时完整加载。你下面的子目录里的文件是按需加载的,只有当 Claude 读那个子目录里的文件时才加载。同一目录内,CLAUDE.local.md 接在 CLAUDE.md 后面,所以你的私人笔记在那一层是最后读的。
对 monorepo 来说,这意味着一份根 CLAUDE.md 写全局规则,加上每个包一份 frontend/CLAUDE.md 或 services/api/CLAUDE.md 写各自 stack 的规则。如果别的团队的祖先文件被误加载进来,用 .claude/settings.local.json 里的 claudeMdExcludes 排掉它(按绝对路径的 glob 匹配)。
用 /init 生成初稿
别从空文件开始。在仓库里跑 /init:Claude 分析代码库,写出一份初始 CLAUDE.md,带上它能检测到的构建命令、测试说明和约定。如果已经有 CLAUDE.md,/init 会建议改进而不是覆盖。它还会读现有的 AGENTS.md、.cursorrules、.devin/rules/、.windsurfrules,把相关部分并进来。设 CLAUDE_CODE_NEW_INIT=1 会启用交互式多阶段流程,它会追问、并在写文件前给你一份可审阅的方案。
把生成的文件当初稿。真正值钱的内容是 /init 发现不了的:你的潜规则、禁碰路径、以及你已经厌倦反复纠正的那些错误。
到底写什么
五个小节扛起几乎全部价值。每条规则都要具体到可验证,配一个小例子。
- 项目说明——3 到 5 句:这是什么、主入口在哪。例:
Next.js 15 应用,App Router,Vercel 部署。入口:app/page.tsx。后台任务:lib/jobs/*.ts。 - 构建 / 测试 / lint 命令——最值钱的一节。没有它,你用
pnpm test --run时 Claude 会去跑npm test,然后浪费好几轮去 debug。写精确:Test: pnpm test --run。Lint: pnpm lint。Type: pnpm typecheck。任务完成前三个都跑一遍。 - 约定,每条带例子——“用命名导出,不要默认导出” 胜过 “写干净代码”。文档自己的对照:“用 2 空格缩进” 有效,“格式化好代码” 无效。
- 禁碰路径——明确写:
不要编辑 src/generated/*、prisma/migrations/*、或任何 *.gen.ts 文件。Claude 对这条服得很好。 - 任务级提示——一小段 “被要求加路由时”,列出要碰的文件和顺序。组件、迁移、测试各来一段。
底部留一小节 “纠正记录”,每次发现 agent 跑偏就补一行。块级 HTML 注释(<!-- 维护者备注 -->)会在内容进入 Claude 上下文前被剥掉,所以可以拿来写只给人看的备注,不花 token。
控制在 200 行以内
文档把目标定在每个 CLAUDE.md 文件 200 行以内。更长的文件吃更多上下文,也实测会降低遵守率——底部的规则会被略读。涨上去时,有三个比堆大文件更好的办法:
- 路径级规则(path-scoped rules)。 把分主题的文件放进
.claude/rules/(比如testing.md、security.md)。在 frontmatter 里加paths:glob,例如"src/api/**/*.ts",这条规则就只在 Claude 碰到匹配文件时加载,其余时间省下上下文。没有paths的规则每次 session 都加载,优先级和.claude/CLAUDE.md一样。 - 导入(imports)。 在 CLAUDE.md 任意位置用
@path/to/file语法引用别的文件。相对路径相对于引用它的那个文件解析;递归最多四跳。注意:导入帮的是组织,不减上下文,因为被导入的文件照样在启动时加载。 - 技能(skills)。 把多步流程搬进一个 skill,只在被调用或被判定相关时才加载——不是每次 session 都加载。
用导入复用 AGENTS.md,别复制
Claude Code 读的是 CLAUDE.md,不是 AGENTS.md。如果你的仓库已经为别的 agent 维护了 AGENTS.md,别复制它。建一个一行的 CLAUDE.md 把它导进来,再在下面加 Claude 专属的几行:
@AGENTS.md
## Claude Code
src/billing/ 下的改动用 plan mode。
软链接(ln -s AGENTS.md CLAUDE.md)在你没有 Claude 专属内容要加时也能用;Windows 上用 @AGENTS.md 导入,因为软链接需要管理员权限。
session 中途改记忆
老的 # 前缀(往记忆里塞一行)已经移除了。截至 2026 年 6 月你有两条干净的路:跑 /memory 列出所有已加载的 CLAUDE.md、CLAUDE.local.md 和 rules 文件,并在编辑器里打开任意一个;或者直接在对话里说 “把这条加进 CLAUDE.md”。如果你只让 Claude “记住” 某事而不指明文件,它会写进自动记忆。
什么时候 CLAUDE.md 不是对的工具
CLAUDE.md 塑造行为,但不强制执行。如果某条规则必须在固定时点跑——每次提交前、每次编辑后——那就写成 hook。Hook 作为 shell 命令在生命周期事件上执行,不管 Claude 怎么决定都会跑,所以 “禁止编辑 migrations/” 或 “提交前跑 make lint” 属于这里,不属于 prose。要把某条指令强行塞进系统 prompt 本身,用 --append-system-prompt(更适合脚本,不适合交互式)。
第一次实操怎么跑
- 翻一个最近 review 过的 PR,写下你给作者的 top 3 nit。
- 把每条转成 CLAUDE.md 里一句规则,配一个小例子。
- 让 Claude Code 跑一个类似代码的小任务,确认它遵循这些规则。
- 没遵循就把措辞写紧(具体例子 > 抽象原则),重跑。
提交前检查
- 跑
/memory,确认文件真的被列为已加载。没在列表里,Claude 就看不见它。 - 是不是在 200 行以内、大致一两屏?
- 命令能原样复制粘贴吗?“跑测试” 会让它糊涂,
pnpm test --run不会。 - 每条规则都带具体例子吗?抽象规则会退化。
- 扫一遍根文件、嵌套文件、
.claude/rules/之间有没有冲突——矛盾的指令会被随意取一个。
FAQ
- CLAUDE.md 多长合适? 目标 200 行以内。文件不论多长都会完整加载,但越长越吃上下文、越降低遵守率,底部规则会被略读。
- 为什么 Claude 不遵守我的 CLAUDE.md? 最常见的是文件没被加载(用
/memory查)、规则太模糊、或两个文件冲突。CLAUDE.md 是上下文不是强制——必须执行的规则用 hook。 - 密钥能写 CLAUDE.md 吗? 不能,它是提交进仓库的源码。引用环境变量名,不要值。私人、需 gitignore 的部分放
CLAUDE.local.md。 - CLAUDE.md 和自动记忆有什么区别? CLAUDE.md 你写(标准、规则),自动记忆 Claude 写(它发现的构建命令、调试心得)。两者每次 session 都加载;自动记忆需 v2.1.59+,默认开启。
- 嵌套的 CLAUDE.md 能挺过
/compact吗? 项目根文件在 compact 后会从磁盘重新读。子目录里的嵌套文件不会自动重新注入——它们会在 Claude 下次读那个子目录里的文件时重新加载。 - 个人项目需要吗? 15 行也比没有强。没它,Claude 每次 session 重新推导你的约定。
容易踩的坑
- 写一次就不再更新——agent 行为在变、文件很快过时。同一个问题纠正第二次时,就补一行进去。
- 模糊约束(“写干净代码”)而不是可验证的(“命名导出,不要默认导出”)。
- 让它涨过 200 行,而不是把主题搬进
.claude/rules/或 skill。 - 把人类 onboarding 内容和 agent 规则混在一起——README.md 和 CLAUDE.md 分开。
- 漏掉禁碰路径——你不说,agent 早晚会改自动生成代码。
- 没写精确的 test/lint/build 命令——agent 自己猜,常猜错。
- 手写自动记忆已经学会的东西——白费行数。跑
/memory看它自己学到了什么。
相关阅读
- Claude Code 不理解整个项目
- Claude Code 新手指南
- Claude Code 项目配置
- AI 编程上下文管理
- Claude Code 斜杠命令
- Claude Code vs Cursor
标签: #AI 编程 #教程 #Claude Code