AIエージェントの「できた」をどう信じるか——OutputとTrajectoryの評価

Executive Summary

Agentが正しい最終回答を返しても、その途中で権限外のデータを見たり、必要な承認を飛ばしたり、不要な変更を行ったなら、仕事としては合格にできません。

逆に、正しいToolを正しい順序で呼んでも、最終回答の金額や宛先が間違っていれば失敗です。

したがってAgentには二つの評価面が必要です。

  • Output Evaluation:最終的に何を返し、何を作ったか
  • Trajectory Evaluation:そこへ至るまで、どのToolをどの順序で使ったか

本稿では、Build With Google Day 1のSkill評価とADK Graphの検証をつなぎ、EXACTIN_ORDERANY_ORDERの使い分け、Evaluation-Driven Development、人間の判断の残し方まで進みます。

シリーズの現在地

全5回で「AIがものすごく賢くなった。では、本当に仕事を任せられるのか?」を追っています。

  1. Agentic Engineeringとは何か
  2. Antigravityという職場
  3. Agent Skillsという業務マニュアル
  4. Agents CLIとADK Graphによる工程設計
  5. OutputとTrajectoryによる評価(今回)

前回からの接続——一度通った経路は、保証ではない

前回は、配送問い合わせをLLMで分類し、Schemaで受け、PythonとGraph edgeでshippingまたはunrelatedへ送る構造を見ました。

VM上では、代表的な二つの入力が期待経路へ進み、route関数のUnit testも通りました。

しかし、これは「観測したケースが通った」という証拠です。

  • 言い回しが変わっても正しく分類するか
  • 必要なToolを呼び忘れないか
  • 不要または禁止されたToolを呼ばないか
  • Toolの順序を守るか
  • 最終回答の内容も正しいか
  • 失敗時に安全に止まるか

これらは別々に検査しなければなりません。

つまり、動作例は理解の入口であり、信頼の完成ではありません。

納品物と作業記録を分ける

新人へ「承認を確認してから商品を手配して」と頼んだとします。

返ってきた回答は「手配済みです」。文章だけ見れば正解です。しかし実際には、顧客の権限外データを参照し、承認を飛ばして手配していたらどうでしょうか。

最終状態が同じでも、仕事としての評価は変わります。

OutputとTrajectoryを分けて評価する

Output Evaluation

最終成果を見ます。

  • 回答の内容は正しいか
  • 指定した形式を守ったか
  • 必要なファイルが作られたか
  • テストが通るか
  • 根拠のない記述がないか

Trajectory Evaluation

観測可能な実行経路を見ます。

  • 期待するToolを呼んだか
  • 順序を守ったか
  • 不要なToolを呼ばなかったか
  • 許可されたGraph edgeを通ったか
  • 人間確認が必要な箇所を飛ばさなかったか

ここでTrajectoryは、モデル内部の非公開な思考文を開示させることではありません。Tool call、引数、状態遷移、外部作用といった、システムが記録できる行動を評価します。

つまり、Outputは「何が届いたか」、Trajectoryは「どう届けたか」です。両方が正しくて初めて業務品質になります。

なぜ最終回答だけでは見抜けないのか

最終回答だけの評価には、三つの見落としがあります。

1. 偶然の正解

誤った根拠や無関係なToolを使っても、最後の文だけ合うことがあります。テストケースを暗記した場合も同じです。

2. 副作用

回答は正しくても、途中でメール送信、データ更新、ファイル削除などの不要な作用が起きた可能性があります。

3. 再現不能

なぜその答えになったのか追えなければ、失敗時に修正できません。次回も同じ品質になるか判断できません。

一方、Trajectoryだけを厳密に合わせても不十分です。正しいTool列を通って、誤ったデータを要約したり、計算を間違えたりする可能性があります。

Outputだけ正しい       → 偶然・危険経路を見落とす
Trajectoryだけ正しい   → 最終内容の誤りを見落とす
両方を評価             → 成果と過程を別々に検査できる

