コンテンツにスキップ

なぜエージェントを評価するのか

python_only

従来のソフトウェア開発では、単体テストと統合テストが、コードが期待通りに機能し、変更を通じて安定しているという信頼を提供します。これらのテストは明確な「合格/不合格」のシグナルを提供し、さらなる開発を導きます。しかし、LLMエージェントは、従来のテストアプローチを不十分にするレベルの変動性を導入します。

モデルの確率的な性質のため、決定論的な「合格/不合格」のアサーションは、エージェントのパフォーマンス評価にはしばしば不適切です。代わりに、最終的な出力と、解決策に到達するために取られた一連のステップであるエージェントの軌跡(trajectory)の両方について、定性的な評価が必要です。これには、エージェントの意思決定の質、その推論プロセス、そして最終結果の評価が含まれます。

これを設定するのは多くの追加作業のように思えるかもしれませんが、評価を自動化するための投資はすぐに元が取れます。プロトタイプを超えて進むつもりなら、これは強く推奨されるベストプラクティスです。

intro_components.png

エージェント評価の準備

エージェント評価を自動化する前に、明確な目標と成功基準を定義します。

  • 成功の定義: あなたのエージェントにとって成功した結果とは何ですか?
  • 重要なタスクの特定: あなたのエージェントが達成しなければならない本質的なタスクは何ですか?
  • 関連するメトリクスの選択: パフォーマンスを測定するために追跡するメトリクスは何ですか?

これらの考慮事項は、評価シナリオの作成を導き、実世界のデプロイメントにおけるエージェントの行動の効果的な監視を可能にします。

何を評価するか?

概念実証と本番稼働可能なAIエージェントの間のギャップを埋めるためには、堅牢で自動化された評価フレームワークが不可欠です。主に最終出力に焦点が当てられる生成モデルの評価とは異なり、エージェントの評価には意思決定プロセスのより深い理解が必要です。エージェントの評価は、2つのコンポーネントに分けることができます。

  1. 軌跡とツールの使用を評価する: ツール、戦略の選択、およびアプローチの効率性を含め、エージェントが解決策に到達するために取るステップを分析します。
  2. 最終応答を評価する: エージェントの最終出力の品質、関連性、および正しさを評価します。

軌跡とは、エージェントがユーザーに応答する前に取ったステップのリストにすぎません。これを、エージェントが取ったと期待するステップのリストと比較することができます。

軌跡とツールの使用を評価する

ユーザーに応答する前に、エージェントは通常一連のアクションを実行します。これを「軌跡(trajectory)」と呼びます。用語を明確にするためにセッション履歴とユーザー入力を比較したり、ポリシー文書を参照したり、ナレッジベースを検索したり、チケットを保存するためにAPIを呼び出したりすることがあります。これをアクションの「軌跡」と呼びます。エージェントのパフォーマンスを評価するには、その実際の軌跡を期待される、または理想的な軌跡と比較する必要があります。この比較により、エージェントのプロセスにおけるエラーや非効率性が明らかになることがあります。期待される軌跡は、我々がエージェントが取るべきだと予測するステップのリストである正解(ground truth)を表します。

例:

# 軌跡の評価では以下を比較します
expected_steps = ["determine_intent", "use_tool", "review_results", "report_generation"]
actual_steps = ["determine_intent", "use_tool", "review_results", "report_generation"]

正解データに基づく軌跡評価にはいくつか存在します。

  1. 完全一致(Exact match): 理想的な軌跡と完全に一致する必要があります。
  2. 順序一致(In-order match): 正しいアクションが正しい順序で実行される必要があり、余分なアクションは許容されます。
  3. 順序不問一致(Any-order match): 正しいアクションが任意の順序で実行される必要があり、余分なアクションは許容されます。
  4. 適合率(Precision): 予測されたアクションの関連性/正しさを測定します。
  5. 再現率(Recall): 予測に不可欠なアクションがどれだけ含まれているかを測定します。
  6. 単一ツール使用(Single-tool use): 特定のアクションが含まれているかを確認します。

適切な評価メトリクスを選択するかは、エージェントの特定の要件と目標に依存します。例えば、ハイステークスなシナリオでは完全一致が重要になるかもしれませんが、より柔軟な状況では順序一致または順序不問一致で十分な場合があります。

