Claude Code 学习站
Mingyu's Library

学习站 / 实战 Tip / A · 稳定与质量

它总说做完了其实没做完—给它能自己跑的验证

Claude 汇报“已完成”,你一跑发现功能是坏的——问题不在它撒谎,在你没给它判断“完成”的客观标准。

Claude 会在工作“看起来完成”时停下。没有可运行的检查,它唯一的信号就是“看起来完成”,于是你成了人肉验证环——每个错误都要等你发现。把验证交给它自己跑,循环才能闭合。

一句话结论

结论 给 Claude 一个它能自己运行、能返回通过/失败信号的检查——测试、构建退出码、lint、对比脚本或截图——并要求它出示运行证据而不是口头汇报。官方官方 best practices 明确:没有检查时,“看起来完成”是它唯一的信号;有了检查,Claude 会自己做、自己跑、自己读结果、迭代到通过。

做法步骤

  1. 写任务时就带上验证标准。不要只说“实现一个校验邮箱的函数”,而是给出具体用例并要求“实现后运行测试”。官方文档列出的检查形式包括:测试套件、构建退出码、linter、把输出和 fixture 做 diff 的脚本、浏览器截图对比设计稿。预期:Claude 实现后自动执行检查,失败就继续改。
  2. 要求出示证据。让 Claude 贴出测试输出、它运行的命令和返回结果、或结果截图,而不是一句“完成了”。官方文档指出审阅证据比你自己重跑验证更快,而且适用于你不在场的会话。
  3. 按需要选择把关强度。检查存在之后,再决定它多“硬”地拦住结束:官方
    档位做法特点
    单次 prompt在同一条消息里要求“跑检查并迭代”零配置,任何任务今天就能用
    整个会话把检查设为 /goal 条件每轮之后由独立评估器复查,不满足就继续干
    确定性闸门Stop hook 以脚本运行检查检查不过就不许结束本轮;连续拦 8 次后 Claude Code 会强制放行
    第二意见验证 subagent 用全新上下文复核干活的模型不给自己打分
  4. hook 是强制的,CLAUDE.md 是劝告的。官方hooks 在固定生命周期点执行脚本,与 CLAUDE.md 里“建议性”的指令不同,它保证动作一定发生。可以直接让 Claude 替你写,例如官方示例的 PostToolUse hook 在每次编辑后自动跑 Prettier:
    {
      "hooks": {
        "PostToolUse": [
          {
            "matcher": "Edit|Write",
            "hooks": [
              { "type": "command",
                "command": "jq -r '.tool_input.file_path' | xargs npx prettier --write" }
            ]
          }
        ]
      }
    }
    注意 Stop hook 在 Claude 每次结束回复时都会触发,不只在“任务完成”时;写 hook 脚本时要检查输入里的 stop_hook_active 字段避免死循环,拦截上限可用 CLAUDE_CODE_STOP_HOOK_BLOCK_CAP 调整。官方
  5. 最后加一道独立复核。让一个没参与实现的 subagent 只看 diff 挑毛病,做法见本簇的对抗式 review本站观点“自己验证 + 别人复核”双保险,基本可以告别“说做完了其实没做完”。

官方官方把“信了但没验证”列为常见失败模式(trust-then-verify gap),给出的修复原则是:永远提供验证手段;无法验证的东西,就不要上线。

可直接抄的 prompt

接下来这个任务,不接受口头的“已完成”,必须给出可验证的证据:
1. 动手前先说明你打算用什么方式验证(测试 / 构建 / lint / 截图对比,按适用选)。
2. 实现后自己运行验证命令(如 npm test、npm run build),把关键输出原样贴出来。
3. 验证失败就继续修,重新验证,直到全部通过;不要用跳过测试、压制报错的方式“变绿”。
4. 结束时汇报:跑了哪些命令、各自结果、哪些部分还没有被验证覆盖。

想把验证固化成强制动作,可以再发一条:官方文档确认 Claude 可以替你写 hook。

帮我写一个 hook:每次文件编辑后自动运行 eslint,输出有错误时把错误反馈给你修复。
写进本项目 .claude/settings.json,写完解释每个字段的含义。

来源与最后核实日期