איך בונים אפליקציה ל-Google Chat עם סוכן Agent2Agent

בדף הזה מוסבר איך ליצור תוסף ל-Google Workspace שפועל ב-Google Chat ומתקשר עם סוכן AI שמשתמש בפרוטוקול Agent2Agent (A2A). מפתחים את הסוכן באמצעות ערכת פיתוח הסוכנים (ADK) ומארחים אותו ב-Vertex AI Agent Engine.

סוכני AI תופסים את הסביבה שלהם באופן אוטונומי, מסיקים מסקנות ומבצעים פעולות מורכבות ומרובות שלבים כדי להשיג מטרה מוגדרת. במדריך הזה נסביר איך פורסים את הדוגמה של LLM Auditor multi-agent, שכוללת ביקורת ועריכה של עובדות באמצעות Gemini וחיפוש Google.

דוגמה לשימוש בכמה סוכנים ב-LLM Auditor כאפליקציית Chat.

התרשים הבא מציג את הארכיטקטורה ואת דפוס העברת ההודעות:

ארכיטקטורה של אפליקציית Chat שהוטמעה באמצעות נציג AI מסוג A2A.

בתרשים, משתמש שמקיים אינטראקציה עם אפליקציית צ'אט שמוטמע בה סוכן A2A, נהנה מזרימת המידע הבאה:

  1. משתמש שולח הודעה לאפליקציית Chat, בצ'אט ישיר או במרחב ב-Chat.
  2. הלוגיקה של אפליקציית Chat, שמוטמעת ב-Apps Script או כשרת אינטרנט עם נקודות קצה של HTTP, מקבלת את ההודעה ומעבדת אותה.
  3. הסוכן A2A שמתארח ב-Vertex AI Agent Engine מקבל את האינטראקציה ומעבד אותה.
  4. אפשר גם לשלב את אפליקציית Chat או את סוכן ה-AI עם שירותי Google Workspace, כמו יומן Google או Google Sheets, או עם שירותים אחרים של Google, כמו מפות Google או YouTube.
  5. אפליקציית Chat שולחת תשובות באופן אסינכרוני, באמצעות Google Chat API כדי להעביר את ההתקדמות של סוכן ה-AI.
  6. התשובות נשלחות למשתמש.

מטרות

  • מגדירים את הסביבה.
  • פורסים את סוכן A2A.
  • פורסים את אפליקציית Chat.
  • מגדירים את אפליקציית Chat.
  • בודקים את אפליקציית Chat.

דרישות מוקדמות

הגדרת הסביבה

הפעלת ממשקי ה-API של Google Cloud

לפני שאתם משתמשים בממשקי Google API, אתם צריכים להפעיל אותם בפרויקט ב-Google Cloud. בכל פרויקט אפשר להפעיל ממשק API אחד או יותר.
  • במסוף Google Cloud, מפעילים את ממשקי ה-API של Google Chat,‏ Vertex AI ו-Cloud Resource Manager.

    הפעלת ממשקי ה-API

מגדירים את מסך ההסכמה של OAuth

כל האפליקציות שמשתמשות ב-OAuth 2.0 דורשות הגדרה של מסך הסכמה. הגדרת מסך ההסכמה ל-OAuth של האפליקציה קובעת מה מוצג למשתמשים ולבודקי האפליקציות, ורושמת את האפליקציה כדי שתוכלו לפרסם אותה בהמשך.

  1. במסוף Google Cloud, עוברים אל תפריט > Google Auth platform > Branding.

    מעבר לדף Branding

  2. אם כבר הגדרתם את Google Auth platform, אתם יכולים לקבוע את ההגדרות הבאות של מסך ההסכמה ל-OAuth בקטעים Branding,‏ Audience וData Access. אם מופיעה ההודעה Google Auth platform not configured yet, לוחצים על Get Started:
    1. בקטע App Information בשדה App name, מזינים שם לאפליקציה.
    2. בקטע User support email, בוחרים כתובת אימייל לתמיכה שאליה משתמשים יפנו אם יש להם שאלות לגבי ההסכמה שלהם.
    3. לוחצים על Next.
    4. בקטע Audience, לוחצים על Internal.
    5. לוחצים על Next.
    6. בקטע Contact Information, מזינים כתובת אימייל שאליה אפשר לשלוח התראות על שינויים בפרויקט.
    7. לוחצים על Next.
    8. בקטע Finish, קוראים את המדיניות של Google בנושא נתוני משתמשים בשירותי API. אם אתם מסכימים, סמנו את התיבה I agree to the Google API Services: User Data Policy.
    9. לוחצים על Continue.
    10. לוחצים על Create.
  3. כרגע אתם יכולים לדלג על הוספת היקפי הרשאות. בעתיד, כשתיצרו אפליקציה לשימוש מחוץ לארגון שלכם ב-Google Workspace, תצטרכו לשנות את סוג המשתמש ל-External. לאחר מכן מוסיפים את היקפי ההרשאות שהאפליקציה דורשת. למידע נוסף, אפשר לעיין במדריך המלא בנושא הגדרת הסכמה ל-OAuth.

