你问 Claude Code 是否读过 CLAUDE.md,它回答读过,却仍然跳过你要求的测试。这时要区分指令根本没有传入模型,以及指令传入后没有得到遵守。“我读过了”这一回答无法证明任何一种情况。

Cursor 的 .cursor/rules、GitHub Copilot 的 .github/copilot-instructions.md 和 Codex CLI 的 AGENTS.md 也是如此:文件从哪里加载、何时适用,各工具并不相同。文件被加载,与模型遵守其中的指令,是两个问题

先说结论,处理分三步。首先查看文件是否已被加载。已加载却没有被遵守的规则,改写成事后能够核实是否遵守的句子。仍然希望每次都必定执行的处理,交给 Hooks 或 CI。Claude Code 官方也说明,CLAUDE.md 是“上下文,而不是强制执行的配置”,如果想不依赖 Claude 的判断而阻止某个操作,应使用钩子。

本文依次介绍加载、压缩后的恢复、指令冲突等五项检查,以及排查步骤和规则的改写示例。

要点

规则为什么被忽略

以及如何建立检查机制

原因
加载条件
根目录 CLAUDE.md 会在压缩后重新注入;只在对话中约定的事项则不同
原因
优先级不清
指令冲突时,要检查来源及适用范围
改进
改写成可验证的句子
写到“何时、做什么、如何核实”,让人事后能够查看是否遵守
改进
建立检查机制
用 Hooks 和 CI 检查可判定的条件,AI 审核提供辅助

1. AI 为什么不遵守规则:五项检查

1. 文件过长,规则被淹没

Claude Code 官方文档建议每个 CLAUDE.md 文件少于 200 行,理由是“较长的文件会消耗更多上下文,并降低遵守程度”。200 行并不是加载的截断位置,4 MiB 以内的 CLAUDE.md 会被完整加载(超过 4 MiB 的文件会被跳过)。文件过长时发生的,不是后半部分不再被读取,而是内容被读取之后,各条规则更难得到遵守。

2. 长会话中的自动压缩

Claude Code 的 /compact 会压缩对话,但项目根目录的 CLAUDE.md 会在压缩后从磁盘重新读取,并重新注入上下文。子目录中的 CLAUDE.md 和按路径适用的规则,则在读取相关文件时重新加载。根据官方文档,压缩后消失的指令必属以下三种之一:① 只在对话中交代过;② 位于尚未重新加载的子目录 CLAUDE.md 中;③ 位于尚未触及目标文件的路径规则中。想保留对话中决定的事项,就把它写进 CLAUDE.md。

3. 指令冲突与适用范围

如果“提交前先测试”和“这次跳过测试”同时存在,适用哪一条就要由模型判断。Claude Code 官方说明,两条规则相互矛盾时,Claude 可能会任意选择其中一条。应定期对照项目、个人和目录级指令,消除矛盾;如果允许例外,要写到“由谁、以何种方式指示时”为止。想阻止操作本身,应使用权限设置或 Hooks,而不是 CLAUDE.md。

4. 规则含糊或相互矛盾

面对“措辞礼貌一些”“妥善处理”等主观或抽象指令,AI 会自行解释,结果可能与你的预期不同。可以改为能够核实是否遵守的要求,例如“最多写三行”或“使用 Slack API 时调用 chat.postMessage”(改写实例见第 3 节)。

5. 规则文件膨胀或分散

从 CLAUDE.md 普通链接到 SPEC.md,不一定会在启动时加载被链接文件的全部内容。Claude Code 会在启动时展开 @path 导入,但导入内容同样占用上下文。为了整理而拆分文件,与只在需要时加载,是两回事。重复规则出现分歧时,应明确唯一正本与适用范围。

以上 Claude Code 的规格依据 Claude Code 官方记忆文档(截至 2026 年 9 月 21 日)。

2. 如何确认规则是否得到遵守

先确认当前情况。可以向 AI 提出以下问题,并检查回答:

问题检查重点
“请逐条列出 CLAUDE.md 中的全部规则。”如有遗漏的规则,用 /context 查看该文件是否已被加载
“写代码前,请说明会遵守哪些 CLAUDE.md 规则。”在工作前让它回想重要规则。是否遵守,看工作后的差异
“请列出最近五轮中可能违反 CLAUDE.md 的操作。”自述只作为线索,与命令历史、退出码及成果文件对照后再确定

