AIエージェントの評価
- エージェント評価がプロンプト評価と異なる理由を理解する — 最終回答だけでなく軌跡が重要
- 20〜100件の実例と明確な合格基準からなるゴールデンセットを構築する
- 4つの層で採点する: ツールコールの正確性、軌跡の質、タスク成功、本番でのドリフト
- LLM-as-judge を安全に使う: ルーブリック優先、人間との校正、判定の抜き取りチェック
- CI で動作し、ユーザーに届く前に悪い変更を落とす評価を出荷する
エージェント評価は「プロンプトが正しい単語を返したか?」より難しい質問に答えます: ループで動作するモデルが、正しいツールを、正しい順序で、正しい引数で選び、正しい結果に到達し、予算と安全境界内に留まったか?
このステップを飛ばすと、システムプロンプトを調整するたびに静かに劣化する「役に立つ」エージェントを出荷することになります。
なぜエージェントに独自の評価が必要か
シングルプロンプト評価は1つの入力 → 1つの出力を採点します。エージェントは軌跡を生成します: 多くのターンにわたる推論、ツールコール、中間観察、修正のチェーン。2つの失敗モードがこれを難しくします:
- 正しい答え、間違った経路。 エージェントは無駄なループ、危険な行動、幸運な推測の後に正しい出力に偶然到達します。最終回答のみの評価は合格と判定しますが、本番では通用しません。
- 間違った答え、もっともらしい経路。 各ステップは単独では合理的に見えますが、エージェントがツールを誤用したり、制約を無視したり、中間事実をハルシネートしたりします。返答だけでなくトレースを見る必要があります。
4つの評価層
安いものから順に重ねて、高価なグレーダーを待たずに悪い変更を素早く落とせるようにします。
Guided walkthrough1 of 4
- 各予想ステップについて、ツール名が一致すること、必須パラメータが存在すること、型が検証されることをチェック。純粋なコード、ミリ秒、モデル不要。他のすべてが実行される前に「write_file を呼ぶべきだったのに search を呼んだ」を捕まえる。
- 完全なトレースを採点: エージェントは合理的な経路を取ったか、それとも彷徨ったり、ループしたり、戻ったりしたか?最小必要ステップに対する実際のステップ数、冗長なコール、ツールエラー後のリトライ、完了時に停止したか。ここでは明示的なルーブリックで LLM ジャッジを使う。
- 目標は達成されたか?可能な限り決定的に(スキーマ有効、ファイル書き込み、テスト合格)、曖昧な場合は LLM 採点(要約が忠実、回答が役立つ)。これがヘッドライン指標。
- 本番では実トレースをサンプリングし、一部を再採点する。介入率(人間がどれくらい介入したか)、拒否率、成功タスクあたりのコストを監視する。これらが変化すると、モデル、ツール、入力が下で変わっている。
価値を予測するメトリクス
すべてのメトリクスがダッシュボードに載るわけではありません。2026年に出荷判断を左右する5つ:
| メトリクス | 何を測るか | なぜ重要か |
|---|---|---|
| タスク成功率 | ゴールデンセット中、エージェントが正しく完了した割合 | ヘッドライン。他はすべて診断用。 |
| 成功タスクあたりコスト | $ / 合格ケース(入力+出力トークン、ツールコスト) | 10倍のコストでの成功は退行。 |
| レイテンシ (p50 / p95) | タスクあたりのウォールクロック、テール含む | p95 が実ユーザーが感じる値 — 平均は嘘をつく。 |
| ツールコール精度 | 予想ツールコールのうち名前+引数が正しい割合 | 軌跡の質を予測。計算が安い。 |
| 介入率 | 本番で人間の引き継ぎが必要だったタスクの割合 | 自律性の数字。上昇 = 信頼低下。 |
一緒に追跡すること — 1つだけが動くのは通常ノイズではなく先行シグナルです。
ゴールデンセットを構築する
Guided walkthrough1 of 5
- 実使用(ログ、サポートチケット、ユーザー要求)から20〜100件のタスクを引く。頻繁な易しい経路、厄介な中間、すでに刺されたエッジケースをカバー。
- 各ケース: 「完了」はどう見えるか?正確な予想出力、必要な事実、有効な JSON スキーマ、存在すべきファイル、または曖昧なケースのルーブリック。基準を書けないなら、ケースは使えない — 削除するか明確化する。
- サブセットについて、良いエージェントが取るツール順序をスケッチ。これが層1がチェックする対象。
- セットをリポジトリにコミット。ケースをその場で編集しない — スコア履歴を比較可能にするため v1 の隣に v2 を追加。
- 本番バグはすべて、修正前に新しい評価ケースになる。それがセットを予測的に保ち、劣化させない方法。
LLM-as-judge — 安価で速いが、校正が必要
曖昧な出力を手で採点するのはスケールしません。明示的なルーブリックで読む能力のあるモデルはスケールします — Anthropic 自身の 評価方法論ガイド がトーン、忠実性、有用性、安全性についてこのパターンを推奨しています。
ジャッジには文書化されたバイアスがあります: 長い回答、最初に表示された選択肢、自身の言い回しを反映した出力を好みます。3つの習慣が正直に保ちます:
- 雰囲気ではなくルーブリック。 「有用性を1〜5で評価」は無用。スケール上の各点を観察可能な行動に固定する。
- 人間ラベルサンプルで校正する。 30〜50ケースを人間に採点させ、ジャッジ対人間の一致度を測る(Cohen κ ≥ 0.6 を目標)。不一致なら、ルーブリックを厳しくする。
- ジャッジには別のモデルを使う。 出力を生成したモデルと同じモデルで採点すると、双方向にバイアスが漏れる。
- 毎週判定を抜き取りチェックする。 ランダムな10件のジャッジスコアとその理由を読む。ドリフトを捕まえる最も安い方法。
LLM-as-judge ルーブリックテンプレート
You are grading an AI assistant's response against a rubric. Be strict. Cite exact evidence from the response.
<task>{task}</task>
<response>{response}</response>
Rubric (rate 1–5 per dimension):
- Task completion: 1 = ignored task; 3 = partial; 5 = fully done, no gaps.
- Faithfulness: 1 = contains false claims; 3 = mostly grounded, one soft claim; 5 = every claim traceable to input/tools.
- Efficiency: 1 = wandered/looped; 3 = extra steps; 5 = minimum viable path.
Output JSON only:
{"task_completion": N, "faithfulness": N, "efficiency": N, "evidence": "<quote>", "verdict": "pass"|"fail"}軌跡レビュープロンプト(層2)
You are auditing an AI agent's tool-call trajectory. The goal was: {goal}
Expected minimum steps: {n_min}
<trajectory>
{list of tool_name(args) -> result, in order}
</trajectory>
Answer in JSON:
{"steps_taken": N, "wasted_steps": N, "wrong_tool_calls": [<indices>], "unsafe_actions": [<indices>], "verdict": "pass"|"fail", "reason": "<one sentence>"}敵対的ケース生成器(セットを成長させる)
Generate 5 new eval cases that are likely to break an agent whose current failures cluster around: {failure_pattern}.
For each case give: input, expected output OR pass criterion, ideal tool sequence, and why this case is hard.
Return YAML.CI ゲート: 出荷前に悪い変更を落とす
評価は自動的に退行をブロックしたときにだけ元が取れます。すべてのプロンプト/モデル/ツール変更のチェックとして CI に組み込む:
# tests/eval_gate.py — runs on every PR
import json, sys
from anthropic import Anthropic
from my_agent import run_agent
client = Anthropic()
golden = json.load(open("evals/golden.v3.json"))
results = []
for case in golden:
trace = run_agent(case["input"])
layer1 = tool_calls_match(trace, case["expected_tools"]) # deterministic
layer3 = judge(client, case, trace.final_output) # LLM rubric
results.append({"id": case["id"], "layer1": layer1, "layer3": layer3["verdict"]})
pass_rate = sum(r["layer3"] == "pass" for r in results) / len(results)
tool_acc = sum(r["layer1"] for r in results) / len(results)
# Gates — tighten over time
assert pass_rate >= 0.85, f"Task success dropped to {pass_rate:.0%}"
assert tool_acc >= 0.90, f"Tool-call accuracy dropped to {tool_acc:.0%}"
print(f"PASS: task={pass_rate:.0%} tools={tool_acc:.0%}")
実行ごとのスコアを保存してトレンドをチャート化。マージ間の3ポイント以上の低下はノイズではなく本物の退行です。
- 最終回答だけを判定 — すべての軌跡バグを見逃す。層1と2も採点する。
- 静的ゴールデンセット — 本番失敗で成長しなければ本番を予測しなくなる。月次で予算を確保する。
- エージェントとジャッジが同じモデル — 双方向のバイアス。採点には別のモデルにローテーション。
- ゲートにコストやレイテンシがない — 8ツールコールを追加するプロンプト調整は評価に「合格」しつつ請求を10倍にできる。
- 雰囲気だけの採点 — 「良く感じる」はメトリクスではない。2つの数字を差分できなければ、自信を持って出荷できない。
- エージェントは回答ではなく軌跡を生む — 結果だけでなく経路を評価する
- 安い順に重ねる: ツールコール正確性 → 軌跡質 → タスク成功 → 本番ドリフト
- 出荷判断を左右する5つのメトリクス: タスク成功率、成功あたりコスト、p50/p95 レイテンシ、ツールコール精度、介入率
- LLM-as-judge はスケールするが、明示的ルーブリック、別モデル、人間ラベルでの校正が必須
- 本番失敗で成長しないゴールデンセットは本番を予測しなくなる — 月次で成長させる
- 評価をハードゲートとして CI に組み込む — ユーザーより先に退行を捕まえるチェック
自分を確認する
自分を確認する
0/41 / 7