つまり、二つの評価は代替ではなく、直交する品質軸です。

EXACTIN_ORDERANY_ORDERは何を許すのか

Google ADKの公式TrajectoryEvaluator実装は、期待するTool call列と実際の列を三つの方式で比較します。

期待する処理を、次の三つとします。

A = 顧客を確認
B = 在庫を確認
C = 注文を確定

expected = [A, B, C]

EXACT——余分も不足も順序違いも許さない

[A, B, C]       PASS
[A, X, B, C]    FAIL
[B, A, C]       FAIL
[A, B]          FAIL

期待列と実際の列が完全一致する方式です。呼び出し名だけでなく、評価実装ではTool引数も比較対象になります。

向く例:返金、送信、削除、承認など、手順と回数を厳密に固定したい処理。

IN_ORDER——順序を守れば、途中の追加を許す

[A, B, C]          PASS
[A, X, B, Y, C]    PASS
[B, A, C]          FAIL

期待したcallが同じ順序で現れれば、間に追加callが入ることを許します。

向く例:必須工程の順序は守りつつ、途中のログ取得や補助的な読み取りが変わり得る処理。

ANY_ORDER——期待callの存在を見て、順序を問わない

[A, B, C]          PASS
[C, X, A, B]       PASS
[A, C]             FAIL

期待したcallがすべて存在すれば、順序と途中の追加callを問いません。

向く例:互いに独立な情報源を複数読むなど、順序が結果や安全性へ影響しない処理。

Mode 順序 追加call 不足call
EXACT 一致が必要 不可 不可
IN_ORDER 期待順が必要 不可
ANY_ORDER 不問 不可

注意すべき点があります。IN_ORDERANY_ORDERは追加callを許すため、期待Toolが含まれていても、同時に危険なToolが呼ばれたケースを自動的に拒否できるとは限りません。必要なら「禁止Toolがないこと」を別のcriteriaで検査します。

また、ANY_ORDERを読み取り専用へ限定することはADK API自体の規則ではありません。本稿では、順序を無視しても副作用が変わりにくい読み取り処理を中心に使うことを、安全側の設計として勧めています。

つまり、最も緩いModeを選ぶのではなく、業務上無視してよい差だけを許すModeを選びます。

Evaluation-Driven Development——先に合格条件を書く

実装後に「何となく動いた」と眺めると、期待する挙動を結果に合わせてしまいます。

Build With Googleの講演では、入力、期待Tool、期待Outputを構造化した評価ケースを先に用意する考え方が、Evaluation-Driven Development(EDD)として示されました。

テスト駆動開発と似ていますが、Agentでは最終値だけでなく、Tool trajectoryや意味品質も対象になります。

{
  "input": "標準配送はいくらですか?",
  "expected_route": "shipping",
  "expected_tools": ["classify_query", "shipping_faq"],
  "forbidden_tools": ["issue_refund"],
  "expected_output": {
    "contains": ["$5.99"],
    "must_not_claim": ["返金しました"]
  }
}

これは説明用の簡略例です。実際のADK評価セットには、会話、期待する中間Tool use trajectory、最終応答、criteriaなどを定義できます。ADKの評価ドキュメントは、CLI、Web UI、pytestから評価を実行する方法を説明しています。

先に評価を書くと、設計上の曖昧さが見えます。

  • 「配送に関する」とは、破損や返品も含むのか
  • FAQ回答は金額の一致だけでよいか
  • 追加の読み取りToolは許すか
  • 無関係な質問で、拒否以外の回答を許すか
  • 分類不能時は、どのsafe defaultへ進むか

つまり、評価仕様はAgentへの採点表であると同時に、人間側が「何を正しい仕事とするか」を明文化する仕様書です。

Skillの評価とGraphの評価は同じ構造を持つ

第3回では、Skillの失敗をTrigger、Execution、Token Budget、Regressionの4面で整理しました。これをOutputとTrajectoryへ重ねると、評価箇所が見えます。

