2140 字
约 7 分钟
8
02-CLAUDE.md 还是 rules?先把项目事实与编码规范分开

CLAUDE.md 还是 rules?先把项目事实与编码规范分开

团队开始维护 Claude Code 指令时,通常会先创建一个 CLAUDE.md。随着项目推进,遇到一个问题就补一条,文件很快从几十行增长到几百行。

这时往往会陷入两难:写得太简单,AI 不知道具体怎么执行;写得太详细,又会占用大量上下文,让真正重要的信息失去焦点。

解决这个问题的关键,不是继续争论“应该写多少行”,而是先把不同性质的内容分开。

CLAUDE.md 的定位:常驻、高频、高信号

CLAUDE.md 会作为项目指令进入 Claude 的上下文。它适合保存几乎每次会话都可能需要的信息,例如:

  • 技术栈和主要框架
  • 包管理器、构建工具和版本要求
  • 启动、测试、格式化、检查命令
  • 关键目录及其职责
  • 重要架构边界
  • 全项目通用的命名或安全要求
  • 很难从代码中推断出的特殊约定

一个精简的示例:

# 订单服务

## 技术栈

- Java 17、Spring Boot 3.x
- PostgreSQL、Redis
- Maven、Flyway

## 常用命令

- 启动:`mvn spring-boot:run`
- 测试:`mvn test`
- 完整检查:`mvn verify`
- 代码风格:`mvn checkstyle:check`

## 架构边界

- Controller 只处理协议适配与参数校验
- 业务逻辑放在 Service
- 数据访问通过 Repository 或 Mapper

## 项目红线

- 数据库变更必须提供 Flyway migration
- 不提交 application-local.yml 和真实密钥
- 支付、权限和资金计算相关改动必须请求人工评审

官方建议每个 CLAUDE.md 以 200 行以内为目标。这不是硬性长度限制,超过后仍然会加载;问题在于长文件会消耗更多上下文,并可能降低指令遵守的稳定性。

因此,与其追求严格的行数数字,不如追求三个标准:

  • 是否每个会话都需要?
  • 是否足够具体?
  • 是否比它占用的上下文更有价值?

rules 的定位:模块化、可维护、可限定范围

对于较大的项目,可以把规则拆到 .claude/rules/

my-project/
├── CLAUDE.md
└── .claude/
    └── rules/
        ├── coding-style.md
        ├── api-design.md
        ├── database.md
        ├── security.md
        └── testing.md

每个文件只负责一个主题:

  • coding-style.md:命名、日志、错误处理和注释。
  • api-design.md:入参、响应、错误码和分页。
  • database.md:查询、写入、索引、事务和 migration。
  • security.md:鉴权、敏感数据、密钥和日志脱敏。
  • testing.md:测试类型、目录、命名和运行命令。

这种拆分带来几个明显好处。

第一,职责清楚。维护 API 规范时不需要在数百行文件中寻找对应段落。

第二,Git 冲突更少。不同负责人可以维护不同规则文件。

第三,可以使用路径规则,只在 Claude 阅读相关代码时加载对应内容。

第四,规则变更可以通过 PR 独立评审,提交记录也能解释规范为什么变化。

一条模糊规则为什么没有用?

下面两条规则看起来合理:

- 不要使用 console.log,统一使用 logger
- 修改接口时要补测试

但对 AI 来说仍然有很多未知信息:

  • logger 从哪里导入?
  • 使用 logger.error() 还是 logger.log()
  • 日志字段是拼接字符串还是结构化对象?
  • 哪些上下文必须记录?
  • 哪些敏感信息不能记录?
  • 要补单元测试还是集成测试?
  • 测试文件放在哪个目录?
  • 用例如何命名?
  • 应该运行哪条验证命令?

所以,团队规则应该尽量写到“可执行”,而不是只表达愿望。

可执行规则的七个组成部分

