Agent2Agent エージェントを使用して Google Chat アプリを構築する

このページでは、 Google Chat で動作し、 Agent2Agent(A2A) プロトコルを使用する AI エージェントと連携する Google Workspace アドオンを構築する方法について説明します。 エージェントは Agent Development Kit(ADK)を使用して開発し、 Vertex AI Agent Engineでホストします。

AI エージェントは、環境を自律的に認識し、推論を行い、定義された目標を達成するために複雑な複数ステップのアクションを実行します。このチュートリアルでは、Gemini と Google 検索のグラウンディングを使用して事実を批判して修正する LLM Auditor マルチエージェント サンプル をデプロイします。

Chat 用アプリとしての LLM Auditor マルチエージェント サンプル。

次の図は、アーキテクチャとメッセージング パターンを示しています。

A2A AI エージェントで実装された Chat 用アプリのアーキテクチャ。

この図では、A2A エージェントで実装された Chat アプリを操作するユーザーの情報フローは次のようになります。

  1. ユーザーは、ダイレクト メッセージまたは Chat スペースで Chat アプリにメッセージを送信します。
  2. Apps Script または HTTP エンドポイントを持つウェブサーバーとして実装された Chat アプリのロジックが、メッセージを受信して処理します。
  3. Vertex AI Agent Engine でホストされている A2A エージェントが、インタラクションを受信して処理します。
  4. 必要に応じて、Chat アプリまたは AI エージェントを Google Workspace サービス(カレンダーやスプレッドシートなど)や、Google サービス(Google マップや YouTube など)と統合できます。
  5. Chat アプリは、Google Chat API を使用して AI エージェントの進行状況を通知し、レスポンスを非同期で送信します。
  6. レスポンスがユーザーに配信されます。

目標

  • 環境をセットアップする。
  • A2A エージェントをデプロイする。
  • Chat アプリをデプロイする。
  • Chat アプリを構成する。
  • Chat アプリをテストする。

前提条件

環境をセットアップする

Google Cloud APIs を有効にする

Google API を使用する前に、Google Cloud プロジェクトで有効にする必要があります。 1 つの Google Cloud プロジェクトで 1 つ以上の API を有効にできます。
  • Google Cloud コンソールで、Google Chat、Vertex AI、Cloud Resource Manager の各 API を有効にします。

    API を有効にする

OAuth 同意画面を構成する

OAuth 2.0 を使用するすべてのアプリで、同意画面の構成が必要です。アプリの OAuth 同意画面を構成すると、ユーザーとアプリの審査担当者に表示される内容が定義され、後で公開できるようにアプリが登録されます。

  1. Google API Console で、メニュー アイコン menu > [Google Auth Platform] > [ブランディング] に移動します。

    [ブランディング] に移動

  2. Google Auth Platform をすでに構成している場合は、[ブランディング]、[対象]、[データアクセス] で次の OAuth 同意画面の設定を構成できます。[**Google Auth Platform はまだ構成されていません**] というメッセージが表示されたら、[**スタートガイド**] をクリックします。
    1. [アプリ情報] の [アプリ名] に、アプリの名前を入力します。
    2. [**ユーザー サポートメール**] で、ユーザーが同意について問い合わせる際に使用するサポートのメールアドレスを選択します。
    3. [続行] をクリックします。
    4. [対象] で [内部] を選択します。
    5. [続行] をクリックします。
    6. [連絡先情報] で、プロジェクトに対する変更の通知を受け取る [メールアドレス] を入力します。
    7. [続行] をクリックします。
    8. [完了] で、Google API サービスのユーザーデータに関するポリシーを確認し、同意する場合は [Google API サービス: ユーザーデータに関するポリシーに同意します] を選択します。
    9. [続行] をクリックします。
    10. [作成] をクリックします。
  3. 現時点では、スコープの追加はスキップできます。 今後、 Google Workspace 組織外で使用するアプリを作成する場合は、[ユーザータイプ] を [外部] に変更する必要があります。次に、アプリに必要な承認スコープを追加します。詳細については、OAuth 同意画面を構成するの完全なガイドをご覧ください。 OAuth 同意画面を構成するの完全なガイドをご覧ください。

Google Cloud コンソールでサービス アカウントを作成する

次の手順に沿って、ロール Vertex AI User を持つ新しいサービス アカウントを作成します。

