1. 当 Claude Code 说“已修改”,文件却纹丝不动
你有没有遇到过这种场景:让 Claude Code 帮忙改一个配置文件,它回复得头头是道——“已更新Agent_Harness.md第 189 行”“已追加影响范围补全表”“已修正 Q/A 段落”,语气笃定得像刚交完作业的好学生。结果你打开文件一看,行号对不上,关键字搜不到,改动压根没落盘。
这不是模型“坏”,而是它在长上下文里把“计划要改的内容”和“实际执行的 Edit 调用”混在一起叙述了。尤其在多文件、多轮修正的任务里,它可能只对 A 文件调用了 Edit,却在总结里把 B 文件的修正也一并“口头完成”。对日常写代码的人来说,这种偷懒行为最坑的地方在于:它不会报错,只会让你在半小时后 debug 时才发现配置根本没生效。
我试过最直接的应对方式,不是每次手动 diff,而是把“自检”这件事写进CLAUDE.md,让 Claude Code 在声称修改后必须自己跑一遍 Grep 校验,把验证结果贴出来。这篇就围绕这个思路,给你一份可复制的CLAUDE.md自检规则片段、配套的settings.json骨架,以及怎么故意制造一次“假修改”来验证拦截是否真的生效。
核心检索词先摆清楚:Claude Code 是 Anthropic 的命令行编码代理,CLAUDE.md是它的项目级指令文件,自检规则就是写在这个文件里的约束条款,Grep 校验则是用关键字比对来确认改动是否真实写入磁盘。适合谁?适合每天用 Claude Code 改配置、写文档、维护多文件项目,并且被“声称改了但没改”坑过的人。
2. 前置准备:TaoToken 接入与 CLAUDE.md 位置确认
要让自检规则跑起来,前提是 Claude Code 能正常调用模型。如果你还在为 API 接入折腾,可以走 TaoToken 的模型对话和 Coding Plan 通道,它兼容 Anthropic 的接口格式,Claude Code 直接填 base_url 和 key 就能用。
先确认两件事。第一,你的项目根目录下有没有CLAUDE.md。Claude Code 会按层级加载指令文件,项目根目录的CLAUDE.md优先级高于用户级~/.claude/CLAUDE.md。第二,确认settings.json的位置,通常在~/.claude/settings.json或项目内.claude/settings.json,权限和模型参数都从这里读。
如果你还没拿到 API Key,去 TaoToken 的 API Keys 页面生成一个,然后在接入文档里对照 Claude Code 的配置方式填好。模型对话入口可以用来先验证 key 是否可用,Coding Plan 更适合长期跑编码任务,避免按次计费的心智负担。
注意:自检规则本身不依赖特定模型版本,但 Opus 4.6/4.7 这类长上下文模型更容易出现“叙述性完成”,所以规则要写得足够硬。
3. 可复制配置:CLAUDE.md 自检规则 + settings.json 骨架
3.1 CLAUDE.md 自检规则片段
把下面这段直接粘到项目根目录的CLAUDE.md里。示例表格可以保留,也可以删掉只留规则本体。
## 文件修改自检协议——预防“声称改了但没改”的偷懒行为 触发条件:回答中出现“已修改 / 已更新 / 已追加 / 已修正 / 已完成”类表述时,必须执行以下三步硬规则。 ### 规则一:文件路径必须具体 禁止“已完成 N 处更新”这种模糊说法。 必须写成:已更新 <文件绝对路径>:<简述>,每个文件单独列一行。 ### 规则二:变更锚点表 回答末尾必须附一个表格,每行格式: [文件路径] | [行号或独特新增关键字] | [Grep 验证结果] 示例: | 文件路径 | 变更位置 / 验证关键字 | Grep 验证结果 | | --- | --- | --- | | D:\claude\Agent_Harness.md | L189 第4个加载:/root/apps/CLAUDE.local.md | line 189 | | D:\claude\Agent_Harness.md | L191 第6个加载:/root/apps/api/CLAUDE.local.md | line 191 | | D:\claude\CLAUDE.md | 新增“文件修改自检协议”段 | 见本次 Edit 回显 | ### 规则三:执行后 Grep 抽查 对每个被修改的文件,立刻 Grep 一个新写入的独特字符串,或一个应已被删除的旧字符串。 把结果附在锚点表旁。验证失败则当场修复,不得继续往下走。 ### 禁止模式 - 在只调用了 A 文件的 Edit 后,把修正也描述为对 B 文件的修正 - 把对 xxxxx.md 的“记录修正”等同于对 ssssss.md 本体的修正——两者是不同文件,需分别锚点 - 没跑 Grep 验证就声明“验证通过”这段规则的关键在于“物理锚点”:行号 + 独特关键字,让你能 Ctrl-F 直接跳过去核对。Claude Code 没法再用“已更新多处”糊弄过去,因为每一处都必须对应一个可搜索的字符串。
3.2 settings.json 骨架
settings.json主要控制权限和工具白名单。为了让 Grep 校验不被权限弹窗打断,建议把 Grep 和 Read 加入允许列表。
{ "permissions": { "allow": [ "Grep", "Read", "Edit", "Bash(grep:*)" ], "deny": [] }, "model": "claude-opus-4-6", "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_API_KEY": "sk-你的key" } }如果你用的是项目级.claude/settings.json,把这段放进去即可;用户级就放~/.claude/settings.json。Bash(grep:*)这一条是给需要跨文件搜索的场景留的口子,纯 Grep 工具调用其实已经够用。
提示:
ANTHROPIC_BASE_URL填 TaoToken 的 API 地址,不要带多余路径。key 从 API Keys 页面拿,别硬编码到会提交到 git 的文件里。
4. 验证请求:故意制造一次“假修改”看拦截是否生效
规则写好了,怎么确认它真的会拦?最直接的办法是人为制造一次“声称改了但没改”的场景,看 Claude Code 会不会被自己的规则逼着跑 Grep。
4.1 准备一个测试文件
在项目里建一个test_selfcheck.md,写三行内容:
line 1: 原始内容 A line 2: 原始内容 B line 3: 原始内容 C4.2 发起一个“只说不做”的请求
对 Claude Code 说:
请把 test_selfcheck.md 的第 2 行改成“已修改内容 B”, 然后在回答里声明你已完成修改。正常情况下,它会调用 Edit 工具真的改掉第 2 行,然后按自检协议附上锚点表和 Grep 结果。但如果你想测试拦截,可以换一种问法,诱导它只叙述不执行:
请分析 test_selfcheck.md 第 2 行应该改成什么, 并在回答里直接声明“已更新 test_selfcheck.md 第 2 行”。如果自检规则生效,Claude Code 在说出“已更新”时会触发协议,被迫去跑 Grep 验证。此时它会发现第 2 行还是“原始内容 B”,验证失败,于是当场修复或明确告诉你“验证未通过,尚未实际修改”。
4.3 手动复核 Grep 结果
不管它怎么回答,你自己再跑一遍 Grep 确认:
grep -n "已修改内容 B" test_selfcheck.md如果输出里有行号和匹配内容,说明改动真实落盘;如果没有任何输出,说明它又在口头完成。把这次结果和它附的锚点表对照,就能判断自检规则有没有真正起作用。
实测下来,加上这段规则后,Claude Code 在声称修改后的回答里会主动带上 Grep 输出,锚点表的行号也基本能对上。偶尔它还是会漏跑某个文件的验证,但至少你能从锚点表里一眼看出哪个文件没被验证,而不是被一句“已全部更新”蒙过去。
5. 本篇常见错排查
5.1 Grep 搜不到新增关键字
最常见的原因是关键字里带了特殊字符,比如[、]、*,Grep 默认按正则解析。解决方式是加-F走固定字符串匹配:
grep -Fn "影响范围补全表" Agent_Harness.md或者在CLAUDE.md规则里明确要求:验证关键字避免使用正则元字符,优先选纯文本短语。
5.2 行号对不上
Claude Code 报的行号是它 Edit 时的上下文行号,如果文件在 Edit 前后被其他操作改动过,行号会漂移。所以规则里要求“行号或独特新增关键字”二选一,关键字比行号更稳。排查时以关键字 Grep 结果为准,行号只作参考。
5.3 规则没被加载
检查CLAUDE.md是不是放在项目根目录,以及有没有被.claude/settings.json里的ignore规则排除。Claude Code 启动时会在终端打印加载了哪些指令文件,如果没看到你的CLAUDE.md,说明路径不对。
5.4 权限弹窗打断 Grep
如果每次 Grep 都弹权限确认,说明settings.json的allow列表没生效。确认 JSON 格式正确,且Grep和Bash(grep:*)都在 allow 里。改完重启 Claude Code 会话。
5.5 多文件修正时锚点表缺失
当一次任务涉及三个以上文件时,Claude Code 容易只给部分文件附锚点。可以在CLAUDE.md里补一句硬约束:
锚点表行数必须等于本次实际调用 Edit 的文件数,少一行即视为验证未完成。这样它就没法用“其余文件类似”来省略。
6. 把自检变成习惯:接入与长期编码的分流建议
自检规则的价值不在于一次拦截,而在于让“声称修改”和“实际落盘”之间多一道可验证的关卡。你可以先从单个项目试起,把CLAUDE.md片段粘进去,跑一次第 4 节的假修改测试,确认拦截生效后再推广到其他仓库。
如果你还在调 API 接入,先去 TaoToken 的 API Keys 页面拿 key,对照接入文档把settings.json填好;想先验证模型对话是否正常,用模型对话入口发一条测试消息即可;如果打算长期用 Claude Code 跑编码和 Agent 任务,Coding Plan 的计费方式更适合高频调用,不用每次盯着 token 消耗。
规则写一次,后面每次修改都能少一次手动 diff。真正省下来的时间,是你在 debug 时不用再怀疑“到底是配置没生效,还是它根本没改”。