一条高质量规则可以包含:

  1. 适用范围:影响哪些目录、语言或组件。
  2. 强度:必须、禁止、建议还是例外情况。
  3. 正确动作:具体使用哪个库、接口或目录。
  4. 禁止动作:明确哪些写法不能出现。
  5. 正反示例:让 AI 看到项目期望的形状。
  6. 验证方法:给出 lint、测试或脚本命令。
  7. 原因或例外:解释不明显的决策,避免 AI 自行“优化”。

团队也可以给规则标注强度,例如:

  • P0 / 必须:违反会造成安全、数据、兼容性或明显质量风险。
  • P1 / 强烈建议:通常应该遵守,但允许在说明理由后采用例外方案。
  • 建议:用于提高一致性,不应阻塞合理实现。

优先级不宜滥用。如果所有规则都是 P0,最终等于没有优先级。真正能够确定性验证的 P0 要求,还应该同步进入权限、Hook 或 CI。

例如日志规则可以这样写:

# 日志规范

## 必须

- 使用项目 `infra/logger` 导出的 logger
- 错误日志调用 `logger.error(message, context)`
- context 必须包含 requestId 和相关业务实体 ID
- 原始异常放在 `error` 字段,不要只记录 error.message

## 禁止

- 禁止使用 console.log、console.error
- 禁止记录密码、Token、Cookie 和完整个人敏感信息
- 禁止通过字符串拼接模拟结构化字段

## 示例

不要这样:

```ts
console.log("Load user failed: " + userId, error);

应该这样:

logger.error("Failed to load user", {
  requestId,
  userId,
  error
});

验证

运行 pnpm lint

这样的规则不仅告诉 AI“不能做什么”,还告诉它应该怎样完成任务。

## 不要把 rules 写成编程教材

“写得详细”不等于把每个概念都解释一遍。AI 本身已经知道 Java、TypeScript、Spring 和 React 的通用知识。

规则应该重点记录项目特有内容,例如:

- 团队选择了哪一种可行方案。
- 当前代码库有哪些容易踩坑的地方。
- 哪些通用最佳实践在本项目中不适用。
- Code Review 中反复出现过什么问题。
- 应该模仿哪个现有模块或测试文件。

下面这种内容通常价值不高:

​```markdown
- 变量名应该有意义
- 代码应该清晰易懂
- 写代码时注意性能
- 尽量遵循最佳实践

它们很难验证,也没有提供项目特有信息。

多步骤流程应该放进 Skills

如果一段规则逐渐变成“第一步做什么、第二步检查什么、第三步提交什么”,它已经不再是普通约定,而是工作流。

例如:

  • 创建并验证数据库迁移
  • 执行生产发布
  • 排查线上性能问题
  • 完成安全审查
  • 按团队模板生成新模块

这类内容更适合放在 .claude/skills/<name>/SKILL.md。Skill 的正文按需加载,不需要在每个会话里常驻。

可以用一句话区分:

rules 描述“写这种代码时应遵守什么”;Skills 描述“这项任务具体如何完成”。

一个实用的内容分流判断

遇到新规范时,可以依次问:

  1. 每个会话都需要知道吗?需要则考虑 CLAUDE.md
  2. 只影响某类文件吗?是则考虑路径规则。
  3. 它是一套多步骤流程吗?是则考虑 Skill。
  4. 能被程序确定性检查吗?能则优先交给 lint、测试或 CI。
  5. 必须阻止某个工具行为吗?是则使用权限或 Hook。
  6. 需要业务判断吗?保留人工 Review。

小结

CLAUDE.md.claude/rules/ 并不是互相替代的两个选项。

  • CLAUDE.md 保持精简,保存需要常驻的项目上下文。
  • rules 按主题拆分,保存具体、可执行的编码规范。
  • 路径规则减少无关内容。
  • Skills 承载较长的任务流程。
  • 自动化工具负责确定性检查。

下一篇将深入 rules 的加载方式:无条件规则、路径规则、用户级规则、符号链接,以及 monorepo 中如何划分团队边界。

参考资料

02-CLAUDE.md 还是 rules?先把项目事实与编码规范分开
http://clxhxhhr.top/posts/138/
作者
clxstart
发布于
2026-07-20
许可协议
CC BY-NC-SA 4.0
评论
0 条
还没有评论,先写一条吧。