01 - CLAUDE.md 设计
1. 定位
CLAUDE.md 是整套体系中影响力最大的单一文件。它在每次会话启动时自动加载,塑造 AI 的每一次交互。
本质:项目级的 AI 行为规则库 + 上下文记忆。
2. 设计约束
- 根 CLAUDE.md 控制在 50-200 行(官方建议 ≤200 行),详细约定通过文件引用或
@path导入深入(如参考 docs/adr/ 了解架构决策) - 不要把 CLAUDE.md 写成"综合最佳实践手册"——只记录 Claude 实际犯错的纠正点
- 对每一行问自己:"去掉这行,Claude 会犯错吗?" 如果不会,删掉
编写六原则
- WHAT/WHY/HOW 结构 — 技术栈(what) → 项目目的(why) → 工作方式(how),三段式组织信息
- 渐进式披露 — 不塞所有信息,告诉 Claude 如何找到信息(引用路径 > 内嵌内容)
- 记录纠正点 — 只写 Claude 实际犯错的地方,不写"综合最佳实践手册"
- 不重复 Linter/Hooks — 确定性规则用 Hooks 执行,CLAUDE.md 只写需要判断力的指引
- 标记关键规则 — 使用 NEVER/MUST/IMPORTANT 分级标记(详见下方粒度指南)
- 提交到 Git — 让规则随项目演进,可追溯
规则标记粒度指南
| 标记 | 语义 | 使用场景 | 示例 | 建议上限 |
|---|---|---|---|---|
NEVER | 绝对禁止,违反即 bug/安全漏洞 | 安全红线、数据完整性 | NEVER commit .env | ≤ 5 条 |
MUST | 必须遵守,跳过导致质量问题 | 流程保障、一致性 | MUST run tests after changes | ≤ 10 条 |
IMPORTANT | 强烈建议,允许合理例外 | 架构偏好、效率建议 | IMPORTANT: prefer server components | ≤ 5 条 |
| (无标记) | 一般约定 | 命名、格式、风格 | Use kebab-case for files | 其余 |
准则:标记过多 = 无标记。如果所有规则都是 MUST,等于没有优先级。
官方确认:使用
IMPORTANT、YOU MUST、NEVER等强调词可显著提升指令遵从度。Claude 会对这些关键词赋予更高权重,因此应将其保留给真正关键的规则。
3. 模板(50-200 行示范)
以 React + Node.js 全栈项目为例,体现 WHAT/WHY/HOW 结构和精简纠正点原则。 注意:模板本身约 70 行,小型项目可精简至 50 行,复杂项目可扩展至 200 行。
# Project: [项目名称]
[一句话描述项目目的]。
技术栈:Next.js 14 App Router + TypeScript + Prisma + PostgreSQL + Tailwind CSS。
## 命令
- `npm run dev` — 开发服务器(端口 3000)
- `npm run build` — 生产构建
- `npm run test` — 运行 Vitest 单元测试
- `npm run test:e2e` — 运行 Playwright E2E 测试
- `npm run lint` — ESLint 检查
- `npm run db:migrate` — Prisma 数据库迁移
## 架构
- `/app` — 页面路由和布局(App Router)
- `/app/api` — API Route Handlers
- `/components` — React 组件,`/components/ui` — shadcn/ui 基础组件
- `/lib` — 工具函数、客户端实例、认证辅助
- `/services` — 业务逻辑层(唯一业务归属地)
- `/prisma` — Schema 定义和迁移文件
- `/types` — 共享 TypeScript 类型定义
- 调用方向(单向):组件 → hooks → API → services → prisma
- 详见 docs/adr/ 了解架构决策,docs/plans/ 了解技术方案
## 关键规则
- NEVER 提交 .env 文件或任何包含密钥的文件
- NEVER 使用 `any` 类型,TypeScript 严格模式
- NEVER 一次性重写整个模块,小步快跑,每步验证
- MUST 所有 API 输入用 zod 校验,错误处理用统一 AppError 类
- MUST 修改代码后运行相关测试确认通过
- MUST 修改文件前先阅读完整内容,引用类型/函数前确认存在
- 文件命名 kebab-case,组件 PascalCase,使用 named exports
- 单文件不超过 300 行,超出则拆分
- 组件/API Route 不直接调 Prisma,统一走 Service 层
## 工作模式
- 每个任务先出方案(列出要修改的文件和改动点),获得批准后再写代码
- 修改共享类型/接口时,先搜索所有引用点,列出影响范围
- 参考项目中已有的类似实现保持风格一致
- 每完成一个可工作的状态就 git commit
## 模块边界
- 组件层不直接调用数据库
- API Route 只做请求解析和响应格式化,业务逻辑在 Service 层
- 引入新依赖前,检查 docs/approved-deps.md
## 项目词汇表
(项目特定术语,防止 AI 误解。格式:术语 — 本项目含义)
## 常见陷阱(AI 犯错时更新此处)
(AI 犯错时逐条添加。格式:- 描述问题和正确做法)
保留(压缩时):已修改文件路径、当前任务进度、测试命令、架构决策、失败的尝试及原因模板设计要点
- WHAT 段(项目名 + 技术栈):让 Claude 立即理解项目上下文
- WHY 段(关键规则 + 模块边界):NEVER/MUST 标记高优先级约束,无标记的是一般约定
- HOW 段(工作模式):规定 Claude 的行为方式,而非编码标准
- 渐进式披露:架构详情引用
docs/adr/,依赖白名单引用docs/approved-deps.md,而非全部内嵌。也可使用@path导入语法(见下文)让 Claude 自动加载引用文件 - 常见陷阱 + 词汇表:初始为空,随项目演进逐条添加真实纠正点
- 压缩保留:告诉 Claude 在上下文压缩时哪些信息不能丢
4. 分层策略
CLAUDE.md 支持多层放置,由上至下加载,各层职责不同:
| 层级 | 路径 | 职责 | 是否入 Git |
|---|---|---|---|
| 托管策略(企业/IT) | /Library/Application Support/ClaudeCode/CLAUDE.md (macOS) | 组织级安全红线、合规策略 | N/A |
| 用户全局 | ~/.claude/CLAUDE.md | 个人编码偏好,跨所有项目生效 | 否 |
| 项目 | ./CLAUDE.md 或 ./.claude/CLAUDE.md | 项目特定规则(模板所示) | 是 |
| 模块 | src/模块/CLAUDE.md | 模块领域约束 | 是 |
| 本地 | ./CLAUDE.local.md | 个人本地覆盖,不入版本控制 | 否(加入 .gitignore) |
加载顺序:托管策略 → 用户全局 → 项目 → 子目录/模块 → 本地。后加载的可覆盖先加载的同名规则。
用户全局层 ~/.claude/CLAUDE.md
放个人编码偏好,跨所有项目生效:
# 全局偏好
- 使用中文与我交流
- 代码注释用英文
- commit message 用英文,Conventional Commits 格式
- 优先使用函数式编程风格
- 先出方案再写代码,除非我明确说"直接改"项目层 ./CLAUDE.md 或 ./.claude/CLAUDE.md
放项目特定规则,上面的模板就是项目层。两种路径等价,选其一即可。
模块层 src/模块/CLAUDE.md(可选)
何时创建:模块有独立领域约定,或 AI 在该模块反复犯特定错误。每个模块层 CLAUDE.md ≤ 30 行。
# Auth 模块上下文
本模块使用 NextAuth.js v5,认证流程:
1. 用户登录 → /api/auth/signin
2. OAuth 回调 → /api/auth/callback/[provider]
3. Session 存储在 JWT 中,不用数据库 session
注意:修改认证逻辑时必须同时更新 middleware.ts 中的路由保护规则。# Payment 模块上下文
领域约束:
- 金额一律使用分(cents)为单位的整数,NEVER 使用浮点数
- 所有支付操作 MUST 有幂等键(idempotency key)
- 退款逻辑必须走 refund service,不能直接调用支付网关
- 状态机:pending → processing → succeeded/failed → refunded
参考 docs/adr/003-payment-flow.md 了解完整流程。规则文件 .claude/rules/(可选)
.claude/rules/ 是比 CLAUDE.md 更细粒度的指令分发机制,在 .claude/rules/ 目录下创建 .md 文件:
- 无
paths前置信息的规则文件在会话启动时全量加载(等同 CLAUDE.md 中的规则) - 有
paths前置信息的规则仅在 Claude 读取/编辑匹配文件时按需加载,节省上下文窗口 - 支持 symlinks 跨项目共享规则(如将公司级规范 symlink 到各项目的
.claude/rules/)
---
paths:
- "src/api/**/*.ts"
- "src/routes/**"
---
# API Development Rules
- All API endpoints must include input validation
- 统一返回 { code, message, data } 格式
- 错误处理走统一中间件# 无 paths 的规则文件 — 会话启动时即加载
# .claude/rules/git-conventions.md
- commit message 使用 Conventional Commits 格式
- PR 描述必须包含改动摘要和测试计划rules/ 与模块层 CLAUDE.md 的选择:
| 场景 | 推荐方式 | 原因 |
|---|---|---|
| 少量规则(1-3 条),针对特定文件类型 | .claude/rules/rule-name.md + paths | 按需加载,节省上下文 |
| 多条规则,针对一个模块的整体约束 | src/模块/CLAUDE.md | 集中管理该模块所有上下文 |
跨目录但只针对特定文件类型(如所有 .test.ts) | .claude/rules/ + paths | 模块层 CLAUDE.md 做不到跨目录匹配 |
| 跨项目共享的规范(如公司编码规范) | .claude/rules/ + symlink | 一处维护,多项目复用 |
@path 导入语法
CLAUDE.md 中可通过 @path 语法引用外部文件,Claude 会自动加载其内容:
# Project: My App
@README.md
@docs/architecture/overview.md
@docs/git-instructions.md- 路径相对于包含导入语句的文件解析(如
src/CLAUDE.md中写@utils.md,解析为src/utils.md) - 支持递归导入(被导入的文件中也可包含
@path),最深 5 层 - 适合将长篇参考文档拆分后按需组合,保持根 CLAUDE.md 精简
claudeMdExcludes 设置(Monorepo)
在 monorepo 中,不相关团队的 CLAUDE.md / rules 文件会浪费上下文。通过项目设置排除:
// .claude/settings.json
{
"claudeMdExcludes": [
"**/other-team/.claude/rules/**",
"packages/legacy/**"
]
}排除后,匹配路径下的 CLAUDE.md 和 .claude/rules/ 文件不会被加载。
5. 与 Skills/Hooks 的优先级关系
规则分流决策:
确定性规则(格式化、导入顺序、文件大小限制) → Hooks 强制执行
编码约定(命名风格、架构偏好、模块边界) → CLAUDE.md 指引
流程性规则(审查步骤、提交流程、测试策略) → Skills 封装
执行优先级:Hooks(自动阻断) > CLAUDE.md(启动注入) > Skills(按需加载)判断原则:
- 如果一条规则可以用正则表达式或脚本检测 → 写成 Hook
- 如果一条规则需要 AI 理解上下文才能遵守 → 写进 CLAUDE.md
- 如果一条规则是多步骤流程 → 封装为 Skill
6. 保持 CLAUDE.md 鲜活
何时更新
- AI 犯了一个你纠正过的错 → 加到"常见陷阱"
- 引入了新的重要模块 → 更新"架构"章节
- 添加了新的开发命令 → 更新"命令"章节
- 确定了新的编码规范 → 更新"关键规则"
更新提示词
每次开发会话结束时:
回顾我们这次对话中你犯的错误和我纠正过的地方,
把需要长期记住的教训更新到 CLAUDE.md 的"常见陷阱"章节。
只加真正有价值的条目,不要加显而易见的东西。定期清理
每月检查一次 CLAUDE.md:
- 删除已经不再适用的规则
- 合并重复的条目
- 确认根 CLAUDE.md 总行数不超过 200 行(复杂项目可适度扩展,但超过 200 行应拆分到
@path导入或.claude/rules/)
与 Auto Memory 的边界
Claude Code 有两个互补的记忆系统,均在每次会话开始时加载:
| 维度 | CLAUDE.md | Auto Memory |
|---|---|---|
| 谁写 | 你 | Claude 自动 |
| 内容 | 规则、约束、纠正点 | 操作偏好、调试经验、架构认知 |
| 范围 | 项目/用户/组织 | 每个 git 仓库(同仓库所有 worktree 共享) |
| 存储 | 项目目录,入 git | ~/.claude/projects/<project>/memory/,本地不共享 |
Auto Memory 工作机制
- 存储结构:
MEMORY.md(索引)+ 可选的主题文件(如debugging.md、patterns.md) - MEMORY.md 前 200 行在每次会话启动时自动加载;超出 200 行的内容不加载
- 主题文件不在启动时加载,Claude 需要时通过文件工具按需读取
- Claude 根据信息的跨会话复用价值决定是否值得记忆,不是每个会话都写
- 使用
/memory命令可查看当前加载了哪些指令文件、切换 Auto Memory 开关、打开记忆目录
信息归属
| 信息类型 | 归属 | 示例 |
|---|---|---|
| 项目规则和约束 | CLAUDE.md | "NEVER 提交 .env" |
| AI 犯错的纠正点 | CLAUDE.md 常见陷阱 | "Prisma 多对多需要嵌套 include" |
| 个人操作偏好 | Auto Memory(自动) | "用中文交流" |
| 构建/调试命令 | Auto Memory(自动) | "运行 npm run test:e2e 前需要先启动 dev server" |
| 项目架构认知 | Auto Memory(自动) | "这个项目有 23 篇设计文档" |
治理建议
- 需要团队共享、版本追溯 → CLAUDE.md(进 git)
- 纯个人/纯操作、Claude 自然会学到 → 留给 Auto Memory
- 定期审视 Auto Memory(
/memory→ 打开记忆目录),将重复出现的重要模式提升到 CLAUDE.md - MEMORY.md 超过 200 行时主动精简,将详细内容移入主题文件
- Auto Memory 是纯本地的,不跨机器同步;需要跨机器保留的知识应写入 CLAUDE.md
7. 故障排除:指令不被遵循
当 CLAUDE.md 中的规则没有被 Claude 遵守时,按以下顺序排查:
- 确认加载:运行
/memory,检查你的 CLAUDE.md 是否出现在已加载文件列表中。不在列表 = Claude 看不到 - 检查冲突:多个 CLAUDE.md 或
.claude/rules/文件可能对同一行为给出矛盾指引,Claude 会任意选一个 - 提高具体性:"使用 2 空格缩进"远比"格式化代码要规范"有效。模糊指令的遵从度天然低
- 检查规则密度:NEVER/MUST 标记过多等于没有优先级(参见 §2 粒度指南)
- 用 Hook 兜底:如果某条规则必须 100% 执行,它不该只是 CLAUDE.md 中的文字——写成 Hook 强制执行(参见 doc-04)
高级调试:可配置
InstructionsLoadedHook 记录每次加载了哪些指令文件及触发原因,用于排查路径规则或延迟加载问题。