「雰囲気の確認」からデータドリブンのエージェント評価へ

1. はじめに

概要

このラボは、ADK を使用してマルチエージェント システムを構築するのフォローアップです。

そのラボでは、次のようなコース作成システムを構築しました。

  1. Researcher Agent: google_search を使用して最新の情報を検索します。
  2. Judge Agent: 調査の品質と完全性を評価します。
  3. コンテンツ ビルダー エージェント: 調査結果を構造化されたコースに変換します。
  4. オーケストレーター エージェント: これらのスペシャリスト間のワークフローとコミュニケーションを管理します。

また、ユーザーがコース作成リクエストを送信し、レスポンスとしてコースを取得できるウェブアプリも含まれていました。

ResearcherJudgeContent Builder は、個別の Cloud Run サービスで A2A エージェントとしてデプロイされます。Orchestrator は、ADK Service API を使用する別の Cloud Run サービスです。

このラボでは、Gemini の Google 検索機能ではなく、Wikipedia 検索ツールを使用するように Researcher エージェントを変更しました。これにより、カスタムツールの呼び出しがどのようにトレースされ、評価されるかを検査できます。

そこで、分散型マルチエージェント システムを構築しました。では、実際にうまく機能しているかどうかをどのように判断すればよいでしょうか?リサーチャーは常に適切な情報を見つけますか?Judge は不適切な調査を正しく識別しますか?

このラボでは、Vertex AI Gen AI Evaluation Service を使用して、主観的な「雰囲気の確認」をデータドリブンな評価に置き換えます。適応型ルーブリックとツール使用品質指標を実装して、ラボ 1 で構築した分散型マルチエージェント システムを厳密に評価します。最後に、このプロセスを CI/CD パイプライン内で自動化し、すべてのデプロイで本番環境エージェントの信頼性と精度が維持されるようにします。

エージェントの継続的評価パイプラインを構築します。ここでは以下について学びます。

  1. エージェントを Google Cloud Run のプライベートなタグ付きリビジョンにデプロイします(シャドー デプロイ)。
  2. Vertex AI Gen AI Evaluation Service を使用して、その特定のリビジョンに対して自動評価スイートを実行します。
  3. 結果を可視化して分析します。
  4. 評価を CI/CD パイプラインの一部として使用します。

2. コアコンセプト: エージェント評価理論

AI エージェントの開発と実行では、オフライン テスト自動回帰テストによる継続的評価という 2 種類の評価を実施します。1 つ目は開発プロセスのクリエイティブ エンジンです。ここでは、アドホックな実験を実施し、プロンプトを改良し、迅速に反復処理を行って、新しい機能を開発します。2 つ目は CI/CD パイプライン内の防御レイヤです。ここでは、「ゴールデン」データセットに対して継続的な評価を実行し、コード変更によってエージェントの品質が低下しないようにします。

根本的な違いは、検出防御にあります。

  • オフライン テストは最適化のプロセスです。オープンエンドで可変です。スコアを最大化したり、特定の問題を解決したりするために、入力(プロンプト、モデル、パラメータ)を積極的に変更している。目標は、エージェントができることの「上限」を引き上げることです。
  • 継続的評価(自動回帰テスト)は検証プロセスです。柔軟性がなく、繰り返しの多い作業です。出力を安定させるため、入力(「ゴールデン」データセット)を一定に保ちます。目標は、パフォーマンスの「下限」が崩壊するのを防ぐことです。

このラボでは、継続的評価に焦点を当てます。単体テストと同様に、AI エージェントに変更が加えられるたびに実行される自動回帰テスト パイプラインを開発します。

コードを記述する前に、何を測定するのかを理解することが重要です。

「バイブチェック」の罠

多くのデベロッパーは、エージェントと手動でチャットしてエージェントをテストしています。これは「バイブ チェック」と呼ばれます。プロトタイピングには便利ですが、本番環境では次の理由で失敗します。

  • 非決定性: エージェントは毎回異なる回答を返す可能性があります。統計的に有意なサンプルサイズが必要です。
  • 目に見えない回帰: 1 つのプロンプトを改善すると、別のユースケースが機能しなくなる可能性があります。
  • 人間のバイアス: 「よさそう」は主観的なものです。
  • 時間のかかる作業: コミットごとに数十のシナリオを手動でテストするのは時間がかかります。

