
阅读时长:约25分钟 难度:★★★☆☆ 适合人群:已掌握 Director Mode 三大支柱,想彻底消除"每次都要重复说规范"的开发者 学完之后:你能为自己的项目写一份 CLAUDE.md,让 Claude 每次都按你的标准来,不需要反复提醒
回头翻一下你这几课写过的 prompt,你会发现一个规律:
《Claude Code 从入门到精通》试读篇:Claude Code 是什么?你可能从第一步就用错了
《Claude Code 从入门到精通》试读篇:你的第一次 Director Mode 体验(二)
《Claude Code 从入门到精通》试读篇:写好 Prompt 的结构化思维,10组正反对比,看完直接套用(三)
《Claude Code 从入门到精通》试读篇:当 Claude 理解错了怎么办(四)
《Claude Code 从入门到精通》目标优于指令,Director Mode 第一支柱(五)
第06课:让 Claude 自己分配任务——并行 Agent 策略
《Claude Code 从入门到精通》第07课:结果验证——你最不能省的一步
第02课的 prompt:
"……查看项目中现有接口的验证方式和错误响应格式,保持一致……"
第04课的纠正:
"API 调用不要直接写在组件里,移到 src/services/ 里,参照 userService 的写法"
第05课的 prompt:
"……参照 src/modules/user/ 下现有代码的结构和风格……"
第06课的并行任务:
"……参照项目现有的校验方式……日志格式参照 src/utils/logger.ts……"
第07课的验证指令:
"……对比项目现有代码,确认风格一致……"
看出来了吗?你每次都在重复同一件事:告诉 Claude 你的项目规范是什么。
每个 prompt 里都要写"参照XXX的风格""用现有的错误处理方式""不要引入新依赖"。这些话你写了几十遍了。
为什么要重复?因为 Claude 没有记忆。每次对话对它来说都是全新的——上一次你花了20分钟教它你的项目规范,这一次它全忘了。
这不是 Claude 的 bug,是它的工作机制。但这个机制导致了一个问题:你的 prompt 有一半篇幅在写"背景信息和项目规范",只有另一半在写"这次要做什么"。
CLAUDE.md 就是解决这个问题的。
它是一个放在项目根目录下的文件。Claude Code 每次启动时会自动读取它。你把项目规范、代码风格、技术栈约定、常见陷阱全部写进去,以后每次 prompt 只需要写"这次要做什么"就行了。
打个比方:CLAUDE.md 就是你给新同事准备的"入职手册"。你不会每次分配任务都从"我们用什么技术栈、代码风格是什么、错误处理怎么写"开始讲——你会说"先看完入职手册,然后来做这个任务"。
CLAUDE.md 就是 Claude 的入职手册。
先看一个直观的前后对比。
给订单模块加一个按日期范围查询的接口。
要求:
- 接口路径按 RESTful 规范设计
- 使用 NestJS 框架的 Controller + Service + Repository 分层
- 数据库用 TypeORM,查询用 QueryBuilder 不要用 raw SQL
- 分页用游标方式,不用 OFFSET
- 接口参数用 DTO 类做校验,用 class-validator 装饰器
- 错误返回用项目统一的 AppError 类,格式是 { code, msg, data }
- 日志用项目的 LoggerService,不要用 console.log
- 返回的时间字段统一用 ISO 8601 格式
- TypeScript 严格模式,不允许 any 类型
- 文件放在 src/modules/order/ 下
- 写完整的单元测试,测试框架用 Jest
- 测试命名用 should_xxx_when_xxx 格式
补充:参照 src/modules/user/ 下的代码风格。
12条规范要求,占了 prompt 80% 的篇幅。而真正的需求只有第一句话——"加一个按日期范围查询的接口"。
给订单模块加一个按日期范围查询的接口。
支持按开始日期和结束日期筛选,返回分页结果。
两句话,搞定。
因为那12条规范已经全部写在 CLAUDE.md 里了。Claude 在开始执行之前就已经读取了这些规范。你不需要再重复。
prompt 从14行缩减到2行,效果完全一样。 这就是 CLAUDE.md 的价值。
技术上很简单:
你的项目根目录/
├── src/
├── package.json
├── tsconfig.json
├── CLAUDE.md ← 放在这里
└── ...
当你在项目目录下启动 Claude Code 时,它会自动检测并读取 CLAUDE.md 文件。你不需要做任何额外配置。
Claude Code 也支持层级 CLAUDE.md——你可以在子目录放更具体的规范:
你的项目根目录/
├── CLAUDE.md ← 项目级规范(全局生效)
├── src/
│ ├── modules/
│ │ ├── order/
│ │ │ └── CLAUDE.md ← 订单模块专用规范
│ │ └── payment/
│ │ └── CLAUDE.md ← 支付模块专用规范
子目录的 CLAUDE.md 会叠加到项目级的上面——Claude 同时遵守两份规范。比如项目级写了"TypeScript 严格模式",订单模块级写了"金额用整数(分)计算",Claude 在处理订单模块时两条都会遵守。
一份好的 CLAUDE.md 应该包含以下板块。不是每个都必须有——根据你项目的实际情况选择。但前4个板块建议每个项目都写。
告诉 Claude 这是什么项目、用了什么技术栈。这决定了 Claude 在写代码时的"基本认知"。
# 项目概览
这是一个电商后台管理系统的后端服务。
技术栈:
- 运行环境:Node.js 20 + TypeScript 5.x
- 框架:NestJS 10
- 数据库:MySQL 8.0 + TypeORM
- 缓存:Redis 7
- 测试:Jest + Supertest
- API 文档:Swagger (nestjs/swagger)
项目结构:
- src/modules/ → 业务模块(每个模块包含 controller/service/repository/dto/entity)
- src/common/ → 公共组件(guards/filters/interceptors/decorators)
- src/utils/ → 工具函数
- src/config/ → 配置文件
为什么重要:没有这段,Claude 在技术选型时可能做出你不想要的决定——比如用 Express 而不是 NestJS 写接口,用 Sequelize 而不是 TypeORM 操作数据库。
这是 CLAUDE.md 里最重要的板块,直接决定了 Claude 写出来的代码长什么样。
# 代码规范
## 命名规则
- 文件名:kebab-case(如 order-item.service.ts)
- 类名:PascalCase(如 OrderItemService)
- 函数/变量:camelCase(如 getOrderList)
- 常量:UPPER_SNAKE_CASE(如 MAX_RETRY_COUNT)
- 数据库表/字段:snake_case(如 order_item, created_at)
## TypeScript 规则
- 严格模式(strict: true),不允许使用 any 类型
- 优先使用 interface 而非 type(除非需要联合类型或工具类型)
- 函数返回类型必须显式标注
- 使用 readonly 修饰不可变属性
## 代码组织
- 每个业务模块独立目录,包含完整的 controller/service/repository/dto/entity
- 公共逻辑放 src/common/,工具函数放 src/utils/
- 不要在 controller 里写业务逻辑,controller 只负责参数校验和调用 service
- 不要在 service 里直接写 SQL,通过 repository 操作数据库
## import 顺序
1. Node.js 内置模块
2. 第三方库
3. 项目内部模块(@/common, @/utils)
4. 当前模块内文件
每组之间空一行。
为什么重要:这些规范如果不写,Claude 会按照它训练数据里最常见的风格来——可能是 camelCase 文件名、可能用 type 而不是 interface、可能在 controller 里塞一堆业务逻辑。每一个小差异都会导致你在验收时需要纠正,累积起来就是大量返工。
这是第04课纠错案例里反复出现的问题。规范化之后一劳永逸。
# 错误处理
## 错误类
使用项目统一的 AppError 类(src/common/errors/app-error.ts):
\`\`\`typescript
throw new AppError(ErrorCode.ORDER_NOT_FOUND, '订单不存在');
\`\`\`
不要直接 throw new Error()。
## 错误响应格式
所有接口的错误响应统一为:
\`\`\`json
{
"code": 40401,
"msg": "订单不存在",
"data": null
}
\`\`\`
## 错误码规范
- 4xxxx:客户端错误(参数错误、权限不足等)
- 5xxxx:服务端错误(内部异常、第三方服务失败等)
- 前两位是 HTTP 状态码,后三位是业务码
## 日志规范
使用 LoggerService(src/utils/logger.service.ts),不要用 console.log。
\`\`\`typescript
this.logger.info('创建订单', { userId, orderData });
this.logger.error('支付失败', { orderId, error: err.message });
\`\`\`
日志中禁止出现:密码、token、完整手机号、完整身份证号。
手机号脱敏格式:138****1234。
为什么重要:错误处理和日志是 Claude 最容易"自由发挥"的地方——因为每个项目的做法都不同。没有明确规范,Claude 每次可能用不同的方式处理错误,导致项目里出现三四种错误返回格式。