先说明一下,我做 CLAUDE.md 这件事,前后折腾了快一个月。最开始只是随手在项目根目录丢了一个说明文件,后来发现这个东西用好了,真的能改变和 AI 协作的方式。这篇内容算是我把这段时间的实践、踩坑、还有最终沉淀下来的写法做个系统整理,希望对正在用或者准备用 CLAUDE.md 的人有点参考价值。
CLAUDE.md 简单说,就是给 Claude Code 这个命令行 AI 编程工具看的项目说明文件。你把它放在项目根目录,Claude 每次启动时都会自动读取,里面写的是你这个项目的背景、技术栈、代码规范、常见的坑、偏好用法等等。它的本质,是让 AI 在动手写代码前就理解你的项目上下文,而不是靠每次对话里反复交代。
我用下来的感觉是:如果你的项目只是临时跑个脚本,那 CLAUDE.md 可有可无;但只要项目稍微复杂一点,比如有多人协作、有固定架构、有历史包袱,一个好用的 CLAUDE.md 能让你少说几百句废话,而且 AI 生成的代码质量会上一个台阶。这篇文章主要面向两类人:一类是刚开始接触 CLAUDE.md,想知道这东西到底怎么用、值不值得花时间写;另一类是已经写了但觉得效果一般,想看看别人是怎么组织和优化的。我会把从零到一的过程、我自己反复调整后的版本、还有实际工作中遇到的典型问题都讲清楚。
1. 整体理解:CLAUDE.md 到底是什么,解决什么问题
1.1 它的工作机理,以及和普通注释的区别
先用大白话解释一下它为什么有用。你平时在代码里写注释,是给路过的程序员看的,AI 当然也能读到,但那是它自己翻文件翻到的,信息是被动的。CLAUDE.md 不一样,它相当于你主动递给 AI 一份"项目使用说明书",而且是在 AI 每次开工前就塞到它手里的那种。
Claude 在处理任务时,会先读这个文件来建立对整个项目的基本认知。你在这个文件里写"本项目使用 React 18 + TypeScript,状态管理用 Zustand,后端 API 走的是 REST 风格,禁止在组件里直接操作 DOM",那么接下来它生成的代码、给的方案建议,天然就会往这个方向上靠。这不是临时的口头叮嘱,而是一种持续生效的项目级约束。
很多人问,这和 README 有什么区别?区别太大了。README 是给人看的,讲究的是讲清楚项目怎么跑起来、怎么用,语气往往是中性的介绍。CLAUDE.md 是给 AI 看的"干活手册",它不需要解释"什么是依赖""怎么安装",它要写的是"这里我们约定怎么干活、有什么禁忌、有哪些痛点和历史包袱"。一个是导航,一个是操作规范。
1.2 我为什么开始写 CLAUDE.md:一次糟糕的协作体验
我决定认真写这个东西,是因为一次非常失败的协作。当时我给一个老项目加新功能,这个项目是几年前写的,技术栈比较老,还是 JavaScript 写的,目录结构也乱,里面各种历史遗留代码。我懒得跟 AI 解释太多,直接甩给它一个需求,结果它给我生成的新代码风格和旧代码完全不一致,用了一堆项目里根本没有的库,还往老模块里塞了新架构的东西。
我当时就意识到,问题不在 AI 的能力,而在于它对项目的理解是"从零开始的"。它不知道这个项目的技术选型为什么是这样,不知道哪些地方是雷区,也不清楚代码风格和历史约定。我如果花十分钟把这些内容写成一份文档,后面能省一个小时甚至更多。CLAUDE.md 就是干这个的。
1.3 适用场景和边界
要说清楚这个东西的边界,我的感受是:CLAUDE.md 不是万能药,它也解决不了所有沟通问题。
它最适合的场景有这么几类:
- 项目有明确的技术栈和架构约定,希望 AI 的代码风格和项目保持一致;
- 项目里有复杂的业务逻辑、历史遗留代码或者模块之间的隐晦依赖,需要 AI 了解这些背景;
- 团队有固定的代码规范、命名规则、提交规范,希望 AI 在生成代码时自动遵守;
- 你经常在同一个项目里反复和 AI 协作,希望它的输出保持稳定和一致。
不适合的场景也有:
- 一次性脚本、demo 项目、临时测试代码,写了反而浪费时间;
- 项目还在快速原型阶段,每天的架构和命名都在变,文档很快就过时了;
- 你的项目本身是全新的、没有历史包袱,AI 直接生成也不会太走样。
一句话总结我的经验:CLAUDE.md 的价值和项目的复杂度成正比,项目越复杂、历史包袱越重,这东西的收益就越大。
2. 内容设计:CLAUDE.md 里该写什么、不写什么
2.1 我最终沉淀下来的信息架构
经过几轮摸索,我把一份好用的 CLAUDE.md 拆成了几个固定的部分,每个部分管一个方向。这个架构不是网上的模板,是我自己根据实际项目中频繁遇到的问题总结出来的,基本已经稳定下来。
我的 CLAUDE.md 包含以下几个板块:
- 项目概况与约束:项目是干什么的,技术栈是什么,有没有硬性的环境约束,比如必须兼容某个 Node 版本、不能使用某个依赖等。
- 代码风格与结构化约定:命名规范、目录组织方式、组件/模块的组织约定、代码注释的风格等。
- 常用命令与开发流程:启动命令、测试命令、构建命令、代码检查命令,以及日常开发的工作流,比如是否用 rebase 还是 merge、提交信息的格式等。
- 架构与模块关系:核心模块有哪些,它们之间是怎么通信的,有没有单向依赖的约束,哪些模块是不能随意改动的底层模块。
- 历史遗留与雷区提示:这个项目里不能碰的地方、已知的坑、某个复杂函数为什么那么写、改动某处会导致什么连锁反应。
- AI 协作偏好:你希望 AI 在回答问题时用什么风格,比如是直接给代码还是先给方案、生成代码时是否要附带注释、遇到不确定的问题时是询问还是自行判断。
2.2 每个板块写什么的思考
项目概况这块,我觉得不用写太长,但是技术栈必须写清楚。尤其是有多个相似技术的时候,比如项目里同时用了 Vue 2 和 Vue 3,你必须在文件里明确说"核心代码是 Vue 3,legacy 目录下的老模块是 Vue 2,新增代码一律使用 Vue 3 API"。这种信息你不写,AI 很容易在混用的代码库中帮你写出风格不一致的东西。
代码风格和结构化约定这部分,要写得具体,不要只写"代码风格保持一致",这种话对 AI 没有约束力。要写明"组件文件使用 PascalCase 命名,工具函数使用 camelCase,样式文件与组件文件放在同一目录下"。关键是要让 AI 能够照做,而不是让它在模糊中猜。
常用命令这部分,我建议写清楚。因为 AI 在帮你改代码时,可能需要跑测试或者构建来验证它的改动,如果你在 CLAUDE.md 里明确写了测试命令是npm run test:unit,它就不会傻乎乎地跑完整套测试,甚至不会试图用一些奇怪的命令。这里有个细节,就是命令要写到"可以直接复制运行"的程度,包括参数。
架构与模块关系,这部分是最难写但也最值钱的。因为这属于项目里只有老人才知道的知识,AI 是不知道的。你把它写下来,AI 相当于瞬间获得了一个老开发者的经验。比如"目前项目的主要模块有 three:a 模块负责用户认证,b 模块负责订单处理,a 模块通过 event bus 通知 b 模块,不允许 b 模块反向引用 a 模块的内部方法"。这种信息一旦写清楚,AI 在生成跨模块代码时就会格外小心,不会乱引依赖。
历史遗留与雷区,这部分是我的最爱。因为一个项目里总有那么几段代码,看起来写得丑陋、不合理,但其实是当时各种条件限制下的产物,是不能随意"优化"的。如果没有在 CLAUDE.md 里标注,AI 很容易把这个当成代码坏味道,自动帮你"重构"一番,结果把系统搞挂。我见过太多次 AI 自作主张改掉"看似不合理但实际上是核心逻辑"的代码。这块一定得写。
AI 协作偏好这一节,一开始我没写。但后来发现,每个人的工作习惯不一样,写进去反而能提升体验。比如我习惯让 AI 先给出方案再动手改代码,遇到对业务影响较大的改动时,先停下来问确认。这些我都可以在 CLAUDE.md 里约定好,不用每次对话都重申。
2.3 内容的长度和写作粒度
关于写多长,我的建议是不要把它变成一本百科全书。太长的 CLAUDE.md,AI 读取和处理的时间会增加,而且信息密度降低,核心约束反而不突出。我自己用的版本大概在三到四百行左右,控制在 AI 能一次性快速读完的范围。太短了起不到约束作用,太长了就是灾难。
而且我后来发现一个重要的经验:CLAUDE.md 是活的,要经常更新。我一开始把它当成一个一次性文档,写完就不管了。后来发现,项目在演化,CLAUDE.md 里的内容如果不跟着更新,AI 就会拿着过时的"事实"去写代码,比没有更糟糕。现在我的习惯是,每当项目里出现一个新的重要约定、踩到一个新的大坑,就顺手把它补充进去。
3. 实操要点:怎么写、怎么调、怎么让 AI 真正听你的
3.1 写作时的一个核心原则:具体、具体、再具体
这是我最想强调的一点。写 CLAUDE.md 最大的忌讳就是写抽象的话。比如你写"注意代码质量",这就等于没写,AI 不知道怎么执行。你要写的是"所有工具函数必须写 JSDoc,类型定义必须使用 TypeScript 的 interface 而不是 type"这种可以直接检查的规则。
我在实践中总结了一个判断标准:如果你写的内容,可以让一个不知道项目背景的新程序员读完就照做,而且做出来的结果符合预期,那这个描述就是合格的;如果你读完还是不知道怎么操作,那这个描述就是无效的。
比如我在 CLAUDE.md 里写:
错误处理: - 所有 async 函数必须 try/catch 包裹,禁止裸抛 error; - 错误信息使用统一的中文文案格式:"操作失败:xxx"; - 用户可见的错误统一抛出 BizError,内部错误直接 console.error 并返回默认值。这种写法,AI 拿到任何一段代码,都知道该怎么处理错误,不用你每次交代。
3.2 用"正向指令 + 反向禁令"组合表达
写 CLAUDE.md 有一个很实用的技巧:既写该怎么做,也写不能怎么做。这种组合往往比单独一种效果更好。
正向指令给 AI 一条明确的路径,比如"列表页使用 Table 组件渲染"。反向禁令则用来划定禁区,比如"禁止在业务代码中直接使用 document.querySelector 操作 DOM,一律通过 ref 获取元素"。
为什么组合有效?因为 AI 在生成代码时存在多种可能的方案,正向指令压缩了选择空间,反向禁令排除了错误选项,两者配合,输出的代码基本就在你设定的范围内了。一个只有禁令的文件会显得很负面,AI 可能不知道正确路径;一个只有正向指令的文件,AI 会在你没覆盖到的地方自由发挥。
我还喜欢在 CLAUDE.md 里使用一些"优先级"词汇,比如"优先""不要""必须""除非"。这些词能被 AI 很好的理解。比如"优先使用函数组件,不要使用 class 组件,除非现有文件已经大量使用 class 组件且改动成本极高"。
3.3 接地气的例子:一份简化版的 CLAUDE.md 片段
为了让内容更有参照性,我贴一段我自己某个项目里 CLAUDE.md 的实际内容,去掉敏感信息后,结构大概是这样的:
# 项目背景 本项目是公司内部数据中台的前端部分,使用 Vue 3 + TypeScript + Vite。 负责数据源的配置、数据任务的编排以及运行日志的查看。 # 技术约束 - Vue 3 使用 Composition API + <script setup> 语法,禁止使用 Options API - 状态管理使用 Pinia,禁止引入 Vuex - 样式使用 less,遵循 BEM 命名规范 - 图表统一使用 ECharts 5.x,版本锁定,禁止自行升级到 6.x - 所有 API 请求必须通过 src/api 目录下的统一封装函数发起,禁止在组件内直接调 axios # 目录说明 - src/api: 与后端接口的封装层,一个后端模块对应一个文件 - src/views: 页面组件,每个路由对应一个文件夹 - src/components: 可复用的业务组件 - src/utils: 纯工具函数 - src/stores: Pinia 状态定义 # 代码规范 - 组件命名使用 PascalCase,文件名与组件名保持一致 - props 定义必须使用类型声明的方式,并给出默认值 - 禁止在组件内写超过 300 行的逻辑,超出的部分拆分到 composables - 日志打印统一使用 src/utils/logger.ts 里的方法,禁止直接用 console.log # 常见任务 - 启动开发环境: npm run dev - 运行单测: npm run test:unit - 构建产物: npm run build - 代码检查: npm run lint # 注意事项 - 数据任务编排的逻辑在 src/views/task/pipeline.ts 里,非常复杂,修改前必须读懂其中 workflow 的构建过程 - service 层与 view 层之间通过 qiankun 微前端通信,不要随意修改消息的格式 - src/utils/date.ts 里的 formatDate 使用了自己实现的日期解析,不要用 dayjs 替换,因为依赖它做特殊解析的地方太多这样的 CLAUDE.md,AI 拿到手之后,做出来的东西基本就在框架内,很少出格。我一般不会写太长,点到为止,但是关键约束全部锁死。
3.4 写作、迭代和更新的工作流
我现在的流程基本稳定成了四步:
- 第一步,先扫描项目里有没有明显的技术栈文件,比如 package.json、tsconfig.json、现有的 README,把可用的信息提炼出来;
- 第二步,结合自己对项目的理解,把脑中那些"我知道但没写下来"的信息补进去。这个步骤最重要,因为 AI 缺少的就是这些隐性知识;
- 第三步,把文件放回项目根目录,跑几个真实任务测试,看 AI 的输出是否符合预期。如果不合预期,回头去修改 CLAUDE.md 的表述,而不是在对话里反复纠正;
- 第四步,项目演进过程中不断补充。比如发现 AI 在某类任务上反复犯错,那就去 CLAUDE.md 里加一条对应的约束。
这个"在对话中暴露问题 → 优化文档 → 再验证"的循环,就是我对 CLAUDE.md 的核心工作方式。它本质上是在把和 AI 的一次性沟通,沉淀成可复用的长期记忆。
4. 实操过程:从零搭建一份可用的 CLAUDE.md 全流程记录
4.1 第一步:先写"雷区"还是先写"规范"
很多人问我是先写哪一部分。我的习惯是:先写雷区,再写规范。原因很简单:雷区是那些一旦踩中就会出大问题的事,优先级最高。比如"禁止修改 a 模块的对外接口"这条,如果漏掉,AI 改坏了你可能半天才发现。而代码风格这种,就算 AI 写得不太对,后面也可以靠格式化工具或者人工 review 兜底。
刚开始写的时候,不要追求完美,先把那些最让你担心的、最容易出错的事情写进去。比如:
- 这个项目里最核心的、绝不能改坏的模块是哪个;
- 现有的第三方库版本有没有锁定,升级会有什么后果;
- 是否存在某些代码是实现特定业务逻辑的"魔法代码",不能按常规逻辑去"优化"。
这些内容优先级最高,先写进去,是在给 AI 划一个安全区。
4.2 第二步:把"AI 反复问的问题"变成文件内容
第二个实操技巧可能比第一个更有效:把你在和 AI 对话中反复说的内容写进文件。
我统计过自己使用 AI 协作的过程,发现很多问题是反复出现的,比如"这个项目的测试命令是什么""这里的 API 是在哪里封装的""为什么这个模块不能直接 import 那个模块"。这些问题在有 CLAUDE.md 之前,我需要每次对话时都给 AI 解释;有了文件之后,AI 自己就懂了,不用我问。
所以,在搭建 CLAUDE.md 的时候,建议你回溯一下和 AI 的对话记录,把反复出现的那些解释性内容提取出来,写进文件。这比凭空想象内容要高效得多,也更贴合项目的实际需求。这里给一个具体的操作建议:你在 AI 对话中如果发现自己说了"我不是这个意思,这个项目里...",那这句话基本上就应该进 CLAUDE.md。
4.3 第三步:验证效果的方法论
写完之后,怎么知道写得好不好?我有一套验证方法:
第一,给 AI 一个不需要太多背景信息的小任务,比如"给 utils/format.ts 增加一个千分位格式化函数"。如果 AI 生成的代码在命名风格、类型定义、注释方式上都符合你的要求,说明基本规范已经起作用了。
第二,给 AI 一个跨模块的修改任务,比如"在用户列表页增加一个导出按钮,导出当前筛选条件下的所有用户数据"。这个任务涉及组件、API、工具函数、类型定义等,AI 如果能在不询问的情况下,自己找到正确的目录和调用方式,说明项目背景和目录说明已经生效。
第三,故意设置一个"雷区"相关的询问,比如问 AI"修改 src/components/pipeline.ts 的 xxx 方法,会影响哪些模块"。如果 AI 能正确识别出这个文件是敏感文件,并给出谨慎的回答,说明雷区部分生效了。
一般我验证三轮左右,就能判断这份 CLAUDE.md 是否达标。
4.4 第四步:持续维护与团队共享
我把 CLAUDE.md 纳入了项目的版本控制,和代码一起提交。这样团队成员拉下来代码之后,也能获得同样的 AI 协作体验。而且提交历史里可以看到 CLAUDE.md 的修改记录,方便追踪内容变化。
现在的维护频率大概是:项目发生大的架构变动时(比如引入新的状态管理库、切换构建工具)必然更新;遇到 AI 反复犯同一个错误时,主动加一条约束;每隔一两周,我会整体扫一遍文件,把过时的信息清理掉,把不准确的描述修正。
5. 常见问题与排查技巧实录
5.1 问题一:AI 好像完全无视 CLAUDE.md 里的规则
这个是大家反映最多的一个问题。我自己的排查思路是这样的:先确认 CLAUDE.md 确实放在项目根目录,而且文件名、大小写都对。Claude Code 对文件名的要求比较严格,如果文件名写成了 claude.md 或者 Claude.md,有可能不会被正确识别。
文件位置没问题的话,再看看文件内容是不是有语法或格式问题。Markdown 格式一般来说都兼容,但有些特殊的嵌套列表或者过于复杂的表格,可能会导致 AI 解析出错。我后来习惯把 CLAUDE.md 写得尽量"平",少用多层嵌套列表,多用简单的短句和标题,解析成功率明显提高。
还有一种情况是:CLAUDE.md 里写的规则和代码里明显的事实冲突。比如你写"项目使用 Vue 3"但 AI 在 package.json 里看到 Vue 2 的依赖,它会更相信代码里的实证。所以要保持文档和代码一致,一旦代码变了文档没跟上,AI 就会困惑,甚至选择性地忽略文档。
5.2 问题二:同样的规则在不同任务里效果不稳定
这个现象我也遇到过。同一份 CLAUDE.md,有些任务 AI 执行得很完美,有些任务好像完全没受文档影响。
我的理解是,AI 在决策时的信息优先级不完全由文档决定。当任务本身很清晰、规则明确时,文档的作用就大;当任务非常泛、需要大量推理时,文档的影响会被稀释。举个例子,如果你让 AI"优化一下代码",它会做很多判断,此时 CLAUDE.md 里的风格规范只能约束一部分;但如果你让 AI"把 utils 里的 format 函数重构一遍,要求符合项目代码规范",那它的注意力就会集中在格式、命名、错误处理这些方面,文档的约束力就会强很多。
所以我现在写 AI 任务提示词时,有意识地让任务描述更具体,配合 CLAUDE.md 一起用,效果比单纯依赖文档好很多。
5.3 问题三:文件越写越长,AI 反而不听话了
有一段时间我陷入了一个误区,觉得规则写得越多越好,把项目里所有细节都塞进去,结果文件超过一千行。这时候我发现 AI 的行为反而变得不稳定了,可能是因为信息太多,核心约束被淹没在大量细节里。
后来我做了一次"减法":把文件压缩到只保留关键信息。我的策略是,同一个类型的规则只保留最核心的一到两句话,把冗余的细节删掉;不重要的背景信息直接删除;把命令清单压缩到只保留高频命令。这次瘦身之后,效果回升了。所以我现在一直提醒自己:CLAUDE.md 不是文档库,是约束集,贵精不贵多。
5.4 问题四:项目里同时有多套代码,怎么写才能不互相干扰
在某些 monorepo 或者多端共存的工程里,一份根目录的 CLAUDE.md 很难照顾到所有子项目的差异。我的做法是分级:根目录放一份适用于全局的说明,然后在各个子项目里放各自的 CLAUDE.md,内容指向子项目特有的约定。
如果 Claude Code 支持读取多个层级的配置文件,那这种"全局 + 局部"的组合方式是最好用的。我在 monorepo 的实践下来,判断标准是:全局文件只写全仓通用的事,子项目文件写这个子项目独有的事,不要交叉混淆,否则 AI 会在处理子项目任务时被无关信息干扰。
6. 我踩过的一些坑,以及最终留下的几条个人经验
写到这里,我想把自己最真实的几个感受分享出来,这些经验不是从文档里学的,是真金白银试出来的。
第一,CLAUDE.md 是拿来用的,不是拿来写的。我曾经花两天时间精心打磨一份完美的文档,结果项目里真正用到的频率没那么高,投入产出比很低。后来我改成边用边写,遇到问题就往里加,反而效率更高。你不需要一开始就写一份完美的 CLAUDE.md,先从一个小而实用的版本开始,然后在真实使用中打磨。
第二,CLAUDE.md 的质量取决于你对项目的理解深度。它其实像一面镜子,你越了解自己的项目,越能把那些隐性知识写清楚,AI 的协作效果就越好。反过来说,如果你对项目本身也一知半解,那这个文件大概率写不到位。
第三,不要把 CLAUDE.md 当成约束 AI 的"枷锁"。它更像是一种思维方式——把模糊的需求变成清晰的规则,把隐性的知识变成显性的文本。这个过程本身就是一次很好的项目知识梳理,即使抛开 AI 协作,单纯做这件事,也能让你对项目的理解更深一层。
第四,具体场景下要有耐心。不是每次写完就立刻见效,有些规则可能需要两三次调整才能达到理想状态。我在实际使用中发现,针对 AI 最容易犯错的那一两类问题,单独花几次迭代去完善对应的规则描述,远比一开始就追求大而全更有用。总的规律是,你先明确最在乎的是什么,然后把那部分写成最具体的规则,其他部分慢慢补。
CLAUDE.md 这个文件名,每次看到其实都在提醒我一个朴素的经验:好工具的价值,不是看你装了多少功能,而是看你把最重要的规则写得有多清楚。