「バイブチェック」の罠

エージェントのパフォーマンスを評価する 2 つの方法

堅牢なパイプラインを構築するために、さまざまな種類のグレーダーを組み合わせています。

  1. コードベースの採点者(決定論的):
    • 測定するもの: 厳格な制約(「有効な JSON が返されましたか?」, 「search ツールを呼び出したか?」)。
    • メリット: 高速、低コスト、100% の精度。
    • 短所: ニュアンスや品質を判断できない。
  2. モデルベースの採点者(確率的):
    • 「LLM-as-a-Judge」とも呼ばれます。強力なモデル(Gemini 3 Pro など)を使用して、エージェントの出力を評価します。
    • 測定対象: ニュアンス、推論、有用性、安全性。
    • メリット: 複雑な自由回答形式のタスクを評価できます。
    • 短所: 処理速度が遅く、コストが高い。判定者向けのプロンプト エンジニアリングを慎重に行う必要がある。

Vertex AI の評価指標

このラボでは、Vertex AI Gen AI Evaluation Service を使用します。このサービスは管理対象の指標を提供するため、すべての判定を最初から作成する必要はありません。

エージェント評価の指標をグループ化する方法は複数あります。

  • ルーブリック ベースの指標: 評価ワークフローに LLM を組み込みます。
    • 適応型ルーブリック: 各プロンプトに対してルーブリックが動的に生成されます。プロンプト固有のきめ細かい説明可能な合否フィードバックで回答が評価されます。
    • 静的ルーブリック: ルーブリックが明示的に定義され、すべてのプロンプトに同じルーブリックが適用されます。同じ数値スコアリング ベースの評価ツールで回答が評価されます。プロンプトごとに 1 つの数値スコア(1~5 など)。特定のディメンションに関する評価が必要な場合、またはすべてのプロンプトでまったく同じルーブリックが必要な場合。
  • 計算ベースの指標: 通常はグラウンド トゥルースを使用して、決定的アルゴリズムで回答を評価します。プロンプトごとの数値スコア(0.0~1.0 など)。グラウンド トゥルースが利用可能で、決定的手法で照合できる場合。
  • カスタム関数指標: Python 関数を使用して独自の指標を定義します。

使用する具体的な指標:

  • Final Response Match:(参照ベース)回答は「ゴールデン アンサー」と一致していますか?
  • Tool Use Quality:(参照なし)エージェントは関連するツールを適切に使用しましたか?
  • Hallucination:(参照なし)回答内の主張は、取得されたコンテキストによって裏付けられていますか?
  • Tool Trajectory PrecisionTool Trajectory Recall(参照ベース)エージェントは適切なツールを選択し、有効な引数を指定したか?Tool Use Quality とは異なり、これらのカスタム指標は参照軌跡(想定されるツール呼び出しと引数のシーケンス)を使用します。

3. セットアップ

構成

  1. Cloud Shell を開く: Google Cloud コンソールの右上にある [Cloud Shell をアクティブにする] アイコンをクリックします。
  2. 次のコマンドを実行して、ログインを更新し、アプリケーションのデフォルト認証情報(ADC)を更新します。
    gcloud auth login --update-adc
    
    手順に沿ってブラウザでのログインを完了します。
  3. gcloud CLI のアクティブなプロジェクトを設定します。次のコマンドを実行して、現在の gcloud プロジェクトを取得します。
    gcloud config get-value project
    
    設定されていない場合は、次のコマンドを実行します。
    gcloud config set project YOUR_PROJECT_ID
    
    YOUR_PROJECT_ID は、プロジェクトの ID に置き換えます。
  4. Cloud Run サービスがデプロイされるデフォルト リージョンを設定します。
    gcloud config set run/region us-central1
    
    us-central1 の代わりに、より近い Cloud Run リージョンを使用できます。

