メインコンテンツにスキップ

パート3: 検証の構築

本物のエンジニアリングをしているか、単にギャンブルをしているかを決める一線がここにあります。アウトプットはどのように検証されますか? 答えが「実行してみて動いているようなら」であれば、どれだけ洗練されたプロンプトを使っていても、あなたはヴァイブコーディングをしています。検証こそが、AIアウトプットを本番環境のリスクに耐えられる信頼できるものにする規律です。

2つのメカニズムが連携して機能します。テストは決定論的な部分をカバーします。エバリュエーションはそれ以外をカバーします。

テスト:決定論的な契約

テストは、特定の入力が特定の出力を生み出さなければならないシステムの部分を検証します。これらは通常書くテストと同じですが、AIワークフローではもう一つの役割を担います:プロンプトよりも正確にエージェントに意図を伝える。

テストはマシンが確認できる仕様です。失敗しているテストと「これを通過させよ」をエージェントに渡せば、明確なターゲットと、完了したときを自動的に知る方法を与えたことになります。だからこそ、先に書くのです:

def test_refund_over_threshold_requires_approval():
charge = make_charge(amount=600_00)
with pytest.raises(ApprovalRequired):
refund_service.issue(charge.id, amount=600_00, approved_by=None)

def test_refund_writes_ledger_entry():
charge = make_charge(amount=50_00)
refund_service.issue(charge.id, amount=50_00, approved_by="alice")
assert ledger.last_entry().type == "refund"

エージェントは今、しきい値ルールと元帳の要件を、散文で説明することなく知っています。テスト説明なのです。

エバリュエーション:非決定論的な部分を判定する

テストはすべてをカバーできません。なぜならエージェントの動作の多くは決定論的ではないからです。エージェントは答えへの合理的なパスを取ったか?適切なツールを選んだか?最終的なアウトプットは、構文的に有効なだけでなく、実際に良いものか?それがエバリュエーションが計測することです。

エバリュエーションはラベル付きデータセット、スコアリングルーブリック、そしてときにはジャッジとして機能するモデルで確認されます。2種類あり、どちらも必要です:

  • アウトプット評価 — 最終的な成果物を判定する。コードはコンパイルされるか?テストは通るか?要約は正確か?
  • 軌跡評価どのように達成したかを判定する。エージェントは適切なツールを合理的な順序で呼び出したか、それとも試行錯誤して偶然に正しい結果にたどり着いたか?

軌跡は見た目以上に重要です。検証ステップをスキップした流暢なアウトプットは、明らかなエラーがあるものよりもより危険です。なぜならリスクを隠すからです。テストスイートを無視しながら偶然に正しいコードを生成したエージェントは、やがて同じ方法で正しくないコードを生成します。

具体的なエバリュエーションルーブリック

ドキュメントから質問に答えるエージェントのエバリュエーションセットは、ケースのリストとルーブリックです:

- question: "How do I rotate an API key?"
must_mention: ["settings page", "revoke old key", "24h grace period"]
must_not: ["email support"] # we have self-serve rotation now
tool_path: ["search_docs"] # should retrieve, not answer from memory

- question: "What's the refund window?"
must_mention: ["30 days"]
tool_path: ["search_docs"]

各実行でスコアを付けます:必要な事実を言及したか、禁止されたものを避けたか、期待されるツールパスを辿ったか?モデルジャッジが、あなたが書いたルーブリックに対して「この答えは明確で正確か」というソフトな次元を評価できます。重要なのは、「良い」が今や明示的に定義され、自動的に確認されること — 目視ではないことです。

品質のフライホイール

テストとエバリュエーションは、複利で効いていくループに組み込まれたときに最大の価値を発揮します:

  1. ベンチマークスイートに対して評価する。
  2. 失敗を根本原因にクラスタリングして診断する(個別対応ではなく)。
  3. クラスターを引き起こしたプロンプト、ルール、またはツールを最適化する。
  4. リグレッションスイートに対して修正を検証し、固定されたままにする。
  5. 新しい障害モードがないか本番トラフィックを監視し、ステップ1にフィードバックする。

このループを一巡するたびに、次のループがより高いベースラインから始まります。これが、モデルを変えることなくエージェントが時間をかけて確実に改善される仕組みです。

自分のワークフローをセットアップする

  • 次のフィーチャーについては、エージェントにコードを生成させる前にテストを書く。
  • 気にかけているエージェントの動作について、小さなエバリュエーションセットを構築する — 10ケースでも十分。
  • 各エバリュエーションケースについて、アウトプットが含まなければならないものと、期待するツールパスの両方を定義する。
  • すべての修正を再実行するリグレッションスイートを追加する。
  • 今週の本番障害を1つ選び、その根本原因クラスターを見つけ、症状ではなく原因を修正する。