G-gen の奥田です。当記事では、Google Cloud (旧称 GCP)のエージェント構築サービスを利用し、最新のドル・円レートを取得するエージェントを構築したので解説します。
はじめに
Conversational Agents とは
Conversational Agents とは、Google Cloud が提供する会話型 AI プラットフォームです。
2024年後半から2025年初頭にかけて、Vertex AI Agents (Playbook とデータストア機能) コンソールと Dialogflow CX コンソールが、単一の会話型エージェントコンソールに統合され、サービス名称も変更になりました。
- 参考 : Dialogflow - Renaming and console consolidation plan
- 参考 : Dialogflow - Conversational Agents console overview

Conversational Agents(旧称 Dialogflow CX)では、生成的(Generative)なエージェントである Playbook と、決定論的(Deterministic)なエージェントである Flow を構築できます。当記事では、Playbook を利用して生成 AI エージェントを開発します。
なお Playbook は、Google の生成 AI エージェントサービスである Google Agentspace とも統合可能です。
Playbook とは
Playbook とは、生成 AI エージェントを構築するためのフルマネージドサービスです。生成 AI の機能を活かし、エンドユーザーの意図を理解して、応答を生成したり、人間の代わりにタスクを実行できます。
- 参考 : Playbook
Playbookは以前、前述のとおり、AI Applications(旧称 Vertex AI Agent Builder)の Agents と呼ばれていましたが、改称されました。AI Applications の詳細は、以下の記事をご参照下さい。
今回の記事では、単一の Playbook から構成される、シングルエージェント構成を実装します。
ツールとは
ツールとは、生成 AI エージェントが外部システムに接続して知識にアクセスしたり、複雑なタスクを実行したりするために使用する機能です。ツールは、Playbook から呼び出されます。
ツールの種類は以下のとおりです。
- 組み込みツール
- OpenAPI ツール
- データストアツール
- コネクタツール
- Function ツール
当記事では、OpenAPI ツールを利用します。
- 参考 : Playbook tools
OpenAPI ツールとは
OpenAPI ツールとは、OpenAPI Specification(OAS) に基づいた API 定義ファイルを用いて定義するツールです。
OpenAPI スキーマにより、API とやり取りするデータの形式を細かく定義します。
認証方式としては、Dialogflow のサービスエージェント認証、サービスアカウント認証、API キー、OAuth、Bearer トークンなどがサポートされています。当記事では、Dialogflow のサービスエージェント認証を使用します。
OpenAPI を利用して関数を呼び出す方法は、他社パブリッククラウドのエージェントでも同様のことが実現可能です。詳しくは以下の記事をご覧ください。
システム構成と手順の概要
構成図
当記事では、以下のような構成でエージェントを構築しました。
実装手順
以下の順序で環境を構築しました。
- API の有効化/取得
- Cloud Run functions の構築
- Conversational Agent の作成
- Tool の構築
- Playbook の構築
API の有効化/取得
Google Cloud プロジェクトで、今回の構成に必要な Google Cloud サービスの API を有効化します。
gcloud services enable \aiplatform.googleapis.com \artifactregistry.googleapis.com \cloudbuild.googleapis.com \cloudfunctions.googleapis.com \dialogflow.googleapis.com \discoveryengine.googleapis.com \logging.googleapis.com \run.googleapis.com
また、今回は Currency Layer API から USD/JPY の為替レートを取得します。事前に Currency Layer API のユーザー登録を行い、API キーを取得しておきます。
- 参考 : Currency Layer API
Cloud Run functions の構築
Python のバージョン
当記事では、Python 3.12.3 を使用しました。
$ python --versionPython 3.12.3
ディレクトリ構成
プロジェクトの構成は、以下のとおりです。
currency/ ├── main.py └── requirements.txt
requirements.txt の作成
以下のライブラリを requirements.txt
に定義します。
functions-framework>=3.0.0 requests pytz Flask google-cloud-logging
main.py の開発
Python スクリプトでは、以下のような処理で Currency Layer API から USD/JPY レートと取得時刻を取得します。
- API キーのチェック
- 環境変数から API キーを取得
- API キーが未設定の場合、エラーメッセージを返す
- API リクエスト
- 取得した API キーを用いて、外部 API へリクエストを送信し、為替レートデータを取得
- データ処理
- API からのレスポンスが成功したかを確認する。失敗した場合はエラーメッセージを返す
- 取得したタイムスタンプを日本時間(JST)に変換
- USD/JPY の為替レートをレスポンスから抽出
- レスポンス
- 抽出した為替レートと変換後のタイムスタンプを JSON 形式で返す
- エラー処理
- API リクエストのタイムアウト、接続エラー、レスポンスの解析エラーなど、発生しうる様々なエラーを取得
- エラー発生時には、適切なエラーメッセージを JSON 形式で返す
また、15行目の Currency Layer API の API キーは Cloud Run functions のデプロイ時に設定します。当記事は簡易的な検証のため、API キーを Cloud Run functions の環境変数に格納しましたが、これはセキュアな方法ではありません。本番環境では、Secret Manager に格納するなどを検討してください。
- 参考 : シークレットを構成する
main.py のソースコードは以下のとおりです。
import functions_frameworkimport osimport requestsimport datetimeimport pytzimport loggingimport jsonfrom flask import Response# ロギングの設定logging.basicConfig(level=logging.INFO)# 環境変数から API キーを取得api_key = os.environ.get("CURRENCY_LAYER_API_KEY")base_url = "https://apilayer.net/api/live"# --- HTTP リクエストを受け取る関数 ---@functions_framework.httpdef get_currency_rate(request):"""HTTP GET リクエストを受け取り、USD/JPY の為替レートを取得して JSON で返す関数。Args:request (flask.Request): Flaskリクエストオブジェクト。リクエストメソッド、ヘッダー、クエリパラメータなどが含まれる。この関数ではrequestの内容は直接利用しない。Returns:flask.Response: JSON形式のレスポンス、またはエラーレスポンス。成功時: {"rate": <レート>, "timestamp_jst": "<JSTタイムスタンプ>"}失敗時: {"error": "<エラーメッセージ>"} と適切なHTTPステータスコード"""# API キーのチェック(関数が呼び出されるたびにチェックする)if not api_key:logging.error("環境変数 'CURRENCY_LAYER_API_KEY' が設定されていません。")error_response = json.dumps({"error": "Server configuration error: API key missing"})return Response(error_response, status=500, mimetype='application/json')params = {"access_key": api_key,"currencies": "JPY","source": "USD","format": 1}try:logging.info("為替レート API へのリクエストを開始します...")response = requests.get(base_url, params=params, timeout=10) # タイムアウトを設定response.raise_for_status() # ステータスコードが200番台以外の場合にエラーdata = response.json()logging.info("APIからのレスポンスを正常に受信しました。")if not data.get('success', False):error_info = data.get('error', {})api_error_msg = f"API Error: Code={error_info.get('code')}, Info='{error_info.get('info')}'"logging.error(api_error_msg)error_response = json.dumps({"error": "Failed to retrieve data from currency API", "details": api_error_msg})# API側の問題なので 502 Bad Gateway や 503 Service Unavailable が適切かもしれないreturn Response(error_response, status=502, mimetype='application/json')# タイムスタンプを日本時間 (JST)に変換formatted_datetime = Nonetimestamp = data.get('timestamp')if timestamp:try:jst = pytz.timezone('Asia/Tokyo')datetime_utc = datetime.datetime.fromtimestamp(timestamp, tz=pytz.utc)datetime_jst = datetime_utc.astimezone(jst)formatted_datetime = datetime_jst.strftime('%Y-%m-%d %H:%M:%S %Z%z')logging.info(f"Timestamp (JST): {formatted_datetime}")except Exception as e:logging.warning(f"タイムスタンプの変換中にエラー: {e}. 元のタイムスタンプ: {timestamp}")# タイムスタンプ変換エラーは致命的ではない場合もあるので、処理は続行するかもしれない# レートの取得quotes = data.get('quotes')if quotes and 'USDJPY' in quotes:usdjpy_rate = quotes['USDJPY']logging.info(f"USDJPY: {usdjpy_rate}")# 成功時のレスポンスデータを作成result_data = {"rate": usdjpy_rate,"timestamp_jst": formatted_datetime # 変換失敗時は None になる}success_response = json.dumps(result_data)return Response(success_response, status=200, mimetype='application/json')else:logging.warning("レスポンスに USDJPY のレートが含まれていませんでした。")logging.debug(f"受信したQuotes: {quotes}")error_response = json.dumps({"error": "Currency data not found in API response", "received_quotes": quotes})return Response(error_response, status=500, mimetype='application/json') # 内部サーバーエラーとして扱うexcept requests.exceptions.Timeout:logging.error("API へのリクエストがタイムアウトしました。")error_response = json.dumps({"error": "Request to currency API timed out"})return Response(error_response, status=504, mimetype='application/json') # Gateway Timeoutexcept requests.exceptions.RequestException as e:logging.error(f"API へのリクエスト中にエラーが発生しました: {e}")error_response = json.dumps({"error": "Error connecting to currency API", "details": str(e)})return Response(error_response, status=502, mimetype='application/json') # Bad Gatewayexcept KeyError as e:logging.error(f"レスポンスデータの解析中にキーエラーが発生しました: {e}")logging.error(f"受信データ: {data}") # デバッグ用に受信データをログ出力error_response = json.dumps({"error": "Error parsing API response", "missing_key": str(e)})return Response(error_response, status=500, mimetype='application/json')except Exception as e:logging.exception(f"予期せぬエラーが発生しました: {e}") # スタックトレースもログに出力error_response = json.dumps({"error": "An unexpected internal server error occurred", "details": str(e)})return Response(error_response, status=500, mimetype='application/json')
Cloud Run function 実行用サービスアカウントの作成
Cloud Run functions を実行するサービスアカウントを作成し、権限を付与します。
PROJECT_ID="your-project-id" # プロジェクトIDSA_NAME="currencytest" # サービスアカウント名SA_DESCRIPTION="My Cloud Functions Service Account for currency test " # サービスアカウントの説明SA_DISPLAY_NAME="My Function SA for currencytest" # Cloud Console に表示される名前gcloud iam service-accounts create "$SA_NAME" \--project="$PROJECT_ID" \--description="$SA_DESCRIPTION" \--display-name="$SA_DISPLAY_NAME"# 権限付与gcloud projects add-iam-policy-binding "$PROJECT_ID" \--member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \--role="roles/logging.logWriter"gcloud projects add-iam-policy-binding "$PROJECT_ID" \--member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \--role="roles/artifactregistry.reader"gcloud projects add-iam-policy-binding $PROJECT_ID \--member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \--role="roles/run.invoker"gcloud projects add-iam-policy-binding $PROJECT_ID \--member="serviceAccount:${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \--role="roles/containeranalysis.occurrences.viewer"
Cloud Run functions のデプロイ
FUNCTION=currencytestYOUR_API_KEY=”Currency Layer API の API キー”gcloud functions deploy ${FUNCTION} \--gen2 \--project=${PROJECT_ID} \--region=us-central1 \--entry-point=get_currency_rate \--runtime=python312 \--service-account="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" \--trigger-http \--allow-unauthenticated \--timeout=540 \--set-env-vars CURRENCY_LAYER_API_KEY=${YOUR_API_KEY}
繰り返しになりますが、API キーのような機密情報を環境変数に設定する方法は推奨されません。実際の環境では、Secret Manager に格納することを検討してください。
Conversational Agent の作成
Google Cloud コンソールから「AI Applications」を選択し、「アプリを作成する」を押下します。
アプリケーションの種類は「会話型エージェント」を選択します。
「Build your own」を選択します。
エージェント名、Location、Time Zone、Default Language を記入します。
Conversational Start は「Playbook」を選択します。
Tool の構築
Tool の設定を行います。
今回設定した値は以下のとおりです。
設定項目 | 名称 |
---|---|
Tool name | Currency-Calculator |
Type | OpenAPI |
Description | API を呼び出し、USD/JPY レートを表示します。 |
今回設定した OpenAPI スキーマは以下のとおりです。
openapi: 3.0.0info:title: Currency Rate APIversion: 1.0.0description: Get USD/JPY currency rate.servers:- url: [デプロイした Cloud Run functions の URL]paths:/:get:summary: Get USD/JPY currency ratedescription: Retrieves the current USD/JPY currency exchange rate from an external API.responses:'200':description: Successful responsecontent:application/json:schema:type: objectproperties:rate:type: numberformat: floatdescription: The USD/JPY exchange rate.timestamp_jst:type: stringformat: date-timedescription: The timestamp of the exchange rate in JST (Japan Standard Time).'500':description: Internal server errorcontent:application/json:schema:type: objectproperties:error:type: stringdescription: Error message.'502':description: Bad Gatewaycontent:application/json:schema:type: objectproperties:error:type: stringdescription: Error message from the external API.details:type: stringdescription: Detailed error message from the external API.'504':description: Gateway Timeoutcontent:application/json:schema:type: objectproperties:error:type: stringdescription: Error message indicating a timeout.
Playbook の構築
設定項目
以下の設定値で Playbook を構築します。
設定項目 | 設定値 |
---|---|
Playbook Name | Currency-Calculator-Playbook |
Goal | ツールを使い、日本円から US ドルの換算レートを表示します。 |
Instructions | ${TOOL:Currency-Calculator} を呼び出し、日本円から USドルの換算レートを表示します。 |
動作検証
設定後はコンソール右上の吹き出しボタンからプレビュー画面を呼び出し、動作を検証します。
Example の格納
動作検証後、回答例を『Examples』に格納します。
カジュアルな質問(例:今日の為替は?)でも回答させたい場合は、カジュアルな質問文からツールを呼び出した会話例を登録します。
- 参考 : Playbook Example
デプロイ
作成したアプリケーションは、Conversational Agents の Integration 機能を利用することで様々なサービスへ接続可能です。
以下のサービスには、Conversational Agents がネイティブに対応しています。
- Dialogflow CX Phone Gateway
- Dialogflow CX Messenger
- Messenger from Meta
- Workplace from Meta
- LINE
- Slack
- Google Chat
他にも Google によって公開されているオープンソースの統合ライブラリも存在します。詳細は、以下のドキュメントを参照してください。
- 参考 : Integrations
また前述の通り、Google Agentspace への接続も可能です。
応用
今回は簡易的な検証のため、ドル・円の為替レートと取得時刻のみを抽出しましたが、本事例を応用することで、ユーザーに為替レートを取得する国を指定させたり、過去の為替レートを取得するなど、複雑なタスクを実行するエージェントも構築可能です。
また、今回は単一の Playbook での実装でしたが、複数の Playbook を組み合わせることで、マルチエージェントシステムを構築可能です。こちらについては、以下の動画でデモを交えて紹介しています。
Risa(記事一覧)
クラウドソリューション部クラウドデベロッパー課
Google Cloudの可能性に惹かれ、2024年4月G-genにジョイン。
Google Cloud Partner Top Engineer 2025
Google Cloud 11 資格保有。日々修行中です!