ADKでの評価の仕組み

ADKは、事前に定義されたデータセットと評価基準に対してエージェントのパフォーマンスを評価するための2つの方法を提供します。概念的には似ていますが、処理できるデータの量が異なり、これが通常、それぞれの適切なユースケースを決定します。

最初のアプローチ:テストファイルの使用

このアプローチでは、それぞれが単一でシンプルなエージェントとモデルの相互作用(セッション)を表す個別のテストファイルを作成します。これは、アクティブなエージェント開発中に最も効果的であり、一種の単体テストとして機能します。これらのテストは迅速な実行のために設計されており、シンプルなセッションの複雑さに焦点を当てるべきです。各テストファイルには単一のセッションが含まれ、これは複数のターンで構成される場合があります。ターンは、ユーザーとエージェント間の単一の相互作用を表します。各ターンには以下が含まれます。

  • User Content:ユーザーが発行したクエリ。
  • Expected Intermediate Tool Use Trajectory:ユーザーのクエリに正しく応答するためにエージェントが実行すると期待されるツール呼び出し。
  • Expected Intermediate Agent Responses:エージェント(またはサブエージェント)が最終的な回答を生成する過程で生成する自然言語の応答です。これらの自然言語の応答は、通常、ルートエージェントが目標を達成するためにサブエージェントに依存するマルチエージェントシステムの成果物です。これらの中間応答は、エンドユーザーにとって興味深いものではないかもしれませんが、システムの開発者/所有者にとっては、エージェントが最終的な応答を生成するために正しいパスをたどったという確信を与えてくれるため、非常に重要です。
  • Final Response:エージェントからの期待される最終応答。

ファイルには、例えばevaluation.test.jsonのような任意の名前を付けることができます。フレームワークは.test.jsonという接尾辞のみをチェックし、ファイル名の前の部分は制約されません。以下はいくつかの例を含むテストファイルです。

注:テストファイルは現在、正式なPydanticデータモデルによって裏付けられています。2つの主要なスキーマファイルは、Eval SetEval Caseです。

(注:コメントは説明目的で含まれており、JSONが有効であるためには削除する必要があります。)

# このドキュメントを読みやすくするために、一部のフィールドは削除されています。
{
  "eval_set_id": "home_automation_agent_light_on_off_set",
  "name": "",
  "description": "これは、エージェントの`x`の動作を単体テストするために使用される評価セットです",
  "eval_cases": [
    {
      "eval_id": "eval_case_id",
      "conversation": [
        {
          "invocation_id": "b7982664-0ab6-47cc-ab13-326656afdf75", # 呼び出しの一意の識別子。
          "user_content": { # この呼び出しでユーザーが提供したコンテンツ。これがクエリです。
            "parts": [
              {
                "text": "寝室のdevice_2をオフにしてください。"
              }
            ],
            "role": "user"
          },
          "final_response": { # ベンチマークの参照として機能するエージェントからの最終応答。
            "parts": [
              {
                "text": "device_2のステータスをオフに設定しました。"
              }
            ],
            "role": "model"
          },
          "intermediate_data": {
            "tool_uses": [ # 時系列でのツール使用軌跡。
              {
                "args": {
                  "location": "Bedroom",
                  "device_id": "device_2",
                  "status": "OFF"
                },
                "name": "set_device_info"
              }
            ],
            "intermediate_responses": [] # 中間的なサブエージェントの応答。
          },
        }
      ],
      "session_input": { # 初期のセッション入力。
        "app_name": "home_automation_agent",
        "user_id": "test_user",
        "state": {}
      },
    }
  ],
}

テストファイルはフォルダにまとめることができます。オプションで、フォルダには評価基準を指定するtest_config.jsonファイルを含めることもできます。

Pydanticスキーマに裏付けられていないテストファイルを移行する方法は?

注:テストファイルがEvalSetスキーマファイルに準拠していない場合、このセクションが該当します。

既存の*.test.jsonファイルをPydanticがサポートするスキーマに移行するには、AgentEvaluator.migrate_eval_data_to_new_schemaを使用してください。

このユーティリティは、現在のテストデータファイルとオプションの初期セッションファイルを受け取り、新しい形式でシリアル化されたデータを持つ単一の出力jsonファイルを生成します。新しいスキーマはより一貫性があるため、古いテストデータファイルと初期セッションファイルの両方を無視(または削除)できます。

