Vertex AI Agent EngineとGen AI Evaluation ServiceによるAgentの品質評価
はじめに
機械学習エンジニアをしています、原です。
Google Developer Experts(Google Cloud/ AI)として選出いただき、活動しています。
今回は、Google ADKで開発したAgentをVertex AI Agent Engineにデプロイし、Vertex AI Gen AI Evaluation Serviceを使って出力品質を評価する方法について紹介します。
Google ADKを使ってAgent開発に取り組んでいる方の参考になれば幸いです。
Vertex AI Gen AI Evaluation Serviceとは
Vertex AI Gen AI Evaluation Serviceは一言で言うと、LLMを活用しているシステムの品質評価するためのサービスです。 公式ドキュメントでは、以下のように紹介されています。
Gen AI Evaluation Serviceは、生成AIモデルの客観的でデータドリブンな評価を行うためのエンタープライズグレードのツールを提供します。モデルの移行、プロンプトの編集、ファインチューニングなど、さまざまな開発タスクをサポートし、情報を提供します。
私も過去に、Evaluation Serviceを使ってLLMの出力評価を行う記事を執筆しています。機能紹介に加えて、実験管理や評価の重要性、LLM-as-a-Judgeなどについても触れています。LLMの出力評価にまだ詳しくない方はイメージを掴めると思いますので、ぜひご覧ください。
ユースケース
Gen AI Evaluation Serviceを使用すると、特定のタスクに対するモデルの出力品質を評価できます。公式ドキュメントでは、以下のようなユースケースが紹介されています。
- モデルの移行: モデルバージョンを比較して動作の違いを把握し、それに応じてプロンプトと設定を調整します。
- 最適なモデルの特定: 新しい生成AIアプリケーションを構築する際、評価は適切なモデルを選択し、その結果を把握するのに役立ちます。
- プロンプトの改善: モデルを選択した後、プロンプトのエンジニアリングを行いながら、プロンプトの変更の影響を評価するために評価を使用します。
- モデルのファインチューニング: ファインチューニングしたモデルのパフォーマンスとベースモデルのパフォーマンスを比較し、改善を測定します。
- エージェントの評価: RAGなどのエージェントシステムや、自律的にツールを呼び出してタスクを実行するエージェントを評価します。
これらのユースケースに対して、「なんとなく良さそう」という感覚で判断するのではなく、データドリブンに定量的・客観的な判断をするためのサービスです。
対応している評価指標について
Gen AI Evaluation Serviceでは大きく3つのカテゴリの指標を扱うことができます。
その中でも、ルーブリックベースの指標には組み込みの評価指標が用意されています。これを用いることで、自身で評価指標を作成しなくとも、すぐに評価を始めることができます。
| カテゴリ | 説明 | ユースケース |
|---|---|---|
| ルーブリックベースの指標 | ルーブリック(評価基準)に基づいてLLM-as-a-Judgeで回答を評価 | きめ細かい説明可能なフィードバックが必要な場合 |
| 計算ベースの指標 | グランドトゥルースを使用して決定的アルゴリズムで回答を評価 | 正解データが明確に定義されている場合 |
| カスタム関数指標 | Python関数を使用して独自の指標を定義して評価 | 上記の指標では対応できない、独自のビジネスロジックに基づく評価が必要な場合など |
本記事では、Agent評価で主に使用されるルーブリックベースの指標に焦点を当てて解説します。
ルーブリックベースの指標では、以下のようなパラメータが使用されます。これらは全てがどの指標でも必要なわけではなく、指標によって必須・オプションが異なります。
-
prompt: ユーザーからの入力プロンプト -
response: Agentの最終レスポンス -
reference: グランドトゥルース -
developer_instruction: エージェント開発者からの指示(Agentのinstructionに相当) -
tool_declarations: ツールの宣言情報 -
intermediate_events: 関数呼び出しとそのレスポンスを含む中間イベント -
rubric_groups: 事前に生成済みのルーブリック -
evaluate_intermediate_nl_responses: 中間テキストレスポンスも評価するかどうかのフラグ
評価処理は内部的にGemini 2.5 FlashやGemini 2.5 Proへの複数回の呼び出しで実行されます。
Adaptive RubricsとStatic Rubrics
ルーブリックベースの指標は、評価基準の生成方法によって2種類のタイプがあります。
| タイプ | 説明 | ユースケース |
|---|---|---|
| Adaptive Rubrics | 各評価対象のサンプルに対して、LLMを用いて評価基準を動的に生成 | サンプルごとに柔軟に評価基準を定めたい場合 |
| Static Rubrics | あらかじめ定義された固定の基準で評価。全てのサンプルに対して同じルーブリックを適用 | 一貫した基準で評価する必要がある場合 |
Adaptive Rubricsの具体例として、公式ドキュメントでは以下のような例が紹介されています。理解しやすかったので引用します。
まずユーザープロンプトで評価すべきポイントをLLMを用いて分解し、ルーブリックに落とし込みます。
ユーザーによるプロンプト: 再生可能エネルギーに関する記事の4文の要約を、楽観的なトーンで記述してください。
このプロンプトでは、ルーブリックの生成ステップで次のルーブリックが生成される可能性があります。
- ルーブリック 1: 回答は、提供された記事の要約になっている。
- ルーブリック 2: 回答に 4 つの文が含まれている。
- ルーブリック 3: 楽観的なトーンを維持している。
続けてその基準に対してLLM-as-a-Judgeを行うイメージです。
モデルは次のような回答を生成する可能性があります。
この記事では、太陽光発電と風力発電の著しい成長が強調されています。これらの技術革新により、クリーンエネルギーがより手頃な価格になっています。再生可能エネルギーの未来は明るいでしょう。ただし、報告書では、電力網のインフラに関する課題も指摘されています。
ルーブリックの検証では、Gen AI Evaluation Service が各ルーブリックに対して回答を評価します。
- ルーブリック 1: 回答は、提供された記事の要約になっている。
- 判定: Pass
- 理由: 回答は要点を正確に要約しています。
- ルーブリック 2: 回答に 4 つの文が含まれている。
- 判定: Pass
- 理由: 回答は 4 つの異なる文で構成されています。
- ルーブリック 3: 楽観的なトーンを維持している。
- 判定: Fail
- 理由: 最後の文で否定的な点が導入されており、楽観的なトーンが損なわれています。
例では単純にユーザープロンプトのみをルーブリック作成に用いていますが、Agent専用の評価指標においてはinstructionやツールの内容などもルーブリックの生成に使用されるため、これらを適切に記述することも重要になってきます。
また、Static Rubricsに関しては指標をカスタマイズすることもできます。
これによって自身のサービスドメインに最適化した評価指標を作成できます。
Agent向けのルーブリックベース指標
単一のLLM評価では、プロンプトに対する最終的な出力の品質を評価していました。これに加えてAgentでは、さまざまなツールやサブエージェントを組み合わせてタスクを実行します。そのため、Agent評価では最終回答の品質に加えて、どのツールを、どの順序で、どのパラメータで使用したかというプロセス全体を評価する必要があります。
Gen AI Evaluation ServiceにおいてもAgent向けのルーブリックベース指標は、この考え方に基づいて設計されています。最終回答を評価する指標であっても、ツールの使用状況を考慮した評価が行われます。
| 指標名 | タイプ | 説明 | 主な入力 |
|---|---|---|---|
| FINAL_RESPONSE_MATCH | Static | グランドトゥルースと最終応答を比較し、一致度を評価 |
prompt, response, reference
|
| FINAL_RESPONSE_REFERENCE_FREE | Adaptive | グランドトゥルースを使用せずに最終応答を評価。事前に生成したルーブリックを使用 |
prompt, response, rubric_groups
|
| FINAL_RESPONSE_QUALITY | Adaptive | Agentの構成(instructionとツール宣言)とユーザープロンプトを元に基準を自動生成し、最終回答を評価 |
prompt, response, developer_instruction, tool_declarations, intermediate_events
|
| HALLUCINATION | Static | 最終応答での主張を分解し、ツール使用状況に基づいて事実性を検証 |
response, developer_instruction, tool_declarations, intermediate_events, evaluate_intermediate_nl_responses
|
| TOOL_USE_QUALITY | Adaptive | 適切なツール選択・パラメータ・操作順序で実行されているかを評価 |
prompt, developer_instruction, tool_declarations, intermediate_events
|
表を見るとわかるように、HALLUCINATIONはツール呼び出しの中間イベント(intermediate_events)を利用しています。また、TOOL_USE_QUALITYはツール選択やパラメータの正確性を直接評価します。このように、Agent向け指標は単一のLLM評価とは異なり、ツールの使用に着目した設計となっています。
ハンズオン
それでは、Google ADKを用いたAgentの作成、Agent Engineへのデプロイ、そしてGen AI Evaluation Serviceでの評価を進めていきます。
1. 環境構築
まず、必要なライブラリをインストールします。パッケージマネージャーには uv を使用します。Pythonのバージョンは3.12を使用しています。
uv add "google-cloud-aiplatform[adk,agent-engines,evaluation]>=1.112"
uv add "pandas>=2.3.3"
uv add "jupyter>=1.1.1"
これ以降のコードはNotebookで実行されることを想定しています。順を追って解説していきますので、お手元でNotebookを用意できる方は、ぜひ試してみてください。
次に、SDKの初期化を設定します。BUCKET_NAMEは評価結果が保存されるGCSのバケット名です。事前にGCSバケットを作成しておきましょう。
PROJECT_ID="your-gcp-project-id"
LOCATION="us-central1"
BUCKET_NAME="your-bucket-name"
import vertexai
from vertexai import Client
from google.genai import types as genai_types
GCS_DEST = f"gs://{BUCKET_NAME}/adk-eval-sample"
vertexai.init(
project=PROJECT_ID,
location=LOCATION,
)
client = Client(
project=PROJECT_ID,
location=LOCATION,
http_options=genai_types.HttpOptions(api_version="v1beta1"),
)
2. Agentの作成
ここでは、評価対象となるAgentをADKを使用して作成します。今回は、旅行会社向けのプラン提案・予約機能を持つAgentを作成します。このAgentは、旅行先の検索、予算に応じたプランの取得、旅行の予約という3つのツールを備えています。なお、本来であれば外部APIやMCPサーバーと連携して実際のデータを取得するのが望ましいですが、ここでは評価機能のデモを目的としているため、モックデータを返す簡易的な実装としています。
以下のコードを実行してAgentを作成しましょう。
from google.adk.agents import LlmAgent
from google.genai import types
from google.adk.planners import BuiltInPlanner
# Define Agent Tools
def search_destination(keyword: str):
"""
キーワードから旅行先を検索するサンプル。
"""
keywords = ["ショッピング", "グルメ", "夜景", "東京"]
if any(kw in keyword for kw in keywords):
return {"destinations": [{"name": "東京", "id": "D-TOKYO"}]}
return {"destinations": []}
def get_budget_plan(destination_id: str, budget: int):
"""
予算に応じたプランを返すサンプル。
"""
if budget < 50000:
return {
"plan": {
"id": "P-TOKYO-ECO-001",
"title": "東京 2日間 エコノミープラン(ショッピング・グルメ・夜景)",
"days": 2,
"highlights": [
"浅草エリアでの食べ歩き(グルメ)",
"上野・秋葉原周辺でのショッピング",
"お台場エリアでの夜景散策"
]
}
}
else:
return {
"plan": {
"id": "P-TOKYO-PREMIUM-001",
"title": "東京 2日間 プレミアムプラン(ショッピング・グルメ・夜景)",
"days": 2,
"highlights": [
"銀座・表参道でのブランドショッピング",
"ミシュラン掲載店や人気レストランでのディナー(グルメ)",
"高層ホテルラウンジでの夜景鑑賞"
]
}
}
def book_trip(destination_id: str, plan_id: str, start_date: str, num_people: int):
"""
予約を作成するサンプル。
"""
reservation_id = f"R-{plan_id}-{start_date.replace('-', '')}-N{num_people}"
return {
"reservation": {
"reservation_id": reservation_id,
"destination_id": destination_id,
"plan_id": plan_id,
"start_date": start_date,
"num_people": num_people,
"status": "CONFIRMED",
"message": "ご予約が完了しました。"
}
}
# Define Root Agent
root_agent = LlmAgent(
model="gemini-2.5-flash",
name="travel_company_agent",
instruction=(
"あなたは旅行会社のエージェントです。"
"下記のツールを使用してお客様からの要望に応えましょう。"
"- お客様の希望(ショッピングしたい、グルメを楽しみたい、夜景を見たいなど)から場所を検索するには search_destination を必ず使用してください。"
"- プランを検索するには get_budget_plan を必ず使用してください"
"- 予約を確定するには、book_trip を必ず使用してください。"
),
tools=[search_destination, get_budget_plan, book_trip],
planner=BuiltInPlanner(
thinking_config=types.ThinkingConfig(
include_thoughts=False,
thinking_budget=5000,
)
)
)
3. Agent Engine へのデプロイ
次に、作成したAgentをAgent Engineにデプロイします。
下記のコードを実行してデプロイを行いましょう。
configパラメータでは、Agent Engineのリソース設定を行えます。resource_limitsでCPUとメモリを指定し、min_instances、max_instances、container_concurrencyでスケーリングの設定を行います。
from vertexai import agent_engines
def deploy_adk_agent(root_agent):
app = agent_engines.AdkApp(
agent=root_agent,
)
remote_app = client.agent_engines.create(
agent=app,
config = {
"staging_bucket": f"gs://{BUCKET_NAME}",
"requirements": ['google-cloud-aiplatform[adk,agent_engines]'],
"env_vars": {"GOOGLE_CLOUD_AGENT_ENGINE_ENABLE_TELEMETRY": "true", "OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT": "true"},
"display_name": "travel_company_agent",
"resource_limits": {"cpu": "4", "memory": "8Gi"},
"min_instances": 0,
"max_instances": 1,
"container_concurrency": 9, #推奨値:2×CPU+1。デフォルトは9
},
)
return remote_app
agent_engine = deploy_adk_agent(root_agent)
agent_engine_resource_name = agent_engine.api_resource.name
実行するとデプロイが完了するまでに5分程度かかりますので、しばらく待ちましょう。
完了したら、Agent Engineのコンソール画面で確認しましょう。下記のように、先ほど作成したAgentがデプロイされていることが確認できればOKです。

