Gli agenti Agent2Agent (A2A) in Agent Registry pubblicizzano le interfacce di protocollo contenenti un URL endpoint e un'associazione del protocollo (ad esempio HTTP_JSON). Puoi scoprire l'URL di un agente nel registro per chiamare i relativi metodi A2A da orchestratori o client personalizzati.
In sintesi
| Specifica | Dettagli |
|---|---|
| API Discovery | agentregistry.googleapis.com (v1) |
| Host proxy di chiamata | LOCATION-discoveryengine.googleapis.com |
| Associazione del protocollo | HTTP_JSON |
| Identificatore del progetto URL | Google Cloud Numero di progetto (non ID progetto) |
| Metodi A2A supportati | GET /v1/card, POST /v1/message:send, POST /v1/message:stream |
| Schema del messaggio richiesto | message.role = "ROLE_USER", content[].text, messageId univoco |
| Autorizzazioni IAM richieste | roles/agentregistry.viewer (rilevamento) e discoveryengine.assistants.assist (chiamata) |
Prima di iniziare
- Abilita l'API Agent Registry (
agentregistry.googleapis.com) e l'API Discovery Engine (discoveryengine.googleapis.com) nel tuo Google Cloud progetto. - Se l'agente non è stato creato direttamente nell'app Gemini Enterprise, importalo da Agent Registry e concedi agli utenti finali l'accesso. Per istruzioni, vedi Importare agenti A2A da Agent Registry.
- Concedi all'entità chiamante le autorizzazioni IAM appropriate:
- Per leggere il registro: visualizzatore di Agent Registry (
roles/agentregistry.viewer). - Per chiamare l'agente: editor di Discovery Engine (
roles/discoveryengine.editor) o un ruolo personalizzato che includediscoveryengine.assistants.assist.
- Per leggere il registro: visualizzatore di Agent Registry (
- Se esegui l'autenticazione utilizzando le Credenziali predefinite dell'applicazione (ADC), configura il client in modo che invii l'intestazione del progetto di quota:
-H "X-Goog-User-Project: PROJECT_ID". - (Facoltativo) Installa la libreria Agent Development Kit (ADK) se prevedi di eseguire il wrapping degli agenti remoti come sub-agenti programmatici:
pip install "google-adk[a2a]>=1.29.0".
Passaggio 1: rileva l'agente e il relativo endpoint A2A
Per chiamare un agente A2A, devi prima scoprire l'url pubblicizzato in Agent Registry. Elenca gli agenti nella località del registro (ad esempio us o eu, passati come parametro di percorso sull'host globale 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"
Puoi anche cercare un agente in base al prefisso del nome visualizzato utilizzando l' Google Cloud interfaccia a riga di comando:
gcloud agent-registry agents search \
--project=PROJECT_ID \
--location=LOCATION \
--search-string="displayName:My_Agent_*"
Nella risorsa dell'agente restituita, esamina l'array protocols. Individua la voce in cui type è uguale a A2A_AGENT e interfaces[].protocolBinding è uguale a HTTP_JSON. Estrai l'url corrispondente:
{
"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"
}
]
}
]
}
Consulta il riferimento API REST projects.locations.agents per lo schema completo della risorsa dell'agente.
Passaggio 2: recupera la scheda dell'agente
La scheda dell'agente fornisce metadati che descrivono l'identità, la descrizione e le funzionalità di input/output dell'agente. Per recuperare la scheda, invia una richiesta GET HTTP al percorso /v1/card aggiunto all'URL dell'endpoint A2A dell'agente:
curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"A2A_ENDPOINT_URL/v1/card"
Esempio di payload di risposta:
{
"name": "My Agent",
"description": "What the agent does.",
"url": "A2A_ENDPOINT_URL",
"capabilities": {},
"defaultInputModes": ["text"],
"defaultOutputModes": ["text"],
"preferredTransport": "HTTP+JSON"
}
Passaggio 3: invia un messaggio
Per inviare una query utente all'agente, invia una richiesta POST a /v1/message:send. Il corpo della richiesta deve essere conforme allo schema del messaggio A2A, che richiede che role sia impostato su ROLE_USER, un array content contenente parti di testo e un messageId generato in modo univoco:
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"
}
}'
Nel payload della risposta, la risposta dell'agente viene restituita all'interno dell'oggetto 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..."
}
]
}
}
Concatena le stringhe di testo all'interno di content[].text per visualizzare la risposta completa. Per continuare la conversazione nella stessa sessione, salva la stringa contextId restituita e forniscila come message.contextId nella richiesta successiva.
Consulta il riferimento API REST A2A message:send per lo schema completo del payload del messaggio.
Risposte dinamiche in modo incrementale
Per l'output dinamico, invia una richiesta POST con un corpo del messaggio identico a /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"
}
}'
L'endpoint restituisce un array JSON di oggetti di blocchi dinamici tramite HTTP. Aggiungi i frammenti content[].text in sequenza man mano che arrivano. I blocchi dinamici contengono anche metadata.sessionInfo e metadata.assistToken.
Consulta il riferimento API REST A2A message:stream per la specifica del payload dinamico.
Chiama un endpoint A2A utilizzando Python
Questo script Python risolve un endpoint A2A in Agent Registry e invia un messaggio utilizzando richieste HTTP non elaborate:
# 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)
Semplifica l'orchestrazione utilizzando l'ADK
Agent Development Kit (ADK) risolve automaticamente gli endpoint del registro ed esegue il wrapping degli agenti A2A remoti come sub-agenti:
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"
)
Note aggiuntive
Gli endpoint A2A hanno i seguenti comportamenti:
- Denominazione rigorosa dei percorsi: per i binding HTTP+JSON sono supportati solo
GET {url}/v1/card,POST {url}/v1/message:sendePOST {url}/v1/message:stream. - Validazione rigorosa dello schema: il passaggio di
"user"semplice come ruolo restituisce un errore HTTP400 Bad Requesterror. Devi passare la stringa di enumerazione"ROLE_USER". Allo stesso modo, il testo del messaggio deve risiedere all'interno dell'arraycontentanzichépartsemessageIdè strettamente obbligatorio. - Errore di chiamata dell'agente non A2A: se un agente non ha una voce di protocollo
A2A_AGENTnel registro (ad esempio alcuni agenti predefiniti o gestiti), la chiamata agetCardsul relativo URL proxy restituisce501 UNIMPLEMENTED("... is not supported yet") e la chiamata amessage:sendrestituisce400 INVALID_ARGUMENT("Unsupported agent"). - Numero di progetto nell'URL: il registro restituisce un URL A2A contenente il numero di progetto anziché l'ID progetto. Non modificare questa stringa numerica quando effettui richieste HTTP.
Risoluzione dei problemi
Utilizza la tabella seguente per risolvere i problemi relativi agli errori comuni degli endpoint A2A:
| Sintomo | Probabile causa | Risoluzione |
|---|---|---|
HTTP 404 sulla richiesta getCard |
Utilizzo di un alias di percorso errato (ad esempio /v1:getCard o /.well-known/agent-card.json). |
Invia la richiesta GET rigorosamente a GET {url}/v1/card. |
| HTTP 400 *"Unknown name 'parts'"* | Utilizzo della formattazione del corpo del client di AI generativa o precedente. | Inserisci le stringhe di testo all'interno di content, non parts. |
HTTP 400 valore di enumerazione non valido per role |
Passaggio di "user" o "user_role" in minuscolo. |
Imposta message.role esattamente su "ROLE_USER". |
| HTTP 501 *"is not supported yet"* | Chiamata a getCard su un agente che non pubblica un'interfaccia A2A. |
Esamina l'array protocols della risorsa del registro per confermare il supporto di A2A_AGENT prima di chiamare. |
| HTTP 400 *"Unsupported agent"* | Chiamata a message:send su un agente non A2A. |
Scegli un agente la cui definizione del registro include un'associazione del protocollo A2A_AGENT attiva. |
HTTP 401 o HTTP 403 Permission Denied |
Ambiti OAuth mancanti, ruoli IAM mancanti o intestazione del progetto di quota mancante. | Controlla i ruoli IAM del chiamante (agentregistry.viewer e assistants.assist); verifica l'ambito cloud-platform; passa -H "X-Goog-User-Project: PROJECT_ID" se utilizzi ADC. |