コードと依存関係

  1. スターター コードのクローンを作成し、ディレクトリをプロジェクトのルートに変更します。
    git clone https://github.com/vladkol/agent-evaluation-lab -b starter
    cd agent-evaluation-lab
    
  2. .env ファイルを作成します。
    echo "GOOGLE_GENAI_USE_VERTEXAI=true" > .env
    echo "GOOGLE_CLOUD_PROJECT=$(gcloud config get-value project -q)" >> .env
    echo "GOOGLE_CLOUD_REGION=$(gcloud config get-value run/region -q)" >> .env
    echo "GOOGLE_CLOUD_LOCATION=global" >> .env
    
  3. Cloud Shell エディタを開きます。
    cloudshell workspace .
    
  4. [ターミナル] > [新しいターミナル] メニューを使用して、新しいターミナル ウィンドウを開きます。
  5. ターミナル ウィンドウで次のコマンドを実行して、依存関係をインストールします。
    uv sync
    

4. 安全なデプロイについて

評価する前に、デプロイする必要があります。ただし、新しいコードが不良の場合に、本番環境のアプリケーションを壊したくはありません。

リビジョンタグとシャドウ デプロイ

Google Cloud Run はリビジョンをサポートしています。デプロイするたびに、新しい不変のリビジョンが作成されます。これらのリビジョンにタグを割り当てると、公開トラフィックの 0% を受信している場合でも、特定の URL を介してアクセスできます。

ローカルで評価を実行するだけでは不十分ですか?

ADK はローカル評価をサポートしていますが、非表示リビジョンにデプロイすると、本番環境システムにとって重要なメリットがあります。これにより、システムレベルの評価(現在実施していること)と単体テストが区別されます。

  1. 環境のパリティ: ローカル環境が異なる(ネットワーク、CPU/メモリ、シークレットが異なる)。クラウドでのテストにより、エージェントが実際のランタイム環境で動作することを確認できます(システム テスト)。
  2. マルチエージェント インタラクション: 分散システムでは、エージェントは HTTP 経由で通信します。「ローカル」テストでは、これらの接続をモックすることがよくあります。シャドー デプロイでは、マイクロサービス間の実際のネットワーク レイテンシ、タイムアウト構成、認証がテストされます。
  3. シークレットと権限: サービス アカウントに、必要な権限(Vertex AI の呼び出しや Firestore からの読み取りなど)が実際に付与されていることを確認します。

注: これは事前評価(ユーザーに表示される前にチェック)です。デプロイ後は、リアクティブ モニタリング(オブザーバビリティ)を使用して、実際の環境で問題を検出します。

CI/CD ワークフロー: デプロイ、評価、昇格

これは、堅牢な継続的デプロイ パイプラインに使用されます。

  1. Commit: エージェントのプロンプトを変更し、リポジトリに push します。
  2. デプロイ(非表示): commit ハッシュ(c-abc1234)。このリビジョンは、パブリック トラフィックの 0% を受信します。
  3. 評価: 評価スクリプトは、特定のリビジョン URL https://c-abc1234---researcher-xyz.run.app をターゲットにします。
  4. プロモート: 評価に合格し、他のテストが成功した場合にのみ、この新しいリビジョンにトラフィックを移行します。
  5. ロールバック: 失敗した場合、ユーザーは不良バージョンを目にすることはありません。不良リビジョンは無視または削除するだけで済みます。

この戦略により、顧客に影響を与えることなく本番環境でテストできます。

evaluate.sh を分析

evaluate.sh を開きます。このスクリプトは、このプロセスを自動化します。

export COMMIT_SHORT_HASH=$(git rev-parse --short HEAD)
export COMMIT_REVISION_TAG="c-${COMMIT_SHORT_HASH}"

# ...

# Deploy services with a revision tag and NO traffic
source ./deploy.sh --revision-tag $COMMIT_REVISION_TAG --no-redeploy

# Run the evaluation against that specific tag
uv run -m evaluator.evaluate_agent

