ADK 向け BigQuery Agent Analytics プラグイン¶
バージョン要件
auto-schema-upgrade、tool provenance 追跡、HITL イベントトレーシングを含むこのドキュメントの機能を完全に利用するには、ADK Python バージョン 1.26.0 以上を使用してください。
BigQuery Agent Analytics プラグインは、Agent Development Kit (ADK) に対して詳細なエージェント動作分析のための堅牢なソリューションを提供し、ADK を大きく強化します。ADK プラグインアーキテクチャと BigQuery Storage Write API を使って重要な運用イベントを Google BigQuery テーブルへ直接キャプチャし記録することで、デバッグ、リアルタイム監視、包括的なオフライン性能評価のための高度な機能を提供します。
バージョン 1.26.0 では、Auto Schema Upgrade (既存テーブルへ新しい列を安全に追加)、Tool Provenance 追跡 (LOCAL, MCP, SUB_AGENT, A2A, TRANSFER_AGENT)、および Human-in-the-Loop 連携のための HITL Event Tracing が追加されました。バージョン 1.27.0 では、Automatic View Creation(フラットでクエリしやすいイベントビューの生成)が追加されました。
プレビュー リリース
BigQuery Agent Analytics プラグインはプレビュー リリースです。詳細は ローンチステージの説明 を参照してください。
BigQuery Storage Write API
この機能は有料サービスである BigQuery Storage Write API を使用します。料金については BigQuery ドキュメント を参照してください。
ユースケース¶
- エージェント ワークフローのデバッグと分析: 幅広い プラグイン ライフサイクル イベント (LLM 呼び出し、ツール使用) と エージェントが生成したイベント (ユーザー入力、モデル応答) を、よく定義されたスキーマへ記録します。
- 大規模分析とデバッグ: ロギング処理は Storage Write API を使って非同期に実行されるため、高スループットと低レイテンシを両立できます。
- マルチモーダル分析: テキスト、画像、その他の modality を記録・分析できます。大きなファイルは GCS へオフロードされ、Object Table 経由で BigQuery ML から利用できます。
- 分散トレーシング:
trace_id,span_idを使う OpenTelemetry 形式のトレーシングを標準でサポートし、エージェント実行フローを可視化できます。 - Tool Provenance: 各ツール呼び出しの出自 (ローカル関数、MCP サーバー、サブエージェント、A2A リモートエージェント、transfer agent) を追跡します。
- Human-in-the-Loop (HITL) トレーシング: 資格情報要求、確認プロンプト、ユーザー入力要求のための専用イベントタイプを提供します。
- クエリ可能なイベントビュー: フラットなイベントタイプ別 BigQuery ビュー(例:
v_llm_request,v_tool_completed)を自動作成し、JSON ペイロードデータの展開を通じて下流分析を簡素化します。
記録されるエージェントイベントデータは ADK のイベントタイプによって異なります。詳細は イベントタイプとペイロード を参照してください。
前提条件¶
- BigQuery API が有効な Google Cloud プロジェクト
- BigQuery データセット: プラグインを使う前にログテーブルを格納するデータセットを作成します。テーブルが存在しない場合、プラグインはそのデータセット内に必要なイベントテーブルを自動作成します。
- Google Cloud Storage バケット (任意): マルチモーダルコンテンツ (画像、音声など) を記録する場合は、大きなファイルをオフロードするために GCS バケットの作成を推奨します。
- 認証
- ローカル:
gcloud auth application-default loginを実行 - クラウド: サービスアカウントに必要な権限があることを確認
- ローカル:
IAM 権限¶
エージェントが正しく動作するには、エージェントを実行するプリンシパル (サービスアカウントやユーザーアカウントなど) に次の Google Cloud ロールが必要です。
roles/bigquery.jobUser: プロジェクトレベルで BigQuery クエリを実行するための権限roles/bigquery.dataEditor: テーブルレベルでログ / イベントデータを書き込むための権限- GCS オフロードを使う場合: 対象バケットに対する
roles/storage.objectCreatorとroles/storage.objectViewer
エージェントで使用¶
BigQuery Agent Analytics プラグインは、ADK エージェントの App オブジェクトへ設定して登録することで利用します。次の例は、GCS オフロードを含むこのプラグイン利用エージェントの実装例です。
# my_bq_agent/agent.py
import os
import google.auth
from google.adk.apps import App
from google.adk.plugins.bigquery_agent_analytics_plugin import BigQueryAgentAnalyticsPlugin, BigQueryLoggerConfig
from google.adk.agents import Agent
from google.adk.models.google_llm import Gemini
from google.adk.tools.bigquery import BigQueryToolset, BigQueryCredentialsConfig
# --- OpenTelemetry TracerProvider Setup (Optional) ---
# ADK includes OpenTelemetry as a core dependency.
# Configuring a TracerProvider enables full distributed tracing
# (populates trace_id, span_id with standard OTel identifiers).
# If no TracerProvider is configured, the plugin falls back to internal
# UUIDs for span correlation while still preserving the parent-child hierarchy.
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
trace.set_tracer_provider(TracerProvider())
# --- Configuration ---
PROJECT_ID = os.environ.get("GOOGLE_CLOUD_PROJECT", "your-gcp-project-id")
DATASET_ID = os.environ.get("BIG_QUERY_DATASET_ID", "your-big-query-dataset-id")
LOCATION = os.environ.get("GOOGLE_CLOUD_LOCATION", "US") # default location is US in the plugin
GCS_BUCKET = os.environ.get("GCS_BUCKET_NAME", "your-gcs-bucket-name") # Optional
if PROJECT_ID == "your-gcp-project-id":
raise ValueError("Please set GOOGLE_CLOUD_PROJECT or update the code.")
# --- CRITICAL: Set environment variables BEFORE Gemini instantiation ---
os.environ['GOOGLE_CLOUD_PROJECT'] = PROJECT_ID
os.environ['GOOGLE_CLOUD_LOCATION'] = LOCATION
os.environ['GOOGLE_GENAI_USE_VERTEXAI'] = 'True'
# --- Initialize the Plugin with Config ---
bq_config = BigQueryLoggerConfig(
enabled=True,
gcs_bucket_name=GCS_BUCKET, # Enable GCS offloading for multimodal content
log_multi_modal_content=True,
max_content_length=500 * 1024, # 500 KB limit for inline text
batch_size=1, # Default is 1 for low latency, increase for high throughput
shutdown_timeout=10.0
)
bq_logging_plugin = BigQueryAgentAnalyticsPlugin(
project_id=PROJECT_ID,
dataset_id=DATASET_ID,
table_id="agent_events", # default table name is agent_events
config=bq_config,
location=LOCATION
)
# --- Initialize Tools and Model ---
credentials, _ = google.auth.default(scopes=["https://www.googleapis.com/auth/cloud-platform"])
bigquery_toolset = BigQueryToolset(
credentials_config=BigQueryCredentialsConfig(credentials=credentials)
)
llm = Gemini(model="gemini-2.5-flash")
root_agent = Agent(
model=llm,
name='my_bq_agent',
instruction="You are a helpful assistant with access to BigQuery tools.",
tools=[bigquery_toolset]
)
# --- Create the App ---
app = App(
name="my_bq_agent",
root_agent=root_agent,
plugins=[bq_logging_plugin],
)
エージェントの実行とテスト¶
チャット インターフェース経由でエージェントを実行し、"tell me what you can do" や "List datasets in my cloud project <your-gcp-project-id> " のようなリクエストをいくつか送ってプラグインをテストします。これらの操作により、Google Cloud プロジェクトの BigQuery インスタンスにイベントが記録されます。イベントが処理された後は、BigQuery Console で次のクエリを使ってデータを確認できます。
SELECT timestamp, event_type, content
FROM `your-gcp-project-id.your-big-query-dataset-id.agent_events`
ORDER BY timestamp DESC
LIMIT 20;
トレーシングと可観測性¶
このプラグインは分散トレーシングのために OpenTelemetry をサポートします。OpenTelemetry は ADK のコア依存関係に含まれているため、常に利用可能です。
- 自動 Span 管理: プラグインは、エージェント実行、LLM 呼び出し、ツール実行に対する span を自動生成します。
- OpenTelemetry 統合: 上の例のように
TracerProviderが設定されている場合、プラグインは有効な OTel span を使ってtrace_id,span_id,parent_span_idを標準 OTel 識別子で埋めます。これにより、分散システム内の他サービスとエージェントログを相関させられます。 - Fallback メカニズム:
TracerProviderが設定されていない場合 (つまりデフォルトの no-op provider のみが有効な場合)、プラグインは内部 UUID ベースの span 生成へ自動でフォールバックし、invocation_idを trace ID として使います。そのため、OTelTracerProviderを設定していなくても、BigQuery ログ内の親子階層 (Agent -> Span -> Tool/LLM) は常に維持されます。
構成オプション¶
BigQueryLoggerConfig を使ってプラグインをカスタマイズできます。
enabled(bool, デフォルト:True): プラグインが BigQuery テーブルへエージェントデータを記録しないようにするにはFalseに設定します。table_id(str, デフォルト:"agent_events"): データセット内の BigQuery テーブル ID です。BigQueryAgentAnalyticsPluginコンストラクタのtable_id引数でも上書きでき、そちらが優先されます。clustering_fields(List[str], デフォルト:["event_type", "agent", "user_id"]): テーブルを自動作成する際にクラスタリングに使用するフィールドです。gcs_bucket_name(Optional[str], デフォルト:None): 大きなコンテンツ (画像、blob、長文テキスト) をオフロードする GCS バケット名です。指定しない場合、大きなコンテンツは切り詰められるかプレースホルダーに置き換えられることがあります。connection_id(Optional[str], デフォルト:None):ObjectRef列の authorizer として使う BigQuery connection ID (例:us.my-connection) です。BigQuery ML でObjectRefを使う場合に必要です。max_content_length(int, デフォルト:500 * 1024): BigQuery に inline で保存するテキストコンテンツの最大長 (文字数) です。これを超えると (GCS が設定されていれば) GCS へオフロードされ、そうでなければ切り詰められます。デフォルトは 500KB です。batch_size(int, デフォルト:1): BigQuery に書き込む前にまとめるイベント数です。batch_flush_interval(float, デフォルト:1.0): 部分バッチを flush するまで待つ最大時間 (秒) です。shutdown_timeout(float, デフォルト:10.0): シャットダウン時にログの flush を待つ時間 (秒) です。event_allowlist(Optional[List[str]], デフォルト:None): 記録するイベントタイプの一覧です。Noneの場合、event_denylistに含まれるイベントを除くすべてのイベントを記録します。対応するイベントタイプ全体は イベントタイプとペイロード を参照してください。event_denylist(Optional[List[str]], デフォルト:None): 記録対象から除外するイベントタイプの一覧です。対応するイベントタイプ全体は イベントタイプとペイロード を参照してください。content_formatter(Optional[Callable[[Any, str], Any]], デフォルト:None): ログ出力前にイベントコンテンツを整形するための任意の関数です。この関数は生のコンテンツとイベントタイプ文字列 (例:"LLM_REQUEST") の 2 引数を受け取ります。log_multi_modal_content(bool, デフォルト:True): 詳細なコンテンツパート (GCS_REFERENCEを含む) を記録するかどうかです。queue_max_size(int, デフォルト:10000): インメモリキューに保持するイベントの最大数です。これを超えると新しいイベントは破棄されます。retry_config(RetryConfig, デフォルト:RetryConfig()): BigQuery 書き込み失敗時の再試行設定です (max_retries,initial_delay,multiplier,max_delayを含む)。log_session_metadata(bool, デフォルト:True):Trueの場合、session_id,app_name,user_id、およびセッションのstate辞書 (gchat thread-id や customer_id のようなカスタム状態を含む) をattributes列へ記録します。custom_tags(Dict[str, Any], デフォルト:{}): 全イベントのattributes列へ含める静的タグの辞書です (例:{"env": "prod", "version": "1.0"})。auto_schema_upgrade(bool, デフォルト:True): 有効にすると、プラグインスキーマが進化した際に既存テーブルへ新しい列を自動追加します。列の削除や変更は行わず、加算的変更のみ実施します。テーブル上のバージョンラベル (adk_schema_version) により、スキーマバージョンごとに diff は最大 1 回だけ実行されます。デフォルトで有効にして問題ありません。create_views(bool, デフォルト:True): 1.27.0 で追加されました。有効にすると、contentやattributesのような構造化 JSON データをフラットで型付きの列に展開するイベントタイプ別 BigQuery ビューを自動生成し、SQL クエリを大幅に簡素化します。
次のコードサンプルは BigQuery Agent Analytics プラグイン向け設定の定義例です。
import json
import re
from google.adk.plugins.bigquery_agent_analytics_plugin import BigQueryLoggerConfig
def redact_dollar_amounts(event_content: Any, event_type: str) -> str:
"""
Custom formatter to redact dollar amounts (e.g., $600, $12.50)
and ensure JSON output if the input is a dict.
Args:
event_content: The raw content of the event.
event_type: The event type string (e.g., "LLM_REQUEST", "LLM_RESPONSE").
"""
text_content = ""
if isinstance(event_content, dict):
text_content = json.dumps(event_content)
else:
text_content = str(event_content)
# Regex to find dollar amounts: $ followed by digits, optionally with commas or decimals.
# Examples: $600, $1,200.50, $0.99
redacted_content = re.sub(r'\$\d+(?:,\d{3})*(?:\.\d+)?', 'xxx', text_content)
return redacted_content
config = BigQueryLoggerConfig(
enabled=True,
event_allowlist=["LLM_REQUEST", "LLM_RESPONSE"], # Only log these events
# event_denylist=["TOOL_STARTING"], # Skip these events
shutdown_timeout=10.0, # Wait up to 10s for logs to flush on exit
max_content_length=500, # Truncate content to 500 chars
content_formatter=redact_dollar_amounts, # Redact the dollar amounts in the logging content
queue_max_size=10000, # Max events to hold in memory
auto_schema_upgrade=True, # Automatically add new columns to existing tables
create_views=True, # Automatically create per-event-type views
# retry_config=RetryConfig(max_retries=3), # Optional: Configure retries
)
plugin = BigQueryAgentAnalyticsPlugin(..., config=config)
スキーマと本番環境セットアップ¶
スキーマ参照¶
イベントテーブル (agent_events) は柔軟なスキーマを使用します。以下の表は、例示値を含む包括的なリファレンスです。
| Field Name | Type | Mode | Description | Example Value |
|---|---|---|---|---|
| timestamp | TIMESTAMP |
REQUIRED |
イベント作成時刻の UTC タイムスタンプです。主な並び順キーであり、日次パーティションキーでもあります。精度はマイクロ秒です。 | 2026-02-03 20:52:17 UTC |
| event_type | STRING |
NULLABLE |
正規化されたイベントカテゴリです。標準値には LLM_REQUEST, LLM_RESPONSE, LLM_ERROR, TOOL_STARTING, TOOL_COMPLETED, TOOL_ERROR, AGENT_STARTING, AGENT_COMPLETED, STATE_DELTA, INVOCATION_STARTING, INVOCATION_COMPLETED, USER_MESSAGE_RECEIVED、および HITL イベント (HITL events 参照) が含まれます。上位レベルのフィルタリングに使用されます。 |
LLM_REQUEST |
| agent | STRING |
NULLABLE |
このイベントの責任を持つエージェント名です。エージェント初期化時または root_agent_name コンテキストを通じて定義されます。 |
my_bq_agent |
| session_id | STRING |
NULLABLE |
会話スレッド全体を識別する永続的な識別子です。複数の turn やサブエージェント呼び出しをまたいでも一定です。 | 04275a01-1649-4a30-b6a7-5b443c69a7bc |
| invocation_id | STRING |
NULLABLE |
単一の実行 turn またはリクエストサイクルの一意識別子です。多くの文脈では trace_id に対応します。 |
e-b55b2000-68c6-4e8b-b3b3-ffb454a92e40 |
| user_id | STRING |
NULLABLE |
セッションを開始したユーザー (人間またはシステム) の識別子です。User オブジェクトまたはメタデータから抽出されます。 |
test_user |
| trace_id | STRING |
NULLABLE |
OpenTelemetry Trace ID (32 文字の 16 進数) です。単一の分散リクエストライフサイクル内のすべての操作を結び付けます。 | e-b55b2000-68c6-4e8b-b3b3-ffb454a92e40 |
| span_id | STRING |
NULLABLE |
OpenTelemetry Span ID (16 文字の 16 進数) です。この特定の原子的操作を一意に識別します。 | 69867a836cd94798be2759d8e0d70215 |
| parent_span_id | STRING |
NULLABLE |
直前の呼び出し元の Span ID です。親子実行ツリー (DAG) の再構築に使用します。 | ef5843fe40764b4b8afec44e78044205 |
| content | JSON |
NULLABLE |
主要なイベントペイロードです。構造は event_type に応じて変化します。 |
{"system_prompt": "You are...", "prompt": [{"role": "user", "content": "hello"}], "response": "Hi", "usage": {"total": 15}} |
| attributes | JSON |
NULLABLE |
メタデータ / エンリッチメント情報 (使用量統計、モデル情報、tool provenance、custom tags) です。 | {"model": "gemini-2.5-flash", "usage_metadata": {"total_token_count": 15}, "session_metadata": {"session_id": "...", "app_name": "...", "user_id": "...", "state": {}}, "custom_tags": {"env": "prod"}} |
| latency_ms | JSON |
NULLABLE |
性能メトリクスです。標準キーは total_ms (総所要時間) と time_to_first_token_ms (ストリーミング遅延) です。 |
{"total_ms": 1250, "time_to_first_token_ms": 450} |
| status | STRING |
NULLABLE |
上位レベルの結果です。値は OK (成功) または ERROR (失敗) です。 |
OK |
| error_message | STRING |
NULLABLE |
人間が読める例外メッセージやスタックトレース断片です。status が ERROR の場合にのみ設定されます。 |
Error 404: Dataset not found |
| is_truncated | BOOLEAN |
NULLABLE |
content または attributes が BigQuery セルサイズ上限 (デフォルト 10MB) を超え、一部が破棄された場合は true です。 |
false |
| content_parts | RECORD |
REPEATED |
マルチモーダルセグメント (Text, Image, Blob) の配列です。単純な JSON としてシリアライズできないコンテンツ (大きなバイナリや GCS 参照など) に使われます。 | [{"mime_type": "text/plain", "text": "hello"}] |
プラグインはテーブルが存在しない場合に自動作成します。ただし本番環境では、柔軟性のための JSON 型とマルチモーダルコンテンツのための REPEATED RECORD を活用する次の DDL を使って、手動でテーブルを作成することを推奨します。
推奨 DDL:
CREATE TABLE `your-gcp-project-id.adk_agent_logs.agent_events`
(
timestamp TIMESTAMP NOT NULL OPTIONS(description="The UTC time at which the event was logged."),
event_type STRING OPTIONS(description="Indicates the type of event being logged (e.g., 'LLM_REQUEST', 'TOOL_COMPLETED')."),
agent STRING OPTIONS(description="The name of the ADK agent or author associated with the event."),
session_id STRING OPTIONS(description="A unique identifier to group events within a single conversation or user session."),
invocation_id STRING OPTIONS(description="A unique identifier for each individual agent execution or turn within a session."),
user_id STRING OPTIONS(description="The identifier of the user associated with the current session."),
trace_id STRING OPTIONS(description="OpenTelemetry trace ID for distributed tracing."),
span_id STRING OPTIONS(description="OpenTelemetry span ID for this specific operation."),
parent_span_id STRING OPTIONS(description="OpenTelemetry parent span ID to reconstruct hierarchy."),
content JSON OPTIONS(description="The event-specific data (payload) stored as JSON."),
content_parts ARRAY<STRUCT<
mime_type STRING,
uri STRING,
object_ref STRUCT<
uri STRING,
version STRING,
authorizer STRING,
details JSON
>,
text STRING,
part_index INT64,
part_attributes STRING,
storage_mode STRING
>> OPTIONS(description="Detailed content parts for multi-modal data."),
attributes JSON OPTIONS(description="Arbitrary key-value pairs for additional metadata (e.g., 'root_agent_name', 'model_version', 'usage_metadata', 'session_metadata', 'custom_tags')."),
latency_ms JSON OPTIONS(description="Latency measurements (e.g., total_ms)."),
status STRING OPTIONS(description="The outcome of the event, typically 'OK' or 'ERROR'."),
error_message STRING OPTIONS(description="Populated if an error occurs."),
is_truncated BOOLEAN OPTIONS(description="Flag indicates if content was truncated.")
)
PARTITION BY DATE(timestamp)
CLUSTER BY event_type, agent, user_id;
自動生成されるビュー(1.27.0+)¶
create_views=True(1.27.0 以降のデフォルト)にすると、プラグインは共通の JSON 構造をフラットで型付きの列へ展開するイベントタイプ別ビューを自動生成します。これにより SQL が大幅に簡素化され、複雑な JSON_VALUE や JSON_QUERY 関数を明示的に書く必要がなくなります。
たとえば、v_llm_request ビューには次のスキーマが含まれます。
| Field Name | Type | Description |
|---|---|---|
| (Common Columns) | VARIES |
標準メタデータの timestamp, event_type, agent, session_id, invocation_id, user_id, trace_id, span_id, parent_span_id, status, error_message, is_truncated を含みます。 |
| model | STRING |
リクエストに使用された LLM モデル名です。 |
| request_content | JSON |
生の LLM リクエストペイロードです。 |
| llm_config | JSON |
LLM に渡された設定パラメータ(temperature、top_p など)です。 |
| tools | JSON |
リクエスト中に利用可能だったツールの配列です。 |
イベントタイプとペイロード¶
content 列には、event_type ごとの JSON オブジェクトが格納されます。content_parts 列はコンテンツの構造化ビューを提供し、特に画像やオフロードされたデータで役立ちます。
コンテンツ切り詰め
- 可変長コンテンツフィールドは
max_content_lengthまで切り詰められます (BigQueryLoggerConfigで設定、デフォルト 500KB)。 gcs_bucket_nameが設定されている場合、大きなコンテンツは切り詰められる代わりに GCS へオフロードされ、その参照がcontent_parts.object_refに保存されます。
LLM インタラクション (プラグイン ライフサイクル)¶
これらのイベントは、LLM へ送信した生のリクエストと LLM から受信した応答を追跡します。
1. LLM_REQUEST
会話履歴とシステム指示を含む、モデルへ送信したプロンプトを記録します。
{
"event_type": "LLM_REQUEST",
"content": {
"system_prompt": "You are a helpful assistant...",
"prompt": [
{
"role": "user",
"content": "hello how are you today"
}
]
},
"attributes": {
"root_agent_name": "my_bq_agent",
"model": "gemini-2.5-flash",
"tools": ["list_dataset_ids", "execute_sql"],
"llm_config": {
"temperature": 0.5,
"top_p": 0.9
}
}
}
2. LLM_RESPONSE
モデル出力とトークン使用量統計を記録します。
{
"event_type": "LLM_RESPONSE",
"content": {
"response": "text: 'Hello! I'm doing well...'",
"usage": {
"completion": 19,
"prompt": 10129,
"total": 10148
}
},
"attributes": {
"root_agent_name": "my_bq_agent",
"model_version": "gemini-2.5-flash-001",
"usage_metadata": {
"prompt_token_count": 10129,
"candidates_token_count": 19,
"total_token_count": 10148
}
},
"latency_ms": {
"time_to_first_token_ms": 2579,
"total_ms": 2579
}
}
3. LLM_ERROR
LLM 呼び出しが例外で失敗したときに記録されます。エラーメッセージが捕捉され、span がクローズされます。
{
"event_type": "LLM_ERROR",
"content": null,
"attributes": {
"root_agent_name": "my_bq_agent"
},
"error_message": "Error 429: Resource exhausted",
"latency_ms": {
"total_ms": 350
}
}
ツール使用 (プラグイン ライフサイクル)¶
これらのイベントはエージェントによるツール実行を追跡します。各ツールイベントには、ツールの出自を分類する tool_origin フィールドが含まれます。
| Tool Origin | Description |
|---|---|
LOCAL |
FunctionTool インスタンス (ローカル Python 関数) |
MCP |
Model Context Protocol ツール (McpTool インスタンス) |
SUB_AGENT |
AgentTool インスタンス (サブエージェント) |
A2A |
リモート Agent-to-Agent インスタンス (RemoteA2aAgent) |
TRANSFER_AGENT |
TransferToAgentTool インスタンス |
UNKNOWN |
未分類のツール |
4. TOOL_STARTING
エージェントがツール実行を開始したときに記録されます。
{
"event_type": "TOOL_STARTING",
"content": {
"tool": "list_dataset_ids",
"args": {
"project_id": "bigquery-public-data"
},
"tool_origin": "LOCAL"
}
}
5. TOOL_COMPLETED
ツール実行が完了したときに記録されます。
{
"event_type": "TOOL_COMPLETED",
"content": {
"tool": "list_dataset_ids",
"result": [
"austin_311",
"austin_bikeshare"
],
"tool_origin": "LOCAL"
},
"latency_ms": {
"total_ms": 467
}
}
6. TOOL_ERROR
ツール実行が例外で失敗したときに記録されます。ツール名、引数、tool origin、エラーメッセージを記録します。
{
"event_type": "TOOL_ERROR",
"content": {
"tool": "list_dataset_ids",
"args": {
"project_id": "nonexistent-project"
},
"tool_origin": "LOCAL"
},
"error_message": "Error 404: Dataset not found",
"latency_ms": {
"total_ms": 150
}
}
状態管理¶
これらのイベントは、通常はツールによって引き起こされるエージェント状態の変化を追跡します。
7. STATE_DELTA
エージェント内部状態の変化 (例: トークンキャッシュ更新) を追跡します。
{
"event_type": "STATE_DELTA",
"attributes": {
"state_delta": {
"bigquery_token_cache": "{\"token\": \"ya29...\", \"expiry\": \"...\"}"
}
}
}
エージェントライフサイクルと汎用イベント¶
| Event Type | Content (JSON) Structure |
|---|---|
INVOCATION_STARTING |
{} |
INVOCATION_COMPLETED |
{} |
AGENT_STARTING |
"You are a helpful agent..." |
AGENT_COMPLETED |
{} |
USER_MESSAGE_RECEIVED |
{"text_summary": "Help me book a flight."} |
Human-in-the-Loop (HITL) イベント¶
このプラグインは ADK の synthetic HITL ツール呼び出しを自動検出し、専用のイベントタイプを出力します。これらのイベントは通常の TOOL_STARTING / TOOL_COMPLETED イベントに 加えて 記録されます。
認識される HITL ツール名は次のとおりです。
adk_request_credential— ユーザー資格情報の要求 (例: OAuth トークン)adk_request_confirmation— 処理を進める前のユーザー確認要求adk_request_input— 自由形式ユーザー入力の要求
| Event Type | Trigger | Content (JSON) Structure |
|---|---|---|
HITL_CREDENTIAL_REQUEST |
Agent calls adk_request_credential |
{"tool": "adk_request_credential", "args": {...}} |
HITL_CREDENTIAL_REQUEST_COMPLETED |
ユーザーが資格情報レスポンスを提供 | {"tool": "adk_request_credential", "result": {...}} |
HITL_CONFIRMATION_REQUEST |
Agent calls adk_request_confirmation |
{"tool": "adk_request_confirmation", "args": {...}} |
HITL_CONFIRMATION_REQUEST_COMPLETED |
ユーザーが確認レスポンスを提供 | {"tool": "adk_request_confirmation", "result": {...}} |
HITL_INPUT_REQUEST |
Agent calls adk_request_input |
{"tool": "adk_request_input", "args": {...}} |
HITL_INPUT_REQUEST_COMPLETED |
ユーザーが入力レスポンスを提供 | {"tool": "adk_request_input", "result": {...}} |
HITL リクエストイベントは on_event_callback 内の function_call パートから検出されます。HITL 完了イベントは on_event_callback と on_user_message_callback の両方にある function_response パートから検出されます。
GCS オフロード例 (マルチモーダルと大容量テキスト)¶
gcs_bucket_name を設定すると、大きなテキストやマルチモーダルコンテンツ (画像、音声など) は自動的に GCS へオフロードされます。content 列には概要またはプレースホルダーが保存され、content_parts には GCS URI を指す object_ref が保存されます。
オフロードされたテキスト例
{
"event_type": "LLM_REQUEST",
"content_parts": [
{
"part_index": 1,
"mime_type": "text/plain",
"storage_mode": "GCS_REFERENCE",
"text": "AAAA... [OFFLOADED]",
"object_ref": {
"uri": "gs://haiyuan-adk-debug-verification-1765319132/2025-12-10/e-f9545d6d/ae5235e6_p1.txt",
"authorizer": "us.bqml_connection",
"details": {"gcs_metadata": {"content_type": "text/plain"}}
}
}
]
}
オフロードされた画像例
{
"event_type": "LLM_REQUEST",
"content_parts": [
{
"part_index": 2,
"mime_type": "image/png",
"storage_mode": "GCS_REFERENCE",
"text": "[MEDIA OFFLOADED]",
"object_ref": {
"uri": "gs://haiyuan-adk-debug-verification-1765319132/2025-12-10/e-f9545d6d/ae5235e6_p2.png",
"authorizer": "us.bqml_connection",
"details": {"gcs_metadata": {"content_type": "image/png"}}
}
}
]
}
オフロード済みコンテンツを問い合わせる (署名付き URL の取得)
SELECT
timestamp,
event_type,
part.mime_type,
part.storage_mode,
part.object_ref.uri AS gcs_uri,
-- Generate a signed URL to read the content directly (requires connection_id configuration)
STRING(OBJ.GET_ACCESS_URL(part.object_ref, 'r').access_urls.read_url) AS signed_url
FROM `your-gcp-project-id.your-dataset-id.agent_events`,
UNNEST(content_parts) AS part
WHERE part.storage_mode = 'GCS_REFERENCE'
ORDER BY timestamp DESC
LIMIT 10;
高度な分析クエリ¶
trace_id を使って特定の会話ターンを追跡¶
SELECT timestamp, event_type, agent, JSON_VALUE(content, '$.response') as summary
FROM `your-gcp-project-id.your-dataset-id.agent_events`
WHERE trace_id = 'your-trace-id'
ORDER BY timestamp ASC;
トークン使用量分析 (JSON フィールドへのアクセス)¶
SELECT
AVG(CAST(JSON_VALUE(content, '$.usage.total') AS INT64)) as avg_tokens
FROM `your-gcp-project-id.your-dataset-id.agent_events`
WHERE event_type = 'LLM_RESPONSE';
マルチモーダルコンテンツの問い合わせ (content_parts と ObjectRef を使用)¶
SELECT
timestamp,
part.mime_type,
part.object_ref.uri as gcs_uri
FROM `your-gcp-project-id.your-dataset-id.agent_events`,
UNNEST(content_parts) as part
WHERE part.mime_type LIKE 'image/%'
ORDER BY timestamp DESC;
BigQuery リモートモデル (Gemini) でマルチモーダルコンテンツを分析¶
SELECT
logs.session_id,
-- Get a signed URL for the image
STRING(OBJ.GET_ACCESS_URL(parts.object_ref, "r").access_urls.read_url) as signed_url,
-- Analyze the image using a remote model (e.g., gemini-pro-vision)
AI.GENERATE(
('Describe this image briefly. What company logo?', parts.object_ref)
) AS generated_result
FROM
`your-gcp-project-id.your-dataset-id.agent_events` logs,
UNNEST(logs.content_parts) AS parts
WHERE
parts.mime_type LIKE 'image/%'
ORDER BY logs.timestamp DESC
LIMIT 1;
レイテンシ分析 (LLM とツール)¶
SELECT
event_type,
AVG(CAST(JSON_VALUE(latency_ms, '$.total_ms') AS INT64)) as avg_latency_ms
FROM `your-gcp-project-id.your-dataset-id.agent_events`
WHERE event_type IN ('LLM_RESPONSE', 'TOOL_COMPLETED')
GROUP BY event_type;
Span 階層と duration 分析¶
SELECT
span_id,
parent_span_id,
event_type,
timestamp,
-- Extract duration from latency_ms for completed operations
CAST(JSON_VALUE(latency_ms, '$.total_ms') AS INT64) as duration_ms,
-- Identify the specific tool or operation
COALESCE(
JSON_VALUE(content, '$.tool'),
'LLM_CALL'
) as operation
FROM `your-gcp-project-id.your-dataset-id.agent_events`
WHERE trace_id = 'your-trace-id'
AND event_type IN ('LLM_RESPONSE', 'TOOL_COMPLETED')
ORDER BY timestamp ASC;
エラー分析 (LLM とツールのエラー)¶
SELECT
timestamp,
event_type,
agent,
error_message,
JSON_VALUE(content, '$.tool') as tool_name,
CAST(JSON_VALUE(latency_ms, '$.total_ms') AS INT64) as latency_ms
FROM `your-gcp-project-id.your-dataset-id.agent_events`
WHERE event_type IN ('LLM_ERROR', 'TOOL_ERROR')
ORDER BY timestamp DESC
LIMIT 20;
Tool Provenance 分析¶
SELECT
JSON_VALUE(content, '$.tool_origin') as tool_origin,
JSON_VALUE(content, '$.tool') as tool_name,
COUNT(*) as call_count,
AVG(CAST(JSON_VALUE(latency_ms, '$.total_ms') AS INT64)) as avg_latency_ms
FROM `your-gcp-project-id.your-dataset-id.agent_events`
WHERE event_type = 'TOOL_COMPLETED'
GROUP BY tool_origin, tool_name
ORDER BY call_count DESC;
HITL インタラクション分析¶
SELECT
timestamp,
event_type,
session_id,
JSON_VALUE(content, '$.tool') as hitl_tool,
content
FROM `your-gcp-project-id.your-dataset-id.agent_events`
WHERE event_type LIKE 'HITL_%'
ORDER BY timestamp DESC
LIMIT 20;
7. AI による根本原因分析 (Agent Ops)¶
BigQuery ML と Gemini を使って失敗したセッションを自動分析し、エラーの根本原因を特定します。
DECLARE failed_session_id STRING;
-- Find a recent failed session
SET failed_session_id = (
SELECT session_id
FROM `your-gcp-project-id.your-dataset-id.agent_events`
WHERE error_message IS NOT NULL
ORDER BY timestamp DESC
LIMIT 1
);
-- Reconstruct the full conversation context
WITH SessionContext AS (
SELECT
session_id,
STRING_AGG(CONCAT(event_type, ': ', COALESCE(TO_JSON_STRING(content), '')), '\n' ORDER BY timestamp) as full_history
FROM `your-gcp-project-id.your-dataset-id.agent_events`
WHERE session_id = failed_session_id
GROUP BY session_id
)
-- Ask Gemini to diagnose the issue
SELECT
session_id,
AI.GENERATE(
('Analyze this conversation log and explain the root cause of the failure. Log: ', full_history),
endpoint => 'gemini-2.5-flash'
).result AS root_cause_explanation
FROM SessionContext;
BigQuery の会話型分析¶
BigQuery Conversational Analytics を使用すると、自然言語でエージェントログを分析できます。次のような質問に答える用途で利用できます。
- "Show me the error rate over time"
- "What are the most common tool calls?"
- "Identify sessions with high token usage"
Looker Studio ダッシュボード¶
用意済みの Looker Studio Dashboard template を使ってエージェント性能を可視化できます。
このダッシュボードを自分の BigQuery テーブルへ接続するには、次のリンク形式でプロジェクト、データセット、テーブル ID のプレースホルダーを実際の値へ置き換えて使ってください。
https://lookerstudio.google.com/reporting/create?c.reportId=f1c5b513-3095-44f8-90a2-54953d41b125&ds.ds3.connector=bigQuery&ds.ds3.type=TABLE&ds.ds3.projectId=<your-project-id>&ds.ds3.datasetId=<your-dataset-id>&ds.ds3.tableId=<your-table-id>
フィードバック¶
BigQuery Agent Analytics に関するフィードバックを歓迎します。質問、提案、問題報告があれば bqaa-feedback@google.com までご連絡ください。