CLAUDE.md 怎么写:Claude Code 的项目 prompt 指南

CLAUDE.md 是 Claude Code 每次 session 都会加载的指令文件。该写什么、放哪、怎么加载——对照 2026 年 6 月官方文档逐条核实。

一句话总结

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.mdCLAUDE.local.md 在启动时完整加载。你下面的子目录里的文件是按需加载的,只有当 Claude 读那个子目录里的文件时才加载。同一目录内,CLAUDE.local.md 接在 CLAUDE.md 后面,所以你的私人笔记在那一层是最后读的。

对 monorepo 来说,这意味着一份根 CLAUDE.md 写全局规则,加上每个包一份 frontend/CLAUDE.mdservices/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 发现不了的:你的潜规则、禁碰路径、以及你已经厌倦反复纠正的那些错误。

到底写什么

五个小节扛起几乎全部价值。每条规则都要具体到可验证,配一个小例子。

  1. 项目说明——3 到 5 句:这是什么、主入口在哪。例:Next.js 15 应用,App Router,Vercel 部署。入口:app/page.tsx。后台任务:lib/jobs/*.ts。
  2. 构建 / 测试 / lint 命令——最值钱的一节。没有它,你用 pnpm test --run 时 Claude 会去跑 npm test,然后浪费好几轮去 debug。写精确:Test: pnpm test --run。Lint: pnpm lint。Type: pnpm typecheck。任务完成前三个都跑一遍。
  3. 约定,每条带例子——“用命名导出,不要默认导出” 胜过 “写干净代码”。文档自己的对照:“用 2 空格缩进” 有效,“格式化好代码” 无效。
  4. 禁碰路径——明确写:不要编辑 src/generated/*、prisma/migrations/*、或任何 *.gen.ts 文件。 Claude 对这条服得很好。
  5. 任务级提示——一小段 “被要求加路由时”,列出要碰的文件和顺序。组件、迁移、测试各来一段。

底部留一小节 “纠正记录”,每次发现 agent 跑偏就补一行。块级 HTML 注释(<!-- 维护者备注 -->)会在内容进入 Claude 上下文前被剥掉,所以可以拿来写只给人看的备注,不花 token。

控制在 200 行以内

文档把目标定在每个 CLAUDE.md 文件 200 行以内。更长的文件吃更多上下文,也实测会降低遵守率——底部的规则会被略读。涨上去时,有三个比堆大文件更好的办法:

  • 路径级规则(path-scoped rules)。 把分主题的文件放进 .claude/rules/(比如 testing.mdsecurity.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(更适合脚本,不适合交互式)。

第一次实操怎么跑

  1. 翻一个最近 review 过的 PR,写下你给作者的 top 3 nit。
  2. 把每条转成 CLAUDE.md 里一句规则,配一个小例子。
  3. 让 Claude Code 跑一个类似代码的小任务,确认它遵循这些规则。
  4. 没遵循就把措辞写紧(具体例子 > 抽象原则),重跑。

提交前检查

  • /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 看它自己学到了什么。

相关阅读

标签: #AI 编程 #教程 #Claude Code