A2A vs ADK — 등록 모드 비교

Gemini Enterprise 에 에이전트를 등록할 때 선택하는 ADK / Agent Engine 모드와 A2A 모드의 차이, 같은 ADK 코드를 두 모드로 노출하는 방법

Gemini Enterprise 에 에이전트를 등록할 때 자주 받는 질문: 이미 Agent Engine 에 deploy 한 ADK 에이전트를 A2A 모드로도 등록할 수 있나? 결론부터: 그대로는 안 됩니다. 두 모드는 호스팅·API·호출 메서드가 모두 다릅니다.


목차

  1. 두 모드의 차이
  2. 언제 어떤 모드를 쓰는가
  3. 같은 ADK 코드를 A2A 로도 노출하기
  4. 선택 가이드

1. 두 모드의 차이

구분 ADK / Agent Engine A2A
호스팅 Vertex AI 관리형 (reasoning engine) Cloud Run / GKE / 자체 호스팅
호출 인터페이스 Google 내부 메서드 (streaming_agent_run_with_events, stream_query) HTTPS + JSON-RPC 2.0
Endpoint 형태 projects/.../reasoningEngines/<ID> resource name 일반 HTTPS URL + agent card (/.well-known/agent.json)
GE 등록 입력값 resource name HTTPS endpoint URL
인증 IAM (GE 서비스 에이전트 → Vertex AI) OAuth / API key / mTLS
빌드 vertexai.agent_engines.create(AdkApp(agent)) A2A SDK 가 export 한 FastAPI 앱
표준 외부 클라이언트 호환 ❌ (Google 전용) ✅ (다른 회사 / open A2A 클라이언트가 호출 가능)

같은 reasoning engine ID 를 GE 에 A2A 로 또 등록해도 API 스펙이 안 맞아서 실패 합니다.


2. 언제 어떤 모드를 쓰는가

🅐 ADK / Agent Engine 모드를 선택

  • GE 안에서만 호출됨 (외부 시스템 호출 없음)
  • Vertex AI 관리형의 운영 편의 (자동 스케일, 로깅, 모니터링) 가 중요
  • 모델 / Vertex AI Search / RAG 와 같은 GCP 자원을 가까이서 호출
  • 대부분의 PoC / 사내 에이전트는 이 모드

🅑 A2A 모드를 선택

  • 외부 시스템 (다른 회사 / 표준 클라이언트) 이 같은 에이전트를 호출해야 함
  • 다른 LLM 에이전트가 본 에이전트를 sub-agent / 협업 agent 로 호출
  • Cloud Run / GKE 같은 컨테이너 플랫폼에서 이미 운영 중인 자원과 동거
  • 인증을 OAuth / mTLS 등 표준 HTTP 패턴으로 통제하고 싶음

3. 같은 ADK 코드를 A2A 로도 노출하기

같은 root_agent 정의를 두 모드 모두에 노출하려면 두 가지 옵션:

🥇 옵션 A: to_a2a() 헬퍼 (권장)

google-adk 1.30+ 에서 ADK 에이전트를 A2A 호환 FastAPI 앱으로 export 하는 헬퍼 제공 (정확한 API 이름은 SDK 버전에 따라 to_a2a / A2aAdapter / a2a_server 중 하나 — python -c "from google.adk import a2a; print(dir(a2a))" 로 확인):

# scripts/deploy_a2a.py (개념)
from google.adk.a2a import to_a2a  # 또는 A2aAdapter / a2a_server
# root_agent 는 deploy_agent.py 와 동일하게 정의

a2a_app = to_a2a(root_agent)        # FastAPI 인스턴스 반환

# uvicorn 서버
if __name__ == "__main__":
    import uvicorn
    uvicorn.run(a2a_app, host="0.0.0.0", port=8080)

Cloud Run 배포:

gcloud run deploy my-agent-a2a \
  --source . \
  --region=<LOCATION> \
  --no-allow-unauthenticated \
  --service-account=<YOUR_SA>

GE 등록: A2A 모드 선택 → Cloud Run URL 입력.

장점: Agent Engine deploy 와 같은 코드 재사용. ADK feature (callback / planner / memory) 그대로 동작.

🥈 옵션 B: 얇은 A2A wrapper 가 Agent Engine 호출

이미 Agent Engine 에 deploy 한 reasoning engine 을 그대로 두고, 앞에 A2A 호환 FastAPI 서버를 띄워서 내부에서 reasoning engine 의 stream_query 를 호출:

# Cloud Run 컨테이너 내부
from fastapi import FastAPI
import vertexai
from vertexai import agent_engines

REASONING_ENGINE = "projects/.../reasoningEngines/<ID>"
engine = agent_engines.get(REASONING_ENGINE)

app = FastAPI()

@app.post("/")
async def a2a_invoke(req: dict):
    # A2A JSON-RPC → reasoning engine query 변환 로직
    user_text = extract_message(req)
    chunks = []
    for event in engine.stream_query(input=user_text, user_id="..."):
        chunks.append(event)
    return to_a2a_response(chunks)

장점: 기존 reasoning engine 자원 재활용 단점: 호출 hop 2단계 (A2A → wrapper → Agent Engine), latency 와 비용 증가, A2A spec 변환 코드 직접 작성


4. 선택 가이드

graph TD
    Q[에이전트를 GE 에 등록하려고 함]
    Q --> A{외부 시스템도 호출하나?}
    A -->|아니오 — GE 만| ADK[ADK / Agent Engine 모드<br/>vertexai.agent_engines.create + AdkApp]
    A -->|예| B{이미 Agent Engine 에 deploy 했나?}
    B -->|예| C{비용 / latency 민감?}
    C -->|예 — 단순한 게 좋음| OptA[옵션 A: to_a2a 로 별도 Cloud Run 배포]
    C -->|아니오 — 자원 재활용 우선| OptB[옵션 B: A2A wrapper + 기존 reasoning engine]
    B -->|아니오 — 처음부터 만듦| OptA

대부분의 시나리오에서 가장 단순한 선택은 옵션 A — 같은 ADK 코드를 Agent Engine 과 Cloud Run 두 곳에 deploy 하는 것입니다. 운영 자원이 두 배가 되지만 디버깅과 코드 관리가 가장 깔끔합니다.