CLAUDE.md 到底该怎么写?从「给 AI 的交接文档」说起
很多人用 Claude Code 一段时间后都会问同一个问题:CLAUDE.md 到底应该写什么?怎么写才有效?本文结合实际开发经验,给出一套可落地的思路------包括 CLAUDE.md 本身,以及它和 Rules、Skill 的配合使用。
一、CLAUDE.md 是什么?给谁用的?
先说结论:CLAUDE.md 是给 Agent 的项目交接文档,不是给人看的 README。
Claude Code 每次启动会话时,会自动将项目根目录的 CLAUDE.md 加载进上下文。这个动作发生在任何对话之前,相当于在 Agent 开口之前,先让它读了一遍"入职材料"。
你可以在三个层级放置 CLAUDE.md:
| 层级 | 路径 | 作用范围 |
|---|---|---|
| 全局 | ~/.claude/CLAUDE.md |
所有项目通用规则 |
| 项目根 | <project>/CLAUDE.md |
当前项目专属规则 |
| 子目录 | <project>/src/CLAUDE.md |
模块级细粒度规则 |
本质是什么? 是上下文注入。Agent 的行为高度依赖上下文------它对你的项目一无所知,除非你告诉它。CLAUDE.md 就是那个"告诉它"的地方。
类比一下:你让一个新同事独立完成一个模块,你会给他什么?项目背景、技术约定、踩过的坑、需要注意的边界。CLAUDE.md 做的是同一件事,只不过对象是 AI。
二、新项目怎么写?先把背景讲清楚
很多人一上来就想写一份"完美的 CLAUDE.md",结果要么写不下去,要么写了一堆 Agent 其实不需要的内容。
不知道怎么开始?先跑 /init。 Claude Code 提供了 /init 命令,会自动扫描项目结构生成一份起步版本的 CLAUDE.md。生成后不要直接用,而是把它当成草稿,删掉不必要的内容,补上项目特有的约定。
新项目的正确姿势:别过度设计,先把基本上下文给够。
Agent 需要的最小信息集只有三样:
- 这个项目是做什么的 --- 产品形态、核心功能
- 技术栈是什么 --- 语言、框架、主要依赖
- 项目结构长什么样 --- 模块划分、关键目录
有了这三样,Agent 基本就能正确地工作了。
一个新项目的 CLAUDE.md 可以只有这些:
markdown
# cc-statistics
AI Coding 用量统计工具,支持 Claude Code / Gemini CLI / Codex / Cursor。
从本地数据文件中提取工程指标,**纯本地运行,不联网**。
## 技术栈
- Python 3.10+
- Click(CLI 框架)
- Rich(终端 UI)
- SQLite(本地缓存)
## 项目结构
src/
cli/ # 命令行入口
parsers/ # 各工具数据解析(每个工具一个模块)
stats/ # 统计计算逻辑
ui/ # 终端渲染
tests/ # 测试
## 构建 & 运行
pip install -e ".[dev]"
python -m cc_statistics
就这些。不需要更多。Agent 看完这个,已经能准确地在正确的目录里新建文件、用正确的框架写代码、不会跑去联网调 API。
原理是什么? 大模型的代码生成质量与上下文质量正相关。给它准确的项目背景,它的"脑补"空间就越小,犯错概率也越低。
三、CLAUDE.md 随项目迭代------核心价值是防止重复犯错
这是最重要的一个认知,也是很多人忽略的:
CLAUDE.md 不是一次性文档,它是你和 Agent 协作过程中积累的「经验库」。
完整的维护循环是这样的:
objectivec
Agent 犯了错误
→ 你纠正它
→ 把这条经验写进 CLAUDE.md(或对应的 Rules 文件)
→ 下次它不会再犯
→ 规则越来越多?拆到 Rules / Skill,按需加载
→ CLAUDE.md 保持精炼,循环继续
这个闭环越跑越顺:项目初期靠 CLAUDE.md 积累经验,项目成熟后把沉淀拆分到 Rules 和 Skill,既保留了历史智慧,又不让 context 越来越臃肿。
举几个真实例子:
例子 1:架构方向错误
你的项目用 Repository Pattern 封装数据层,但 Agent 每次都直接在 Service 里写 SQL。你纠正了三次之后,终于意识到应该写进规则:
markdown
## 架构约定
- 所有数据库操作必须通过 Repository 层,禁止在 Service 里直接查询
- Repository 接口定义在 `src/repositories/base.py`
- 参考实现:`src/repositories/session_repository.py`
加了这条之后,Agent 会主动去看 base.py,按照你的架构模式实现代码。
例子 2:用错了 API
你的项目已经把某个第三方库替换掉了,但 Agent 每次都去调老的 API。
markdown
## 依赖注意事项
- 已弃用 `requests`,统一使用 `httpx`(支持异步)
- 已弃用 `argparse`,统一使用 `click`
- 不要引入 `pandas`,数据处理用标准库或 `polars`
例子 3:测试习惯
你希望所有新功能都先写测试,但 Agent 老是跳过:
markdown
## 开发规范
- TDD 优先:先写测试(tests/ 目录),再写实现
- 覆盖率要求 ≥ 80%,用 `pytest --cov` 验证
- 禁止 mock 数据库,集成测试必须跑真实 SQLite
为什么这种模式有效?
大模型本质上是在做"给定上下文,预测最合理的输出"。当你把规则显式写进 CLAUDE.md,它在生成代码前已经看过了这些约束,自然会把它们纳入决策。
这和人类的学习机制类似:你告诉新人"我们不用 pandas",他以后就会自然地往 polars 方向想。CLAUDE.md 起的是同样的作用------把隐性知识显性化,把口头约定书面化。
四、CLAUDE.md、Rules 与 Skill:三件套怎么配合
当项目变大,你会发现 CLAUDE.md 越来越臃肿------前端规范、后端规范、数据库规范、测试规范全堆在一起,既难维护,又在每次会话开始时把不相关的内容全塞进 context。
这时候就需要认识 Claude Code 上下文管理的完整体系:CLAUDE.md + Rules + Skill,三件套各司其职。
4.1 三者的定位
| 维度 | CLAUDE.md | Rules(.claude/rules/*.md) |
Skill(.claude/skills/*/SKILL.md) |
|---|---|---|---|
| 定位 | 项目级永久背景 | CLAUDE.md 的模块化拆分 | 按需加载的可复用工作流 |
| 加载时机 | 启动全量加载 | 全量 或 按路径触发 | description 常驻,正文按需注入 |
| context 消耗 | 高 | 中(可按路径控制) | 低 |
| 适合内容 | 项目背景、架构原则 | 领域规范、路径约束 | 操作手册、执行流程 |
4.2 加载机制原理------本质是 context window 管理
理解三者的差异,关键在于理解它们的加载机制。
CLAUDE.md 的加载方式:Agent 启动时,从当前工作目录向上遍历目录树,全量加载每一级的 CLAUDE.md,并以 user message 的形式注入到对话上下文里。子目录的 CLAUDE.md 在 Agent 读取该目录文件时才触发。
Rules 的两种模式:
- 无
pathsfrontmatter:等同于 CLAUDE.md,启动时全量加载。 - 有
pathsfrontmatter :仅当 Agent 打开匹配路径的文件时才加载。这是关键能力------你可以把 API 层的规范只在 Agent 操作src/api/下的文件时才注入,不相关的任务不会被这段规范占用 context。
yaml
---
paths:
- "src/api/**/*.ts"
- "lib/**/*.{ts,tsx}"
---
# API 层规范
- 所有接口必须通过 Zod 校验入参
- 返回统一的 ApiResponse<T> 格式
- 错误码使用 src/errors/codes.ts 中的枚举
Skill 的懒加载设计 :启动时只把 description 字段(几十个字)常驻在 context 里,Agent 据此判断何时应该调用这个 Skill。完整的 Skill 内容(可能很长)只在真正需要时才注入。
这个设计思路其实和软件工程里的懒加载一脉相承------不需要的东西不占内存,context window 也是如此。
4.3 Skill 的关键 frontmatter 字段
yaml
---
description: 执行数据库迁移,当用户提到 migration、数据库变更时自动调用
disable-model-invocation: true # 禁止自动调用,必须手动 /db-migrate 触发
context: fork # 在独立子 agent 中运行,不污染主 context
allowed-tools: Bash, Read, Write
model: claude-haiku-4-5 # 用便宜的模型跑简单任务
---
# 数据库迁移流程
1. 检查 prisma/migrations/ 目录...
(以下是完整执行步骤)
有副作用的操作(比如跑数据库迁移、部署、发邮件)建议加 disable-model-invocation: true,防止 Agent 在不合适的时机自动触发。
4.4 三者配合的典型模式
以一个有数据库迁移需求的项目为例:
bash
CLAUDE.md
└── 项目背景、整体架构原则
"遇到数据库迁移需求时,调用 /db-migrate Skill" ← 识别层
.claude/rules/db.md
└── paths: prisma/migrations/**
迁移文件命名规范、Prisma Schema 约定 ← 约束层(仅操作迁移文件时触发)
.claude/skills/db-migrate/SKILL.md
└── 完整迁移执行流程:备份 → 运行 migrate → 验证 ← 执行层(按需加载)
这样一来:
- 日常写业务代码时,数据库迁移的规范不会占 context
- 只有当 Agent 真的在操作迁移文件时,相关规范才注入
- 执行迁移时,完整流程才被加载进来
三层分工的本质:识别层(知道什么时候该做)→ 约束层(知道做的边界)→ 执行层(知道怎么做)。
4.5 何时该从 CLAUDE.md 拆到 Rules / Skill?
一个简单的判断标准:
- CLAUDE.md 超过 200 行 → 考虑拆分。过长的 CLAUDE.md 会稀释关键信息的权重,后面写的规则可能根本不被 Agent 注意到。
- 某段规范只和特定目录/文件相关 → 移到带
paths的 Rules 文件。 - 某个操作有固定的执行步骤 → 做成 Skill,让 Agent 按需调用。
五、实战模板:一份成熟项目的 CLAUDE.md
下面是一份结合以上思路整理的模板,可以直接参考:
markdown
# [项目名]
一句话说明这个项目是什么。
## 技术栈
- 语言版本:
- 主框架:
- 关键依赖:
## 项目结构
(关键目录及其职责,3-8 行足够)
## 构建 & 运行
(安装依赖、启动命令)
## 架构约定
(数据流、模块划分原则、禁止跨层调用的规则)
## 开发规范
(代码风格、测试要求、提交规范)
## 注意事项 ⚠️
(踩过的坑、已弃用的东西、Agent 容易犯错的地方)
「注意事项」区块最关键。 这里写的都是 Agent 最容易出错的地方,是你和它协作历史的沉淀。新入职的人类同事也会首先关注这个区块。
当 CLAUDE.md 超过 200 行,就开始把领域规范拆到
.claude/rules/,把操作流程拆到.claude/skills/。
六、几个常见误区
误区 1:CLAUDE.md 越详细越好
不对。有个很有说服力的对比数据:Claude Code 的创始人 Boris Cherny 自己的 CLAUDE.md 只有约 100 行 / 2.5k tokens。而有人写了一份 847 行 / 15k tokens 的"超详细"版本,实际效果反而更差。
原因在于:过长的 CLAUDE.md 会稀释关键信息的权重------规则越多,每条规则被"看到"的概率越低,引入的噪音也越多。精简 > 详尽,保持关键规则用加粗或代码块突出,超过 200 行就该拆分了。
误区 2:只写一次,从不更新
这是最大的浪费。CLAUDE.md 的价值在于持续积累,每次 Agent 犯错都是一次更新机会。
误区 3:把 README 复制进去
README 是给人看的,CLAUDE.md 是给 Agent 看的,侧重点不同。Agent 不需要功能介绍,它需要约束和上下文。
误区 4:写全局规则,忽略项目专属
~/.claude/CLAUDE.md 适合放通用规则(比如语言偏好、代码风格),但项目的架构约定和踩坑记录应该在项目级 CLAUDE.md 里。
误区 5:不知道 Rules 和 Skill 的存在
很多人用了半年 Claude Code,还不知道 .claude/rules/ 和 .claude/skills/ 这两个目录。当你的 CLAUDE.md 开始膨胀,这两个才是正确的拆分方向。
总结
四句话概括:
- CLAUDE.md 是给 Agent 的入职材料,在每次会话开始时自动加载,决定了 Agent 对项目的初始理解。
- 新项目从最小上下文开始:项目背景 + 技术栈 + 目录结构,够用了。
- 随协作迭代:每次 Agent 犯错,把纠正经验写进去------这是 CLAUDE.md 最核心的使用姿势。
- 项目大了用三件套:CLAUDE.md 保全局背景,Rules 做领域隔离,Skill 封装执行流程------本质都是 context window 管理。
把 CLAUDE.md 当成一个活文档,而不是一次性配置。它越成熟,你和 Agent 的协作效率就越高。
如果你在用 Claude Code,顺手试试 cc-statistics ------ 可以统计你的 AI 编码用量、费用和工具调用分布,帮你更好地理解自己的 AI 使用习惯。