また、リソースの「名前」をクリックすると、各種メトリクスやトレース、セッション、プレイグラウンドでの動作確認、メモリの管理、評価などが行えます。ADK Webと同様のことができるイメージです。
試しに、デプロイした旅行予約Agentに「夜景が綺麗な場所で予算10万円の場合の旅行プランを教えて」と問いかけると、しっかりと目的地の検索とプラン検索のツールを使用した上で、適切な回答を返してくれました。

評価のタブにはこれから実行する評価の履歴が表示されていきます。
「+新しい評価」を押すと、ステップバイステップで実行可能なノートブックがColab Enterpriseで開きます。こちらから評価を実行することも可能です。今回は、カスタマイズの柔軟性も考慮して別途評価用のコードを記載して進めていきましょう。

4. 評価サンプルの用意
次に、評価用のデータを用意していきます。Agentに対してさまざまなプロンプトを入力し、その応答を評価するためのテストケースを定義します。
下記のコードを実行すると、評価用のDataFrameが作成されます。今回は4つのサンプルを用意しました。1個目は旅行先検索ツールのみを使用するケースです。2,3個目は旅行先の検索に加えてプランの取得を行うケースです。4個目は予約までを行うケースです。
import pandas as pd
from vertexai import types
session_inputs = types.evals.SessionInput(
user_id="test_user_001",
state={},
)
agent_prompts = [
"夜景がきれいな旅行先を教えて",
"東京に旅行に行きたいです。予算は4万円以下で考えているんだけど、どんなプランがある?",
"東京旅行で予算10万円の場合のプランを見せて。",
"東京旅行を一人当たり予算5万円で2人分予約して。2025-06-10出発でお願いします。"
]
agent_dataset = pd.DataFrame({
"prompt": agent_prompts,
"session_inputs": [session_inputs] * len(agent_prompts),
})
agent_dataset.head()