Google Cloud Console

  1. Google Cloud Console で、メニュー アイコン > [**IAM と管理**] > [**サービス アカウント**] に移動します。

    [サービス アカウント] に移動

    残りの手順は、Google Cloud Console に表示されます。

  2. Google Cloud プロジェクトを選択します。
  3. [サービス アカウントを作成] をクリックします。
  4. Google Cloud Console に表示するサービス アカウント名を入力します。
  5. アクセス制御を今すぐ設定しない場合は、[完了] をクリックしてサービス アカウントの作成を終了します。アクセス制御を今すぐ設定するには、[作成して続行] をクリックして次の手順に進みます。
  6. 省略可: サービス アカウントにロールを割り当て、Google Workspace リソースに加えて Google Cloud プロジェクトのリソースへのアクセス権を付与します。詳細については、プロジェクト、フォルダ、組織へのアクセスの管理をご覧ください。
  7. [続行] をクリックします。
  8. 省略可: このサービス アカウントで管理とアクションの実行が可能なユーザーまたはグループを入力します。詳細については、サービス アカウントの権限借用をご覧ください。
  9. [完了] をクリックして、サービス アカウントの作成を完了します。

    サービス アカウントのメールアドレスをメモします。

gcloud CLI

  1. サービス アカウントを作成します。
    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name="SERVICE_ACCOUNT_NAME"
  2. 省略可: サービス アカウントにロールを割り当て、Google Workspace リソースに加えて Google Cloud プロジェクトのリソースへのアクセス権を付与します。詳細については、プロジェクト、フォルダ、組織へのアクセスの管理をご覧ください。

サービス アカウントが [サービス アカウント] ページに表示されます。

秘密鍵を作成する

サービス アカウントの秘密鍵を作成してダウンロードする手順は次のとおりです。

  1. Google Cloud Console で、メニュー アイコン menu > [IAM と管理] > [サービス アカウント] に移動します。

    [サービス アカウント] に移動

    残りの手順は、Google Cloud Console に表示されます。

  2. Google Cloud プロジェクトを選択します。
  3. キーを作成するサービス アカウントのメールアドレスをクリックします。
  4. [キー] タブをクリックします。
  5. [鍵を追加] プルダウン メニューをクリックして、[新しい鍵を作成] を選択します。
  6. [鍵のタイプ] として [JSON] を選択し、[作成] をクリックします。

    新しい公開鍵と秘密鍵のペアが生成され、サービス アカウント キーファイルとしてパソコンにダウンロードされます。ダウンロードした JSON ファイルを credentials.json として作業ディレクトリに保存します。このファイルはこの鍵の唯一のコピーです。鍵ファイルをダウンロードした後、再度ダウンロードすることはできません。鍵を安全に保存する方法については、サービス アカウント キーの管理のベスト プラクティスをご覧ください。

サービス アカウントの詳細については、 Google Cloud IAM ドキュメントのサービス アカウントをご覧ください。