“读过了”“理解了”这样的回答,既不能证明已加载,也不能证明已应用。能作为证据的,是加载列表中的显示和执行后的成果。

定位原因的四个步骤

  1. 查看入口。在 Claude Code 的 /context 中查看 Memory files 里是否列出了目标 CLAUDE.md 和规则。如果没有,检查文件位置和排除设置(claudeMdExcludes)。如果让 Claude Code 直接加载 AGENTS.md,这份 AGENTS.md 不会出现在该列表中。在默认设置下,查看启动时是否显示 no CLAUDE.md found; AGENTS.md loaded: … 这一行(从 CLAUDE.md 导入的 AGENTS.md 会出现在列表中)。
  2. 触发规则的适用条件。对于路径规则,让智能体读取匹配的文件。压缩后若尚未读取该文件,相关规则就没有重新加载。想记录何时加载了什么,可以用 InstructionsLoaded 钩子把 CLAUDE.md 和规则的加载写入日志(直接加载的 AGENTS.md 不会触发)。
  3. 执行小型、无害的任务。让智能体修改可丢弃的示例,并遵守“修改前说出目标文件”“完成后报告测试命令和退出码”等规则。不要用删除生产数据或发布来测试。如果用暗号测试,暗号只写在指令文件中,不要写进问题。
  4. 独立核验结果。检查差异中是否有意外修改,确认报告的测试确实运行,并核查检查数量是否足够。记录测试时的设置、工具版本和目标文件,其中任何一项改变后,都要重新测试。

例如,“提交前先测试”这条指令已被加载,测试却没有执行,那么改变文件位置也解决不了问题。要改的是规则的写法(见下一节的改写示例)和检查机制。把必需的 CI 检查设为合并条件,就能获得 AI 自述之外的判断依据。

如果加载列表中缺少相关 CLAUDE.md,应先修正启动位置与设置,再考虑加强措辞。确认已加载后仍有违规,再检查指令是否具体、验证流程是否有效。这样就不会把所有失败都归因于“AI 忘了”。

3. 五分钟内可以尝试的改进

1. 区分常用规则与按需读取的细节

可以参考 Claude Code 官方“少于 200 行”的建议,但重点是减少重复和多余解释,而非追求某个行数。例如:

  • 核心规则(10–20 行)→ CLAUDE.md 开头
  • 详细服务规格 → 独立的 SPEC-xxx.md 文件
  • 历史与背景 → docs/ 目录

把细节移到其他文件后,要在入口文件写清各类任务开始前应读什么。如果每次会话仍导入全部内容,拆分文件并不会减少启动上下文。需要按条件加载时,可使用路径规则或技能。

2. 把规则改写成“能够核实是否遵守的句子”

对于已加载却没有被遵守的规则,先看其中是否写明了“做到什么才算遵守”。Claude Code 官方也建议把指令写得具体到可以验证,并举例说:不要写“测试你的更改”,而要写“提交前运行 npm test”。再进一步写出失败时的做法和例外条件,就会变成下面这样。

改写前改写后事后能判定的内容
先测试再提交提交前运行 npm test,确认退出码为 0。失败时不要提交,并报告失败的测试名称。只有在用户明确指示时,才可以跳过测试执行的命令、退出码、跳过的理由
把代码整理干净缩进使用 2 个空格查看差异就能发现违规
把文件整理好API 处理程序放在 src/api/handlers/看新文件放在哪里就能判断
写清楚易懂的提交信息第一行以 feat: fix: docs: 之一开头,并控制在 50 个字符以内可以在提交历史中逐条判定

改写后的句子,可以通过差异、命令历史和退出码判定是否得到遵守。一旦写成可判定的形式,之后交给 Hooks 或 CI 时,也能直接作为检查条件(第 4 节)。

3. 标明优先级

重要性标记有助于人和 AI 理解意图,但标记本身不能强制执行。例如可以这样定义:

  • CRITICAL:违反后可能引发生产事故
  • MUST:必须执行
  • SHOULD:通常应当执行
  • NICE TO HAVE:有余力时可选