5. Agentからの応答の生成
次に、各サンプルを入力したときのAgentからの応答を取得します。
client.evals.run_inferenceを実行すると、プログレスバーが表示され、各プロンプト(ユーザーからの入力に該当)に対するAgentの応答が生成されます。
agent_dataset_with_inference = client.evals.run_inference(
agent=agent_engine_resource_name,
src=agent_dataset,
)
生成が完了したら、モデルの出力結果を元のプロンプトや参照データなどと並べてDataFrameで確認できます。今回は、先ほど準備したpromptに加えて、セッション情報であるsession_inputs、発生したツール実行などのイベントであるintermediate_events、そして最終的な応答であるresponseが含まれています。
agent_dataset_with_inference.show()

6. 評価の実行
いよいよ、評価の実行です。
まず、ヘルパー関数を使用して、先ほど定義・デプロイしたAgentの情報を取得します。この情報にはAgent名、instruction、ツール宣言などが含まれています。
agent_info = types.evals.AgentInfo.load_from_agent(
root_agent,
agent_engine_resource_name
)
print(agent_info)
下記が取得できるAgentの情報の例です。
agent_resource_name='projects/XXXXXXXXXX/locations/us-central1/reasoningEngines/XXXXXXXXXXXXXXXXXXX' name='travel_company_agent' instruction='あなたは旅行会社のエージェントです。下記のツールを使用してお客様からの要望に応えましょう。- お客様の希望(ショッピングしたい、グルメを楽しみたい、夜景を見たいなど)から場所を検索するには search_destination を必ず使用してください。- プランを検索するには get_budget_plan を必ず使用してください- 予約を確定するには、book_trip を必ず使用してください。' description='' tool_declarations=[Tool(
function_declarations=[
FunctionDeclaration(
description='キーワードから旅行先を検索するサンプル。',
name='search_destination',
parameters=Schema(
properties={
'keyword': Schema(
type=<Type.STRING: 'STRING'>
)
},
required=[
'keyword',
],
type=<Type.OBJECT: 'OBJECT'>
)
),
]
), Tool(
function_declarations=[
FunctionDeclaration(
description='予算に応じたプランを返すサンプル。',
name='get_budget_plan',
parameters=Schema(
properties={
'budget': Schema(
type=<Type.INTEGER: 'INTEGER'>
),
'destination_id': Schema(
type=<Type.STRING: 'STRING'>
)
},
required=[
'destination_id',
'budget',
],
type=<Type.OBJECT: 'OBJECT'>
)
),
]
), Tool(
function_declarations=[
FunctionDeclaration(
description='予約を作成するサンプル。',
name='book_trip',
parameters=Schema(
properties={
'destination_id': Schema(
type=<Type.STRING: 'STRING'>
),
'num_people': Schema(
type=<Type.INTEGER: 'INTEGER'>
),
'plan_id': Schema(
type=<Type.STRING: 'STRING'>
),
'start_date': Schema(
type=<Type.STRING: 'STRING'>
)
},
required=[
'destination_id',
'plan_id',
'start_date',
'num_people',
],
type=<Type.OBJECT: 'OBJECT'>
)
),
]
)]
続いて、取得した評価用データセット・Agentの情報に加えて、評価指標を選択して、モデルの応答評価を実行します。
今回は、Agent評価専用の組み込み済指標の中から、FINAL_RESPONSE_QUALITY、TOOL_USE_QUALITY、HALLUCINATIONを選択しました。これに加えて、Agent以外の評価でも利用可能なSAFETYとGENERAL_QUALITYを使用して評価を実行します。
SAFETY はヘイトスピーチや有害なコンテンツの生成を防ぐための安全性ガイドラインに違反しているかどうかを評価する指標です。また、GENERAL_QUALITY は入力プロンプトに応じてさまざまなタスクをカバーする一連のルーブリックを作成する指標です。これには、guidelines パラメータを使用することで、重要な基準を指定できます。
全指標の詳細・最新の指標については下記ををご覧ください。
下記が評価実行のコード例です。
evaluation_run = client.evals.create_evaluation_run(
dataset=agent_dataset_with_inference,
agent_info=agent_info,
metrics=[
types.RubricMetric.FINAL_RESPONSE_QUALITY,
types.RubricMetric.TOOL_USE_QUALITY,
types.RubricMetric.HALLUCINATION,
types.RubricMetric.SAFETY,
types.RubricMetric.GENERAL_QUALITY(
metric_spec_parameters={
"guidelines": "常に丁寧かつ専門的な対応を心がけ、旅行プランのご提案やご予約手続きに専念し、旅行以外の専門的な助言は行わない"
})
],
dest=GCS_DEST,
display_name="travel_company_agent_eval"
)
7. 評価結果の確認
最後に、Vertex AI SDKを使用して、評価結果を確認しましょう。
評価実行結果を取得して可視化するには、.show()メソッドを呼び出します。実行すると評価レポートが作成されます。
evaluation_run = client.evals.get_evaluation_run(
name=evaluation_run.name,
include_evaluation_items=True
)
evaluation_run.show()
作成された評価レポートを見ていきましょう。
まず、Evaluation Reportのセクションでは、算出された指標のサマリーと、評価対象となったAgentの情報(InstructionやToolなど)を確認できます。
サマリーを確認すると、general_quality_v1以外の指標では満点を獲得できていますね。