2番目のアプローチ:Evalsetファイルの使用

evalsetアプローチは、エージェントとモデルの相互作用を評価するために「evalset」と呼ばれる専用のデータセットを利用します。テストファイルと同様に、evalsetには相互作用の例が含まれています。ただし、evalsetには複数の、潜在的に長いセッションを含めることができるため、複雑な複数ターンの会話をシミュレートするのに理想的です。複雑なセッションを表現できるため、evalsetは統合テストに適しています。これらのテストは、その広範な性質のため、通常、単体テストよりも頻繁に実行されることはありません。

evalsetファイルには、それぞれが異なるセッションを表す複数の「eval」が含まれています。各evalは、ユーザーのクエリ、期待されるツールの使用、期待される中間エージェントの応答、および参照応答を含む1つ以上の「ターン」で構成されます。これらのフィールドは、テストファイルアプローチと同じ意味を持ちます。各evalは一意の名前で識別されます。さらに、各evalには関連する初期セッション状態が含まれています。

evalsetを手動で作成するのは複雑な場合があるため、関連するセッションをキャプチャし、evalset内のevalに簡単に変換するのに役立つUIツールが提供されています。評価にWeb UIを使用する方法については、以下で詳しく学びます。以下は、2つのセッションを含むevalsetの例です。

注:eval setファイルは現在、正式なPydanticデータモデルによって裏付けられています。2つの主要なスキーマファイルは、Eval SetEval Caseです。

(注:コメントは説明目的で含まれており、JSONが有効であるためには削除する必要があります。)

# このドキュメントを読みやすくするために、一部のフィールドは削除されています。
{
  "eval_set_id": "eval_set_example_with_multiple_sessions",
  "name": "複数のセッションを持つ評価セットの例",
  "description": "この評価セットは、評価セットが複数のセッションを持つことができることを示す例です。",
  "eval_cases": [
    {
      "eval_id": "session_01",
      "conversation": [
        {
          "invocation_id": "e-0067f6c4-ac27-4f24-81d7-3ab994c28768",
          "user_content": {
            "parts": [
              {
                "text": "あなたは何ができますか?"
              }
            ],
            "role": "user"
          },
          "final_response": {
            "parts": [
              {
                "text": "私は様々なサイズのサイコロを振り、数字が素数かどうかをチェックできます。"
              }
            ],
            "role": null
          },
          "intermediate_data": {
            "tool_uses": [],
            "intermediate_responses": []
          },
        },
      ],
      "session_input": {
        "app_name": "hello_world",
        "user_id": "user",
        "state": {}
      },
    },
    {
      "eval_id": "session_02",
      "conversation": [
        {
          "invocation_id": "e-92d34c6d-0a1b-452a-ba90-33af2838647a",
          "user_content": {
            "parts": [
              {
                "text": "19面のサイコロを振って"
              }
            ],
            "role": "user"
          },
          "final_response": {
            "parts": [
              {
                "text": "17が出ました。"
              }
            ],
            "role": null
          },
          "intermediate_data": {
            "tool_uses": [],
            "intermediate_responses": []
          },
        },
        {
          "invocation_id": "e-bf8549a1-2a61-4ecc-a4ee-4efbbf25a8ea",
          "user_content": {
            "parts": [
              {
                "text": "10面のサイコロを2回振って、9が素数かどうかをチェックして"
              }
            ],
            "role": "user"
          },
          "final_response": {
            "parts": [
              {
                "text": "サイコロの目は4と7が出ました。9は素数ではありません。\n"
              }
            ],
            "role": null
          },
          "intermediate_data": {
            "tool_uses": [
              {
                "id": "adk-1a3f5a01-1782-4530-949f-07cf53fc6f05",
                "args": {
                  "sides": 10
                },
                "name": "roll_die"
              },
              {
                "id": "adk-52fc3269-caaf-41c3-833d-511e454c7058",
                "args": {
                  "sides": 10
                },
                "name": "roll_die"
              },
              {
                "id": "adk-5274768e-9ec5-4915-b6cf-f5d7f0387056",
                "args": {
                  "nums": [
                    9
                  ]
                },
                "name": "check_prime"
              }
            ],
            "intermediate_responses": [
              [
                "data_processing_agent",
                [
                  {
                    "text": "10面のサイコロを2回振りました。最初の目は5で、2番目の目は3です。\n"
                  }
                ]
              ]
            ]
          },
        }
      ],
      "session_input": {
        "app_name": "hello_world",
        "user_id": "user",
        "state": {}
      },
    }
  ],
}

