AIにコードを書かせていると、必ずこのセリフに出会う。
実装が完了しました!✅
そして、動かしてみると動かない。
デプロイまで済ませたと報告された機能が、本番で開くと真っ白。原因を調べると、 ビルドは通っているがAPIのレスポンス形式が変わっていて、フロントが表示できていない。 AIは嘘をついたわけではない。AIの「完了」と自分の「完了」の定義がズレていただけだ。
この問題は、モデルが賢くなっても消えない。だから私は、賢さに期待するのをやめて、 「完了」の定義をルールで固定することにした。
AIの「完了」は3段階ある
AIが「できました」と言うとき、実際の状態は3つのどれかだ。
- レベル1:コードを書き終えた。 構文エラーがないだけ。動くかは不明
- レベル2:build / 型チェックが通った。 整合性はあるが、実際の挙動は未確認
- レベル3:対象のフローを実際に動かして、期待どおりの挙動を目視した
放っておくと、AIはレベル1〜2で「完了しました」と言う。 悪気はない。コードの整合性が取れた時点で、AIの中ではタスクが終わっているからだ。
しかし業務で「完了」と呼べるのはレベル3だけだ。 クライアントに「できました」と報告してから動かないことが発覚するのが、一番痛い。
対策:完了の定義をグローバルルールに書く
私は Claude Code のグローバル設定(CLAUDE.md)に、こう書いている。
build成功 = 完了ではない。デプロイ / 完了報告の前に、対象フローを1回実際に動かす。
たったこれだけの文で、挙動は目に見えて変わる。 「完了しました」の前に、AIが自分でローカルサーバーを立てて、 curl でエンドポイントを叩き、レスポンスを確認してから報告してくるようになる。
ポイントは「テストを書け」ではなく**「実際に動かせ」**と書くことだ。 ユニットテストはユニットテストで通ってしまう。事故が起きるのはいつも結合部 ——APIとフロントの間、ビルド設定と本番環境の間——で、 そこを検知できるのは「本物のフローを1回通す」ことだけだ。
「正直に報告させる」ルールもセットで要る
検証を強制すると、次の問題が出る。検証で問題が見つかったとき、 AIがそれを小さく報告することがあるのだ。「概ね完了しました。一部注意点があります」 のような書き方で、重大な未完成が「注意点」に紛れる。
なので、報告のルールも明文化している。
- 自己評価で基準を下回った項目は、正直に報告する(盛らない)
- テストが失敗したら、失敗した出力をそのまま見せる
- スキップした手順があれば、スキップしたと明記する
「盛らない」という一言をルールに入れるのは滑稽に見えるかもしれないが、実際に効く。 AIは基本的に会話相手を喜ばせる方向にバイアスがかかっており、 それを打ち消す明示的な指示には素直に従う。
逆に、検証が済んだら止めない
ここまでは「勝手に完了と言わせない」話だが、逆側のルールも一緒に運用している。
一度承認された方針に沿った作業は、承認待ちで止めない。 build / 型 / 構文が通り、実動作を確認できたら、そのまま本番反映してよい。
検証を厳しくする代わりに、検証を通ったものはノンストップで出荷する。 「AIを信用しない」と「AIに任せない」は別の話で、 検証の仕組みがあるからこそ、細かい承認プロセスを全部撤廃できる。
結果として、私の開発フローはこうなった。
- 方針だけ人間が承認する(最初の1回)
- 実装・検証・デプロイはAIがノンストップで進める
- ただし「完了」の宣言には実動作の証拠が要る
まとめ:賢さではなく、定義で解決する
- AIの「完了しました」はbuildが通っただけのことがある
- 「完了報告の前に対象フローを1回実際に動かす」をルールとして書く
- 「盛らない」「失敗はそのまま見せる」という報告ルールをセットにする
- 検証を通ったものは止めない。厳格な検証と高速な出荷はセットで機能する
AI駆動開発の信頼性は、モデルの賢さではなく**「完了」の定義を誰が握っているか**で決まる。 定義を握るのは、人間の仕事だ。