| 编辑推荐: |
文章系统讲解了如何正确编写 CLAUDE.md 文件,通过设定明确的代码规范、架构约束和禁止事项来为 AI 编程助手建立规则边界,从而有效避免其在辅助开发时“乱猜”或偏离预期,希望对你的学习有帮助。
本文来自于小撒的私房菜,由火龙果软件Alice编辑,推荐。 |
|
Claude Code 每次启动会先读 CLAUDE.md,再干活。写这个文件不是在写文档,是在给 AI 设规则。大多数人写错了,所以 AI 还是会乱来。这篇文章教你怎么写对。文末附两份可直接复用的模板。
你可能不知道的一件事
Claude Code 每次启动,在你输入任何内容之前,有一个固定动作: 读 CLAUDE.md 。
这个文件的内容会被注入到每一次对话的系统提示里——不是作为参考,而是作为前置规则。你之后说的所有话,Claude 都会在这个背景下去理解和执行。
这意味着,如果你没有 CLAUDE.md,或者 CLAUDE.md 写得很糟糕,Claude 每次启动都是"白板状态":它不知道你的项目用什么框架,不知道你有哪些代码规范,不知道哪些目录不能动,不知道测试怎么跑。它只能靠猜。而我们在上一篇已经说过了——AI 一旦开始猜,就有概率猜错,你就要开始收拾。
反过来,一个写得好的 CLAUDE.md 相当于给 AI 做了一次完整的入职培训:它清楚你的项目是怎么组织的,知道你的代码偏好,知道什么事要先问你再做,什么事可以直接执行。从第一条指令开始,它就在正确的轨道上。
但问题是,大多数人写 CLAUDE.md 的方式从一开始就跑偏了。
最常见的错误:把它当文档写
看过不少开发者晒出的 CLAUDE.md,最常见的模式是这样的:
# 项目介绍 这是一个基于 FastAPI 和 PostgreSQL 的后端服务,采用 RESTful API 架构, 使用 Redis 做缓存,Celery 处理异步任务,部署在 AWS 上……
# 目录结构 app/ ├── api/ # 路由和接口 ├── models/ # 数据库模型 ├── services/ # 业务逻辑 ...
|
看起来挺认真的,对吧?实际上,这两段内容对 Claude 来说几乎没有价值。
为什么?因为 Claude Code 可以自己读代码。它能扫描目录结构,能看 pyproject.toml 和 requirements.txt ,能理解你用了什么框架。你告诉它"这是一个 FastAPI 项目",它扫一眼依赖文件就知道了。你用两百个字描述的项目背景,它通过读代码能自己推断出来。
CLAUDE.md 的价值不在于告诉 Claude 它能自己发现的事,而在于告诉它通过读代码无法知道的事 :你的偏好、你的边界、你的决策、你的禁区。
换一个比喻:新来的工程师不需要你告诉他们"这是一个 Python 项目,我们用 FastAPI"——他们一看代码就知道了。他们真正需要知道的是:我们的 PR 流程是什么?哪些模块是历史包袱、别碰?有没有什么团队规范在代码里看不出来?这次 sprint 的优先级是什么?这些才是入职培训的核心内容,CLAUDE.md 也是。
它应该写什么
如果要把 CLAUDE.md 里真正有价值的内容归类,大概是这五个方向:
一、不运行一遍不知道的命令
构建、测试、 lint 、启动本地服务——这些命令每个项目都不一样,Claude 必须知道才能完成工作、验证结果。这是 CLAUDE.md 里最基础的内容,也是 Anthropic 官方文档里唯一明确推荐要写的内容之一。
## 常用命令 - 创建虚拟环境:`python -m venv .venv && source .venv/bin/activate` - 安装依赖:`pip install -e ".[dev]"` - 启动开发服务器:`uvicorn app.main:app --reload` - 运行全部测试:`pytest` - 运行单个测试:`pytest tests/test_users.py::test_create_user -v` - 代码检查:`ruff check . && mypy app/` - 格式化:`ruff format .` - 提交前必须跑:`ruff check . && mypy app/ && pytest`
|
这看起来很基础,但少了它,Claude 每次想验证自己的改动是否正确时,都得猜你的测试命令,或者问你,或者扫遍项目找配置文件再解析——白白消耗上下文。
二、你的代码偏好,尤其是"和默认值不一样的地方"
这里有一个关键判断:不要把语言默认规范写进去,只写你的项目和主流约定不一样的地方。"用类型注解""避免裸 except ""函数命名用小写下划线"——这些是 Python 的基本规范,Claude 已经知道了,写了也是浪费 token;但"我们用 loguru 而不是标准库的 logging ""依赖注入统一用 dishka ""所有数据库操作必须走 Repository 层"——这些项目特有的约定,不写进去 Claude 就不知道。
## 代码规范(只列与默认约定不同的地方) - 日志统一用 `loguru`,禁止使用标准库 `logging` 或 `print` - 错误处理用自定义异常类(见 `app/exceptions.py`),不要直接 `raise Exception` - 所有数据库操作通过 Repository 层,禁止在路由或服务层直接写 SQL - API 响应统一用 `app/schemas/response.py` 中的 `APIResponse` 包装 - 异步函数一律用 `async def`,即使当前没有 await,保持风格统一 - 配置项全部通过 `app/config.py` 的 `Settings` 类读取,禁止直接 `os.environ`
|
三、架构约束和目录边界
这一块是防止 Claude "顺手乱改"的关键。Claude 处理任务时有时候会发现"顺手做一件相关的事会更好",然后它就去做了。问题是它判断的"更好"不一定是你想要的。明确告诉它目录的用途和边界,可以大幅减少这种情况。
## 目录职责与边界 - `app/api/` — 路由定义和请求/响应处理,不包含业务逻辑 - `app/services/` — 所有业务逻辑,调用 Repository,不直接操作数据库 - `app/repositories/` — 数据库操作,只负责 CRUD,不包含业务判断 - `app/models/` — SQLAlchemy ORM 模型,不包含任何业务方法 - `app/schemas/` — Pydantic 数据校验模型,不引入数据库依赖 - `tests/` — 测试与 `app/` 目录结构镜像,每个模块有对应测试文件
|
四、明确的禁止事项
这是最被低估的一个部分,也是实际效果最立竿见影的一个部分。把你曾经因为 AI 乱来而吃过亏的地方,用"禁止"的方式写进去。
## 禁止事项 - 永远不要修改 `alembic/versions/` 目录下的迁移文件,有需要告诉我新建 - 不要删除任何函数或类,即使你认为没有被调用——可能有动态引用或插件加载 - 不要自动用 pip 安装新包,先告诉我需要哪个库、为什么需要 - 不要修改 `.env` 文件,所有新的环境变量先和我确认变量名再添加 - 不要在同一个 commit 里混入功能改动和 `ruff format` 格式化改动 - 不要修改 `app/core/security.py`,这个文件涉及认证逻辑,改动需要专项审查
|
这个列表的价值会随时间增长。每次 Claude 做了一件你不想要的事,把它加进来。有开发者总结:这个"禁止事项"列表,就是他和 Claude 合作一段时间之后积累下来的经验结晶,每一条都对应一次真实的踩坑。
五、工作方式偏好
告诉 Claude 你希望它在什么时候停下来问你,什么时候可以自己决定往下走。这决定了它的自主程度。
## 工作方式 - 任何会影响超过 3 个文件的改动,先列计划确认再执行 - 遇到不确定的需求,停下来问我,不要自己猜 - 每完成一个有意义的改动,自动运行 `pytest` 验证没有引入回归 - 发现潜在的 bug 或改进点,可以提出来,但不要自行修改
|
四个文件,各司其职
很多人不知道的是,CLAUDE.md 并不是唯一一个 Claude Code 会读的配置文件,而且它们有明确的层级关系:
全局配置 ( ~/.claude/CLAUDE.md ):放在你的主目录下,对你所有项目都生效。适合存放跨项目通用的个人偏好——比如你希望 Claude 的回答风格、你惯用的代码格式、你的全局禁忌(比如"不要在任何地方硬编码密钥")。这个文件只有你自己用,不提交到版本控制。
项目配置 ( /项目根目录/CLAUDE.md ):放在项目根目录,提交到 Git,团队所有人共用。存放项目特有的规范、命令、架构约定。这是最核心的一层。
子目录配置 ( /项目/app/CLAUDE.md 、 /项目/tests/CLAUDE.md 等):在大型项目里,不同模块可以有自己的 CLAUDE.md。当 Claude 处理某个子目录里的文件时,它会额外加载那个子目录下的 CLAUDE.md 作为补充规则——比如 tests/ 目录下可以单独写测试规范, scripts/ 目录下写脚本规范,互不干扰。
本地个人配置 ( /项目根目录/CLAUDE.local.md ):这个文件加入 .gitignore,不提交。适合存放你个人的、不适合共享给团队的设置——比如你自己的调试偏好、你的本地环境特殊配置。
四层规则同时生效,更具体的层级会覆盖更通用的层级里的冲突项。理解这个结构,你就能在"全局通用"和"项目特殊"之间做出合理的分配,而不是把所有东西都堆在一个文件里。
一个实用技巧:让 Claude 自己写第一版
从零开始手写 CLAUDE.md 有一定成本,尤其是对一个已有规模的项目。有一个更高效的方法:
在项目目录下运行 /init 命令,Claude Code 会扫描你的代码库,分析构建系统、测试框架、代码风格,自动在 项目根目录 生成 CLAUDE.md 文件,路径就是 /你的项目名/CLAUDE.md 。这个版本覆盖了 70-80% 的基础内容,你在此基础上补充你的个人规则、禁止事项和工作方式偏好就好,比从空白文件开始省了很多功夫。
之后的维护方式,按照 Boris Cherny (Claude Code 团队的工程师)的建议是: 每次 Claude 出错,让它自己把教训写回 CLAUDE.md 。具体来说,当 Claude 做了一件你不想要的事,纠正它之后,加一句:"把这条规则更新到 CLAUDE.md。"它会自己写一条清晰的限制规则,以后不再犯同样的错误。
这个反馈循环让 CLAUDE.md 随时间变得越来越符合你的工作方式,而不是一份写了一次就放在那里的静态文件。
关于长度:有一个反直觉的事实
很多人第一次写 CLAUDE.md 会犯两种相反的错误:要么几行带过,要么洋洋洒洒写了好几百行。
写太少是问题,写太多也是问题。原因有些技术性,但值得理解: CLAUDE.md 的内容会占用上下文窗口 。Claude Code 的上下文窗口是有限的,系统提示、工具定义、 MCP 配置……在你敲第一个字之前,这些东西加在一起已经消耗了大约三到四万 token。CLAUDE.md 写得越长,能留给真正工作内容(代码、对话、工具输出)的空间就越小。
一份团队总结的数据:一个维护良好的结构化 CLAUDE.md,每次会话能减少约 40% 的输入 token——因为 Claude 不需要通过读代码来重新理解项目背景。但这个前提是文件足够精准,没有冗余。
写 CLAUDE.md 的目标不是"写得全",而是"写得准"。 一份 200 token 的精准规则,比一份 3000 token 充满废话的文件更有效 。每增加一条规则,问自己一个问题:如果不写这条,Claude 会做错什么具体的事?如果答不上来,这条可以不写。
一份可以直接用的 Python 项目模板
这份模板保存在 项目根目录 下,文件路径是 /你的项目名/CLAUDE.md ,和 README.md 、 pyproject.toml 放在同一层级,提交到 Git 后团队所有人共用。
下面是一个适用于大多数 Python 后端项目的通用模板,可以直接作为起点:
# [项目名] — Claude Code 工作手册
## 这个项目是什么 [用 1-2 句话说明项目做什么,指出任何不读代码无法知道的背景信息]
## 常用命令 - 激活环境:`source .venv/bin/activate` - 安装依赖:`pip install -e ".[dev]"` - 启动服务:`uvicorn app.main:app --reload` - 运行全部测试:`pytest` - 运行单个测试:`pytest tests/路径/test_文件.py::test_函数名 -v` - 代码检查:`ruff check . && mypy app/` - 格式化:`ruff format .` - 数据库迁移:`alembic upgrade head` - 提交前必跑:`ruff check . && mypy app/ && pytest`
## 代码规范(只列与默认约定不同的地方) - [规范 1,例如:日志统一用 loguru,禁用 print 和 logging] - [规范 2,例如:自定义异常继承 app/exceptions.py 中的 BaseAppError]
## 目录职责 - `app/api/`:路由层,只处理请求/响应,不写业务逻辑 - `app/services/`:业务逻辑层,调用 repository,不直接操作数据库 - `app/repositories/`:数据库操作层,只做 CRUD - `app/models/`:ORM 模型,不包含业务方法 - `app/schemas/`:Pydantic 校验模型,不引入数据库依赖 - [补充项目特有的目录说明]
## 禁止事项 - 不要修改 `alembic/versions/` 下的迁移文件,需要变更就新建迁移 - 不要自动 pip install 新包,先说明需要什么、为什么 - 不要修改 `.env` 文件,新变量先和我确认名称 - [项目特有的禁区]
## 工作方式 - 影响超过 3 个文件的改动,先列计划确认 - 需求不明确时停下来问,不要猜 - 每次改动后自动运行 `pytest` 验证 - 发现问题可以提,但不要自行修改超出任务范围的东西
## 已知坑(随时补充) - [坑的描述] → 正确做法是 [...]
|
给独立开发者的全局 CLAUDE.md 模板
这两份模板 可以同时存在,互不冲突 。Claude Code 启动时会先读全局配置,再读项目配置,两份规则叠加生效——全局模板管的是你个人的跨项目偏好,项目模板管的是这个项目特有的规范。如果某条规则有冲突,项目级别的优先级更高,会覆盖全局配置里的同类设置。
全局模板保存在你的 用户主目录 下,路径是 ~/.claude/CLAUDE.md (macOS/Linux),这个文件不属于任何项目,不会出现在任何 Git 仓库里,只对你自己的机器生效。Windows 用户对应路径是 C:\Users\你的用户名\.claude\CLAUDE.md 。
如果你维护多个 Python 项目,这份全局配置写一次,以后所有项目都受益:
# 我的全局 Claude Code 偏好
## 工作方式 - 对于任何改动超过 5 个文件的任务,先列出完整计划,等我确认再执行 - 遇到多种实现方案时,列出 2-3 个选项并说明各自的权衡,不要自行决定 - 完成任务后,主动说明做了什么、为什么这样做、有什么值得注意的地方
## Python 代码偏好 - 函数优先于类,除非明确需要封装状态或实现接口 - 类型注解必须完整,包括返回值;不接受 `Any` 类型除非有充分理由 - 错误处理要明确,不接受空的 `except` 块或只写 `pass` - 注释解释"为什么",不解释"是什么"(代码本身说明是什么) - 新增依赖前告诉我,说明有无标准库替代方案
## 安全底线(任何项目都适用) - 绝对不要硬编码任何密钥、token、密码、数据库连接串 - 不要创建不在 `.gitignore` 里的包含凭证的文件 - SQL 查询必须参数化,禁止用字符串拼接构造查询 - 用户输入必须校验,不信任任何外部数据
## 禁止事项 - 不要自动 push 到任何远程仓库 - 不要修改 `.env` 文件,新的环境变量先问我 - 不要在生产代码里留 `print()`,用日志工具代替 - 不要删除带有 `# TODO` 或 `# FIXME` 的注释,这些是待办项
|
最后一个建议
把 CLAUDE.md 当成一个 活的文档 ,而不是一次性写完就忘了的配置文件。最有价值的 CLAUDE.md,不是花一个下午精心设计的那个,而是在真实使用中,跟着每一次 AI 的犯错一起生长起来的那个。
每一条"禁止事项"背后,都是一次具体的教训;每一条"工作方式"背后,都是一次你发现 AI 的行为和你期待不一致时的调整。积累到一定程度,你会发现这份文件里记录的,其实是你和 AI 协作方式的一次次磨合结果——它变得越来越懂你,不是因为模型变聪明了,而是因为你把规则写清楚了。
|