Claude Code Plan 模式偏离计划:6 个 scope creep 来源 + 把 plan 当合同

你批准 5 步 plan,Claude 做了 7 步、跳了 1 步、顺手 refactor 旁边代码——把 plan 当 numbered checklist + 每步停下来汇报。

你进 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.tsprocessPayment 改名 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 模式