失敗 主に見るもの
Trigger Failure Route / Skill selection code review依頼で別Skillを選ぶ
Execution Failure Trajectory+Output Skillは選ぶがChecklistを飛ばす
Token Budget Failure Context telemetry+品質 長大な本文で重要条件を落とす
Regression 評価セット全体 新Skill追加で既存依頼の選択が変わる

一つのSkillを一回試すだけでは、Regressionは見えません。Skill libraryを変更するたびに、既存の代表入力と非対象入力を再実行する必要があります。

同様にGraphでも、shipping入力だけでなく、unrelated、境界事例、Schema不適合、Tool失敗を評価します。

つまり、評価対象は一つの回答ではなく、選択・実行・結果を含むライフサイクル全体です。

VMでの検証を、証拠の強さごとに読む

VM上のCustomer Support Agentでは、検査を分けて行いました。

  • Lint:通過
  • Unit test:通過
  • 代表的なshipping入力:通過
  • 代表的なunrelated入力:通過
  • Integration test:想定する実行環境の契約を明示した条件で通過

検査を層に分けた実行結果

ここで、Integration testには重要な観測がありました。

生のpytest実行では、Labが前提とする環境設定が読み込まれず、Graph routingへ到達する前に停止しました。必要な環境変数名だけを明示して同じ検証を行うと、workflow routingのtestは通過しました。値そのものは検証記録へ残していません。

これは、最初の失敗がGraph logicの誤りだったことを意味しません。反対に、二回目の成功が本番全体を保証するわけでもありません。

示しているのは、再現可能性の単位です。

再現可能な実行
  = Code
  + Dependency versions
  + Runtime
  + Environment contract
  + Test data
  + Command

「コマンドだけ同じ」でも、前提環境が違えば同じ検証にはなりません。

つまり、テスト結果にはPASS/FAILだけでなく、どの環境契約の下で、どこまで到達したかが必要です。

小さな事例——報告ではなく、実物も見る

Agentが「不要なcacheを除外して成果物をまとめた」と報告したとします。報告文が整っていても、実際のarchive内容とは別に確認すべきです。

VM上の演習後成果物では、Manifestがcache除外を示している一方、archive内に14件のcache-like memberが残っていることを確認しました。

記載とアーカイブ実物の照合

これは公式Labそのものの問題でも、AI固有の失敗原因でもありません。人間が作ったscriptでも同じ不一致は起こります。

この小例が示すのは一つだけです。

「除外した」という報告  = claim
archiveのmember一覧      = artifact

claimとartifactは、独立に照合する

最終成果がfileならfileを開き、archiveならmemberを列挙し、API変更なら実際のstateを読み返します。Agentの自己報告は証拠の一部ですが、唯一の証拠にはしません。

つまり、完了報告を信頼する最短経路は、報告を豪華にすることではなく、実物を機械的に照合できるようにすることです。

人間はどこに残るのか

評価を自動化すると、人間が不要になるように見えるかもしれません。しかし、機械評価にも境界があります。

コードで強く検査できるもの

  • Schemaに適合したか
  • 期待Toolを呼んだか
  • 禁止Toolを呼んでいないか
  • 状態遷移が許可集合内か
  • Unit testやproperty testが通るか

LLM Judgeが補助しやすいもの

  • 表現は違うが意味が一致するか
  • 回答が根拠に沿っているか
  • Rubric上の丁寧さや完全性を満たすか

人間が最終判断すべきもの

  • そもそもその目的を実行してよいか
  • 例外が業務・法務・顧客へ与える影響
  • 正解が一つでない設計trade-off
  • 評価指標自体が、本来の目的を歪めていないか
  • 不可逆な操作を承認する責任

LLM Judgeも確率的です。回答の並び順で評価が揺れる位置バイアス、Judge model自身の知識不足、rubricの曖昧さがあります。順序を入れ替えて校正する、複数回評価する、決定的な検査と組み合わせる、といった対策が必要です。