加えて、Detailed Resultsのセクションでは、各ケースごとの入出力とツール使用時のパラメータを確認できます。

このセクションの下部にあるMetricsのサブセクションでは、各評価指標で作成されたルーブリックとそのスコア、評価理由などを確認できます。

では、失敗していたgeneral_quality_v1のルーブリックである「The response includes a breakdown or estimate of costs for the suggested plan components.」の結果を見てみましょう。

日本語にすると下記のようになります。
「提案されたプランの構成要素について、費用の内訳または見積もりが回答に含まれている」
評価されたルーブリック:
内容:
特性:提案された計画要素に対する費用の内訳または見積もりが含まれている。
タイプ:オプションコンテンツ:費用見積もり
重要度:中
理由:
回答には、提案された旅行計画のどの部分についても、具体的な費用の見積もりや内訳が記載されていません。
理由に加えて、重要度やタイプなども出力されています。重要度は複数のケースが失敗した際に、対応の優先順位をつけるのに便利そうです。
理由を見てみると、「具体的な費用の見積もりや内訳が記載されていない」と記載があります。確かに具体的な費用や内訳があった方が親切そうです。ただし、今回は具体的な費用や内訳をツールから返却しない仕様で実装をしたので、問題はありません。
もし今回のように仕様上問題がないのであれば、Agentのinstruction(システムプロンプト)に「費用や内訳は出力しない」と記載することを検討してもよいでしょう。これにより、LLMのハルシネーションによって、根拠のない数値をユーザーに返す可能性を軽減できます。
このように、評価を通してプロンプトやツールを改善するための糸口を見つけることで、Agentのinstruction改善ループを回すことができます。
Colab Enterpriseからの実験結果の確認
なお、今回のハンズオンのようにローカルで実験結果を確認できるだけでなく、結果確認用のNotebookがColab Enterpriseで用意されています。これは、Agent Engineのコンソール画面から遷移できます。評価結果をAgent EngineにデプロイしたAgentと統合して管理できるのは利点だと感じました。


