Git 저장소:A2A MCP
이 저장소는 a2a-python SDK를 설정하고 사용하여 간단한 서버와 클라이언트를 만들어 a2a 프로토콜을 구현하는 방법을 보여주며, 에이전트 서버는 mcp로 구현됩니다.
개요
- A2A (Agent-to-Agent): 상호 운용 가능한 AI 에이전트를 구축하기 위한 프로토콜 및 SDK입니다.
- 이 예제: 기본 A2A 서버와 클라이언트를 실행하고, 메시지를 교환하며, 응답을 확인하는 방법을 보여줍니다.
전제 조건
- Python 3.13+
- uv (빠른 종속성 관리 및 실행용)
- OpenRouter API 키 (
OPENROUTER_API_KEY
로 설정)
설치
-
저장소 복제:
git clone https://github.com/sing1ee/a2a-mcp-openrouter cd https://github.com/sing1ee/a2a-mcp-openrouter
-
종속성 설치:
uv venv source .venv/bin/activate
-
환경 변수 설정:
export OPENROUTER_API_KEY=your-openrouter-api-key
또는 다음 내용으로
.env
파일을 생성하세요:OPENROUTER_API_KEY=your-openrouter-api-key
참고: OpenRouter API 키는 https://openrouter.ai/에서 얻을 수 있습니다.
예제 실행
1. 서버 시작
uv run --env-file .env a2a-server
- 서버는 포트 9999에서 시작됩니다.
에이전트 카드 검증:
2. 클라이언트 실행
새 터미널에서:
uv venv
source .venv/bin/activate
uv run --env-file .env a2a-client --question "A2A 프로토콜이 무엇인가요?"
- 클라이언트가 서버에 연결하여 요청을 보냅니다.
3. 응답 확인
- 클라이언트의 응답은 response.xml에 저장됩니다.
구성
시스템은 다음 구성을 사용합니다:
- 모델: OpenRouter를 통한
google/gemini-flash-1.5
- 기본 URL:
https://openrouter.ai/api/v1
파일 구조
src/a2a_mcp_openrouter/server/
: 서버 구현.src/a2a_mcp_openrouter/client/
: 클라이언트 구현.response.xml
: 클라이언트의 예제 응답.
문제 해결
- 종속성 누락:
uv
가 설치되어 있는지 확인하세요. - API 키 오류:
OPENROUTER_API_KEY
가 올바르게 설정되어 있는지 확인하세요. - 포트 충돌: 포트 9999가 사용 가능한지 확인하세요.
A2A vs MCP: 프로토콜 유사성과 통합 접근법
이 구현을 통해 **A2A (Agent-to-Agent)**와 **MCP (Model Context Protocol)**가 놀라운 아키텍처 유사성을 공유한다는 것을 발견했습니다. 두 프로토콜 모두 발견, 기능 교환 및 실행에 대해 유사한 패턴을 따릅니다.
통합 구현 패턴
핵심 발견: A2A와 MCP 모두 동일한 기본 구현 패턴을 따릅니다:
- HTTP 기반 통신: 둘 다 통신에 HTTP를 사용합니다 (A2A는 REST API, MCP는 Server-Sent Events 사용)
- 프롬프트 기반 설계: 둘 다 무엇을 호출할지와 어떻게 호출할지 결정하기 위해 LLM 프롬프트에 의존합니다
- 발견 메커니즘: 둘 다 사용 가능한 기능을 발견하는 방법을 제공합니다
- 구조화된 응답: 둘 다 프로그래밍 방식으로 처리할 수 있는 구조화된 데이터를 반환합니다
mcp.py
구현을 보면 다음과 같습니다:
# HTTP를 통한 MCP 도구 발견
async with sse_client(url) as (read, write):
resources = await session.list_tools()
# LLM 의사 결정을 위한 프롬프트 생성
return template.render(tools=resources.tools)
# HTTP를 통한 도구 호출 실행
return await session.call_tool(tool_name, arguments=arguments)
이는 A2A 에이전트 호출 패턴과 개념적으로 동일합니다 - 기능을 발견하고, LLM을 사용하여 무엇을 호출할지 결정한 다음, 호출을 실행합니다.
범용 인터페이스로서의 A2A
핵심 통찰: A2A는 호출 패턴이 본질적으로 동일하기 때문에 에이전트 간 통신과 도구 호출 모두에 대한 통합 인터페이스 역할을 할 수 있습니다:
- A2A → 에이전트:
클라이언트 → HTTP → 에이전트 → LLM 응답
- A2A → 도구:
클라이언트 → HTTP → 도구 래퍼 → MCP 도구 응답
두 패턴 모두 다음을 사용합니다:
- HTTP 통신
- 기능 발견
- LLM 기반 의사 결정
- 구조화된 요청/응답 형식
이 통합 접근법의 이점
- 단일 인터페이스: 클라이언트는 하나의 호출 패턴만 이해하면 됩니다
- 상호 운용성: 동일한 워크플로에서 에이전트와 도구를 원활하게 혼합할 수 있습니다
- 일관된 아키텍처: 다양한 기능 유형에 걸쳐 동일한 구현 패턴을 사용합니다
- LLM 네이티브 설계: 둘 다 지능적인 기능 선택을 위해 LLM 추론을 활용합니다
이는 A2A와 MCP가 경쟁하는 프로토콜이 아니라 단일 인터페이스 패러다임 하에서 통합될 수 있는 상호 보완적인 패턴임을 보여줍니다.
시스템 아키텍처 및 플로우
다음은 클라이언트 입력에서 최종 응답까지 A2A 프로토콜의 완전한 플로우를 보여주는 상세한 시퀀스 다이어그램입니다:
sequenceDiagram
participant User
participant Client as A2A Client
participant LLM_Client as OpenRouter LLM (Client)
participant Server as A2A Server
participant AgentExecutor as Agent Executor
participant Agent as Server Agent
participant LLM_Server as OpenRouter LLM (Server)
participant MCP as MCP Tool
User->>Client: 질문 입력: "A2A 프로토콜이 무엇인가요?"
Note over Client: agent_urls로 에이전트 초기화
Client->>Server: GET /agent-card - 사용 가능한 에이전트 발견
Server-->>Client: 기능이 포함된 AgentCard 반환
Note over Client: 에이전트 프롬프트 템플릿 렌더링
Client->>LLM_Client: 질문과 사용 가능한 에이전트가 포함된 결정 프롬프트 전송
LLM_Client-->>Client: 선택된 에이전트가 포함된 JSON 반환
loop 선택된 각 에이전트에 대해
Client->>Server: POST /send-message-streaming
Server->>AgentExecutor: execute(context, event_queue)
AgentExecutor->>Agent: stream(query)
Agent->>MCP: 사용 가능한 도구 가져오기
MCP-->>Agent: 도구 정의 반환
Note over Agent: 도구 프롬프트 템플릿 렌더링
Agent->>LLM_Server: 질문과 도구가 포함된 결정 프롬프트 전송
LLM_Server-->>Agent: 선택된 도구가 포함된 JSON 반환
loop 선택된 각 도구에 대해 (최대 반복)
Agent->>MCP: 인수와 함께 도구 호출
MCP-->>Agent: 도구 결과 반환
Note over Agent: called_tools 히스토리 업데이트
Agent->>LLM_Server: 도구 결과가 포함된 업데이트된 프롬프트 전송
LLM_Server-->>Agent: 다음 도구 또는 최종 답변 반환
alt 더 많은 도구가 필요한 경우
Note over Agent: 다음 반복으로 계속
else 작업 완료
Note over Agent: 작업 완료됨
end
end
Agent-->>AgentExecutor: 스트리밍 이벤트 생성
AgentExecutor-->>Server: 이벤트를 event_queue로 전달
Server-->>Client: HTTP를 통해 응답 청크 스트리밍
Client->>Client: 응답 태그에서 답변 추출
Note over Client: agent_answers 목록에 추가
end
alt 최종 합성이 필요한 경우
Client->>LLM_Client: 모든 답변이 포함된 합성 프롬프트 전송
LLM_Client-->>Client: 최종 합성된 답변 반환
else 합성이 필요하지 않은 경우
Note over Client: 기존 답변 사용
end
Client-->>User: 에이전트 출력과 함께 최종 응답 스트리밍
주요 기능
- 에이전트 발견: A2A 프로토콜을 통한 사용 가능한 에이전트의 자동 발견
- LLM 기반 선택: LLM 추론을 사용한 지능적인 에이전트 및 도구 선택
- MCP 통합: 지식 검색을 위한 MCP 도구와의 원활한 통합
- 스트리밍 파이프라인: 전체 파이프라인에 걸친 실시간 스트리밍 응답
- 반복 처리: 컨텍스트가 유지되는 다중 반복 도구 호출
플로우 설명
시스템은 다음과 같은 주요 단계를 따릅니다:
클라이언트 단계: 사용자 질문 입력 → 클라이언트가 에이전트 발견 → LLM이 관련 에이전트 선택
서버 단계: 서버가 요청 수신 → 에이전트가 도구 발견 → LLM이 도구 선택 → 도구가 반복적으로 실행
응답 단계: 결과가 파이프라인을 통해 스트리밍됨 → 클라이언트가 최종 답변 합성 → 사용자가 응답 수신
이 아키텍처는 서로를 발견하고 협력할 수 있는 상호 운용 가능한 AI 에이전트를 만드는 A2A 프로토콜의 힘을 보여주며, 외부 지식 소스에 액세스하기 위해 MCP 도구를 활용합니다.