撰写高效CLAUDE.md文件的实用指南
学习21条具体且可验证的规则,用于精简臃肿的CLAUDE.md文件,从而确保在长时间使用中Claude Code依然可靠、可预测且值得信赖。
上个月,有位开发者从一份已存在了一年的CLAUDE.md文件中删去了340行代码。
该文件的规模一直在持续扩大。每当Claude Code出现令人恼火的行为时,就会新增一条规则;而一旦某条规则不起作用,就会在它下面再添加更长的版本。到8月份时,该文件已达到400行,Claude的表现明显比文件还只有60行时糟糕得多。
在将文件精简到61行后,改善效果立刻显现。
这其实并非关于个人自律的教训,而是关于规则文件用途的启示。它不是你逐渐积累的愿望清单,而是一组模型在每次会话开始时都会读取的指令,每新增一行都必须与其他现有内容竞争用户的注意力。
以下是经过筛选的21条规则,以及每条规则背后的依据。
臃肿的CLAUDE.md所带来的真实代价
2026年8月,Claude Code社区中有人决定测试一个看似显而易见但实际上无人验证过的问题:Claude是否真的会遵循给定的CLAUDE.md指令。
初步检测显示,典型文件中的规则中有55.7%在原则上是可以被验证的。经过人工审查后,这一比例降至18%,再降到8.75%,最终确定为6.67%。
先想想这个数字。在典型的 CLAUDE.md 文件中,15 条规则里实际上只有大约 1 条能够被验证。剩下的 14 条本质上只是些原则,比如“编写整洁的代码”、“遵循最佳实践”、“注意性能问题”。无论是模型还是你,都无法确定这些原则是否真的被遵守了。
这就是文件臃肿带来的真正代价。问题不仅在于那些无法验证的规则会被忽略,更在于它们在每一轮对话中都会占用上下文窗口的空间,从而挤占那些真正重要的规则的位置。
大约在同一时间,Anthropic的工程师们也对他们的系统提示进行了相关观察:超过一定长度后,增加更多指令非但无法提升性能,反而会降低它。他们最新的模型所使用的系统提示长度已大幅缩减。
您的CLAUDE.md文件遵循完全相同的模式。以下的21条规则旨在帮助您保持在高效的工作区间内。
规则1–7:避免性能下降
这些初始规则的存在是为了防止Claude把简单的任务搞得一团糟。
规则1:仅进行精确的修改
## Editing
Change the minimum number of lines needed.
Do not reformat, reorder, or rename anything you were not asked to change.
Match the style already in the file, even if you would write it differently.
其作用原理:如果没有这一限制,Claude往往会“改进”它所处理的每一个文件。你原本只要求进行简单的一行修改,结果却要查看长达200行的差异内容,而真正的修复方案还藏在其中某处。这大概是人们对编程助手最常有的抱怨,同时也是最容易解决的问题的之一。
修改前:你要求修复回调函数中的“偏移量错误”。结果代码被改成了async/await格式,还有三个变量被重命名,但原来的错误依然存在。
修改后:只有一行代码被更改,查看该改动大约只需要四秒钟。
规则2:绝不要重写我的测试代码
## Tests
Do not edit existing tests to make failing code pass.
If a test fails, fix the code.
If you believe the test itself is wrong, say so and stop. Do not edit it.
其作用原理:当模型被要求让测试通过时,它总会选择最简单的办法,而重写断言语句显然比真正修复底层错误更为简单。这条规则彻底杜绝了这种捷径。
修改前:三个测试变为绿色。其中两个现在正在验证错误的内容。
修改后:Claude会指出某个测试期望得到404状态码,而实际代码返回的是500,随后会询问到底哪个是错误的。
规则3:不要添加依赖项
## Dependencies
Do not add packages. Use what is already in package.json.
If you are convinced a new package is needed, name it, name what it
replaces, and stop. Wait for approval.
其作用原理:每个编程工具获取新库的方式都类似于初级开发人员。如果不加以控制,最终会出现三个独立的日期处理模块,导致包体积大到令人难以解释。
之前:一个简单的四行日期格式化任务却变成了新增的依赖项以及锁文件修改。
之后:依然使用那四行代码,只不过是通过已有的Intl API来实现。
规则4:不对不可能发生的情况进行错误处理
## Error Handling
Handle errors that can actually occur here.
Do not add try/catch around code that cannot throw.
Do not add null checks for values this function is guaranteed to receive.
为何有效:为防止不可能出现的情况而编写的防御性代码并非真正的安全措施,反而只是冗余代码。它掩盖了真正重要的两项检查,还毫无益处地使函数长度翻倍。
之前:一个12行的函数,其中包含了四段防御性代码,而其中三段永远不可能被触发。
之后:依然是12行的函数,但只保留了唯一可能真正出错的检查。
规则5:不要触碰未被要求修改的内容
## Scope
Work only on what was asked.
Unrelated dead code, bad names, or missing types: mention them, do not fix them.
Remove imports and variables that YOUR change made unused. Nothing else.
为何有效:隐藏在差异对比中的范围扩展问题在有人审查之前不会显现,而到那时已经浪费了大量时间。提前明确界定范围可以避免对哪些内容属于允许修改范围的猜测。
规则6:绝不要提交机密信息
## Security
Never write a key, token, password, or connection string into a file.
Never commit .env, .env.*, or any credentials file.
If a value is needed, reference the environment variable by name.
为何有效:这是少数一旦出错就无法挽回的情况之一。该指令简短、无条件且易于验证,这正是良好规则应有的形式。
规则7:执行任何破坏性操作前先询问
## Destructive Actions
Stop and ask before: dropping a table, deleting a branch, force pushing,
rewriting history, deleting a file you did not create, or running a
migration against anything that is not local.
其生效原理:模型本身并不存在对哪些操作可以撤销、哪些不能撤销的固有认知。在模型看来,覆盖历史记录与格式化文本文件属于同一类操作:都只是另一种工具调用而已。这条规则为模型提供了它自身无法识别的风险类别。
规则8-14:制定模型真正能够遵循的编写规则
这一部分旨在解决合规率低背后的根本问题。这些规则并非直接针对行为本身,而是关于如何表述那些用于规范行为的规则。
规则8:每条规则都必须可验证
Bad: Write clean, maintainable code.
Good: Functions over 40 lines must be split.
为何有效:如果无法通过查看输出结果就判断是对是错,那么这条规则除了占用上下文空间外毫无作用。在向该文件添加新行之前,先思考什么证据能证明这条规则已被违反。如果无法给出答案,就不要添加这条规则。
之前:像“编写整洁、易于维护的代码”这样的要求在文件中闲置数月,从未对输出结果产生任何影响,你也找不到它被违反的实例。
之后:在差异对比中出现了61行的函数,你可以直接指出它违反了哪条规则。之后要么遵守该规则,要么将其删除。无论哪种结果都能推动事情向前发展。
规则9:一条规则,一行代码
Bad: When you are working on components, please try to keep them
focused and reasonably small, and generally avoid mixing data
fetching with presentation where that makes sense.
Good: Components do not fetch data. Fetch in the route, pass props down.
其生效原因:用含糊的措辞表述规则时,听起来只像是一种温和的建议。而建议总是会输给模型原本就倾向采取的行动。
规则10:命名文件,而非描述感受
Bad: Follow our API conventions.
Good: New routes follow the shape in src/api/users/route.ts.
其生效原因:像“我们的惯例”这样的表述只对人类有意义。而文件路径则是模型能够实际打开并读取的内容。直接指向真实存在的代码,远比任何描述该代码的文字都有效。
规则11:禁止而非鼓励
Bad: Prefer simple solutions.
Good: Do not add an interface with one implementation.
Do not add a config option for a value that never changes.
其生效原理:像“优先考虑”这样的表述仅作为平局时的决胜因素,且仅在模型本身已存在不确定性时起作用。而“禁止”则起到强制阻止的作用。在实际使用中几乎所有失效的规则,都是因为其表述方式属于鼓励而非禁止。
有一个简单的测试方法:读完某条规则后,思考如果模型决定去做你试图阻止的行为,它是否仍能从技术上遵循该规则。如果是,那么你所写的只是偏好建议,而非真正的规则。
规则12:将规则置于操作发生的地方
Core rules live in the root CLAUDE.md, not only in path-scoped rule files.
为何会这样:这一点很容易被忽视,一旦忽略就可能导致真正的错误。2026年8月,有人向 Claude Code 提出了一个问题,指出当智能体通过shell命令而非内置编辑工具修改文件时,由于规则注入与特定的编辑路径相关联,基于路径范围的规则文件可能会悄无声息地无法加载。其他用户也报告了将规则保存在嵌套子目录文件中时出现的相同问题。
无论该特定错误是否得到修复,这一教训都依然适用。任何绝对不能被忽略的内容都应该放在始终会被加载的根文件中,而不应藏在只有偶尔才会被读取的条件文件里。
规则13:限制文件长度
CLAUDE.md stays under 60 lines. If you need line 61, delete something first.
为何有效:这条规则显著改善了某个团队的实际工作流程,但它与人们的直觉相悖。将文件长度扩展到400行并不意味着模型就有400条可执行的规则,它只会生成一大段密密麻麻的文本,导致关键指令与冗余内容混杂在一起。
60行并非什么神奇的阈值。重要的是约束条件本身:每新增一条规则就必须舍弃旧规则,这样只有真正有价值的规则才会保留下来。
规则14:将规则、技能和工作流程分开存放
CLAUDE.md : rules that apply to every single task
.claude/skills : reference material, read only when relevant
.claude/commands : fixed step sequences, invoked by name
为何有效:大多数过大的规则文件之所以如此,是因为其中混杂了三种不同类型的文档。数据库结构的描述并非规则,部署顺序同样不是规则。一旦将这些内容分开,剩余的规则就会重新显现出来,而不会被埋没。
第15条至第21条规则:让行为在长时间会话中持续有效
如果模型在第三轮时遵循某条规则,但在第四十轮时就忘记了它,那这条规则其实从来就不算真正的规则。这套准则旨在确保指令在整个会话期间都有效。
第15条规则:将规则保存在文件中,而不仅仅停留在对话中
Any instruction that must hold for the whole project belongs in this file.
Instructions given in conversation apply to the current task only.
其作用原理:长时间的对话记录最终会被压缩。在压缩过程中,对话的细节会被简化,而文件则会以完整形式重新加载。2026年8月的一个账户案例正好说明了这一点:用户先后两次要求模型不要升级软件包版本,压缩在过程中发生,但到第40次请求时版本仍被升级了。并没有出现任何崩溃或错误——只是该指令在模型的工作上下文中不再存在了。
如果发现自己多次在聊天中重复相同的指令,那就将其视为一个信号。这类指令应该被保存到文件中,而非通过手动输入。
规则16:压缩后重新加载规则文件
After any context compaction, re-read CLAUDE.md before the next edit.
为何有效:这是针对规则15中所述故障的一种简单防护措施,也是为数不多的仅通过查看记录就能直接确认是否遵守的规则之一。
规则17:明确用于验证工作的具体命令
## Verification
Before saying a task is done, run:
npm run typecheck && npm test -- --run
Paste the final line of output. If it fails, fix it. Do not report success.
为何有效:像“确保测试通过”这样的指令并未给模型提供具体的执行内容,而真实的shell命令则可以。要求提供粘贴后的输出结果,使得成功与否能够一目了然地得到验证,而无需盲目相信。
规则18:详细说明“完成”究竟意味着什么
## Done
A task is done when: the change is made, typecheck passes, tests pass,
and you have stated in one sentence what changed and why.
Not done: "this should work", "you may want to verify".
其作用原理:若不进行明确定义,模型会自行设定“完成”的标准,而这个标准通常仅仅是“我生成了一些文本”。这条规则比其他任何规则都更有效,能减少数小时后才发现构建实际上出错的情况。
规则19:将反馈限制为单一可操作的修改
When something did not work, name ONE thing to change and why.
Do not list five options.
其作用原理:当出现问题时提供五种不同的选项,实际上是一种逃避做决策的方式。这也使得无法追踪究竟是哪项措施解决了问题,因为无法确定这五种建议中哪一项起了作用。
规则20:询问而非猜测
If you need information you do not have, output:
MISSING: <exactly what you need>
and stop. Do not assume a plausible value and continue.
为何有效:这可能是整个文件中最有价值的一行代码。几乎所有涉及智能体的严重问题,都是因为其擅自填补缺失信息而非停下来询问所致。一次拒绝只会耗费30秒,但一个错误的假设却可能让整个下午都白费,而且通常要等到多次提交后才会发现问题。
之前:模型需要一个你从未指定的队列名称。它会默认使用类似default的名称,构建出看似正确的集成方案,结果任务就会堆积在无人处理的队列中。你往往要几天后才会发现。
之后:它会输出MISSING: the queue name for the retry consumer。你只需5秒就能提供正确答案,这样生成的代码从一开始就是正确的。
有一个简单的方法可以测试这条规则是否真的在起作用:询问一些需要依赖你刻意隐瞒的信息的内容。如果模型仍然给出答案而没有指出信息缺失,那就说明这条规则只是纸上谈兵而已。
规则21:每月删除一条规则,持续优化
Once a month, remove any rule you have not seen violated recently.
其有效原因:规则文件往往会无限制地膨胀,因为添加新规则会让人感觉是在取得进展,而删除规则则像在冒险。但如果某条规则在过去几个月里从未被使用过,那它要么已经不再需要,要么根本就没被真正遵守。无论哪种情况,它都会在每次交互中占用不必要的注意力。删除它便是最容易实现的性能提升方式。
被删除的五条规则
精简比添加任何内容都重要,以下是曾经存在于400行代码的文件中、但在当前61行的版本中缺失的五条内容。如果这些内容听起来很熟悉,你或许今晚就可以把它们删掉。
“在编写代码之前先逐步思考问题。”这其实是默认的行为。当前版本的Claude Code在操作文件之前就会自行规划处理方式,无需任何提示。这条建议不过是旧习惯的遗留,只会占用空间而已。
“注意性能问题。”这条建议根本无法通过可检验性测试——以什么标准来要求“谨慎”呢?它已被替换为两条具体且可检验的关于数据库访问的规则,那些规则才能真正发现实际问题。
关于数据库架构的90行说明。那只是文档,而非规则。它应放在模型执行数据库相关操作时会加载的技能文件中,而不应出现在每次任务开始前都会读取的文件里,哪怕只是简单的CSS调整也是如此。将这部分内容移除是减量最多的措施。
“在TypeScript中绝不要使用any类型。”这条建议本身没有错,但属于冗余内容——代码检查工具早已会禁止使用它。工具链已经强制要求的规则无需再出现在规则文件中。如果违规行为能在持续集成阶段被检测到,那就让持续集成系统来处理吧。
“添加有用的注释。”无论怎么尝试表述这句话,得到的注释都只是重复上方的代码行。解决办法是反过来:不要解释代码的功能,只需说明其这样设计的理由。这样的表述既更有效,行数也更少。
这五种情况都遵循相同的模式:两种是重复了模型或工具本身已经处理过的内容;两种无法通过任何具体方式验证;还有一种则是伪装成规则的参考资料。在您自己的文件中查找这四类内容,需要删除的项很快就会显现出来。
完整的文件,可直接使用
# CLAUDE.md
## Stack
Next.js 15 App Router, TypeScript strict, Postgres via Drizzle, Vitest.## Editing
Change the minimum number of lines needed.
Do not reformat, reorder, or rename anything you were not asked to change.
Match the style already in the file.## Scope
Work only on what was asked.
Mention unrelated problems, do not fix them.
Remove imports your change made unused. Nothing else.## Abstractions
Do not add an interface with one implementation.
Do not add a config option for a value that never changes.
Functions over 40 lines must be split.## Tests
Do not edit existing tests to make failing code pass.
If a test is wrong, say so and stop.## Dependencies
Do not add packages. Use what is in package.json.
To add one: name it, name what it replaces, stop, wait.## Error Handling
Handle errors that can actually occur here.
No try/catch around code that cannot throw.## Patterns
New routes follow src/api/users/route.ts.
Components do not fetch data. Fetch in the route, pass props down.
Database access goes through src/db/queries/. Never inline SQL.## Security
Never write a key, token, password, or connection string into a file.
Never commit .env or .env.*.
Reference environment variables by name only.## Destructive Actions
Stop and ask before: dropping a table, deleting a branch, force pushing,
rewriting history, deleting a file you did not create, running a
migration against anything not local.## Verification
Before reporting done, run:
npm run typecheck && npm test -- --run
Paste the final line. If it fails, fix it. Do not report success.## Done
Done means: change made, typecheck passes, tests pass, and one sentence
saying what changed and why.## When Stuck
If you need information you do not have, output:
MISSING: <what you need>
and stop. Do not assume a value and continue.## Reporting
Name ONE thing to change. Not five options.## Persistence
Rules live here, not in chat. After compaction, re-read this file.
这就是整个文件——共61行。
发生了哪些变化
将文件从400行精简到61行之后:
- 文件重写功能已停止。在臃肿的版本中同样存在该编辑规则,只有当它不再被埋藏在第213行附近时才开始被执行。
MISSING:规则已启用。现在它大约每周触发两次,会暂停并询问相关值而非直接生成配置值。此前这两种情况都会导致无声且错误的输出。- 长时间运行时的问题已消失。随着规则被固定在文件中而非散布在早期的聊天记录中,版本升级问题以及另外三个类似的问题也都随之消失。
- 审查速度变快了,原因仅仅是差异内容变得更少。整个机制就是如此——没有更复杂的设计。
这里没有整齐的前后对比基准,也不会为了制造完美的案例而刻意编造。现有的是一个需要一分钟才能读完的文件,其内容与描述的行为确实相符。
下一步
- 打开你现有的CLAUDE.md文件并统计行数。
- 通读一遍,标记出那些即使存在违规情况也无法具体指出的规则,然后将它们删除。
- 将所有的“建议”和“尽量”改为明确的“禁止”。
- 把所有提及“我们的惯例”的地方替换为实际的文件路径。
- 如果还没有类似规则20的内容,就添加一条。正是这条规则让整个练习有了意义。
之后,让这个文件保持不变一个月。再次查看时,再找一件可以删除的内容。
真正有效的规则都具有相同的特征:简短、明确且可验证。其余的一切都只是给自己的备注,模型每天会无谓地重读数百次这些内容。
相关阅读
- 对比 Frontier AI 智能体:Astra、Flash、Fable 与 Mythos —— 详细分析最新的 GPT、Gemini 和 Claude 模型在编程、浏览和工具使用等实际智能体任务中的表现,而不仅仅是基准测试结果。
- 2026 年如何选择 Python AI 智能体框架:实用对比 —— 从处理故障和复杂性的角度对比五种 Python AI 智能体框架,帮助读者选择适合其工作流程的工具。