deploy.sh は、--no-traffic オプションと --tag オプションを使用してリビジョン デプロイを処理します。すでに実行中のサービスがある場合、影響はありません。新しい「非表示」リビジョンは、リビジョン タグ(https://c-abc1234---researcher-xyz.run.app など)を含む特別な URL で明示的に呼び出さない限り、トラフィックを受信しません。

5. 評価スクリプトを実装する

それでは、実際にテストを実行するコードを記述しましょう。

  1. evaluator/evaluate_agent.py を開きます。
  2. インポートと設定は表示されますが、指標と実行ロジックは表示されません。

指標を定義する

リサーチャー エージェントの場合、予想される回答を含む「ゴールデン アンサー」または「グラウンド トゥルース」があります。これはケーパビリティ評価です。エージェントがジョブを正しく実行できるかどうかを測定します。

測定したい内容は次のとおりです。

  • 最終回答の一致:(機能)回答は期待される回答と一致していますか?これは参照ベースの指標です。判定 LLM を使用して、エージェントの出力と期待される回答を比較します。回答が完全に同じであることは想定していませんが、意味的にも事実的にも類似していることは想定しています。
  • ツールの使用品質:(品質)適切なツールの選択、正しいパラメータの使用、指定された操作シーケンスの遵守を評価する、ターゲット設定された適応型ルーブリック指標。
  • ツールの使用軌跡:(トレース)エージェントのツールの使用軌跡(適合率と再現率)を期待される軌跡と比較する 2 つのカスタム指標。これらの指標は、shared/evaluation/tool_metrics.py でカスタム関数として実装されます。ツールの使用品質とは異なり、この指標は決定論的な参照ベースの指標です。コードは、実際のツール呼び出しが参照データ(評価データの reference_trajectory)と一致するかどうかを文字どおりに確認します。

カスタム ツールの使用状況の軌跡指標

カスタムのツール使用軌跡指標については、shared/evaluation/tool_metrics.py に一連の Python 関数を作成しました。Vertex AI Gen AI Evaluation Service でこれらの関数を実行できるようにするには、その Python コードを渡す必要があります。

これを行うには、UnifiedMetricCustomCodeExecutionSpec の構成で EvaluationRunMetric オブジェクトを定義します。パラメータ remote_custom_function は、関数の Python コードを含む文字列です。関数には evaluate という名前を付ける必要があります。

def evaluate(
    instance: dict
) -> float:
    ...

Python 関数をカスタムコード評価指標に変換する get_custom_function_metric ヘルパー(shared/evaluation/evaluate.py 内)を作成しました。

関数のモジュールのコードを取得し(ローカル依存関係をキャプチャするため)、元の関数を呼び出す追加の evaluate 関数を作成し、CustomCodeExecutionSpec を含む EvaluationRunMetric オブジェクトを返します。

import inspect
module_source = inspect.getsource(
    inspect.getmodule(metrics_function)
)
module_source += (
    "\n\ndef evaluate(instance: dict) -> float:\n"
    f"    return {metrics_function.__name__}(instance)\n"
)
return types.EvaluationRunMetric(
    metric=metric_name,
    metric_config=types.UnifiedMetric(
        custom_code_execution_spec=types.CustomCodeExecutionSpec(
            remote_custom_function=module_source
        )
    )
)

Gen AI Evaluation Service は、そのコードをサンドボックス実行環境で実行し、評価データを渡します。

指標と評価コードを追加する

if __name__ == "__main__": 行の後に、次のコードを evaluator/evaluate_agent.py に追加します。

Researcher エージェントの指標リストを定義し、評価を実行します。

    eval_data_researcher = os.path.dirname(__file__) + "/eval_data_researcher.json"
    metrics=[
        # Compares the agent's output against a "Golden Answer"
        types.RubricMetric.FINAL_RESPONSE_MATCH,
        # Did the agent use the tools effectively?
        types.RubricMetric.TOOL_USE_QUALITY,
        # Custom metrics for tools trajectory analysis
        get_custom_function_metric("trajectory_precision", trajectory_precision_func),
        get_custom_function_metric("trajectory_recall", trajectory_recall_func)
    ]

    print("🧪 Running Researcher Evaluation...")
    eval_results = asyncio.run(
        # Run the evaluation and retrieve the results.
        evaluate_agent(
            agent_api_server=RESEARCHER_URL, # Agent Service URL (in Cloud Run).
            agent_name="agent", # Agent name as it's exposed by the server.
            evaluation_data_file=eval_data_researcher, # Evaluation data file.
            # GCS location for the Evaluation Service to store the result to.
            evaluation_storage_uri=f"gs://{GOOGLE_CLOUD_PROJECT}-agents/evaluation",
            metrics=metrics, # Metrics to use when evaluating the agent.
            project_id=GOOGLE_CLOUD_PROJECT,
            location=GOOGLE_CLOUD_REGION
        )
    )
    print(f"\n🧪 Researcher Evaluation results:\n{eval_results}")
    print(f"Evaluation Run ID: {eval_results.run_id}")

実際の本番環境パイプラインでは、評価の成功基準が必要です。評価が完了し、指標の準備が整ったら、ここにゲートステップが配置されます。例: 「Final Response Match スコアが 0.75 未満の場合は、ビルドを失敗させます。」これにより、不良なリビジョンがトラフィックを受信することを防ぐことができます。

次のコードを evaluator/evaluate_agent.py に追加します。

    METRIC_THRESHOLD = 0.75
    researcher_eval_failed = False
    for metric_name, metric_values in eval_results.metrics.items():
        if metric_values["mean"] < METRIC_THRESHOLD:
            print(f"🛑 Researcher Evaluation failed with metric `{metric_name}` below {METRIC_THRESHOLD} threshold.")
            researcher_eval_failed = True
    if researcher_eval_failed:
        exit(1)

評価指標のいずれかの平均値しきい値0.75)を下回るたびに、デプロイは失敗します。

