工程师们写CLAUDE.md的姿势,像极了写README——堆上技术栈、撒几条个人偏好、补一句"记得写测试"。文件是有了,Claude也"读"了,但写出来的代码照旧跟着训练数据走,跟你的代码库没什么关系。

问题不在用不用心,在搞错了品类。README是描述项目的,技术规格才是约束行为的。CLAUDE.md要生效,得按后者写。但大多数工程师没给AI写过规格书,本能地套用了熟悉的格式。

打开网易新闻 查看精彩图片

这篇内容聊三个维度:文件怎么搭结构、规则怎么写才能被遵守、代码库演进时怎么维护这份文件。

Claude Code从项目根目录读CLAUDE.md,但很多人不知道的是——它在任何子目录工作时,也会读该目录下的CLAUDE.md,而且这些文件会继承根目录的配置。

这很关键,因为上下文是有方向的。写迁移脚本时的规则,和写Sidekiq任务时的规则,本就不是一回事。硬塞进一个根文件,结果要么是冗余,要么是自相矛盾。

一种可行的结构:

project/
├── CLAUDE.md —— 全局约束、技术栈、沟通协议
├── app/
│ ├── models/CLAUDE.md —— 表结构规则、验证模式、查询约束
│ ├── jobs/CLAUDE.md —— 幂等性规则、重试逻辑、失败处理
│ └── services/CLAUDE.md —— 何时抽取、接口契约、禁止上帝对象
└── db/
└── migrate/CLAUDE.md —— 迁移规则、索引要求、可回滚性

每个文件回答同一个问题:在这个代码库的特定角落,什么样的产出算好的?

根目录管放之四海而皆准的东西:锁定版本、已敲定的架构决策、沟通协议(先规划再执行、动表结构前先问)。目录文件则编码本地经验。当Claude打开app/jobs/,它会读两份,本地文件冲突时优先。

根文件建议最后写。等你写完各目录文件,自然能看出哪些东西在重复——那些就是该上浮到全局的。

在任何CLAUDE.md内部,有两类内容离AI的决策距离不同。

事实描述环境:

## Stack
- Ruby 3.3.4
- Rails 7.2.1
- PostgreSQL 15
- Sidekiq 7.3
- pgvector 0.7(用于app/models/document.rb,非广泛可用)

规则约束行为:

## Database
禁止在循环里更新记录,用集合更新。
禁止不带WHERE条件调用update_all。
任何触及documents表的查询,合并前必须有EXPLAIN ANALYZE。

工程师们习惯把这两类混成段落,AI对它们的权重判断 roughly equal。分开写,AI才能区分什么是背景信息、什么是必须遵守的边界。