[MCP&A2A] 04. MCP와 A2A 비교
[MCP&A2A] 04. MCP와 A2A 비교
프로토콜 비교 개요
MCP와 A2A는 서로 다른 문제를 해결하는 상호보완적 프로토콜입니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
┌────────────────────────────────────────┐
│ 사용자/애플리케이션 │
└──────────────┬─────────────────────────┘
│
┌──────▼──────┐
│ AI 에이전트 │
└──┬────────┬─┘
│ │
MCP ◄──┘ └──► A2A
(도구) (에이전트)
│ │
┌──────▼─────┐ ┌────▼──────┐
│ 데이터소스 │ │ 다른 AI │
│ • DB │ │ 에이전트 │
│ • API │ │ │
└────────────┘ └────────────┘
핵심 차이점
| 특성 | MCP | A2A |
|---|---|---|
| 목적 | AI ↔ 도구/데이터 연결 | AI ↔ AI 협업 |
| 통신 패턴 | 동기식 요청-응답 | 비동기 태스크 기반 |
| 실행 시간 | 짧음 (<30초) | 길 수 있음 (분~시간) |
| 상태 관리 | 무상태 (stateless) | 상태 유지 (stateful) |
| 프로토콜 | JSON-RPC 2.0 | JSON-RPC 2.0 + SSE |
| 진행 상황 | 없음 | SSE 스트리밍 |
| 적합 사례 | 데이터 검색, 함수 실행 | 복잡한 워크플로우 |
실제 시나리오로 보는 차이
시나리오 1: 단순 문서 검색
요구사항: 특정 키워드로 문서 검색
MCP 사용 ✅ 적합:
1
2
3
4
5
6
# 빠르고 간단한 검색
results = mcp_client.hybrid_search(
query="AI ethics",
limit=10
)
# 즉시 결과 반환 (~100ms)
A2A 사용 ❌ 과도함:
1
2
3
4
5
6
# 불필요하게 복잡
task_id = a2a_client.create_task(
skill="search",
input={"query": "AI ethics"}
)
# 태스크 생성, 모니터링, 결과 조회 필요
결론: 단순 도구 실행은 MCP가 효율적
시나리오 2: 멀티스텝 리서치
요구사항:
- 회사 정보 검색
- 경쟁사 분석
- 재무 데이터 수집
- 보고서 생성
MCP만 사용 ❌ 한계:
1
2
3
4
5
6
7
# 클라이언트가 모든 조율 담당
docs = mcp_client.search("company X")
competitors = mcp_client.search("competitors")
financials = mcp_client.search("financial data")
# 진행 상황 추적 불가
# 중간 결과 저장 복잡
# 에러 처리 복잡
A2A 사용 ✅ 적합:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 에이전트가 자동 조율
task_id = a2a_client.create_task(
skill="comprehensive_research",
input={"company": "Company X"}
)
# 실시간 진행 상황
for event in a2a_client.stream_events(task_id):
print(event["message"])
# "문서 검색 중..."
# "경쟁사 분석 중..."
# "보고서 생성 중..."
# 완료 후 결과 조회
result = a2a_client.get_task(task_id)
결론: 복잡한 워크플로우는 A2A가 효과적
시나리오 3: 에이전트 협업
요구사항: HR 에이전트가 재무 에이전트에게 예산 확인
MCP만으로는 불가능 ❌:
1
2
MCP는 에이전트 간 통신 프로토콜 아님
에이전트는 도구로만 작동
A2A 사용 ✅:
1
2
3
4
5
6
7
8
9
10
11
12
# HR 에이전트
class HRAgent:
def process_request(self, employee_id: str):
# 재무 에이전트에게 예산 확인 요청
task_id = self.a2a_client.create_task(
agent_id="finance-agent",
skill="check_budget",
input={"department": "Engineering"}
)
budget = self.a2a_client.get_task(task_id)
return budget
결론: 에이전트 간 협업은 A2A 필수
통합 사용 패턴
패턴 1: A2A 에이전트가 MCP 도구 사용
가장 일반적이고 권장되는 패턴:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class ResearchAgent:
def __init__(self):
self.mcp_client = MCPClient(MCP_URL) # 도구 접근
self.workflow = self.build_workflow()
def execute_research(self, query: str):
# A2A 태스크로 실행
state = {"query": query}
# 내부적으로 MCP 도구 사용
results = self.workflow.invoke(state)
return results
def search_step(self, state):
# MCP 하이브리드 검색 도구 사용
docs = self.mcp_client.hybrid_search(
query=state["query"],
limit=20
)
state["documents"] = docs
return state
1
2
3
4
5
6
7
사용자 요청
↓
A2A 에이전트 (워크플로우 조율)
↓
MCP 도구들 (데이터 접근)
↓
결과 반환
패턴 2: MCP 서버가 A2A 에이전트 호출
덜 일반적이지만 유효한 패턴:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// MCP 도구가 복잡한 분석을 A2A 에이전트에 위임
type ComplexAnalysisTool struct {
a2aClient *A2AClient
}
func (t *ComplexAnalysisTool) Execute(ctx context.Context, args map[string]interface{}) {
query := args["query"].(string)
// 간단한 검색은 로컬 처리
if isSimpleQuery(query) {
return t.localSearch(query)
}
// 복잡한 분석은 A2A 에이전트에 위임
taskID := t.a2aClient.CreateTask("deep-analysis", map[string]interface{}{
"query": query,
})
// 결과 대기
result := t.a2aClient.WaitForCompletion(taskID)
return result
}
프로토콜 선택 기준
MCP를 선택해야 할 때
✅ 다음 조건을 모두 만족하면 MCP:
- 단일 단계 작업
- 빠른 응답 필요 (<30초)
- 상태 유지 불필요
- 진행 상황 추적 불필요
- 도구/데이터 접근이 목적
예시:
- 데이터베이스 쿼리
- 문서 검색
- API 호출
- 파일 읽기/쓰기
- 간단한 계산
A2A를 선택해야 할 때
✅ 다음 조건 중 하나라도 해당하면 A2A:
- 멀티스텝 워크플로우
- 장기 실행 (>30초)
- 진행 상황 추적 필요
- 중간 결과 저장 필요
- 에이전트 간 협업
- 복잡한 의사결정 필요
예시:
- 종합 리서치 보고서 생성
- 멀티소스 데이터 분석
- 코드 리뷰 및 리팩토링
- 프로젝트 계획 수립
- 에이전트 팀 협업
둘 다 사용해야 할 때
✅ 대부분의 엔터프라이즈 시스템:
- A2A: 에이전트 간 조율 및 복잡한 워크플로우
- MCP: 개별 에이전트의 도구/데이터 접근
1
2
3
4
5
6
7
8
9
10
11
복잡한 엔터프라이즈 시나리오:
사용자 요청
↓
메인 A2A 에이전트 (조율자)
├─► 리서치 A2A 에이전트
│ └─► MCP: 문서 검색, 웹 크롤링
├─► 분석 A2A 에이전트
│ └─► MCP: 데이터베이스 쿼리, 계산
└─► 보고서 A2A 에이전트
└─► MCP: 템플릿 로드, 파일 생성
성능 비교
처리량
1
2
3
4
5
6
7
8
MCP (동기식):
- 단일 요청: ~10-100ms
- 처리량: 5,000+ req/sec
A2A (비동기식):
- 태스크 생성: ~50ms
- 태스크 실행: 초~분~시간
- 처리량: 태스크 복잡도에 따라 다름
리소스 사용
1
2
3
4
5
6
7
8
9
MCP:
- 메모리: 낮음 (무상태)
- CPU: 요청 시에만
- 네트워크: 요청-응답만
A2A:
- 메모리: 높음 (상태 유지)
- CPU: 백그라운드 실행
- 네트워크: SSE 지속 연결
실전 의사결정 플로우차트
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
질문 시작
↓
에이전트 간 협업이 필요한가?
├─ YES → A2A 사용
└─ NO → 다음 질문
↓
멀티스텝 워크플로우인가?
├─ YES → A2A 사용
└─ NO → 다음 질문
↓
30초 이상 걸리는가?
├─ YES → A2A 사용
└─ NO → 다음 질문
↓
진행 상황 추적이 필요한가?
├─ YES → A2A 사용
└─ NO → MCP 사용
핵심 요약
핵심 원칙
1
2
3
4
5
6
MCP = 도구 (Tools)
A2A = 에이전트 (Agents)
도구가 필요하면 → MCP
에이전트 협업이 필요하면 → A2A
둘 다 필요하면 → 둘 다 사용
실무 권장사항
✅ DO:
- 단순 작업은 MCP
- 복잡한 워크플로우는 A2A
- A2A 에이전트 내부에서 MCP 도구 사용
- 각 프로토콜의 강점 활용
❌ DON’T:
- 단순 검색에 A2A 사용
- 에이전트 협업에 MCP만 사용
- 프로토콜 혼동
- 과도한 추상화
다음 장: 시스템 아키텍처 - MCP와 A2A를 통합한 전체 시스템 설계
참고 자료:
- MCP 사양: https://spec.modelcontextprotocol.io/
- A2A 사양: https://a2a-protocol.org/latest/
- 통합 가이드: IBM A2A 문서
작성일: 2024년 12월 13일
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.