Pydanticスキーマに裏付けられていないeval setファイルを移行する方法は?

注:eval setファイルがEvalSetスキーマファイルに準拠していない場合、このセクションが該当します。

eval setデータを誰が維持しているかに基づいて、2つのルートがあります。

  1. ADK UIによって維持されるeval setデータ ADK UIを使用してEval setデータを維持する場合、あなたからのアクションは不要です。

  2. 手動で開発・維持され、ADK eval CLIで使用されるeval setデータ 移行ツールは開発中ですが、それまではADK eval CLIコマンドは古い形式のデータを引き続きサポートします。

評価基準

評価基準は、evalsetに対してエージェントのパフォーマンスをどのように測定するかを定義します。以下のメトリクスがサポートされています。

  • tool_trajectory_avg_score:このメトリックは、評価中のエージェントの実際のツール使用を、expected_tool_useフィールドで定義された期待されるツール使用と比較します。一致する各ツール使用ステップは1のスコアを受け取り、不一致の場合は0のスコアを受け取ります。最終スコアはこれらの一致の平均であり、ツール使用軌跡の正確さを表します。
  • response_match_score:このメトリックは、エージェントの最終的な自然言語応答を、referenceフィールドに保存されている期待される最終応答と比較します。2つの応答の類似性を計算するためにROUGEメトリックを使用します。

評価基準が提供されない場合、以下のデフォルト設定が使用されます。

  • tool_trajectory_avg_score:デフォルトは1.0で、ツール使用軌跡の100%一致が必要です。
  • response_match_score:デフォルトは0.8で、エージェントの自然言語応答に小さな誤差のマージンを許容します。

以下は、カスタム評価基準を指定するtest_config.jsonファイルの例です。

{
  "criteria": {
    "tool_trajectory_avg_score": 1.0,
    "response_match_score": 0.8
  }
}

ADKで評価を実行する方法

開発者は、ADKを使用してエージェントを以下の方法で評価できます。

  1. WebベースのUI(adk web): Webベースのインターフェースを通じてインタラクティブにエージェントを評価します。
  2. プログラム的に(pytest): pytestとテストファイルを使用して、評価をテストパイプラインに統合します。
  3. コマンドラインインターフェース(adk eval): 既存の評価セットファイルに対して、コマンドラインから直接評価を実行します。

1. adk web - Web UIを介して評価を実行する

Web UIは、エージェントをインタラクティブに評価し、評価データセットを生成し、エージェントの動作を詳細に検査するためのインタラクティブな方法を提供します。

ステップ1:テストケースの作成と保存

  1. Webサーバーを起動します:adk web <path_to_your_agents_folder>
  2. Webインターフェースでエージェントを選択し、対話してセッションを作成します。
  3. インターフェースの右側にあるEvalタブに移動します。
  4. 新しい評価セットを作成するか、既存のものを選択します。
  5. "現在のセッションを追加"をクリックして、会話を新しい評価ケースとして保存します。

ステップ2:テストケースの表示と編集

ケースが保存されると、リスト内のIDをクリックしてそれを検査できます。変更を加えるには、現在の評価ケースを編集アイコン(鉛筆)をクリックします。このインタラクティブなビューでは、次のことができます。

  • テストシナリオを洗練させるためにエージェントのテキスト応答を修正します。
  • 会話から個々のエージェントメッセージを削除します。
  • 不要になった場合は、評価ケース全体を削除します。

adk-eval-case.gif

ステップ3:カスタムメトリクスで評価を実行する

  1. 評価セットから1つ以上のテストケースを選択します。
  2. 評価を実行をクリックします。評価メトリクスダイアログが表示されます。
  3. ダイアログで、スライダーを使用して以下のしきい値を設定します。
    • Tool trajectory avg score (ツール軌跡平均スコア)
    • Response match score (応答一致スコア)
  4. 開始をクリックして、カスタム基準を使用して評価を実行します。評価履歴には、各実行で使用されたメトリクスが記録されます。