評価時のポイント
今回サンプルコードを作成するにあたり、developer_instructionを必要とする指標を正しく評価するためには、Agentのプロンプトに指示やツールの利用基準を正確に記述することが重要だと感じました。これは、ルーブリックを生成する際にAgentの目的や使用するツールが考慮されているためだと思われます。
instructionが曖昧であると、評価モデルが適切なルーブリックを生成できず、正確な評価が困難になることがありました。そのため、正しく評価できるように、Agentのプロンプトで指示やツールの利用基準を丁寧に設定することをお勧めします。これはAgentの品質向上にもつながる重要なポイントです。
終わりに
今回は、Vertex AI Agent EngineとGen AI Evaluation Serviceを組み合わせて、ADKで構築したAgentの品質を評価する方法を紹介しました。
Agent開発においては、柔軟性を活かしつつ、意図した動作を担保するのは容易ではありません。Gen AI Evaluation Serviceに組み込み済の指標を使えば、評価指標を自前で設計・実装せずにAgentの評価を始めることができます。
Adaptive Rubricsがユーザープロンプトやinstructionの内容から評価基準を動的に生成し、最終回答の品質だけでなくツール使用の適切さまで評価してくれます。これにより、今回の例で示したように、評価結果からinstructionの改善点を発見し、Agentの品質向上ループを回すことができます。
ぜひ皆さんもAgent EngineとGen AI Evaluation Serviceを活用して、信頼性の高いAgent開発に取り組んでみてください!
参考資料
Discussion