大家好,我是伍肆。一个正在从大数据转AI的工程师。现在一边学习AI,一边把Claude Code运用到日常工作中。
看完上一篇零基础Claude Code安装教程,相信绝大多数人都已经顺利装完工具、配好国产模型、搞定环境变量,跑通AI编程环境。
搞定安装,只是迈入AI智能编程的第一步,接下来,大家一定会接触到、也是学习Claude Code绝对绕不开的核心文件------CLAUDE.md。它是Claude Code"跑得稳、用得强、够专业"的核心根基。
今天这篇全网最全CLAUDE.md学习攻略,将会讲到它的核心定位,底层加载机制、Token成本、特性以及创建和验证的全流程操作。
看完能解决使用CLAUDE.md遇到的80%以上的问题,告别AI输出混乱、规则失效、性能卡顿,彻底解锁Claude Code的满血稳定状态!
01 核心定位
CLAUDE.md是放在项目里给Claude读的项目说明书。它的价值在于让Claude免去重复摸索就能理解项目。
它的核心原则:只写Claude能看懂、但无法自动推断的隐性信息。
比如像文件目录,表结构这种通过程序就可以获取的信息,都不用写;一般写的内容包括项目隐性约定、团队规范、禁止行为、固定工作流程、反直觉规则等。
很多新手将CLAUDE.md当成是可以随便写的提示词模板,以为内容越多、规则越细越好。实际恰恰相反,CLAUDE.md需要非常精简,每一行都有存在的必要。
之所以需要非常精简,跟它的加载机制密切相关。
02 底层加载机制
1. 核心加载时机
当会话启动时,也就是你在某个项目目录下输入claude然后回车,程序会自动查找并读取CLAUDE.md文件,将该文件中的所有内容,都注入到对话的上下文。
这里内容作为Claude理解项目的背景,注意这里是全部内容都会被加载,不会只挑"相关部分"。这正是强调 Token 成本和保持精简的根本原因。
另外,不是每次提问都会重新读取CLAUDE.md,而是会话开始时载入一次,之后一直驻留在上下文中。
所以,如果会话中途手动修改CLAUDE.md,通常需要重新加载(或新开会话)才会生效。
命令
/memory可以查看当前已加载的CLAUDE.md文件的绝对路径
2. 文件层级
CLAUDE.md支持多个层级,按优先级从低到高叠加生效:
objectivec
全局 ~/.claude/CLAUDE.md
↓
项目 <项目根目录>/CLAUDE.md
↓
项目 <项目根目录>/CLAUDE.local.md
↓
子目录 <子目录>/CLAUDE.md
↓
子目录 <子目录>/CLAUDE.local.md ← 最高优先级
每个CLAUDE.md的生效范围 = 它所在目录(记为 dir),以及 dir 的所有子目录(后代)。多个文件同时存在时,内容叠加合并,冲突时高优先级覆盖低优先级。
之所以要分多个层级,是为了兼顾团队规范和个人偏好的需要,如团队规范放公共文件、个人隐私放local文件、全局习惯放用户文件、模块差异放子目录文件等。
团队统一规范统一放进公共CLAUDE.md,全员共用、版本同步;个人编码习惯、本地环境配置、隐私数据单独放在全局配置和CLAUDE.local.md中。
大家可以按照自己的偏好灵活工作、自定义AI使用习惯,全程不会改动、污染团队公共规范,兼顾个性化使用体验与团队协作的统一性。
对应到这个目录结构,当在项目目录开启会话时,项目和全局的CLAUDE.md都会被加载,而子目录的CLAUDE.md是按需加载,当操作该子目录下文件时才载入。
3. 子目录的懒加载机制
子目录的CLAUDE.md不会在启动时全部扫描加载(否则大型项目上下文会爆掉),触发条件是:
当Claude真正读取或修改某个子目录下的文件时,那个子目录(及其路径上)的
CLAUDE.md才被加载进来。
举例:
objectivec
项目根/
├── CLAUDE.md ← 启动就加载
├── frontend/
│ └── CLAUDE.md ← 只有当处理 frontend/ 里的文件时才加载
└── data-service/
└── CLAUDE.md ← 只有当处理 data-service/ 里的文件时才加载
如果整个会话没碰过frontend/,它的CLAUDE.md始终不会加载,不占Token。
4. 向上递归遍历机制
实际项目的目录结构更为复杂,不单单只有项目目录和子目录,这时的加载机制是怎样的?
会话启动时,从当前工作目录(cwd)开始,沿父目录一路向上递归到文件系统根目录,把沿途遇到的每一个CLAUDE.md都加载进来------不是只读"项目根"那一个。
举例:在/home/user/proj/data-service/sql/启动:
objectivec
/home/user/proj/data-service/sql/CLAUDE.md ← 有就加载
/home/user/proj/data-service/CLAUDE.md ← 有就加载
/home/user/proj/CLAUDE.md ← 有就加载
/home/user/CLAUDE.md ← 有就加载
/home/CLAUDE.md ← 有就加载
/CLAUDE.md ← 有就加载
再加上独立的全局~/.claude/CLAUDE.md。
说白了,就是会加载启动会话所在目录以及所有父目录下的CLAUDE.md和全局的CLAUDE.md。
因此,只有两层的项目和子目录就是这里的一个特例。
5. 上下文中的排列顺序
前面说到,多个CLAUDE.md会被载入到上下文,那么这些内容在上下文中肯定有各自的排列顺序,有先有后。
排列遵循从通用到具体,越靠上层(越通用)的越先加载,也就越靠前;所以越接近 cwd(越具体)的越慢加载:
bash
全局 ~/.claude/CLAUDE.md
↓(更靠前,优先级低)
/proj/CLAUDE.md
↓
/proj/data-service/CLAUDE.md
↓(更靠后,优先级高)
/proj/data-service/sql/CLAUDE.md
这种设计是很合理的,更靠后优先级更高,因为越具体,适用范围窄的规则,更贴近当前任务,自然应该优先遵循。
这个排序跟文件层级是一样的,靠后的内容在模型注意力中通常权重更高,从而实现"具体层级覆盖通用层级"的优先级效果。
6. 向上遍历 vs 向下子目录
| 方向 | 行为 | 时机 |
|---|---|---|
| 向上(cwd → 根) | 递归遍历,全部加载 | 会话启动时 |
| 向下(cwd 的子目录) | 不预先扫描 | 实际操作到该子目录文件时按需加载,即懒加载 |
在深层目录启动会把上面每一层的CLAUDE.md 都加到上下文。因此,需要注意在哪个目录启动 Claude Code,避免某些上层目录有大段无关规则,平白占用上下文。
03 Token成本
每次提问都需要消耗Token。
大模型是无状态模型,没有永久记忆。虽然CLAUDE.md只在启动时读一次磁盘,但这些内容都保存在上下文中,每一轮对话,都会将全文重新打包发送给模型。
objectivec
每轮请求 = system 提示 + CLAUDE.md 全文 + 历史对话 + 你这次的提问
CLAUDE.md作为背景的一部分,每一轮都在这个包里,所以每轮都计入 Token。
这就好比模型是一个每次都失忆的专家,读一次磁盘是把项目说明书打印出来,只打印一次就行,而每次对话消耗Token相当于每次问问题都得把说明书重新念给他听一遍。
因此,消耗的Token随着对话轮次的增多成倍增长。
2000Token的CLAUDE.md,10轮对话累计消耗2万Token;
8000Token的臃肿文件,10轮对话直接消耗8万Token。
即便平台开启提示词缓存,能降低计费成本,但依然会挤占上下文窗口空间,压缩模型推理、读代码、分析逻辑的可用资源,直接导致AI降智、失误率飙升。
因此,CLAUDE.md要做到非常精简,每写一行规则都要问自己:删掉这条,Claude会不会出错?
如果会出错就保留这条规则,不会出错则果断删除。
04 执行特性
1. 概率模型
很多人可能会有疑惑:明明已经写好了规则,为什么AI还是不遵守?
其实,CLAUDE.md写了不一定会严格执行,它是"理解参考",是有概率的"遵守"。毕竟大模型是概率生成,不是规则校验器。
它通过对上下文的综合理解,预测出最可能的输出,定规则只是提高了"遵守"的概率,并且这个概率到不了100%。
2. 软硬约束对比
如果说CLAUDE.md是软约束,那settings.json就是硬约束,本质区别在于settings.json由程序底层强制拦截,100%无法违反,不占用任何上下文,适合安全风控、高危操作拦截。
通俗的讲CLAUDE.md是贴在墙上的"员工守则",靠人自觉遵守,可能看漏、忘记。而settings.json是门禁系统,没权限的门根本打不开。
| 维度 | CLAUDE.md | settings.json |
|---|---|---|
| 格式 | Markdown 自然语言 | JSON 结构化配置 |
| 读取者 | 模型(理解后执行) | 程序(解析执行) |
| 作用 | 告诉 Claude 该做什么、怎么做 | 控制能做什么、自动做什么 |
| 强制力 | 软约束,靠理解,有概率偏差 | 硬约束,程序强制,100% 生效 |
| 是否占上下文 | 占用,每轮消耗 Token | 不占用对话 |
软硬约束可以搭配使用,单纯靠CLAUDE.md规范代码有概率遗漏,搭配settings.json的hooks钩子,可实现代码编辑后自动执行lint扫描,自动排查不规范问题,用工具兜底模型的疏漏,杜绝代码不规范问题。
3. 搭配准则
- 写CLAUDE.md:风格、注释、流程、沟通规范
- 写settings.json强制拦截:删文件、读密钥、高危命令、生产操作
05 编写规范
学会精准编写,是用好CLAUDE.md的核心,避开绝大多数的冗余与踩坑。
/init命令可以自动扫描项目并生成CLAUDE.md初稿,#快捷输入可以在对话中随手把一条规则快速追加进CLAUDE.md。
1. 必须写的内容
- 项目固定构建、测试、部署命令
- 核心目录结构、模块职责说明
- 代码无法体现的隐性约定、反直觉规则
- 明确的禁止操作、风险红线及替代方案
2. 绝对别写的内容
- 代码可直接读取的框架版本、函数签名、表结构
- Git历史可查询的老旧信息
- 时效性极强的临时任务、迭代进度
3. 禁止项编写技巧
禁止项必须描述具体,拒绝模糊不清的术语,模糊的禁止 Claude 可能理解偏差,要写出不能做什么 + 应该改用什么。
- 写"注意数据安全",Claude 理解为"加注释提醒";写"禁止将用户 ID 打印到日志,脱敏后只记录哈希值",才能准确执行。
- 写"不要影响线上"含义模糊;写"禁止在业务代码里直接调用 DELETE 语句,删除逻辑必须走 DataCleaner 统一接口",边界清晰。
4. 格式优化技巧
同样的内容,结构化清单比散文段落理解更准确。
markdown
# 差(段落式)
项目使用 StarRocks作为查询引擎,所有查询必须经过语义层,
不允许前端直接写SQL,新指标需要在配置文件里注册。
# 好(清单式)
## 查询规范
- 所有查询必须经过语义层,禁止前端直接写 SQL
- 新增指标必须在 semantic/metrics.yaml 中注册
- 查询引擎:StarRocks(不支持事务,批量写入用 Stream Load)
Claude对结构化清单的解析效率远高于段落,清单天然自带优先级和分组。
用##分节、列表罗列规则、代码块包裹命令,AI识别准确率大幅提升,避免规则遗漏。
5. 高级Import拆分语法
CLAUDE.md支持引入其他Markdown文件,适合大型项目拆分管理:
bash
@./docs/sql-conventions.md
@./docs/api-conventions.md
@./docs/architecture.md
适合拆分的内容:独立演进的规范模块(SQL 规范、API 规范、测试规范),主文件只保留命令和核心约定。
不适合 import 的:.env等非 Markdown 文件,@语法只支持 Markdown 文本,不解析 key=value 格式。
注意:被import的内容同样会展开加载,照样算Token。
正确拆分:
markdown
# CLAUDE.md(主文件保持简洁)
@./docs/sql-conventions.md
@./docs/api-conventions.md
## 启动命令
- 开发:`npm run dev`
- 测试:`mvn test`
修改 SQL 规范只动sql-conventions.md,职责清晰,主文件稳定。
6. 敏感信息绝对禁忌
项目公共CLAUDE.md会提交Git,严禁写入密码、密钥、接口私密信息,敏感内容统一放入CLAUDE.local.md,避免永久泄漏。
7. 引导Claude的提问方式
控制Claude在不确定情况下的行为,避免自行假设导致返工。
markdown
## 遇到不确定时
- 需求不明确时,先列出 2-3 种理解方式让我选,不要自行假设
- 涉及删除操作前,必须描述将要删除的内容并等待确认
## 响应风格
- 解释代码时结合项目业务场景举例,不要用通用教材式例子
- 方案建议控制在 3 个以内,不要列举所有可能性
06 写作风格与结构模板
1. 写作风格
用祈使句、命令式,别用描述性长句:
csharp
# ✅ 好
- 金额字段必须 cast as double
- 提交前运行 sqlfluff lint
# ❌ 啰嗦
- 我们这个项目里,因为历史原因,金额相关的字段最好都转成 double 类型......
关键规则用强调词突出:
markdown
- **IMPORTANT**: *_all 是分布式表,禁止直接写入,必须写本地表
给正例 + 反例:
scss
- 数值字段用 cast,不要用 toString
- ✅ cast(cash_cost as double)
- ❌ toString(cash_cost)
2. 推荐结构模板
markdown
# 项目简介
## 常用命令
- 构建 / 测试 / 部署命令
## 项目结构
- 核心目录和职责
## 编码规范
- 命名、类型、格式约定
## 隐性约定
- 从代码看不出来的规则
## 禁止事项
- 明确不能做什么 + 替代方案
3. 内容质量原则
- 写"反直觉"的,省略"显而易见"的:常识不写,写它猜不到的
- 避免过度规范:规则太多太细反而稀释重点、增加 Token、容易自相矛盾
- 引用而非粘贴:长规范用
@import引入独立文件
07 文件校验
编写完成CLAUDE.md后必须验证,因为它是软约束,靠的是Claude 理解后尽量遵守,不像settings.json那样程序强制执行。
即使我们已经写得很清楚了,但Claude也不一定加载到、理解对、照着做。
1. 为什么必须验证
写了并不等于生效了。
可能Claude没加载到,比如cwd不对、路径错、放错目录,所以启动时压根没读到;或是因为理解偏差,描述的规则含糊不清,Claude无法解读。
这些都会导致规则不生效,如果你不去验证,一直以为有规则在防护,结果就是问题一直积累,最后爆发。
另外,写了没生效的规则,却还一直占着上下文,每轮对话都会消耗Token。
2. 如何验证
分三个层次:
1.验证有没有被加载 :用/memory命令,列出当前生效的所有层级CLAUDE.md
2.验证有没有被理解:直接让Claude复述规则,比如问它:本项目有哪些约定和禁止事项?如果它准确复述,说明已经正确理解,否则就是哪里出问题了。
3.验证有没有真正影响行为:让它做具体的事情,看有没有照着做规则完成,包括测试禁止项。因为是概率生成的,所以单次通过不代表稳定,重要规则多跑几轮看一致性。
这里总结了前面创建到测试的相关流程,一般是这样操作的:
- cd 到项目根目录,启动 Claude Code;
- 执行
/init,这时Claude会生成骨架初稿; - 我们按情况删减掉一些冗余,去掉显而易见,过时以及占Token的内容;
- 手动补充一些隐性约定即
/init写不出来的规则; - 用
#在日常对话中迭代追加,比如遇到Claude犯错就可以补一条; - 通过
/memory以及实际任务测试确认规则是否真正生效。
写在最后
用好CLAUDE.md,才是AI提效的终极密码。
CLAUDE.md的价值不在于写得多长,而在于每一条都能让Claude少犯一次错。持续迭代它,就像打磨项目的另一份说明书------只不过这份说明书,Claude会自动读、自动守。
CLAUDE.md不是文档,是你和Claude之间的契约。写好它,Claude 就懂你的项目、你的风格、你的底线。不写它,Claude 每次都是从零猜起。
如果本文对你有帮助的话,别忘记点赞、在看、转发!也欢迎在评论区交流~
关注【伍肆聊AI】,持续更新Claude Code教程、实战模板、避坑干货。