[省略可] Orchestrator の参照なし指標で評価を追加する

オーケストレーター エージェントの場合、インタラクションはより複雑になり、常に単一の「正しい」答えがあるとは限りません。代わりに、参照なし指標のいずれかを使用して一般的な動作を評価します。

  • ハルシネーション: レスポンスを原子単位の主張に分割して、テキスト レスポンスの事実性と整合性をチェックするスコアベースの指標。中間イベントでのツールの使用状況に基づいて、各クレームが根拠のあるものかどうかを確認します。これは、「正確性」は主観的だが「真実性」は交渉の余地がないオープンエンド エージェントにとって重要です。スコアは、ソース コンテンツに基づいてグラウンディングされている主張の割合として計算されます。この場合、オーケストレーター(Content Builder が生成)からの最終レスポンスは、Researcher が Wikipedia 検索ツールを使用して取得したコンテンツに事実に基づいて基づいていることが期待されます。

Orchestrator の評価ロジックを追加します。

    eval_data_orchestrator = os.path.dirname(__file__) + "/eval_data_orchestrator.json"
    metrics=[
        types.RubricMetric.HALLUCINATION,
    ]

    print("🧪 Running Orchestrator Evaluation...")
    eval_results = asyncio.run(evaluate_agent(
        agent_api_server=ORCHESTRATOR_URL,
        agent_name="agent",
        evaluation_data_file=eval_data_orchestrator,
        evaluation_storage_uri=f"gs://{GOOGLE_CLOUD_PROJECT}-agents/evaluation",
        metrics=metrics,
        project_id=GOOGLE_CLOUD_PROJECT,
        location=GOOGLE_CLOUD_REGION
    ))
    print(f"\n🧪 Orchestrator Evaluation results:\n{eval_results}")
    print(f"Evaluation Run ID: {eval_results.run_id}")
    METRIC_THRESHOLD = 0.75
    orchestrator_eval_failed = False
    for metric_name, metric_values in eval_results.metrics.items():
        if metric_values["mean"] < METRIC_THRESHOLD:
            print(f"🛑 Orchestrator Evaluation failed with metric `{metric_name}` below {METRIC_THRESHOLD} threshold.")
            orchestrator_eval_failed = True
    if orchestrator_eval_failed:
        exit(1)

評価データを検査する

evaluator/ ディレクトリを開きます。2 つのデータファイルが表示されます。

  • eval_data_researcher.json: 研究者向けのプロンプトとゴールデン/グラウンド トゥルースの参照。
  • eval_data_orchestrator.json: Orchestrator のプロンプト(Orchestrator の参照なし評価のみを行います)。

通常、各エントリには次のものが含まれます。

  • prompt: エージェントのプロンプト。
  • reference: 理想的な回答(グラウンド トゥルース)(該当する場合)。
  • reference_trajectory: 期待されるツール呼び出しの順序。

6. 評価コードについて

shared/evaluation/evaluate.py を開きます。このモジュールには、評価を実行するためのコアロジックが含まれています。主な関数は evaluate_agent です。

次の手順を実行します。

  1. データ読み込み: ファイルから評価データセット(プロンプトとリファレンス)を読み取ります。
  2. 並列推論: データセットに対してエージェントを並列で実行します。セッションの作成、プロンプトの送信、最終的なレスポンスと中間ツール実行トレースの両方のキャプチャを処理します。
  3. Vertex AI Evaluation: 元の評価データと最終的な回答、中間ツールの実行トレースを統合し、Vertex AI SDK の生成 AI クライアントを使用して結果を Vertex AI Evaluation Service に送信します。このサービスは、構成された指標を実行してエージェントのパフォーマンスを評価します。