CRITICAL:对生产数据库执行破坏性查询前,必须获得批准”明确了操作与审批条件。要实际拦截未经授权的操作,还需要权限设置或执行前检查。

4. 在对话中重申重要规则

在会话开始时补充“开始工作前,请列出最重要的三条规则。”用这种声明让它回想规则,是否遵守则看工作后的结果。

5. 把完成条件写进计划

AI 智能体的任务追踪中加入“核查规则”,明确每一步的完成条件。要求提供命令、退出码和未验证范围,而不只是“已测试”。如果证据栏为空却标记了完成,就不要视为已完成。

4. 长期保障:Hooks、审核与技能

把可判定的条件写成脚本,通过设置控制操作权限。Hooks、CI、AI 审核和技能各有用途。把它们统称为“自动强制执行”,会掩盖未检查的范围。

1. 用 Claude Code Hooks 执行检查

Claude Code 的 Hooks 功能可以在特定工具调用前后运行脚本,建立即使 AI 忘记规则,系统也能拦截操作的机制。

例如,PreToolUse 钩子可以执行以下检查:

  • Bash 工具执行前识别危险命令(rm -rfgit push --force)并拒绝
  • Edit 工具执行前检查目标文件权限或锁定状态
  • 提交前运行项目专用测试,失败则阻止提交

如果 PreToolUse 钩子需要阻止操作,应返回退出码 2 或相应的拒绝 JSON。失败的测试若只返回 1 和普通文本输出,会被视为非阻断错误,操作仍会继续。PostToolUse 在操作之后运行,不能用于撤销已经完成的操作。

钩子只能在已配置的事件上,拦截脚本实际判定的情况。只监控 Edit 无法覆盖通过 shell 写入文件的路径,简单匹配危险字符串也不全面。应结合权限、沙箱和 CI,并同时测试应放行与应拒绝的输入。

2. 用子智能体分担审核职责

可以利用 Claude Agent SDK 或 Cursor 的子智能体能力,建立专门审核规则的智能体。由审核智能体检查主智能体写出的代码,有机会从另一个角度发现遗漏,但两者仍可能犯相同的错误或漏掉同一问题。

把需要检查的规则、差异和期望的证据(测试名称、退出码)交给审核方。返回的每项指出都应与实际文件或测试结果核对,职责范围之外的部分按未验证处理。

3. 用技能调用可重复的流程

在 Claude Code 中,可以把重复流程写进 .claude/skills/precommit/SKILL.md,并用自己创建的 /precommit 调用。这是自定义示例,并非内置命令。旧版 .claude/commands/ 中的文件仍可使用,但当前文档已将其纳入技能体系。调用流程与所有检查通过是两回事,结束时要查看检查结果。

文件位置与调用方法见官方技能文档。技能中应同时写明操作流程和合格条件,并要求提供步骤实际运行的证据。

4. 用自动化脚本检测违规

可以在 CI 或提交前钩子中,用 grep 检测禁止出现的模式,例如:

  • 生产代码中遗留的 console.log
  • 硬编码的 API 密钥
  • 文件开头缺失版权注释

脚本无法检查未实现的规则或范围之外的文件。应测试正常示例、违规示例和读取失败,并显示检查及跳过的数量。例如,十个文件有两个无法读取,其余八个通过,不等于“全部通过”。

5. 各工具的规则设计方法

主要 AI 智能体的规则设计要点

