סוכני Agent2Agent (A2A) ב-Agent Registry מפרסמים ממשקי פרוטוקול שמכילים כתובת URL של נקודת קצה וקישור פרוטוקול (למשל HTTP_JSON). אתם יכולים למצוא את כתובת ה-URL של סוכן במאגר כדי להפעיל את שיטות ה-A2A שלו מלקוחות או מכלים מותאמים אישית לניהול תהליכים.
בקצרה
| מפרט | פרטים |
|---|---|
| Discovery API | agentregistry.googleapis.com (v1) |
| מארח של שרת proxy להפעלת פונקציות | LOCATION-discoveryengine.googleapis.com |
| קישור לפרוטוקול | HTTP_JSON |
| מזהה פרויקט של כתובת URL | Google Cloud מספר הפרויקט (לא מזהה הפרויקט) |
| שיטות A2A נתמכות | GET /v1/card, POST /v1/message:send, POST /v1/message:stream |
| סכימת הודעות נדרשת | message.role = "ROLE_USER", content[].text, ייחודי messageId |
| הרשאות IAM נדרשות | roles/agentregistry.viewer (גילוי) וdiscoveryengine.assistants.assist (הפעלה) |
לפני שמתחילים
- מפעילים את Agent Registry API (
agentregistry.googleapis.com) ואת Discovery Engine API (discoveryengine.googleapis.com) ב Google Cloud פרויקט. - אם הסוכן לא נוצר ישירות באפליקציית Gemini Enterprise, מייבאים את הסוכן מ-Agent Registry ומעניקים למשתמשי הקצה גישה אליו. הוראות מפורטות מופיעות במאמר ייבוא סוכני A2A מ-Agent Registry.
- נותנים לחשבון המשתמש של המבצע את ההרשאות המתאימות ב-IAM:
- כדי לקרוא את המרשם: Agent Registry Viewer (
roles/agentregistry.viewer). - כדי להפעיל את הסוכן: עורך Discovery Engine (
roles/discoveryengine.editor) או תפקיד מותאם אישית שכולל את ההרשאהdiscoveryengine.assistants.assist.
- כדי לקרוא את המרשם: Agent Registry Viewer (
- אם אתם מבצעים אימות באמצעות Application Default Credentials (ADC), אתם צריכים להגדיר את הלקוח כך שישלח את כותרת פרויקט המכסה:
-H "X-Goog-User-Project: PROJECT_ID". - אופציונלי: אם אתם מתכננים לעטוף סוכנים מרוחקים כסוכני משנה ברמת התוכנה, אתם יכולים להתקין את ספריית הערכה לפיתוח סוכנים (ADK):
pip install "google-adk[a2a]>=1.29.0".
שלב 1: גילוי הסוכן ונקודת הקצה שלו מסוג A2A
כדי להפעיל סוכן A2A, קודם צריך למצוא את הurl שלו שפורסם ב-Agent Registry. מפרטים את הסוכנים במיקום הרישום (למשל us או eu, שמועברים כפרמטר של הנתיב במארח הגלובלי agentregistry.googleapis.com):
curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://agentregistry.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/agents?pageSize=100"
אפשר גם לחפש סוכן לפי קידומת של שם לתצוגה באמצעות Google Cloud CLI:
gcloud agent-registry agents search \
--project=PROJECT_ID \
--location=LOCATION \
--search-string="displayName:My_Agent_*"
במשאב הסוכן שמוחזר, בודקים את המערך protocols. מאתרים את הרשומה שבה type שווה ל-A2A_AGENT ו-interfaces[].protocolBinding שווה ל-HTTP_JSON. מחפשים את url המתאים:
{
"name": "projects/PROJECT_ID/locations/LOCATION/agents/AGENT_RESOURCE_ID",
"displayName": "My Agent",
"protocols": [
{
"type": "A2A_AGENT",
"protocolVersion": "0.3.0",
"interfaces": [
{
"url": "https://LOCATION-discoveryengine.googleapis.com/v1/projects/PROJECT_NUMBER/locations/LOCATION/collections/default_collection/engines/ENGINE_ID/assistants/default_assistant/agents/AGENT_ID/a2a",
"protocolBinding": "HTTP_JSON"
}
]
}
]
}
לסכימת משאבי הסוכן המלאה, אפשר לעיין במאמרי העזרה של ה-API בארכיטקטורת REST projects.locations.agents.
שלב 2: שליפת כרטיס הנציג
כרטיס הסוכן מספק מטא-נתונים שמתארים את הזהות, התיאור והיכולות של הקלט והפלט של הסוכן. כדי לאחזר את הכרטיס, שולחים בקשת GET לנתיב /v1/card שנוסף לכתובת נקודת הקצה של הסוכן מסוג A2A:
curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"A2A_ENDPOINT_URL/v1/card"
דוגמה למטען ייעודי (payload) של תגובה:
{
"name": "My Agent",
"description": "What the agent does.",
"url": "A2A_ENDPOINT_URL",
"capabilities": {},
"defaultInputModes": ["text"],
"defaultOutputModes": ["text"],
"preferredTransport": "HTTP+JSON"
}
שלב 3: שליחת הודעה
כדי לשלוח שאילתת משתמש לסוכן, שולחים בקשת POST אל /v1/message:send. גוף הבקשה צריך להיות בהתאם לסכימת ההודעות A2A, ולכלול את הערך ROLE_USER בשדה role, מערך content שמכיל חלקי טקסט ומזהה messageId שנוצר באופן ייחודי:
curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"A2A_ENDPOINT_URL/v1/message:send" \
-d '{
"message": {
"role": "ROLE_USER",
"content": [
{
"text": "What can you help me with?"
}
],
"messageId": "UNIQUE_UUID_STRING"
}
}'
במטען הייעודי (payload) של התגובה, התשובה של הסוכן מוחזרת באובייקט message:
{
"message": {
"contextId": "projects/PROJECT_NUMBER/locations/LOCATION/collections/default_collection/engines/ENGINE_ID/sessions/SESSION_ID",
"role": "ROLE_AGENT",
"content": [
{
"text": "I am an AI assistant..."
}
]
}
}
משרשרים את מחרוזות הטקסט בתוך content[].text כדי להציג את התשובה המלאה. כדי להמשיך את השיחה באותו סשן, שומרים את המחרוזת contextId שמוחזרת ומספקים אותה כ-message.contextId בבקשה הבאה.
כאן אפשר לראות את הסכימה המלאה של מטען הנתונים של ההודעה ב-REST API של A2A message:send.
הצגת התשובות באופן שוטף
כדי להזרים את הפלט, שולחים בקשת POST עם גוף הודעה זהה לכתובת /v1/message:stream:
curl -N -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"A2A_ENDPOINT_URL/v1/message:stream" \
-d '{
"message": {
"role": "ROLE_USER",
"content": [
{
"text": "Say hello."
}
],
"messageId": "UNIQUE_UUID_STRING"
}
}'
נקודת הקצה מחזירה מערך JSON של אובייקטים של נתחים שמוזרמים דרך HTTP. מצרפים את חלקי content[].text ברצף כשהם מגיעים. חלקים של תוכן בסטרימינג מכילים גם את התוכן metadata.sessionInfo ואת התוכן metadata.assistToken.
מידע על מפרט המטען הייעודי (payload) של הסטרימינג זמין במאמר A2A message:stream REST API reference.
קריאה לנקודת קצה (endpoint) של A2A באמצעות Python
סקריפט Python הזה מפענח נקודת קצה של סוכן A2A ב-Agent Registry ושולח הודעה באמצעות בקשות HTTP גולמיות:
# Install dependencies: pip install google-auth requests
import uuid
import google.auth
from google.auth.transport.requests import AuthorizedSession
# TODO(developer): Replace placeholder values with your project ID and location.
project_id = "PROJECT_ID"
location = "LOCATION" # Registry location (for example: "us" or "eu")
target_display_name = "My Agent"
query_text = "What can you help me with?"
# Initialize credentials and authorized session
creds, _ = google.auth.default(
scopes=["https://www.googleapis.com/auth/cloud-platform"]
)
session = AuthorizedSession(creds)
# Step 1: Resolve the A2A endpoint URL from the Agent Registry
registry_url = (
f"https://agentregistry.googleapis.com/v1/"
f"projects/{project_id}/locations/{location}/agents"
)
response = session.get(registry_url)
response.raise_for_status()
agents = response.json().get("agents", [])
def get_a2a_url(agent_resource):
for proto in agent_resource.get("protocols") or []:
if proto.get("type") == "A2A_AGENT":
for iface in proto.get("interfaces", []):
if iface.get("protocolBinding") == "HTTP_JSON":
return iface.get("url")
return None
target_agent = next(
(a for a in agents if a.get("displayName") == target_display_name),
None
)
if not target_agent:
raise SystemExit(f"Agent '{target_display_name}' not found in registry.")
endpoint_url = get_a2a_url(target_agent)
if not endpoint_url:
raise SystemExit("Target agent does not publish an HTTP_JSON A2A endpoint.")
# Step 2: Fetch and verify the agent card
card_resp = session.get(f"{endpoint_url}/v1/card")
card_resp.raise_for_status()
card = card_resp.json()
print("Resolved Agent:", card.get("name"))
# Step 3: Send an A2A message
body = {
"message": {
"role": "ROLE_USER",
"content": [{"text": query_text}],
"messageId": str(uuid.uuid4()),
}
}
send_resp = session.post(f"{endpoint_url}/v1/message:send", json=body)
send_resp.raise_for_status()
reply_message = send_resp.json().get("message", {})
full_reply_text = "".join(
part.get("text", "") for part in reply_message.get("content", [])
)
print("Agent Reply:", full_reply_text)
פישוט התזמור באמצעות ADK
הערכה לפיתוח סוכנים (ADK) פותרת אוטומטית נקודות קצה של רישום ועוטפת סוכני A2A מרוחקים כסוכני משנה:
from google.adk.integrations.agent_registry import AgentRegistry
# Initialize registry client
registry = AgentRegistry(project_id="PROJECT_ID", location="LOCATION")
# Resolve remote A2A agent directly by resource name
remote_agent = registry.get_remote_a2a_agent(
agent_name="agents/AGENT_RESOURCE_ID"
)
הערות נוספות
נקודות קצה מסוג A2A מתנהגות באופן הבא:
- שמות נתיבים מדויקים: רק
GET {url}/v1/card,POST {url}/v1/message:sendו-POST {url}/v1/message:streamנתמכים עבור קישורי HTTP+JSON. - אימות סכמה מחמיר: העברת
"user"רגיל בתור התפקיד מחזירה שגיאת HTTP400 Bad Request. חובה להעביר את מחרוזת ה-enum"ROLE_USER". באופן דומה, טקסט ההודעה צריך להיות בתוך המערךcontentולא בתוךparts, וחובה להשתמש ב-messageId. - שגיאה בהפעלת סוכן שאינו סוכן A2A: אם לסוכן אין רשומה של פרוטוקול
A2A_AGENTבמאגר (למשל, סוכנים מסוימים שנוצרו מראש או סוכנים מנוהלים), קריאה ל-getCardבכתובת ה-URL של ה-proxy שלו מחזירה501 UNIMPLEMENTED("... is not supported yet"), וקריאה ל-message:sendמחזירה400 INVALID_ARGUMENT("Unsupported agent"). - מספר הפרויקט בכתובת ה-URL: המאגר מחזיר כתובת URL של A2A שמכילה את מספר הפרויקט ולא את מזהה הפרויקט. אין לשנות את המחרוזת המספרית הזו כששולחים בקשות HTTP.
פתרון בעיות
בטבלה הבאה מפורטות שגיאות נפוצות בנקודות קצה של A2A ופתרונות לבעיות האלה:
| תיאור הבעיה | הסיבה הנפוצה | רזולוציה |
|---|---|---|
HTTP 404 בבקשה getCard |
שימוש בכינוי נתיב שגוי (כמו /v1:getCard או /.well-known/agent-card.json). |
שליחת בקשת GET אך ורק אל GET {url}/v1/card. |
| HTTP 400 *"Unknown name 'parts'"* | שימוש בעיצוב ישן או בעיצוב של גוף הלקוח ב-AI גנרטיבי. | מחרוזות הטקסט צריכות להיות בתוך content ולא בתוך parts. |
HTTP 400 invalid enum value for role |
העברת אותיות קטנות "user" או "user_role". |
מגדירים את message.role בדיוק לערך "ROLE_USER". |
| HTTP 501 *"is not supported yet"* | התקשרות אל getCard לסוכן שלא מפרסם ממשק A2A. |
לפני שמתקשרים, בודקים את המערך protocols של משאב הרישום כדי לוודא שיש תמיכה ב-A2A_AGENT. |
| HTTP 400 *"Unsupported agent"* | מתקשרים אל message:send בנציג שאינו A2A. |
בוחרים סוכן שהגדרת הרישום שלו כוללת קישור לפרוטוקול A2A_AGENT פעיל. |
HTTP 401 או HTTP 403 Permission Denied |
חסרות הרשאות OAuth, חסרים תפקידי IAM או שחסרה כותרת של פרויקט מכסה. | בודקים את התפקידים ב-IAM של המתקשר (agentregistry.viewer ו-assistants.assist), מאמתים את ההיקף של cloud-platform ומעבירים את -H "X-Goog-User-Project: PROJECT_ID" אם משתמשים ב-ADC. |
מקורות מידע שקשורים לנושא
- סקירה כללית של Agent Registry
- חיפוש סוכנים וכלים ב-Agent Registry
- פתרון בעיות בנקודות קצה ובכלי תזמור (ADK)
- הפניה ל-API ל-REST של הודעות A2A:send