最後の手順の重要なポイントは、生成 AI SDK の eval モジュールの create_evaluation_run 関数を呼び出すことです。

evaluation_run = client.evals.create_evaluation_run(
    dataset=agent_dataset_with_inference,
    agent_info=agent_info,
    metrics=metrics,
    dest=evaluation_storage_uri
)

これは、shared/evaluation/evaluate.pyevaluate_agent 関数で行います。

統合された評価データセット、エージェントに関する情報、使用する指標、宛先ストレージ URI を取得します。この関数は、Vertex AI Evaluation Service で評価実行を作成し、評価実行オブジェクトを返します。

Agent Info API

正確な評価を行うには、評価サービスがエージェントの構成(システム指示、説明、利用可能なツール)を把握している必要があります。agent_info パラメータとして create_evaluation_run に渡します。

しかし、この情報をどのように取得すればよいのでしょうか。ADK Service API の一部にします。

shared/adk_app.py を開き、def agent_info を検索します。ADK アプリケーションがヘルパー エンドポイントを公開していることがわかります。

@app.get("/apps/{agent_name}/agent-info")
async def agent_info(agent_name: str) -> typing.Dict[str, typing.Any]:
    # ...
    return {
        "name": agent.name,
        "instruction": str(getattr(agent, "instruction", None)),
        "tool_declarations": tools_dict_list
    }

このエンドポイント(--publish_agent_info フラグで有効)を使用すると、評価スクリプトはエージェントのランタイム構成を動的に取得できます。これは、ツール使用状況を評価する指標にとって重要です。判定モデルは、会話中にエージェントが使用できたツールを具体的に把握していれば、エージェントのツール使用状況をより適切に評価できます。

7. 評価を実行する

評価ツールを実装したので、実行してみましょう。

  1. リポジトリのルートから評価スクリプトを実行します。
    ./evaluate.sh
    
    今後の流れ
    1. 現在の git commit ハッシュを取得します。
    2. deploy.sh を呼び出して、commit ハッシュに基づいてタグ付きのリビジョンをデプロイします。
    3. デプロイされると、evaluator.evaluate_agent が開始されます。
    4. クラウド サービスに対してテストケースを実行すると、進行状況バーが表示されます。
    5. 最後に、結果の概要 JSON を出力します。
    スクリプトの実行時に、次のプロンプトが表示されることがあります。
    Deploying from source requires an Artifact Registry Docker repository to store built containers. A repository named [cloud-run-source-deploy] in region [us-central1] will be created.
    
    Do you want to continue (Y/n)?
    
    <Enter> キーを押して、リポジトリの作成を許可します。
    注: 初回実行時にサービスのデプロイに数分かかることがあります。

8. ノートブックで結果を可視化する

未加工の JSON 出力は読みにくい。Vertex AI SDK の生成 AI クライアントを使用すると、これらの実行を時間の経過とともに追跡できます。結果を可視化するには、Colab ノートブックを使用します。

  1. このリンクを使用して、evaluator/show_evaluation_run.ipynbGoogle Colab で開きます
  2. GOOGLE_CLOUD_PROJECTGOOGLE_CLOUD_REGIONEVAL_RUN_ID 変数をプロジェクト ID、リージョン、実行 ID に設定します。
  1. 依存関係をインストールして認証します。

評価実行を取得して結果を表示する

Vertex AI から評価実行データを取得する必要があります。[評価実行を取得して結果を表示する] の下のセルを見つけ、# TODO 行を次のコードブロックに置き換えます。

from google.genai import types as genai_types
from vertexai import Client

# Initialize SDK
client = Client(
    project=GOOGLE_CLOUD_PROJECT,
    location=GOOGLE_CLOUD_REGION,
    http_options=genai_types.HttpOptions(api_version="v1beta1"),
)

evaluation_run = client.evals.get_evaluation_run(
    name=EVAL_RUN_ID,
    include_evaluation_items=True
)
evaluation_run.show()

結果の解釈