Claude Code
Anthropic
配置文件
CLAUDE.md + ~/.claude/CLAUDE.md
篇幅与加载
官方建议少于 200 行。越长,遵守程度越低
检查与约束
Hooks / subagents / Skills
Cursor
Anysphere
配置文件
.cursor/rules/*.mdc
篇幅与加载
官方建议少于 500 行,按用途拆分
检查与约束
用 glob 限定范围 / 用 @ 引用
GitHub Copilot
GitHub
配置文件
.github/copilot-instructions.md
篇幅与加载
指令应简短且独立完整,确认所用功能的支持情况
检查与约束
.github/instructions/*.instructions.md 中的按文件规则
Codex CLI
OpenAI
配置文件
AGENTS.md
篇幅与加载
默认合计加载上限为 32 KiB,并非行数
检查与约束
审批模式 / 沙箱约束

各工具的条件可查阅 Cursor 规则文档GitHub Copilot 自定义指令OpenAI 的 AGENTS.md 指南。Copilot 的路径指令使用 *.instructions.md,哪些功能会读取它,因功能而异。Codex 的 32 KiB 是默认合计字节上限,并非字数或行数。

共同原则是“简洁、具体、优先级明确”。不同工具的文件名和位置不同,但写法上的原则相通。

6. 规则设计的三种反面做法

1. 只写“请遵循最佳实践”

只写这句话,并未定义“最佳实践”。应明确项目采用什么方法,以及如何验证。与其说“适当测试”,不如列出必需的测试命令,并写清失败时应暂停哪一步(第 3 节的改写示例)。

2. 在多个文件中重复同一条规则

同样的提交规范如果同时出现在 CLAUDE.md、SPEC.md 和 README.md,更新时可能造成三份内容不一致。选定唯一正本,其他文件链接到它

3. 到处写“绝对必须”

对所有条件使用同等强调,反而难以传达优先级。只对后果确实严重的条件使用“CRITICAL”,其余用普通语言说明。强调用得过多,就会失去作用

总结

规则没有得到遵守时,按加载条件 → 适用范围 → 指令冲突 → 执行结果的顺序排查。根目录 CLAUDE.md 在压缩后也会重新注入,所以压缩后消失的指令,要么只在对话中交代过,要么位于尚未重新加载的下级 CLAUDE.md 或路径规则中。

  • 没有被加载:修正文件位置、排除设置和 AGENTS.md 的加载条件
  • 已加载却没有被遵守:把规则改写成事后能够核实是否遵守的句子
  • 希望每次都必定执行:用 Hooks 或 CI 检查,允许哪些操作则由权限设置规定

完成的证据是执行结果与成果文件,而不是一句“我读过了”。

常见问题

Q1. CLAUDE.md 多长比较合适?

官方建议每个文件少于 200 行,并说明文件越长,消耗的上下文越多,遵守程度也会下降。超过 200 行也不会中途停止加载(4 MiB 以内会完整加载)。只保留每次都需要的规则,只在特定文件中使用的规则移到路径规则。用 @path 导入拆出去的文件同样会在启动时加载,因此上下文用量并不会减少。

Q2. Cursor 应使用 .cursorrules 还是 .cursor/rules/*.mdc

新配置建议使用 .cursor/rules/*.mdc,保持每个文件一条规则,用 glob 模式指定适用范围。旧版 .cursorrules 是单个文件,容易变得臃肿。

Q3. 规则写得越长,约束就越严格吗?

单凭长度不会使规则更严格。官方也说明,较长的文件会降低遵守程度。如果要补充,就补充可验证的条件和具体示例,并删掉重复和矛盾之处。

Q4. 同一个项目同时使用 Claude Code 和 Cursor 等工具怎么办?

把共享规则的正本集中在 AGENTS.md,各工具特有的设置放在各自的入口。Codex 和 Cursor 支持 AGENTS.md。Claude Code 从 v2.1.277 起,如果工作目录及其上级目录中既没有 CLAUDE.md.claude/CLAUDE.md,也没有 CLAUDE.local.md,就会直接加载 AGENTS.md。只要存在其中任何一个,默认只会读取它们;哪怕只放了一个个人用的 CLAUDE.local.md,AGENTS.md 也不会再被读取。同时使用 CLAUDE.md 的项目,应在 CLAUDE.md 中写一行 @AGENTS.md 来导入(也可以在 /config 中把 Project instructions 设为 claude-md-and-agents-md,让两者都被读取)。通过 Amazon Bedrock 等外部提供商、关闭了遥测的会话、安装或更新后的第一个会话,以及用 disableAllHooks 等方式停用了钩子的环境中,直接加载不会生效,应改用导入。至于是通过哪条路径读取的,可以用第 2 节的第 1 步来区分。

Q5. AI 回答“读过了”,是否可能其实没读?

回答既不能证明读过,也不能证明没读过。按第 2 节的诊断步骤查看加载列表,再与差异、测试结果和执行记录对照。