在 Claude Code 启动时,它的系统提示词已经占据了大约 50 条指令。研究表明,大语言模型(LLM)在指令总数达到 150 到 200 条时,遵循指令的能力就开始下降。这意味着你只有约 100 到 150 条指令的"额度",来向 Claude 解释你的项目规则。
CLAUDE.md 就是用来填补这些额度的核心文件。它是一个位于项目根目录的 Markdown 文件,Claude Code 在每次对话开始时都会自动读取它。这让 Claude 具备了持续的项目上下文,无需你反复叮嘱。
然而,如果这个文件过于臃肿,它不仅会浪费 Token,还会干扰核心规则的执行。本文将讨论如何构建一个"字字珠玑"的 CLAUDE.md,以及如何随项目演进而维护它。
什么是 CLAUDE.md?
CLAUDE.md 存放的是项目的"常驻指令",涵盖了 Claude 需要了解的方方面面:
- 技术栈细节
- 测试运行方式
- 编码规范与约定
- 不可触碰的禁区
没有它,每个会话都像是在开盲盒。你会发现自己一直在解释相同的背景,纠正相同的错误。
在 Claude Code 的上下文中,有几类文件共同分担了记忆任务:
| 系统 | 维护者 | 作用 | 加载时机 |
|---|---|---|---|
CLAUDE.md |
开发者 | 定义项目规则、规范和约束 | 每次会话开始(全量加载) |
MEMORY.md |
Claude | 记录 Claude 在会话中发现的模式和事实 | 每次会话开始(前 200 行) |
| Skills | 开发者 | 针对特定工作流的领域知识 | 按需加载 |
| Hooks | 开发者 | 触发点执行的脚本(如 pre-commit) | 特定触发点 |
运行 /init 命令会自动分析你的代码库并生成一个初始的 CLAUDE.md。这是一个不错的起点,但要让它真正好用,必须经过人工打磨。
文件优先级与位置
CLAUDE.md 的加载遵循从全局到具体的优先级顺序,更具体的文件会覆盖宽泛的规则:
- 管理策略(全局):位于系统级目录(如 macOS 的
/Library/Application Support/ClaudeCode/),适用于机器上所有用户。 - 用户级别:
~/.claude/CLAUDE.md,适用于你本机的所有项目,适合存放个人偏好。 - 项目级别:根目录下的
./CLAUDE.md,这是最常用的,应随 Git 提交。 - 子目录级别:
./subdir/CLAUDE.md,仅当 Claude 处理该目录下的文件时按需加载。
如果你有不希望提交到版本控制系统的个人偏好,可以创建 CLAUDE.local.md 并将其加入 .gitignore。
CLAUDE.md 应该包含什么?
一个高效的 CLAUDE.md 通常分为三层逻辑:项目是什么、为什么这么做、Claude 应该怎么做。
高信号的项目概览
开头用一两行说明项目目标和具体的技术栈版本。虽然 Claude 能通过分析代码推断,但直接告诉它"我们使用的是 Next.js 15 而非 14",能省去很多麻烦。
提供一个清晰的目录结构图,只列出关键层级:
src/
data/ # 数据处理流水线
models/ # 模型定义与训练逻辑
api/ # 基于 FastAPI 的服务端点
tests/ # 与源码同位置的测试文件 (test_*.py)
将常用命令放在代码块中。Claude 会优先执行代码块内的命令,而对正文中的描述则可能采取"即兴发挥"的态度。
架构意图与约束
如果你的项目出于某种原因选择了 SQLite 而非 Postgres,或者 API 遵循特定的分层模式,请务必写清楚。
单纯说"严禁强制推送(Force Push)“效果有限。如果解释为"严禁强制推送,因为这会重写共享历史,导致协作环境不可逆的损坏”,Claude 就能理解其背后的逻辑,从而在执行类似 git reset --hard 的操作时也会更加谨慎。带原因的规则可以泛化,仅有结论的规则只能死记硬背。
给 Claude 的操作指南
这部分主要解决那些无法从代码中直接推断出的约定。比如 Conventional Commits 规范、特定的分支命名模式,或是某些必须在构建前运行的特殊脚本。
不要在文件中塞入语言本身的常识。例如,不需要告诉 Claude 在现代 JS 中使用 async/await,这些属于"背景噪音",会挤占更有价值的指令额度。
如何编写 CLAUDE.md
编写有效的指令
具体性大于意图。 “编写整洁的代码"是废话,“使用 2 空格缩进,不使用分号,使用单引号"才是指令。
对每一行指令进行压力测试:“如果删掉这一行,Claude 会出错吗?” 如果答案是否定的,那就删掉它。目标是将文件控制在 200 行以内——成熟团队往往能压缩到 60 行以下。文件越短,指令的遵循度越高。
另外建议:
- 标题层级不超过三级。深层嵌套会让模型难以索引到具体规则。
- 使用易识别的小节名(“命令”、“约定”、“陷阱”),便于 Claude 在长文件中跳转检索。
应该剔除的内容
最大的陷阱,就是把 CLAUDE.md 当成代码风格的"执法者”。
- 代码风格规则:缩进、引号、导入排序——交给 ESLint 或 Prettier。让 Linter 免费完成的事,不要烧昂贵的指令额度去做。
- 语言通用约定:现代 JS 用
async/await、Python 用类型注解,这些 Claude 已经知道,写了等于浪费。 - 完整 API 文档:不要粘贴整篇文档,给一个链接或文件名 (
docs/api.md) 让 Claude 按需查阅。 - 任务级指令:一次性任务的步骤应该写进 Skill,而不是常驻
CLAUDE.md。 - 只有"不要做"的约束:每一条禁令都要配一个替代方案。“不要使用 X,请改用 Y” 远胜于 “不要使用 X”。
示例对比:从臃肿到精炼
下面是一个真实改造前后的对照。
优化前(臃肿、空洞):
# 我们的项目
我们重视高质量代码,请遵循最佳实践。
- 使用语义化命名
- 保持函数简洁
- 编写整洁、可维护、可读性强的代码
- 添加恰当的注释
- 确保代码经过良好测试
- 使用 async/await 而非回调
- 缩进使用 2 个空格
- 字符串使用单引号
...
优化后(精炼、聚焦):
# data-pipeline
Python 3.11 + FastAPI,处理客户分析数据。
## 命令
- `make test` - 运行测试套件(先启动 docker compose 中的 Redis)
- `make lint` - ruff + mypy
- `make migrate` - 应用 alembic 迁移
## 约定
- 测试与源码同目录,命名 `test_*.py`
- 使用 Conventional Commits(feat:, fix:, chore:)
- API 路由统一使用 Pydantic 模型校验入参
## 陷阱
- Redis 必须先于测试启动,否则会卡死在连接池
- 迁移文件不要手改,统一通过 `alembic revision --autogenerate`
精炼版只保留项目特有、且无法从代码推断出的事实——其他内容都被剥离了。
从零构建文件
如果你刚接手项目,没有 /init 的输出可参考,可以按下面 5 个小节起手:
- Project overview——一两行说明项目做什么,使用什么技术栈版本。
- Directory map——只列关键目录,每个目录一行说明。
- Commands——构建、测试、Lint、部署的入口命令,全部包在代码块里。
- Conventions——提交规范、分支命名、测试位置等无法从代码推断的约定。
- Quirks / Gotchas——项目里那些"坑”,比如必须先启动某个容器、某个端口被占用、某个测试是脆弱的。
完成后,再回到第一节做删减,目标 60 行以内。
团队协作与规模化管理
当项目涉及多人协作或属于单体大仓(Monorepo)时,单一的 CLAUDE.md 会变得难以维护。
版本控制与共享所有权
CLAUDE.md 应当被视为项目的共享文档,进入 Git 并接受 Code Review。任何对它的修改都应通过 Pull Request 流程,避免某个开发者在本地塞入个人偏好后污染整个团队。
如果是 Monorepo,往往需要让不同团队的子目录拥有自己的规则。Claude Code 支持在 .claude/settings.local.json 中通过 claudeMdExcludes 字段排除其他团队的规则文件,避免前端开发被后端的迁移规则干扰。
模块化规则
可以将规则拆分到 .claude/rules/ 目录下,按主题命名(如 testing.md、api-design.md)。Claude 会递归发现这些文件。
更进一步,可以使用路径感知的加载方式。在规则文件顶部添加 YAML Frontmatter:
---
paths:
- "src/api/**/*.ts"
---
# 这里是 API 相关的特定约定
这样,当 Claude 在处理前端文件时,就不会被后端的数据库迁移规则干扰。
渐进披露:拆分而非集中
经验表明,把一个 600 行的 CLAUDE.md 拆成多个按路径加载的小文件,能在保持指令完整性的前提下,把每次会话实际加载的字数削减 80% 左右。模型只会看到与当前任务相关的规则,遵循度反而提升。
引用而非嵌入
对于大型架构文档,不要使用 @docs/architecture.md 这种导入语法——它会把整篇文档塞进每一次会话上下文。
正确做法是:在 CLAUDE.md 里写一句"关于迁移流程,请参考 docs/migrations.md"。Claude 在确实需要时会主动阅读,而不是无差别预加载。
子目录下的 CLAUDE.md 同样遵循"按需加载"原则——只有当 Claude 在该子目录下工作时才会被读入,这是天然的渐进披露机制。
持续维护:避免规则腐化
项目在演进,规则也会过时。
让文件保持新鲜
添加规则要比直觉慢一拍。 每写下一条新规则前,问自己:这条规则是否对应一次真实发生过的事故? 如果只是"假想中可能出问题",那就先不加。靠假想堆砌的规则,最终会淹没那些靠血泪换来的关键约束。
两个清晰的信号说明该维护了:
- Claude 为忽视已有的指令道歉——说明该指令表达模糊,需要重写得更具体。
- Claude 在多个会话中重复同一个错误——说明文件已经太长,指令被模型过滤掉了,应当精简。
低成本的维护习惯:
- 每隔几周对 Claude 说"审查当前的
CLAUDE.md并提出改进建议",让它自己找出冗余和冲突。 - 在
CLAUDE.md末尾留一条常驻指令:“如果你发现某条规则与当前代码现实不符,请主动指出。” - 定期删掉那些 Claude 已经稳定遵循、不写也不会出错的条款。
应该避免的反模式
CLAUDE.md 失效,几乎都来自下面这几个共同的失败模式:
- 持续累加,从不删减——规则越加越多,Claude 终于开始"打折扣"地遵循,于是你又加更严厉的规则,进入恶性循环。正确做法:每加一条,删一条。
- 用
@大量嵌入外部文档——把 5000 行的架构文档塞进每一次会话,效果是 Claude 反而看不懂重点。改用引用即可。 - 从不打磨
/init的产物——/init生成的是骨架,直接用相当于发布一份只过了草稿的需求文档。 - 多个文件互相矛盾——用户级、项目级、子目录级
CLAUDE.md出现冲突时,Claude 通常会两边都不完美遵守。定期跨文件审查。 - 为每个边缘情况单独加一条规则——这会迅速把文件撑到 500 行。聚焦在高影响的规则上,边缘情况留给 review 修。
总结
CLAUDE.md 是 Claude Code 项目中权重最高的文件。它不是一个随手抓取的垃圾桶,而是一份精炼的项目路线图。
如果你的项目复杂到必须依靠超长的 CLAUDE.md 才能运转,那通常说明的是工具链或文档结构有问题,而不是"指令额度需要扩容"。
最好的行动方案:
- 现在就运行
/init生成基准版本。 - 果断删掉显而易见的废话,只保留真正能防止 Claude “翻车"的关键信息。
- 目标 60 行以内,按真实事故慢慢扩充。
常见问题(FAQ)
Q: 什么是 CLAUDE.md? A: 一个 Markdown 文件,存放项目级常驻指令,Claude Code 在每次会话开始时全量加载。它告诉 Claude 项目的技术栈、命令、约定和陷阱。
Q: 应该把 CLAUDE.md 放在哪里?
A: 默认放在项目根目录并提交到 Git。个人偏好放 ~/.claude/CLAUDE.md;不想入库的临时偏好用 CLAUDE.local.md 并加入 .gitignore;针对子模块的规则放对应子目录。
Q: CLAUDE.md 该写多长? A: 200 行以内为宜,60 行以下为佳。LLM 在指令总数达到 150 到 200 条时遵循能力开始下降,超过这个阈值规则会被模型"过滤”。
Q: 哪些内容不应该写进去? A: Linter 能管的代码风格、语言通用约定、完整 API 文档、一次性任务步骤、只有禁令没有替代方案的规则。
Q: 团队和 Monorepo 怎么扩展?
A: 拆到 .claude/rules/ 多个文件 + YAML Frontmatter 路径限定 + Monorepo 用 claudeMdExcludes 屏蔽其他团队的规则。优先采用路径感知的渐进披露,而不是把所有规则集中在一个根 CLAUDE.md。
关于
关注我获取更多资讯