つまり、人間の役割は全出力を手作業で読むことから、目的・例外・責任と、評価系そのものを設計することへ移ります。

もう一段深く:評価を「防御の層」として設計する

一つの巨大な「Agent品質スコア」へ集約すると、何が壊れたか分からなくなります。評価を境界ごとに置く方が、原因と対策を対応させやすくなります。

入力境界
  └─ 対象/非対象/危険意図を分類できるか

Context境界
  └─ 必要資料を取得し、古い資料を混ぜていないか

Schema境界
  └─ 次工程が読める型か

Workflow境界
  └─ 許可された状態遷移だけか

Tool境界
  └─ 最小権限か、禁止操作はないか

Output境界
  └─ 内容・形式・根拠が要件を満たすか

Artifact境界
  └─ 報告と実物が一致するか

さらに、テストケースを三種類へ分けます。

  1. Happy path:代表的な正しい依頼。
  2. Boundary / adversarial:曖昧、矛盾、誘導、権限外の依頼。
  3. Failure injection:Tool timeout、空結果、Schema不適合、途中再試行。

合格率だけでなく、「危険な失敗を一度でも許したか」を別に見ます。100件中99件成功しても、1件で無承認返金を行うAgentは、単純な99%として扱えません。失敗の重みは均等ではないからです。

評価は、平均品質を上げる仕組みであると同時に、許容できない失敗を明示する安全設計です。

5回を一本に戻す

シリーズの最初に、こう問いかけました。

AIがものすごく賢くなった。では、本当に仕事を任せられるのか?

5回を通した答えは、次のようになります。

Model       優秀な新人の能力
  +
Antigravity 案件・権限・接続・証拠を持つ職場
  +
Skills       必要時に開く業務マニュアル
  +
ADK Graph    許可された順序と分岐
  +
Evaluation   納品物と作業経路の検査
  =
仕事を任せられるAgent systemへ近づく

「任せられる」は、失敗しないという宣言ではありません。

何を正しいとするかが書ける。できることを制限できる。途中経過を観測できる。失敗を検出できる。人間へ戻す境界がある。問題が起きたとき、原因を特定して改善できる。

この性質を一つずつ設計することが、Agentic Engineeringです。

今回の持ち帰り

  • OutputとTrajectoryは別々に評価する。 正しい答えと、正しい到達経路の両方が必要。
  • 評価の厳しさはリスクで選ぶ。 EXACTIN_ORDERANY_ORDERで、無視してよい差だけを許す。
  • 人間は評価系の外へ消えない。 目的、例外、不可逆操作、評価指標そのものを判断する。

Day 2へ——「作れた」の先を観察する

Day 1の振り返りは、ここでひと区切りです。ただし、これは結論というより、Day 2を深く読むための設計図でもあります。

Day 1で扱ったのは、Agentへ仕事を渡すための基礎でした。目的をProjectへ置き、必要な知識をSkillとして分離し、Toolと権限を制限し、Workflowで順序を固定し、OutputとTrajectoryを評価する。これらが揃って初めて、AIの能力を継続的な開発や運用へ接続できます。

Day 2では、新しい機能を追うだけでなく、次の5問を観察軸として持ち込みます。

  1. 何をもって完了とするか。
  2. どの文脈とSkillを、いつ読ませるか。
  3. どのToolと権限を許すか。
  4. どの状態遷移だけを許すか。
  5. OutputとTrajectoryを、どう検査するか。

この5問に対して、Day 2の各機能や実装がどんな答えを与えるのか。逆に、どの判断は人間の側に残るのか。そこまで追うことで、単なる機能紹介ではなく、Agentを実務へ載せるための設計として読めるようになります。

AIが賢くなったあとに必要なのは、さらに長い指示文ではありません。賢さを、検査可能で、制御可能で、人が責任を持てる仕事へ変える仕組みです。Day 2では、この土台の上から続きを見ていきます。

参考資料