AIコーディングエージェントが早まって完了を宣言するのを防ぐ方法

AIコーディングエージェントがタスクを終え、機能が実装済みと報告して次へ進む。コードはコンパイルされ、作成を依頼された関数は正しい型を返す。エージェントがアクセスできるあらゆるシグナルによれば、仕事は完了している。
エージェントは嘘をついているわけではない。ただ、本当に重要な問いよりも狭い問いに答えているだけだ。「説明どおりの動作をするコードを書けたか」と「実際のユーザーにとって機能するか」は別の問いであり、自分が書いたコードを基に作業するエージェントは、実質的に前者にしか答えられない。
エージェント自身の確信が正しいシグナルではない理由
AIコーディングエージェントが完了を判断する根拠は、自身のアウトプットだ。関数が書かれ、ファイルが保存され、構文が有効で、自分で書いたユニットテストが通るかもしれない。これは閉じたループである。エージェントは、そもそもコードを生成したのと同じタスク理解に照らして自分の成果物を検証している。
その理解にギャップがあれば、エージェントの自己チェックにはそのギャップが現れない。要件の読み違い、見落としたエッジケース、2つのコンポーネントの連携に関する思い込み——これらはいずれも、同じモデルが生成したコードを同じモデルで評価する際には浮かび上がってこない。
だからこそ「エージェントが完了と言っている」と「機能が実際に動く」の間に、セッション中に明らかな警告サインなく乖離が生じ得る。
この問題が実際に生み出すパターン
この失敗モードには一定の形がある。エージェントが機能を実装し、完了と宣言する。開発者はきれいなサマリーと内部チェックの合格を信じて、次のタスクへ進むかPRを開く。
ギャップが露わになるのは後になってからだ。たいていはユーザーやチームメンバーからの指摘で、エージェントの自己チェックが決して触れなかった部分から問題が出てくる。アクション完了後にUIが実際に表示するもの、値が入力済みではなく空のときに何が起きるか、あるコンポーネントへの変更が別のコンポーネントに静かな影響を及ぼしているかどうか——といった点だ。発見されるころには、修正を迅速にできた文脈はすでに失われている。開発者はすでに3タスク先に進んでおり、元のセッションで何をしていたかを再構築するには相当な時間がかかる。
これがそのポイントに達する前に捕捉するには、エージェントが自分の成果物を評価するのとは異なるチェックを導入する必要がある。
「エージェントが完了と言った」を「製品が実際に使われた」に置き換える
解決策は、エージェントが完了宣言に慎重になることではない。エージェント自身の自己評価に一切依存しない検証ステップ——実際に動作するアプリケーションを開き、人間と同じように操作するステップ——を追加することだ。
これはエージェントが自分自身に対して実行できるあらゆるチェックとは異なる種類の検証であり、同じコードを二度見直すよりもAI UIテストに近い。Claude CodeまたはCursor内のMCP Serverを通じて連携するTestSpriteは、まさにこれを実現する。コーディングセッション終了後、探索エージェントの群れが実際に動作するアプリケーションをナビゲートし、実際のフローをクリックして回り、リアルな入力を入力し、インターフェースが実際に表示しているものと表示すべきものを照合する。
他の検証ツールはコードを読んで推測します。TestSpriteはあなたのアプリを開いて実際に使います。
この区別は、特にここで重要になる。コーディングエージェントの確信は自分のコードを読んだ結果に基づいている。TestSpriteの結果はプロダクトを実際に使った結果に基づいている。これらは独立したチェックであり、その独立性こそが「エージェントが完了と思っている」と「実際に完了している」の間のギャップを捕捉する。
シナリオ:犬の散歩アプリと嘘をついていた完了画面
2人チームが犬の散歩サービス向けのスケジューリングアプリを構築している。ウォーカーが散歩開始時にチェックインし、終了時に完了をマークできるものだ。一方の開発者がClaude Codeに、チェックイン時にウォーカーのGPS位置情報を取得する要件の追加を依頼する。ウォーカーが実際にクライアントの住所にいることを確認するためだ。
エージェントは変更を実装し、位置情報取得の呼び出しを追加し、チェックインフローを更新し、機能完了と報告する。開発者がローカルで位置情報サービスを有効にした自分のマシンでテストすると、説明どおりに動作する。
開発者はマージ前にTestSpriteをトリガーする。探索エージェントがチェックインフローを実行し、その中に位置情報の許可が拒否された場合——GPSがオフになっているかブロックされているウォーカーの端末で起こり得る状況——のパスも含まれる。その場合、チェックインは問題なく完了する。エラーも、ブロックも、位置情報が取得されなかったことを示す表示も一切ない。散歩が、位置情報データなしで検証済みとして記録されてしまい、機能の本来の目的が静かに無効化される。
エージェント自身の評価にはこれを捕捉する手段がなかった。エージェントは自分が構築したフローを、位置情報アクセスが許可されるという前提でテストしていた。それはまさに、コードを書いた際に働いていた前提だ。TestSpriteのエージェントは、実際のウォーカーの端末が直面するケースを試みた。
失敗の説明には何が起きたかが正確に記述されている。位置情報の許可が拒否された、チェックインは完了した、エラーは表示されなかった。コーディングエージェントはその説明を使って、チェックイン完了前に必須の許可チェックを追加する。開発者はトリガーを再実行して、許可が付与された場合と拒否された場合の両方のパスが正しく動作することを確認する。
これをその場限りの捕捉ではなく、標準的な実践にする
このチェックの価値は1つのバグを捕捉することにあるのではない。ユーザーに届く機能において「エージェントが完了と言った」を最終的な判断として決して信用しないことにある。
「Help me test this project with TestSprite(TestSpriteでこのプロジェクトをテストしてください)」というトリガー指示を、すべてのコーディングセッションの標準的な締めくくりとして組み込むことで、独立したチェックが毎回実行される。開発者がたまたま疑念を持ったときだけでなく。Webポータルを通じてスケジュールされたリグレッションを実行しているチームでは、同じ独立した検証が夜間にも実行され、機能が完了と宣言されて誰も戻ってこなかった1日のセッションで蓄積されたものを捕捉する。
まとめ
AIコーディングエージェントが自分の成果物に対して持つ確信は有用なシグナルであり、かつ不完全なシグナルでもある。それが反映するのは、コードがエージェントのタスク理解と一致しているかどうかであり、実際にそれを使う人にとってプロダクトが機能するかどうかではない。
TestSpriteは、書かれたばかりのコードを読む代わりに動作するアプリケーションを開くという独立したチェックで、そのギャップを埋める。
TestSpriteをワークフローに追加して、「エージェントが完了と言った」を最終的な答えとして扱うのをやめよう。