A2A エージェントをデプロイする

  1. まだ行っていない場合は、Google Cloud アカウントで認証し、Google Cloud プロジェクトを使用するように Google Cloud CLI を構成します。

    gcloud auth application-default login
    gcloud config set project PROJECT_ID
    gcloud auth application-default set-quota-project PROJECT_ID

    PROJECT_ID は実際の Cloud プロジェクトの ID に置き換えます。

  2. 次のボタンを使用して、ADK サンプルの GitHub リポジトリをダウンロードします。

    adk-samples をダウンロード

  3. 任意のローカル開発環境で、ダウンロードしたアーカイブ ファイルを解凍し、adk-samples/python/agents/llm-auditor ディレクトリを開きます。

    unzip adk-samples-main.zip
    cd adk-samples-main/python/agents/llm-auditor
  4. 実装を更新して、ADK エージェントを A2A リモート エージェントとしてデプロイします。

    1. pyproject.toml: デプロイ グループに ADK と A2A SDK の依存関係を追加します。

      apps-script/chat/a2a-ai-agent/llm-auditor/pyproject.toml
      [project]
      name = "llm-auditor"
      version = "0.1.0"
      description = "The LLM Auditor evaluates LLM-generated answers, verifies actual accuracy using the web, and refines the response to ensure alignment with real-world knowledge."
      authors = [
          { name = "Chun-Sung Ferng", email = "csferng@google.com" },
          { name = "Cyrus Rashtchian", email = "cyroid@google.com" },
          { name = "Da-Cheng Juan", email = "dacheng@google.com" },
          { name = "Ivan Kuznetsov", email = "ivanku@google.com" },
      ]
      license = "Apache License 2.0"
      readme = "README.md"
      
      [tool.poetry.dependencies]
      python = "^3.10"
      google-adk = "^1.0.0"
      google-cloud-aiplatform = { extras = [
          "adk",
          "agent-engines",
      ], version = "^1.93.0" }
      google-genai = "^1.9.0"
      pydantic = "^2.10.6"
      python-dotenv = "^1.0.1"
      
      [tool.poetry.group.dev]
      optional = true
      
      [tool.poetry.group.dev.dependencies]
      google-adk = { version = "^1.0.0", extras = ["eval"] }
      pytest = "^8.3.5"
      pytest-asyncio = "^0.26.0"
      
      [tool.poetry.group.deployment]
      optional = true
      
      [tool.poetry.group.deployment.dependencies]
      absl-py = "^2.2.1"
      google-adk = "^1.0.0"
      a2a-sdk = "^0.3.0"
      
      [build-system]
      requires = ["poetry-core>=2.0.0,<3.0.0"]
      build-backend = "poetry.core.masonry.api"
    2. deployment/deploy.py: ADK アプリのデプロイを A2A エージェントとカードに置き換えます。

      apps-script/chat/a2a-ai-agent/llm-auditor/deployment/deploy.py
      # Copyright 2025 Google LLC
      #
      # Licensed under the Apache License, Version 2.0 (the "License");
      # you may not use this file except in compliance with the License.
      # You may obtain a copy of the License at
      #
      #     http://www.apache.org/licenses/LICENSE-2.0
      #
      # Unless required by applicable law or agreed to in writing, software
      # distributed under the License is distributed on an "AS IS" BASIS,
      # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
      # See the License for the specific language governing permissions and
      # limitations under the License.
      
      """Deployment script for LLM Auditor."""
      
      import os
      
      from absl import app
      from absl import flags
      from dotenv import load_dotenv
      from llm_auditor.agent import root_agent
      import vertexai
      from vertexai import agent_engines
      
      # A2A wrapping
      from a2a.types import AgentSkill
      from google.adk.a2a.executor.a2a_agent_executor import A2aAgentExecutor
      from google.adk.runners import InMemoryRunner
      from vertexai.preview.reasoning_engines.templates.a2a import create_agent_card
      from vertexai.preview.reasoning_engines import A2aAgent
      
      FLAGS = flags.FLAGS
      flags.DEFINE_string("project_id", None, "GCP project ID.")
      flags.DEFINE_string("location", None, "GCP location.")
      flags.DEFINE_string("bucket", None, "GCP bucket.")
      flags.DEFINE_string("resource_id", None, "ReasoningEngine resource ID.")
      
      flags.DEFINE_bool("list", False, "List all agents.")
      flags.DEFINE_bool("create", False, "Creates a new agent.")
      flags.DEFINE_bool("delete", False, "Deletes an existing agent.")
      flags.mark_bool_flags_as_mutual_exclusive(["create", "delete"])
      
      
      def create() -> None:
          """Creates an agent engine for LLM Auditor."""
          agent_card = create_agent_card(
              agent_name=root_agent.name,
              description=root_agent.description,
              skills=[AgentSkill(
                  id='audit_llm_output',
                  name='Audit LLM Output',
                  description='Critiques and revises outputs from large language models.',
                  tags=['LLM', 'Audit', 'Revision'],
                  examples=[
                      'The earth is flat.',
                      'The capital of France is Berlin.',
                      'The last winner of the Super Bowl was the New England Patriots in 2020.',
                  ],
              )]
          )
          a2a_agent = A2aAgent(
              agent_card=agent_card,
              agent_executor_builder=lambda: A2aAgentExecutor(
                  runner=InMemoryRunner(
                      app_name=root_agent.name,
                      agent=root_agent,
                  )
              )
          )
          a2a_agent.set_up()
      
          remote_agent = agent_engines.create(
              a2a_agent,
              display_name=root_agent.name,
              requirements=[
                      "google-adk (>=0.0.2)",
                      "google-cloud-aiplatform[agent_engines] (>=1.88.0,<2.0.0)",
                      "google-genai (>=1.5.0,<2.0.0)",
                      "pydantic (>=2.10.6,<3.0.0)",
                      "absl-py (>=2.2.1,<3.0.0)",
                      "a2a-sdk>=0.3.22",
                      "uvicorn",
              ],
              # In-memory runner
              max_instances=1,
              env_vars ={
                  "NUM_WORKERS": "1"
              },
              extra_packages=["./llm_auditor"],
          )
          print(f"Created remote agent: {remote_agent.resource_name}")
      
      
      def delete(resource_id: str) -> None:
          remote_agent = agent_engines.get(resource_id)
          remote_agent.delete(force=True)
          print(f"Deleted remote agent: {resource_id}")
      
      
      def list_agents() -> None:
          remote_agents = agent_engines.list()
          TEMPLATE = '''
      {agent.name} ("{agent.display_name}")
      - Create time: {agent.create_time}
      - Update time: {agent.update_time}
      '''
          remote_agents_string = '\n'.join(TEMPLATE.format(agent=agent) for agent in remote_agents)
          print(f"All remote agents:\n{remote_agents_string}")
      
      def main(argv: list[str]) -> None:
          del argv  # unused
          load_dotenv()
      
          project_id = (
              FLAGS.project_id
              if FLAGS.project_id
              else os.getenv("GOOGLE_CLOUD_PROJECT")
          )
          location = (
              FLAGS.location if FLAGS.location else os.getenv("GOOGLE_CLOUD_LOCATION")
          )
          bucket = (
              FLAGS.bucket if FLAGS.bucket
              else os.getenv("GOOGLE_CLOUD_STORAGE_BUCKET")
          )
      
          print(f"PROJECT: {project_id}")
          print(f"LOCATION: {location}")
          print(f"BUCKET: {bucket}")
      
          if not project_id:
              print("Missing required environment variable: GOOGLE_CLOUD_PROJECT")
              return
          elif not location:
              print("Missing required environment variable: GOOGLE_CLOUD_LOCATION")
              return
          elif not bucket:
              print(
                  "Missing required environment variable: GOOGLE_CLOUD_STORAGE_BUCKET"
              )
              return
      
          vertexai.init(
              project=project_id,
              location=location,
              staging_bucket=f"gs://{bucket}",
          )
      
          if FLAGS.list:
              list_agents()
          elif FLAGS.create:
              create()
          elif FLAGS.delete:
              if not FLAGS.resource_id:
                  print("resource_id is required for delete")
                  return
              delete(FLAGS.resource_id)
          else:
              print("Unknown command")
      
      
      if __name__ == "__main__":
          app.run(main)
  5. ADK エージェント専用の新しい Cloud Storage バケットを作成します。

    gcloud storage buckets create gs://CLOUD_STORAGE_BUCKET_NAME --project=PROJECT_ID --location=PROJECT_LOCATION

    次のように置き換えます。

    1. CLOUD_STORAGE_BUCKET_NAME は、使用する一意のバケット名 に置き換えます。
    2. PROJECT_ID は実際の Cloud プロジェクトの ID に置き換えます。
    3. PROJECT_LOCATION は Cloud プロジェクトのロケーションに置き換えます。
  6. 次の環境変数を設定します。

    export GOOGLE_GENAI_USE_VERTEXAI=true
    export GOOGLE_CLOUD_PROJECT=PROJECT_ID
    export GOOGLE_CLOUD_LOCATION=PROJECT_LOCATION
    export GOOGLE_CLOUD_STORAGE_BUCKET=CLOUD_STORAGE_BUCKET_NAME

    次のように置き換えます。

    1. CLOUD_STORAGE_BUCKET_NAME は、作成したバケットの名前に置き換えます。
    2. PROJECT_ID は実際の Cloud プロジェクトの ID に置き換えます。
    3. PROJECT_LOCATION は Cloud プロジェクトのロケーションに置き換えます。
  7. 仮想環境から ADK エージェントをインストールしてデプロイします。

    python3 -m venv myenv
    source myenv/bin/activate
    poetry install --with deployment
    python3 deployment/deploy.py --create
  8. エージェント ID を取得します。これは、後で Chat アプリを構成するときに必要になります。

    python3 deployment/deploy.py --list

