你进 plan 模式,Claude 提了一份 5 步 plan,你批了。执行开始。最后:D、E 文件被改了(不在 plan 里)、step 3 因”现有代码已经做了”被跳了(其实没做)、step 4 偷塞了个”为清晰度做的小 refactor”。PR 比 plan 大,你从 diff 看不出哪些改动是授权的。
Plan 模式是规划辅助,不是合同。批准给你 plan 阶段的对齐,但不绑定执行——除非 prompt 让这个绑定显式。修法:把 plan 当编号 checklist、要求每步 status 确认、范围外改动一律拒收。
常见原因
按命中率从高到低:
1. Plan 太松、Claude 推了额外活儿
Plan 写”更新 billing flow”——没说哪些文件。Claude 改了 5 个文件包括你没预期的 2 个。Plan 没钉路径,任何合理解读都被授权。
如何判断:回看批准的 plan——步骤引用概念(「the billing flow」)而非文件路径——Claude 就有空间扩。
2. 原 prompt 有「顺手改」隐含授权
你说「修 bug 和看到问题清理一下」。「和清理」就是 scope creep license。Claude plan 修 bug,执行时扩到清理(plan 里没显出来)。
如何判断:在 prompt 里搜「顺手」「也修」「清理」「改进一下」——任意一个都授权了 plan 越界。
3. Claude 中途静默改了 plan
plan 写 5 步,执行到中间 Claude 自己判 step 3 没必要就跳了——也没说。或者沿路看到坏的东西自己加了 step 6。
如何判断:实际 diff 和批准 plan 逐步对比——不一致 = 静默 plan 更新。
4. Plan 步骤太粗
「Step 4:把 billing.ts 重构成新模式」——具体什么意思?步骤没规定,Claude 解读宽泛。
如何判断:步骤是 1 行抽象(「为清晰度 refactor X」)而不是具体操作(「在 billing.ts 把 processPayment 改名 processCharge,仅此」)。
5. 执行中发现 edge case
Claude 跑 step 2 时发现一个真 edge case。不是停下来问,是把修法纳入这一步——diff 比 plan 大了。
如何判断:单步 diff 触达的文件 / 关切超出步骤描述——edge-case 顺手扫了。
6. CLAUDE.md 授权了机会主义改进
某些 CLAUDE.md 写「看到问题就改进代码质量」——这是常设授权,凌驾于 plan 边界。
如何判断:grep -i "improve\|clean up\|opportun" CLAUDE.md 返回让 Claude 扩 scope 的规则。
最短修复路径
按收益从高到低。Step 1 + 2 把 plan 变成可强制合同。
Step 1:plan 步骤具体 + 锚到文件
能用的 plan 步骤指名文件、符号、精确改动——不是抽象:
差:「Step 3:为清晰度 refactor billing 逻辑。」
好:「Step 3:把 `processPayment` 在 src/billing.ts:42 改名 `processCharge`,更新 3 处 call site(src/api/checkout.ts:87、src/jobs/billing-sweep.ts:23、src/services/refund.ts:55)。无其他改动。」
具体步骤有可验证结果——抽象步骤无法”偏离”因为它本身就模糊。
Step 2:执行时绑「不许越界」
批准 plan 后执行前 prepend:
仅执行上面批准的 plan。
- 不要加步骤。
- 不要跳步骤;觉得没必要就停下来问。
- 不要动 plan 里没显式列的文件。
- plan 外发现问题在末尾列 TODO,不要修。
每步后:
1. 贴一行总结说改了什么。
2. 停,等 "proceed"。
「每步停等」是合同强制。
Step 3:执行中 diff 实际 vs plan
每步后批准下一步前:
git diff --stat HEAD
对照步骤的显式文件清单——多出来的文件 = scope creep。回退 + 重 prompt:
你的 step 3 动了 D 和 E,plan 里没有。
撤掉那些改动。step 3 只动 src/billing.ts。
Step 4:拒静默 plan 更新
Claude 宣布「我打算跳 step 3 因为…」或「我加个 step 6 处理…」:
plan 变更要我批准。停。
说你打算改什么、为什么。
我要么更新 plan、要么你按原计划继续。
在宣布阶段 catch 偏移,不在代码落地后。
Step 5:审 prompt + CLAUDE.md 找 scope-creep 授权
搜并删常设越界授权:
# 在 prompt / CLAUDE.md 里
grep -in "while you're there\|also fix\|opportunistically\|improve where you see" \
CLAUDE.md src/**/CLAUDE.md
每条换成更紧的:「只修指定的,其他问题 flag 成 TODO」。
Step 6:重复偏移就一步一 commit
逼 Claude 每步一 commit,每个 commit 的 diff 就是可审计单位:
每步后:
1. git add <仅本步文件>
2. git commit -m "step N: <一行总结>"
3. 停
commit 后 `git status` 还有未 stage 改动——就越界了。
每步一个干净 commit log——“你照 plan 了吗”就可验证。
预防建议
- plan 步骤指名 文件 + 符号 + 具体操作,永不写”refactor for clarity”
- 批准后用「不许越界」+ 每步 status 绑执行
- 审 CLAUDE.md / prompt 模板找常设 scope-creep 授权,删掉
- 每步后 diff 实际 vs plan,不要拖到最后
- 拒静默 plan 更新——Claude 必须宣布 + 重批
- 一步一 commit,审计轨迹原生在 git 里
相关阅读
标签: #排查 #Claude Code #排查 #Plan 模式