01 · CLAUDE.md 怎么写

01 · CLAUDE.md 怎么写

项目宪法。不是 README,不是说明书。

写在最前面

很多人把 CLAUDE.md 想象成"给 Claude 的项目说明书"。错。

更准确的比喻是道路上的交通标志——限速牌、禁行标志、单行道指示。Claude 每次进来干活,都是开车经过。你的任务不是给它讲这条路的历史、沿途风景、建造动机,而是告诉它:

  • 这里限速 60(→ 项目约定)
  • 那个路口禁止左转(→ 禁区)
  • 前方施工改道(→ 踩过的坑)

说明书是给开车新手看的,交通标志是给所有司机看的。CLAUDE.md 属于后者。

一句话记住

CLAUDE.md 是写给 Claude 看的,不是写给人看的。

这句话听起来像废话,但 90% 的 CLAUDE.md 翻车都是因为忘了它。

该写什么

类别例子
技术栈和版本Next.js 16 + React 19 + TS strict,防止用过时 API
项目特有约定所有 API 路由必须用 zod 校验输入
禁区不要修改 legacy/ 目录
常用命令dev: pnpm devbuild: pnpm build
非显而易见的架构决策我们故意不用 ORM,原因是 xxx
反复翻车的教训只能用 pnpm,用 npm 会污染 lockfile

不该写什么

  • 代码能推导的东西:目录结构、文件列表、函数签名——Claude 会 lsgrep,写进去只会过时
  • 文学叙事:项目愿景、使用场景——放 README 去
  • 一次性任务上下文:今天要做的功能、临时的 debug 线索——这是对话内容
  • 长篇重复:同一规则说三遍不会让 Claude 更听话,只会稀释其他规则
  • 废话口号请写出优雅、可维护、高性能的代码——等于没写

❌ README 式写法(反例)

# MyApp
 
MyApp 是一个面向企业用户的 SaaS 平台,致力于帮助团队……
我们采用现代化的 Web 技术栈,追求极致的用户体验……

Claude 读完——什么约束也没拿到。

✅ 宪法式写法(正例)

# MyApp
 
## 技术栈(避免用过时 API)
- Next.js 16 App Router(`params` 是 async,必须 await)
- React 19(不需要手动 memo,编译器会处理——前提是启用了 React Compiler)
- TS strict
- Tailwind 4(首选 `@utility``@apply` 不再推荐)
 
## 约定
- 新组件先看 `src/components/` 有没有能复用的
- 所有 server action 用 zod 校验入参
 
## 禁区
- 不要自己安装新依赖,先讨论

每一行都在给 Claude 下一个可执行的约束

分层加载

Claude Code 会自动叠加加载三层:

~/.claude/CLAUDE.md          ← 你的个人偏好(跨所有项目)
<repo>/CLAUDE.md             ← 项目宪法
<repo>/<subdir>/CLAUDE.md    ← 工作目录在子目录时追加

实用技巧:大项目前后端约定不一样?

  • frontend/CLAUDE.md 写 React / Tailwind 约定
  • backend/CLAUDE.md 写 API / DB 约定
  • CLAUDE.md 只写全局的

比塞一大坨在根目录清爽得多,Claude 也只会加载相关的。

一个能直接抄的骨架

# <项目名>
 
## 技术栈
- <语言 / 框架 + 版本 + 关键坑>
 
## 命令
- `pnpm dev` — 开发
- `pnpm build` — 提交前必须通过
- `pnpm test` — 单元测试
 
## 约定
- <规则 1,具体可执行>
- <规则 2>
 
## 禁区
- <别动的目录 / 文件>
- <不要做的事>
 
## 踩过的坑
- <教训 1>
- <教训 2>

演进:CLAUDE.md 是活的

CLAUDE.md 不是写完就锁起来的

成长公式

每次 Claude 犯错 → 问自己:"这个错误,是不是该进 CLAUDE.md?" → 是 → 加一条

比如 Claude 又一次忘了 await params,你不该只说"这里要 await",你应该同时更新 CLAUDE.md。下一次的 Claude 就不会再犯。

定期瘦身

  • 每月扫一遍,删过时的、合并重复的
  • 目标:100 行以内
  • 超过 200 行多半有冗余,该拆子目录或瘦身

越具体越好

写**"函数超过 50 行必须拆",不写"写高质量代码"**。

❌ 废话✅ 可执行
保持简洁一段不超过 4 行
多举例子每个观点配 ✅ / ❌ 示例
写高质量代码函数超过 50 行必须拆
注意类型禁止 any,用 unknown 窄化
遵循最佳实践服务层失败返回默认值,不抛异常

价值观 vs 规则:前者是情绪,后者 Claude 能自我检查。写 CLAUDE.md 最关键的一步就是把感受翻译成规则

容易踩的坑:技术断言必须准确

CLAUDE.md 里一条错的规则比不写更糟——因为 Claude 会照执行。

典型案例

错误写法

- React 19 — 编译器自动 memo,不要手动 memo / useMemo

问题

  • React 19 本身不会自动 memo
  • React Compiler 是独立编译器,需要手动启用(experimental.reactCompiler: true
  • 即使启用,也不是"禁止手动 memo",而是"未证明必要时优先让编译器处理"

纠正后

- React 19 + React Compiler(next.config.ts 已启用)
  优先让编译器处理 memoization,手动 memo / useMemo 需先证明必要性

校准三原则

  1. 技术断言配具体版本号,或"本项目实际如何"(比如 next.config.ts 里到底开没开)
  2. 模糊的倾向用"优先 / 除非"而非"必须 / 禁止"
  3. 不确定的,宁可不写

三个典型反例

  • ❌ "本项目是一个面向企业用户的 SaaS 平台,致力于……"(营销稿)
  • ❌ "src/ 目录下有 components/、pages/、utils/……"(Claude 自己会看)
  • ❌ "请尽量写出优雅、可维护、高性能的代码"(价值观不是规则)

一句话总结

每一行都要能被 Claude 执行。不能被执行的,挪去别处。

速查

写 CLAUDE.md 前自问

这条信息

Claude 看代码 / git log 能得到?  ── 是 → 不写
  ↓ 否
有版本 / 具体约束 / 可检查?       ── 否 → 改具体
  ↓ 是
过 6 个月还会重要?                ── 否 → 放对话
  ↓ 是
入 CLAUDE.md

每行都该能回答

"如果这行没了,Claude 的行为会变差吗?"

答案是"不会"的,就删掉。


← 序言 | 目录 | 02 · 记忆的三层体系 →