איך יוצרים חשבון שירות במסוף Google Cloud

כדי ליצור חשבון שירות חדש עם התפקיד Vertex AI User, פועלים לפי השלבים הבאים:

מסוף Google Cloud

  1. במסוף Google Cloud, לוחצים על סמל התפריט > IAM & Admin > Service Accounts (חשבונות שירות).

    לדף Service accounts

  2. לוחצים על יצירת חשבון שירות.
  3. ממלאים את פרטי חשבון השירות ולוחצים על יצירה והמשך.
  4. אופציונלי: מקצים תפקידים לחשבון השירות כדי לתת גישה למשאבים בפרויקט Google Cloud. פרטים נוספים זמינים במאמר הענקה, שינוי וביטול גישה למשאבים.
  5. לוחצים על המשך.
  6. אופציונלי: מזינים משתמשים או קבוצות שיכולים לנהל את חשבון השירות הזה ולבצע בו פעולות. פרטים נוספים מופיעים במאמר ניהול התחזות לחשבון שירות.
  7. לוחצים על סיום. רושמים את כתובת האימייל של חשבון השירות.

CLI של gcloud

  1. יוצרים את חשבון השירות:
    gcloud iam service-accounts create SERVICE_ACCOUNT_NAME \
      --display-name="SERVICE_ACCOUNT_NAME"
  2. אופציונלי: מקצים תפקידים לחשבון השירות כדי לתת גישה למשאבים בפרויקט Google Cloud. פרטים נוספים זמינים במאמר הענקה, שינוי וביטול גישה למשאבים.

חשבון השירות מופיע בדף של חשבון השירות.

יצירת מפתח פרטי

כדי ליצור ולהוריד מפתח פרטי לחשבון השירות, פועלים לפי השלבים הבאים:

  1. במסוף Google Cloud, לוחצים על סמל התפריט > IAM & Admin > Service Accounts (חשבונות שירות).

    לדף Service accounts

  2. בוחרים את חשבון השירות.
  3. לוחצים על מפתחות > הוספת מפתח > יצירת מפתח חדש.
  4. בוחרים באפשרות JSON ולוחצים על Create.

    זוג המפתחות הציבורי/הפרטי החדש נוצר ומורד למחשב שלכם כקובץ חדש. שומרים את קובץ ה-JSON שהורדתם בשם credentials.json בספריית העבודה. הקובץ הזה הוא העותק היחיד של המפתח. מידע על אחסון מאובטח של המפתח זמין במאמר ניהול מפתחות לחשבונות שירות.

  5. לוחצים על סגירה.

מידע נוסף על חשבונות שירות זמין במאמר בנושא חשבונות שירות במסמכי העזרה של Google Cloud IAM.

פריסת סוכן A2A

  1. אם עדיין לא עשיתם זאת, צריך לבצע אימות באמצעות חשבון Google Cloud ולהגדיר את Google Cloud CLI לשימוש בפרויקט Google Cloud.

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

    מחליפים את PROJECT_ID במזהה הפרויקט ב-Cloud.

  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. יוצרים קטגוריה חדשה ב-Cloud Storage שמוקדשת לסוכן ADK.

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

    מחליפים את מה שכתוב בשדות הבאים:

    1. CLOUD_STORAGE_BUCKET_NAME בשם ייחודי לקטגוריה שרוצים להשתמש בה.
    2. PROJECT_ID במזהה הפרויקט ב-Cloud.
    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.
    3. PROJECT_LOCATION במיקום של הפרויקט ב-Cloud.
  7. מתקינים ומפעילים את סוכן ADK מסביבה וירטואלית.

    python3 -m venv myenv
    source myenv/bin/activate
    poetry install --with deployment
    python3 deployment/deploy.py --create
  8. אחזור מזהה הסוכן. תצטרכו אותה מאוחר יותר, כשמגדירים את אפליקציית Chat.

    python3 deployment/deploy.py --list

יצירה והגדרה של פרויקט אפליקציית Chat

  1. לוחצים על הלחצן הבא כדי לפתוח את הפרויקט A2A AI Agent Quickstart ב-Apps Script.

    פתיחת הפרויקט

  2. לוחצים על סקירה כללית > הסמל ליצירת עותק יצירת עותק.

  3. בפרויקט Apps Script, לוחצים על הסמל של הגדרות הפרויקט Project Settings (הגדרות הפרויקט) > Edit script properties (עריכת מאפייני הסקריפט) > Add script property (הוספת מאפיין סקריפט) כדי להוסיף את מאפייני הסקריפט הבאים:

    1. REASONING_ENGINE_RESOURCE_NAME עם שם המשאב של סוכן Vertex AI שהעתקתם בשלבים הקודמים.
    2. SERVICE_ACCOUNT_KEY עם מפתח ה-JSON מחשבון השירות שהורד בשלבים הקודמים, כמו { ... }.
  4. לוחצים על שמירת מאפייני סקריפט.

  5. במסוף Google Cloud, לוחצים על סמל התפריט > IAM & Admin > Settings.

    כניסה לדף IAM & Admin Settings

  6. מעתיקים את הערך בשדה מספר הפרויקט.

  7. בפרויקט Apps Script, לוחצים על הסמל של הגדרות הפרויקט הגדרות הפרויקט.

  8. בקטע פרויקט Google Cloud Platform (GCP)‎, לוחצים על שינוי הפרויקט.

  9. בשדה מספר פרויקט GCP, מדביקים את מספר הפרויקט ב-Google Cloud שהועתק בשלבים הקודמים.

  10. לוחצים על הגדרת פרויקט. הפרויקט ב-Cloud והפרויקט ב-Apps Script מקושרים עכשיו.

