在Claude Code的众多功能中,CLAUDE.md可能是最容易被误解的一个。
不少人的第一反应是把它写成一个"大而全"的文件——项目规范、编码标准、工作流程,恨不得把所有能想到的东西都塞进去。结果往往是:每次会话都要消耗大量token去处理这些冗余信息,Claude反而在规则堆里迷失方向,效率不升反降。
真正高质量的CLAUDE.md,追求的是精准,而非全面。这篇文章将分享在实践中逐步形成的CLAUDE.md配置哲学与具体技巧。
一、CLAUDE.md的本质是什么
简单来说,CLAUDE.md是项目级的系统提示扩展。它会在每次Claude Code会话启动时自动加载,为AI提供理解"这个项目"所需的基础上下文。
会话初始化流程:
↓
加载 Claude Code 系统提示(内置,约15-20K token)
↓
发现并加载 CLAUDE.md 文件(从当前目录向上查找,直到 git root)
↓
加载 .claude/rules/ 目录下的规则(按需或全量)
↓
会话就绪,等待用户输入
多层级加载:CLAUDE.md可以共存
在Monorepo项目中,Claude会按照路径层级收集所有CLAUDE.md文件:
monorepo/
+-- CLAUDE.md # 仓库级规范(总是加载)
+-- apps/
| +-- frontend/
| | +-- CLAUDE.md # 前端特定规范(在前端目录工作时加载)
| +-- backend/
| +-- CLAUDE.md # 后端特定规范(在后端目录工作时加载)
+-- packages/
+-- shared/
+-- CLAUDE.md # 共享包规范当你在apps/frontend/目录下工作时,Claude会加载两层:仓库根目录的CLAUDE.md,再加上apps/frontend/的CLAUDE.md,后者优先级更高。
这个设计非常实用:团队通用规范放在根级,技术栈特定的规范放在子目录,各司其职。
二、CLAUDE.md的内容设计原则
原则一:Litmus Test(石蕊测试)
对于CLAUDE.md的每一行内容,不妨问自己一个问题:“没有这行,Claude会犯具体的错误吗?”
# 删掉这行,会发生什么? "使用 TypeScript 编写代码" → Claude 可能默认用 Ja vaScript,有价值 ✓ "代码要清晰可读" → Claude 本来就会写清晰代码,没有价值 ✗ "所有错误处理必须记录到 logger,不能用 console.log" → 不写,Claude 可能用 console.log,有价值 ✓ "请保持代码的高质量" → 废话,删除 ✗
原则二:60-200行是黄金区间
- 少于60行:可能缺少关键约定,Claude容易做出错误假设。
- 60-200行:黄金区间,足够提供有效指引,又不会过度占用上下文。
- 超过200行:建议考虑拆分到
.claude/rules/目录。
原则三:写约束,不写教程
CLAUDE.md的核心价值在于告诉Claude"不能做什么"和"必须做什么",而不是教它基础的操作方法:
# 不好(教程式,Claude 早就知道这些) API端点应该处理错误并返回适当的HTTP状态码。 使用404表示资源不存在,400表示请求无效,500表示服务器错误。 # 好(约束式,告诉 Claude 项目特定规范) 所有API错误必须使用 ErrorResponse 结构体,不能直接返回字符串。 错误代码使用项目定义的 ErrorCode 枚举,参见 pkg/errors/codes.go。
三、一个真实项目的CLAUDE.md示例
下面是一个精简优化后的CLAUDE.md示例,来自一个Go + React全栈项目:
# 项目:用户行为分析平台 ## 技术栈 - 后端:Go 1.21,使用 Gin 框架,gorm + PostgreSQL - 前端:React 18 + TypeScript,Vite,Zustand 状态管理 - 部署:Docker,k8s,使用 GitHub Actions CI/CD ## 关键约定 ### Go 后端 - 错误处理:必须使用 `pkg/errors` 包的 `AppError`,不能用 `errors.New` 或 `fmt.Errorf` - 日志:使用 `pkg/logger` 的结构化日志,不能用 `fmt.Println` 或 `log.Print` - 数据库:所有查询必须通过 Repository 层,不能在 Handler 里直接调用 gorm - 测试:表驱动测试风格,mock 放在 `_test.go` 文件的 `TestMain` 中 ### React 前端 - 组件状态:局部用 `useState`,跨组件用 `useStore`(Zustand),禁止用 Redux - API 调用:统一使用 `src/api/` 目录下的 API 客户端,不能直接 `fetch` - 样式:Tailwind CSS only,不能写内联 style,不能新建 CSS 文件 ### 通用规范 - 所有公共 API 函数必须有 JSDoc/GoDoc 注释 - 禁止提交 `.env` 文件,使用 `.env.example` 作为模板 - 分支命名:`feat/`, `fix/`, `chore/` 前缀 ## 常用命令 - 启动开发:`make dev` - 运行测试:`make test` - 数据库迁移:`make migrate-up` - 生成 API 文档:`make docs`
总计约55行,所有项目特定的关键约束清晰可见。
四、.claude/rules/目录:按需加载的规则
当CLAUDE.md开始变得臃肿时,一个有效的策略是将细分规则迁移到.claude/rules/目录:
.claude/rules/ +-- typescript.md # TypeScript 特定规范 +-- testing.md # 测试规范 +-- database.md # 数据库使用规范 +-- security.md # 安全规范 +-- api-design.md # API 设计规范
条件加载功能可以确保只在处理相关文件时才加载这些规则:
--- paths: - "**/*.ts" - "**/*.tsx" --- # TypeScript 规范 - 优先使用 `interface` 而不是 `type`(除非需要联合类型) - 不允许 `any` 类型,使用 `unknown` + 类型守卫 - 所有 Promise 必须有错误处理(`.catch()` 或 `try/catch`) - 使用 `satisfies` 运算符代替 `as` 类型断言
当Claude处理.ts或.tsx文件时,这条规则自动加载;处理.go文件时则不加载,从而节省上下文空间。
五、@imports引用机制
CLAUDE.md支持用@语法引用其他文件,实现动态内容注入:
# 项目规范 ## API 文档 请参考以下 API 设计规范: @docs/api-design-guide.md ## Git 工作流 @docs/git-workflow.md ## 当前架构 @ARCHITECTURE.md
被引用的文件在会话中按需加载,不直接写在CLAUDE.md里就不占用上下文token。
# 常用的 @imports 模式 # 引用 README(让 Claude 了解项目背景) @README.md # 引用包依赖(让 Claude 知道可用的库) @package.json # 引用全局个人配置 @~/.claude/personal-preferences.md
六、Monorepo的CLAUDE.md架构
Monorepo是CLAUDE.md层级系统最能发挥价值的场景:
monorepo/CLAUDE.md(约50行): - 通用代码规范 - 跨包的接口约定 - CI/CD 流程 apps/frontend/CLAUDE.md(约40行): - React/TypeScript 特定规范 - 组件库使用规范 - 测试框架(Vitest + Testing Library) apps/backend/CLAUDE.md(约40行): - Go 编码规范 - 内部包使用约定 - 数据库访问模式
每个子目录中的Claude会话只会加载"仓库级 + 当前目录级"的规范,不会加载其他子目录的规范。精准,高效。
七、CLAUDE.md质量检查清单
建议定期用这个清单对CLAUDE.md进行一次审查:
[ ] 每一行都能回答"没有这行会出错吗?"(Litmus Test) [ ] 总行数在 200 行以内 [ ] 没有解释 Claude 已经知道的通用最佳实践 [ ] 有明确的技术栈声明(语言版本、框架版本) [ ] 有项目特定的约束(非通用规范) [ ] 有常用命令(不需要 Claude 自己去猜) [ ] 细分规范已迁移到 .claude/rules/ 目录 [ ] 被 @imports 引用的文件都存在
总结
CLAUDE.md的最高境界是:任何新加入项目的开发者,打开Claude Code,说一句"跑一下测试",它就能正确执行——无需额外解释,因为CLAUDE.md已经提供了所有必要的上下文。
记住三个核心原则:
- Litmus Test:每一行都能防止Claude犯具体错误。
- 精简优于全面:60-200行是健康区间。
- 按需分层:细分规范用
.claude/rules/条件加载。