adk-eval-config.gif

ステップ4:結果の分析

実行が完了したら、結果を分析できます。

  • 実行の失敗を分析PassまたはFailの結果をクリックします。失敗の場合、Failラベルにカーソルを合わせると、実績 vs. 期待出力の並べて比較と、失敗の原因となったスコアが表示されます。

Traceビューによるデバッグ

ADK Web UIには、エージェントの動作をデバッグするための強力なTraceタブが含まれています。この機能は、評価中だけでなく、任意のエージェントセッションで利用できます。

Traceタブは、エージェントの実行フローを詳細かつインタラクティブに検査する方法を提供します。トレースはユーザーメッセージごとに自動的にグループ化されるため、イベントの連鎖を簡単に追うことができます。

各トレース行はインタラクティブです。

  • トレース行にカーソルを合わせると、チャットウィンドウ内の対応するメッセージが強調表示されます。
  • トレース行をクリックすると、4つのタブを持つ詳細な検査パネルが開きます。
    • Event:生のイベントデータ。
    • Request:モデルに送信されたリクエスト。
    • Response:モデルから受信したレスポンス。
    • Graph:ツール呼び出しとエージェントロジックフローの視覚的表現。

adk-trace1.gif adk-trace2.gif

トレースビューの青い行は、その相互作用からイベントが生成されたことを示します。これらの青い行をクリックすると、下部のイベント詳細パネルが開き、エージェントの実行フローに関するより深い洞察が得られます。

2. pytest - プログラムでテストを実行する

pytestを使用して、統合テストの一部としてテストファイルを実行することもできます。

コマンド例

pytest tests/integration/

テストコード例

以下は、単一のテストファイルを実行するpytestテストケースの例です。

from google.adk.evaluation.agent_evaluator import AgentEvaluator
import pytest

@pytest.mark.asyncio
async def test_with_single_test_file():
    """セッションファイルを介してエージェントの基本的な能力をテストします。"""
    await AgentEvaluator.evaluate(
        agent_module="home_automation_agent",
        eval_dataset_file_path_or_dir="tests/integration/fixture/home_automation_agent/simple_test.test.json",
    )

このアプローチにより、エージェントの評価をCI/CDパイプラインやより大規模なテストスイートに統合できます。テストの初期セッション状態を指定したい場合は、セッションの詳細をファイルに保存し、それをAgentEvaluator.evaluateメソッドに渡すことで可能です。

3. adk eval - CLI経由で評価を実行する

コマンドラインインターフェース(CLI)を介して評価セットファイルの評価を実行することもできます。これはUIで実行されるのと同じ評価を実行しますが、自動化に役立ちます。つまり、このコマンドを通常のビルド生成および検証プロセスの一部として追加できます。

コマンドは次のとおりです。

adk eval \
    <AGENT_MODULE_FILE_PATH> \
    <EVAL_SET_FILE_PATH> \
    [--config_file_path=<PATH_TO_TEST_JSON_CONFIG_FILE>] \
    [--print_detailed_results]

例:

adk eval \
    samples_for_testing/hello_world \
    samples_for_testing/hello_world/hello_world_eval_set_001.evalset.json

各コマンドライン引数の詳細は次のとおりです。

  • AGENT_MODULE_FILE_PATH:「agent」という名前のモジュールを含む__init__.pyファイルへのパスです。「agent」モジュールにはroot_agentが含まれています。
  • EVAL_SET_FILE_PATH:評価ファイルへのパスです。1つ以上の評価セットファイルのパスを指定できます。各ファイルについて、デフォルトではすべての評価が実行されます。評価セットから特定の評価のみを実行したい場合は、まず評価名のカンマ区切りリストを作成し、それをコロン:で区切って評価セットファイル名のサフィックスとして追加します。
  • 例:sample_eval_set_file.json:eval_1,eval_2,eval_3
    これにより、sample_eval_set_file.jsonからeval_1、eval_2、eval_3のみが実行されます。
  • CONFIG_FILE_PATH:設定ファイルへのパスです。
  • PRINT_DETAILED_RESULTS:コンソールに詳細な結果を出力します。