結果を確認する際は、次の点に注意してください。

  1. 回帰と機能:
    • 回帰: 古いテストでスコアが低下しましたか?(良くないため、調査が必要です)。
    • 能力: 新しいテストでスコアは改善されましたか?(よし、進歩だ)。
  2. 失敗の分析: スコアだけを見るのではなく、
    • トレースを確認します。間違ったツールを呼び出したか?出力を解析できませんでしたか?バグを見つける場所です。
    • 裁判官 LLM が提供する説明と判決を確認します。多くの場合、テストが失敗した理由を把握するのに役立ちます。

Pass@1 と Pass@k: 特定のテストを 1 回実行すると、Pass@1 スコアが得られます。エージェントが失敗した場合、非決定論が原因である可能性があります。高度な設定では、各テストを k 回実行する場合があります(例: 5 回)を計算し、pass@k(少なくとも 1 回は成功したか)または pass^k(毎回成功したか)を計算します。これは、多くの指標がすでに内部で行っていることです。たとえば、types.RubricMetric.FINAL_RESPONSE_MATCH(最終レスポンスの一致)は、判定モデル LLM を 5 回呼び出して、最終レスポンスの一致スコアを決定します。

9. 継続的インテグレーションと継続的デプロイ(CI/CD)

本番環境システムでは、エージェントの評価は CI/CD パイプラインの一部として実行する必要があります。この場合は、Cloud Build を選択することをおすすめします。

エージェントのコード リポジトリに push された commit ごとに、評価が他のテストとともに実行されます。テストに合格すると、デプロイはユーザー リクエストの処理に「昇格」できます。失敗した場合、すべてはそのままですが、デベロッパーは何が問題だったかを確認できます。

継続評価

Cloud Build 構成

次に、次の手順を実行する Cloud Run デプロイ構成スクリプトを作成します。

  1. サービスをプライベート リビジョンにデプロイします。
  2. エージェントの評価を実行します。
  3. 評価に合格すると、リビジョンのデプロイが「昇格」して 100% のトラフィックを処理します。

cloudbuild.yaml を作成します。

steps:
- name: gcr.io/google.com/cloudsdktool/google-cloud-cli:latest
  entrypoint: /bin/bash
  args:
      - "-c"
      - |
        if [[ "$_COMMIT_SHORT_HASH" != "" ]]; then
          export COMMIT_SHORT_HASH=$_COMMIT_SHORT_HASH
        else
          export COMMIT_SHORT_HASH=$SHORT_SHA
        fi
        export COMMIT_REVISION_TAG="c-$${COMMIT_SHORT_HASH}"
        echo "Deploying with revision tag: $$COMMIT_REVISION_TAG"
        set -e
        # Install uv and sync dependencies.
        curl -LsSf https://astral.sh/uv/install.sh | sh
        source $$HOME/.local/bin/env
        uv sync

        # Deploy services with the revision tag.
        source ./deploy.sh --revision-tag $$COMMIT_REVISION_TAG --no-redeploy

        # Run evaluation.
        uv run -m evaluator.evaluate_agent
        # If evaluation fails, the deployment will stop here.

        # If evaluation passes, it will continue with promoting the revisions to serve 100% of traffic.
        echo "Promoting revisions $$COMMIT_REVISION_TAG to serve 100% of traffic."
        gcloud run services update-traffic researcher --to-tags $$COMMIT_REVISION_TAG=100 --region $$GOOGLE_CLOUD_REGION --project $$GOOGLE_CLOUD_PROJECT
        gcloud run services update-traffic judge --to-tags $$COMMIT_REVISION_TAG=100 --region $$GOOGLE_CLOUD_REGION --project $$GOOGLE_CLOUD_PROJECT
        gcloud run services update-traffic content-builder --to-tags $$COMMIT_REVISION_TAG=100 --region $$GOOGLE_CLOUD_REGION --project $$GOOGLE_CLOUD_PROJECT
        gcloud run services update-traffic orchestrator --to-tags $$COMMIT_REVISION_TAG=100 --region $$GOOGLE_CLOUD_REGION --project $$GOOGLE_CLOUD_PROJECT
        gcloud run services update-traffic course-creator --to-tags $$COMMIT_REVISION_TAG=100 --region $$GOOGLE_CLOUD_REGION --project $$GOOGLE_CLOUD_PROJECT