יצירת פריסת בדיקה

כדי להשתמש בפרויקט Apps Script הזה בשלב הבא, צריך מזהה פריסה.

כדי לקבל את מזהה הפריסה העיקרית:

  1. בפרויקט Apps Script של אפליקציית Chat, לוחצים על Deploy (פריסה) > Test deployments (פריסות לבדיקה).
  2. בקטע מזהה פריסה של גרסת Head, לוחצים על הסמל ליצירת עותק העתקה.
  3. לוחצים על סיום.

הגדרת אפליקציית Chat

כדי לפרוס את אפליקציית Google Chat לבדיקה, פועלים לפי השלבים הבאים באמצעות הפריסה של Apps Script:

  1. במסוף, מחפשים את Google Chat API ולוחצים על Google Chat API.
  2. לוחצים על ניהול.
  3. לוחצים על Configuration (הגדרה) ומגדירים את אפליקציית Chat:

    1. בשדה שם האפליקציה, מזינים A2A Quickstart.
    2. בשדה כתובת ה-URL של האווטאר מזינים את הערך https://developers.google.com/workspace/add-ons/images/quickstart-app-avatar.png.
    3. בשדה Description (תיאור) מזינים A2A Quickstart.
    4. בקטע פונקציונליות, בוחרים באפשרות הצטרפות למרחבים ולשיחות קבוצתיות.
    5. בקטע 'הגדרות חיבור', בוחרים באפשרות פרויקט Apps Script.
    6. בשדה Deployment ID (מזהה פריסה), מדביקים את מזהה הפריסה של Head שהעתקתם קודם.
    7. בקטע 'חשיפה', בוחרים באפשרות אנשים וקבוצות ספציפיים בדומיין ומזינים את כתובת האימייל.
  4. לוחצים על שמירה.

אפליקציית Chat מוכנה להגיב להודעות.

בדיקת אפליקציית Chat

כדי לבדוק את אפליקציית Chat, פותחים מרחב לצ'אט ישיר עם אפליקציית Chat ושולחים הודעה:

  1. פותחים את Google Chat באמצעות חשבון Google Workspace שציינתם כשנוספתם כבודקים מהימנים.

    מעבר אל Google Chat

  2. לוחצים על צ'אט חדש.
  3. בשדה הוספת אדם אחד או יותר, מקלידים את השם של אפליקציית Chat.
  4. בוחרים את אפליקציית Chat מתוך התוצאות. ייפתח צ'אט ישיר.

  5. בצ'אט הישיר החדש עם האפליקציה, כותבים The Eiffel Tower was completed in 1900 ולוחצים עלenter.

    אפליקציית Chat משיבה עם תשובות של סוכני משנה מבקר ועורך.

כדי להוסיף בודקים מהימנים ולקבל מידע נוסף על בדיקת תכונות אינטראקטיביות, אפשר לעיין במאמר בדיקת תכונות אינטראקטיביות באפליקציות ל-Google Chat.

פתרון בעיות

כשמוחזרת שגיאה מאפליקציית Google Chat או מכרטיס, בממשק של Chat מוצגת ההודעה "משהו השתבש". או 'לא ניתן לעבד את הבקשה שלך'. לפעמים בממשק המשתמש של Chat לא מוצגת הודעת שגיאה, אבל אפליקציית Chat או הכרטיס מפיקים תוצאה לא צפויה. לדוגמה, יכול להיות שהודעה בכרטיס לא תופיע.

יכול להיות שלא תוצג הודעת שגיאה בממשק המשתמש של Chat, אבל אם הפעלתם את רישום השגיאות באפליקציות של Chat, תוכלו לראות הודעות שגיאה תיאוריות ונתוני יומן שיעזרו לכם לתקן את השגיאות. לקבלת עזרה בצפייה בשגיאות, באיתור באגים ובתיקון שגיאות, אפשר לעיין במאמר פתרון בעיות ותיקון שגיאות ב-Google Chat.

הסרת המשאבים

כדי להימנע מחיובים בחשבון Google Cloud בגלל השימוש במשאבים שנעשה במסגרת המדריך הזה, מומלץ למחוק את פרויקט Cloud.

  1. במסוף Google Cloud, עוברים לדף Manage resources. לוחצים על תפריט > IAM & Admin > Manage Resources.

    כניסה ל-Resource Manager

  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete .
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.