Chat アプリ プロジェクトを作成して構成する

  1. 次のボタンをクリックして、A2A AI Agent Quickstart Apps Script プロジェクトを開きます。

    プロジェクトを開く

  2. [概要] > コピーを作成するためのアイコン [コピーを作成] をクリックします。

  3. Apps Script プロジェクトで、 プロジェクト設定のアイコン [**プロジェクトの設定**] > [**スクリプトのプロパティを編集**] > [**スクリプトのプロパティを追加**] をクリックして、次のスクリプト プロパティを追加します。

    1. REASONING_ENGINE_RESOURCE_NAME は、前の手順でコピーした Vertex AI エージェントのリソース名に置き換えます。
    2. SERVICE_ACCOUNT_KEY は、前の手順でダウンロードしたサービス アカウントの JSON キー({ ... } など)に置き換えます。
  4. [スクリプトのプロパティを保存] をクリックします。

  5. Google API Console で、メニュー アイコン > [IAM と管理] > [設定] に移動します。

    [IAM と管理] の [設定] に移動

  6. [プロジェクト番号] フィールドで、値をコピーします。

  7. Apps Script プロジェクトで、 [プロジェクト設定のアイコン プロジェクトの設定] をクリックします。

  8. [Google Cloud Platform(GCP)プロジェクト] で、[プロジェクトを変更] をクリックします。

  9. [GCP プロジェクト番号] に、 前の手順でコピーした Google Cloud プロジェクト番号を貼り付けます。

  10. [プロジェクトを設定] をクリックします。これで、Cloud プロジェクトと Apps Script プロジェクトが接続されました。