options:
  substitutionOption: 'ALLOW_LOOSE'
  defaultLogsBucketBehavior: REGIONAL_USER_OWNED_BUCKET

パイプラインを実行する

最後に、評価パイプラインを実行します。

Cloud Run サービスにリクエストを行う評価パイプラインを実行する前に、複数の権限を持つ個別のサービス アカウントが必要です。これを行うスクリプトを作成して、パイプラインを起動しましょう。

  1. スクリプト run_cloud_build.sh を作成します。
    #!/bin/bash
    
    set -e
    source .env
    
    BUILD_SA_NAME="agent-eval-build-sa"
    BUILD_SA_EMAIL="${BUILD_SA_NAME}@${GOOGLE_CLOUD_PROJECT}.iam.gserviceaccount.com"
    COMMIT_SHORT_HASH=$(git rev-parse --short HEAD)
    
    # Creating service account for build, if it doesn't exist
    if ! gcloud iam service-accounts describe "${BUILD_SA_EMAIL}" --project "${GOOGLE_CLOUD_PROJECT}" &> /dev/null; then
        echo "Creating service account ${BUILD_SA_NAME} for Cloud Build."
        gcloud iam service-accounts create ${BUILD_SA_NAME} --project "${GOOGLE_CLOUD_PROJECT}" --display-name "Agent Build Service Account"
    
        echo "Granting roles to service account ${BUILD_SA_NAME}."
        ROLES=(
            "roles/cloudbuild.builds.builder"
            "roles/run.admin"
            "roles/run.invoker"
            "roles/iam.serviceAccountOpenIdTokenCreator"
            "roles/iam.serviceAccountUser"
            "roles/serviceusage.serviceUsageAdmin"
            "roles/serviceusage.serviceUsageConsumer"
            "roles/aiplatform.user"
        )
    
        # Loop through and grant each role
        for ROLE in "${ROLES[@]}"; do
            gcloud projects add-iam-policy-binding "$GOOGLE_CLOUD_PROJECT" \
                --member="serviceAccount:$BUILD_SA_EMAIL" \
                --role="$ROLE"
        done
    fi
    
    gcloud builds submit --config cloudbuild.yaml \
        --service-account="projects/${GOOGLE_CLOUD_PROJECT}/serviceAccounts/${BUILD_SA_EMAIL}" \
        --machine-type=e2-highcpu-32 \
        --timeout=120m \
        --substitutions _COMMIT_SHORT_HASH=$COMMIT_SHORT_HASH,_GOOGLE_CLOUD_PROJECT=$GOOGLE_CLOUD_PROJECT,_GOOGLE_CLOUD_LOCATION=$GOOGLE_CLOUD_LOCATION,_GOOGLE_CLOUD_REGION=$GOOGLE_CLOUD_REGION
    
    
    このスクリプトでは、以下の処理が行われます。
    • 専用のサービス アカウント agent-eval-build-sa を作成します。
    • 必要なロール(roles/run.adminroles/aiplatform.user など)を付与します。*. Cloud Build にビルドを送信します。
  2. パイプラインを実行します。
    chmod +x run_cloud_build.sh
    ./run_cloud_build.sh
    

ビルドの進行状況はターミナルで確認できます。また、リンクをクリックして Cloud コンソールに移動することもできます。

: 実際の本番環境では、Cloud Build トリガーを設定して、すべての git push で自動的に実行するようにします。ワークフローは同じです。トリガーが cloudbuild.yaml を実行し、すべての commit が評価されます。

10. まとめ

これで、評価パイプラインが正常に構築されました。

  • デプロイ: リビジョン タグと git commit ハッシュを使用して、本番環境のデプロイに影響を与えることなく、エージェントを実際の環境に安全にデプロイしてテストしました。
  • 評価: 評価指標を定義し、Vertex AI Gen AI Evaluation Service を使用して評価プロセスを自動化しました。
  • 分析: Colab ノートブックを使用して評価結果を可視化し、エージェントを改善しました。
  • ロールアウト: Cloud Build を使用して評価パイプラインを自動的に実行し、最適なリビジョンを昇格させてトラフィックの 100% を処理します。

このサイクル(コードの編集 -> タグのデプロイ -> 評価とテストの実行 -> 分析 -> ロールアウト -> 繰り返し)は、本番環境グレードのエージェント エンジニアリングの中核です。