Agent Registry의 Agent2Agent (A2A) 에이전트는 엔드포인트 URL과 프로토콜 바인딩 (예: HTTP_JSON)이 포함된 프로토콜 인터페이스를 알립니다. 레지스트리에서 에이전트의 URL을 검색하여 커스텀 오케스트레이터 또는 클라이언트에서 A2A 메서드를 호출할 수 있습니다.
요약 정보
| 사양 | 세부정보 |
|---|---|
| Discovery API | agentregistry.googleapis.com (v1) |
| 호출 프록시 호스트 | LOCATION-discoveryengine.googleapis.com |
| 프로토콜 바인딩 | HTTP_JSON |
| URL 프로젝트 식별자 | Google Cloud 프로젝트 번호 (프로젝트 ID 아님) |
| 지원되는 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 (호출) |
시작하기 전에
- your Google Cloud project에서 Agent Registry API (
agentregistry.googleapis.com) 및 Discovery Engine API (discoveryengine.googleapis.com)를 사용 설정합니다. - Gemini Enterprise 앱에서 직접 에이전트를 만들지 않은 경우 Agent Registry에서 에이전트를 가져오고 최종 사용자에게 액세스 권한을 부여합니다. 자세한 내용은 Agent Registry에서 A2A 에이전트 가져오기를 참고하세요.
- 호출자 주 구성원에게 적절한 IAM 권한을 부여합니다.
- 레지스트리 읽기: Agent Registry 뷰어 (
roles/agentregistry.viewer) - 에이전트 호출: Discovery Engine 편집자 (
roles/discoveryengine.editor) 또는discoveryengine.assistants.assist가 포함된 커스텀 역할
- 레지스트리 읽기: Agent Registry 뷰어 (
- 애플리케이션 기본 사용자 인증 정보 (ADC)를 사용하여 인증하는 경우 할당량 프로젝트 헤더를 전송하도록 클라이언트를 구성합니다.
-H "X-Goog-User-Project: PROJECT_ID". - 원격 에이전트를 프로그래매틱 하위 에이전트로 래핑하려는 경우 선택적으로 에이전트 개발 키트(ADK) 라이브러리(
pip install "google-adk[a2a]>=1.29.0")를 설치합니다.
1단계: 에이전트 및 A2A 엔드포인트 검색
A2A 에이전트를 호출하려면 먼저 Agent Registry에서 공지된 url을 검색합니다. 레지스트리 위치 (예: 전역 agentregistry.googleapis.com 호스트에서 경로 매개변수로 전달되는 us 또는 eu)의 에이전트를 나열합니다.
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"
CLI를 사용하여 표시 이름 프리픽스로 에이전트를 검색할 수도 있습니다: Google Cloud
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"
}
]
}
]
}
전체 에이전트 리소스 스키마는 projects.locations.agents REST API 참조를 확인하세요.
2단계: 에이전트 카드 가져오기
에이전트 카드는 에이전트의 ID, 설명, 입력/출력 기능을 설명하는 메타데이터를 제공합니다. 카드를 가져오려면 에이전트의 A2A 엔드포인트 URL에 추가된 /v1/card 경로로 HTTP GET 요청을 전송합니다.
curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"A2A_ENDPOINT_URL/v1/card"
응답 페이로드 예시:
{
"name": "My Agent",
"description": "What the agent does.",
"url": "A2A_ENDPOINT_URL",
"capabilities": {},
"defaultInputModes": ["text"],
"defaultOutputModes": ["text"],
"preferredTransport": "HTTP+JSON"
}
3단계: 메시지 보내기
사용자 쿼리를 에이전트에 보내려면 /v1/message:send에 POST 요청을 합니다. 요청 본문은 ROLE_USER로 설정된 role, 텍스트 부분이 포함된 content 배열, 고유하게 생성된 messageId가 필요한 A2A 메시지 스키마를 준수해야 합니다.
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"
}
}'
응답 페이로드에서 에이전트의 답장이 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로 제공합니다.
전체 메시지 페이로드 스키마는 A2A message:send REST API 참조를 확인하세요.
응답을 점진적으로 스트리밍
출력을 스트리밍하려면 동일한 메시지 본문으로 /v1/message:stream에 POST 요청을 전송합니다.
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"
}
}'
엔드포인트는 HTTP를 통해 스트리밍된 청크 객체의 JSON 배열을 반환합니다. content[].text 프래그먼트가 도착하면 순차적으로 추가합니다. 스트리밍된 청크에는 metadata.sessionInfo 및 metadata.assistToken도 포함됩니다.
스트리밍 페이로드 사양은 A2A message:stream REST API 참조를 확인하세요.
Python을 사용하여 A2A 엔드포인트 호출
이 Python 스크립트는 Agent Registry에서 A2A 엔드포인트를 확인하고 원시 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 엔드포인트에는 다음과 같은 동작이 있습니다.
- 엄격한 경로 이름 지정: HTTP+JSON 바인딩의 경우
GET {url}/v1/card,POST {url}/v1/message:send,POST {url}/v1/message:stream만 지원됩니다. - 엄격한 스키마 유효성 검사: 일반
"user"를 역할로 전달하면 HTTP400 Bad Request오류가 반환됩니다. 열거형 문자열"ROLE_USER"를 전달해야 합니다. 마찬가지로 메시지 텍스트는parts가 아닌content배열 내에 있어야 하며messageId가 엄격하게 필요합니다. - 비 A2A 에이전트 호출 오류: 에이전트 레지스트리에
A2A_AGENT프로토콜 항목이 없는 경우 (예: 특정 사전 빌드 또는 관리형 에이전트) 프록시 URL에서getCard를 호출하면501 UNIMPLEMENTED("... is not supported yet")가 반환되고message:send를 호출하면400 INVALID_ARGUMENT("Unsupported agent")가 반환됩니다. - URL의 프로젝트 번호: 레지스트리는 프로젝트 ID가 아닌 프로젝트 번호가 포함된 A2A URL을 반환합니다. HTTP 요청을 할 때 이 숫자 문자열을 변경하지 마세요.
문제 해결
다음 표를 사용하여 일반적인 A2A 엔드포인트 오류를 해결하세요.
| 증상 | 가능한 원인 | 해결 방법 |
|---|---|---|
요청에 대한 HTTP 404getCard |
잘못된 경로 별칭 (예: /v1:getCard 또는 /.well-known/agent-card.json)을 사용합니다. |
GET 요청을 GET {url}/v1/card로 엄격하게 전송합니다. |
| HTTP 400 *"Unknown name 'parts'"* | 이전 또는 생성형 AI 클라이언트 본문 형식을 사용합니다. | 텍스트 문자열을 parts가 아닌 content 내에 배치합니다. |
role에 대한 HTTP 400 잘못된 열거형 값 |
소문자 "user" 또는 "user_role"을 전달합니다. |
message.role을 정확히 "ROLE_USER"로 설정합니다. |
| HTTP 501 *"is not supported yet"* | A2A 인터페이스를 게시하지 않는 에이전트에서 getCard를 호출합니다. |
호출하기 전에 레지스트리 리소스의 protocols 배열을 검사하여 A2A_AGENT 지원을 확인합니다. |
| HTTP 400 *'Unsupported agent'* | 비 A2A 에이전트에서 message:send를 호출합니다. |
레지스트리 정의에 활성 A2A_AGENT 프로토콜 바인딩이 포함된 에이전트를 선택합니다. |
HTTP 401 또는 HTTP 403 Permission Denied |
OAuth 범위 누락, IAM 역할 누락 또는 할당량 프로젝트 헤더 누락 | 호출자 IAM 역할 (agentregistry.viewer 및 assistants.assist)을 확인하고 cloud-platform 범위를 확인하며 ADC를 사용하는 경우 -H "X-Goog-User-Project: PROJECT_ID"를 전달합니다. |
관련 리소스
- Agent Registry 개요
- Agent Registry에서 에이전트 및 도구 검색
- 엔드포인트 확인 및 오케스트레이터 빌드 (ADK)
- A2A message:send REST API 참조