テスト デプロイを作成する

この Apps Script プロジェクトにはデプロイ ID が必要です。次の手順で使用します。

ヘッド デプロイ ID を取得する手順は次のとおりです。

  1. Chat アプリの Apps Script プロジェクトで、 [デプロイ] > [デプロイをテスト] をクリックします。
  2. [**ヘッド デプロイ ID**] で、コピーを作成するためのアイコン [**コピー**] をクリックします。
  3. [完了] をクリックします。

Chat アプリを構成する

Apps Script デプロイを使用して、次の手順に沿ってテスト用の Google Chat アプリをデプロイします。

  1. [API Console] で Google Chat API を検索し、 [Google Chat API] をクリックします。
  2. [管理] をクリックします。
  3. [構成] をクリックして、Chat アプリを設定します。

    1. [アプリ名] フィールドに「A2A Quickstart」と入力します。
    2. [アバターの URL] フィールドに「https://developers.google.com/workspace/add-ons/images/quickstart-app-avatar.png」と入力します。
    3. [説明] フィールドに「A2A Quickstart」と入力します。
    4. [機能] で [スペースとグループ会話に参加する] を選択します。
    5. [接続設定] で [Apps Script プロジェクト] を選択します。
    6. [デプロイ ID] フィールドに、先ほどコピーしたヘッド デプロイ ID を貼り付けます。
    7. [可視性] で [**ドメイン内の特定のユーザーとグループ**] を選択し、メールアドレスを入力します。
  4. [保存] をクリックします。

Chat アプリはメッセージに応答する準備ができました。

Chat アプリをテストする

Chat アプリをテストするには、Chat アプリとのダイレクト メッセージ スペースを開いてメッセージを送信します。

  1. 信頼できるテスターとして追加したときに指定した Google Workspace アカウントを使用して、Google Chat を開きます。

    Google Chat に移動

  2. [新しいチャット] をクリックします。
  3. [1 人以上のユーザーを追加] フィールドに、Chat アプリの名前を入力します。
  4. 結果から Chat アプリを選択します。ダイレクト メッセージが開きます。

  5. そのアプリの新しいダイレクト メッセージに、「The Eiffel Tower was completed in 1900」と入力して enter を押します。

    Chat アプリは、Critic サブエージェントと Reviser サブエージェントのレスポンスを返します。

信頼できるテスターを追加して、インタラクティブ機能のテストの詳細を確認するには、 Google Chat アプリのインタラクティブ機能をテストするをご覧ください。

トラブルシューティング

Google Chat アプリまたは カードがエラーを返すと、 Chat インターフェースに「問題が発生しました」というメッセージが表示されます。 または「リクエストを処理できません。」Chat UI にエラー メッセージが表示されない場合でも、Chat アプリまたは カードで予期しない結果が生成されることがあります。たとえば、カード メッセージが表示されないことがあります。

Chat UI にエラー メッセージが表示されない場合でも、 エラーの修正に役立つ説明的なエラー メッセージとログデータを利用できます Chat アプリのエラー ロギングが有効になっている場合は、。エラーの表示、 デバッグ、修正については、 Google Chat エラーのトラブルシューティングと修正をご覧ください。

クリーンアップ

このチュートリアルで使用した リソースについて、Google Cloud アカウントに課金されないようにするには、 Cloud プロジェクトを削除することをおすすめします。

  1. Google API Console で、[リソースの管理] ページに移動します。 [Menu] > [IAM & Admin] > [Manage Resources] をクリックします。

    [Resource Manager] に移動

  2. プロジェクト リストで、削除するプロジェクトを選択し、 [Delete] . をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。