포스트

[MCP&A2A] 01. 개요와 문제 정의

[MCP&A2A] 01. 개요와 문제 정의

엔터프라이즈 AI 통합의 핵심 문제

AI 캄브리아기 대폭발

현대 엔터프라이즈 AI 환경은 전례 없는 속도로 확장되고 있습니다. 대규모 언어 모델(LLM), 멀티모달 시스템, RAG(Retrieval-Augmented Generation) 프레임워크, 자율 에이전트, 벡터 데이터베이스 등이 폭발적으로 증가하고 있습니다.

산업 현황 데이터:

  • Forrester 2024년 5월 조사: AI 의사결정권자의 67%가 생성 AI 투자 증가 계획
  • IDC 예측: 2025년까지 핵심 IT 지출의 40% 이상이 AI 이니셔티브에 투입
  • Gartner 분석: 통합 문제와 시스템 복잡성이 AI 이니셔티브의 가치 실현에 가장 큰 장애물

M×N 통합 문제

전통적인 AI 시스템 통합은 “M×N 문제”로 알려진 근본적인 복잡성에 직면합니다.

1
M개의 AI 애플리케이션 × N개의 데이터 소스 = M×N개의 커스텀 통합

실제 사례:

1
2
3
4
5
6
7
8
9
10
11
기업 환경 예시:
- AI 애플리케이션: 5개 (챗봇, RAG 시스템, 분석 도구, 코딩 어시스턴트, 리서치 에이전트)
- 데이터 소스: 8개 (PostgreSQL, MongoDB, S3, Slack, Google Drive, GitHub, Jira, Salesforce)
- 필요한 커스텀 통합: 5 × 8 = 40개

각 통합마다:
- 인증/권한 로직 구현
- 데이터 변환 로직 작성
- 에러 처리 및 재시도 메커니즘
- 모니터링 및 로깅
- 유지보수 및 업데이트

통합 복잡성의 구체적인 문제점

1. 인증과 권한의 파편화

각 데이터 소스마다 다른 인증 메커니즘:

  • OAuth 2.0: Google Drive, Slack
  • API Keys: OpenAI, Anthropic
  • Database Credentials: PostgreSQL, MongoDB
  • JWT Tokens: 커스텀 내부 시스템
  • SAML/SSO: 엔터프라이즈 애플리케이션

문제점:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# ❌ 각 시스템마다 별도 인증 코드
def get_google_drive_files():
    oauth_client = GoogleOAuthClient()
    token = oauth_client.get_access_token()
    return drive_api.list_files(token)

def get_slack_messages():
    slack_token = os.getenv("SLACK_BOT_TOKEN")
    return slack_client.get_messages(slack_token)

def query_database():
    db_conn = psycopg2.connect(
        host=DB_HOST,
        user=DB_USER,
        password=DB_PASSWORD
    )
    return db_conn.execute(query)

2. 데이터 형식의 불일치

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 각 소스마다 다른 응답 형식
# Slack API 응답
{
    "messages": [
        {"text": "...", "user": "U123", "ts": "1234567.89"}
    ]
}

# Google Drive API 응답
{
    "files": [
        {"name": "...", "id": "xyz", "mimeType": "..."}
    ]
}

# Database 쿼리 결과
[
    {"title": "...", "content": "...", "created_at": datetime(...)}
]

3. 보안 취약점

실제 보안 사고 사례:

사례 1: Salesloft 챗봇 유출 (2024)

  • AI 챗봇이 수백 개 서비스의 인증 토큰을 의도치 않게 저장
  • 여러 플랫폼에 걸친 고객 데이터 노출
  • 원인: 적절한 인증/권한 제어 부재

사례 2: Filevine 문서 유출 (2025년 10월)

  • 10만 개 이상의 기밀 법률 문서 노출
  • 인증되지 않은 API 엔드포인트가 Box 파일시스템의 전체 관리자 토큰 반환
  • 단순 API 호출만으로 접근 가능
  • 원인: AuthN/AuthZ 제어 부재

비용 과다 사례:

1
2
3
4
5
6
7
8
실제 경험담:
- 초기 프로토타입: OpenAI API 사용, 사용량 추적 없음
- 한 달 후: $45,000 청구서 도착
- 원인: 
  * 무제한 사용자 쿼리
  * 토큰 사용량 모니터링 없음
  * 예산 제한 없음
  * gpt-4 모델 무분별 사용

4. 확장성 문제

1
2
3
4
5
6
7
8
9
10
11
12
13
# ❌ 각 통합마다 별도 확장 전략
# Slack 통합: 웹소켓 유지
async def slack_integration():
    websocket = await slack.connect()
    while True:
        message = await websocket.recv()
        process_message(message)

# Database 통합: 연결 풀 관리
db_pool = create_pool(min_size=5, max_size=20)

# API 통합: Rate limiting 처리
rate_limiter = RateLimiter(calls=100, period=60)

에이전트 협업의 어려움

복잡한 멀티 컴포넌트 AI 워크플로우 구축의 어려움:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
기존 방식의 문제:
┌─────────────┐
│ AI Agent A  │──┐
└─────────────┘  │
                 ├──► 수동 오케스트레이션 필요
┌─────────────┐  │
│ AI Agent B  │──┘
└─────────────┘
    │
    ├──► 각각 다른 도구 접근 방식
    │
┌─────────────┐
│   Tools     │
│ (파편화)    │
└─────────────┘

문제점:

  1. 에이전트 간 컨텍스트 공유 불가
  2. 표준화된 통신 프로토콜 부재
  3. 각 에이전트가 독립적으로 도구 통합
  4. 복잡한 워크플로우 오케스트레이션

기존 솔루션의 한계

1. 커스텀 통합 레이어

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# ❌ 각 팀이 자체 통합 레이어 구축
class DataIntegrationLayer:
    def __init__(self):
        self.google_drive = GoogleDriveClient()
        self.slack = SlackClient()
        self.database = DatabaseClient()
        
    def search_all(self, query):
        # 각 소스에서 별도로 검색
        drive_results = self.google_drive.search(query)
        slack_results = self.slack.search(query)
        db_results = self.database.search(query)
        
        # 수동으로 결과 병합
        return self._merge_results(
            drive_results, 
            slack_results, 
            db_results
        )

단점:

  • ❌ 중복 코드 발생
  • ❌ 유지보수 부담 증가
  • ❌ 표준화 부재
  • ❌ 재사용 불가능

2. 단일 벤더 종속

일부 기업은 단일 플랫폼(예: LangChain, LlamaIndex)에 의존:

문제점:

  • ❌ 벤더 락인(Vendor Lock-in)
  • ❌ 플랫폼 제약 사항 제한
  • ❌ 다른 프레임워크와 통합 어려움
  • ❌ 혁신 속도 플랫폼에 종속

3. 수동 오케스트레이션

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# ❌ 워크플로우 수동 관리
def research_workflow(topic):
    # 1단계: 문서 검색
    documents = search_documents(topic)
    
    # 2단계: 경쟁사 분석
    competitors = analyze_competitors(documents)
    
    # 3단계: 재무 데이터 수집
    financial_data = get_financial_data(competitors)
    
    # 4단계: 보고서 생성
    report = generate_report(documents, competitors, financial_data)
    
    return report

문제점:

  • ❌ 진행 상황 추적 어려움
  • ❌ 에러 처리 복잡
  • ❌ 중간 결과 저장 불가
  • ❌ 재시작 메커니즘 없음

MCP와 A2A의 등장 배경

Model Context Protocol (MCP) - Anthropic, 2024년 11월

MCP는 AI 어시스턴트를 콘텐츠 리포지토리, 비즈니스 도구, 개발 환경 등 데이터가 존재하는 시스템에 연결하기 위한 새로운 표준입니다.

핵심 목표:

1
M개의 AI 애플리케이션 × 1개의 MCP 표준 × N개의 MCP 서버 = M + N 통합

MCP가 해결하는 문제:

  • ✅ 표준화된 도구 실행 인터페이스
  • ✅ 데이터 소스 접근 통일
  • ✅ 컨텍스트 주입 메커니즘
  • ✅ JSON-RPC 2.0 기반 언어 중립적 프로토콜

Agent-to-Agent Protocol (A2A) - Google, 2025년 4월

A2A는 다양한 프레임워크와 벤더가 구축한 AI 에이전트들이 효과적으로 통신하고 협업할 수 있도록 하는 오픈 프로토콜입니다.

핵심 목표:

  • ✅ 에이전트 간 표준화된 통신
  • ✅ 장기 실행 태스크 관리
  • ✅ 실시간 진행 상황 스트리밍
  • ✅ 에이전트 기능 디스커버리

MCP와 A2A의 상호보완성

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
┌──────────────────────────────────────┐
│          사용자/애플리케이션          │
└─────────────┬────────────────────────┘
              │
              ▼
┌─────────────────────────────────────┐
│        AI Agent (클라이언트)         │
│  ┌─────────────────────────────┐   │
│  │   A2A로 다른 에이전트와 협업  │   │
│  └─────────────────────────────┘   │
│  ┌─────────────────────────────┐   │
│  │   MCP로 도구/데이터 접근     │   │
│  └─────────────────────────────┘   │
└─────────────┬───────────────────────┘
              │
    ┌─────────┴─────────┐
    │                   │
    ▼                   ▼
┌─────────┐      ┌─────────────┐
│ MCP 서버 │      │ A2A 에이전트 │
│ (도구)   │      │  (협업)      │
└─────────┘      └─────────────┘

역할 분담: | 프로토콜 | 용도 | 특성 | |———|——|——| | MCP | Agent ↔ Tool | 동기식, 무상태, 빠른 실행 | | A2A | Agent ↔ Agent | 비동기식, 상태 유지, 복잡한 워크플로우 |

실제 시나리오로 보는 필요성

시나리오: 금융 규제 컴플라이언스 분석

요구사항:

1
2
3
4
5
컴플라이언스 분석가가 특정 회사에 대해 다음을 수행:
1. 10,000개 이상의 계약 문서에서 관련 조항 검색
2. SEC 규제 파일과 교차 참조
3. GDPR Article 33 데이터 유출 신고 요구사항 확인
4. 감사 가능한 보고서 생성

MCP만 사용할 경우:

1
2
3
4
5
6
7
8
9
10
# ❌ 문제점
# 1. 진행 상황 추적 불가
# 2. 중간 결과 저장 불가
# 3. 멀티스텝 조정 복잡
# 4. 클라이언트가 모든 오케스트레이션 처리

results = mcp_client.search(query="data breach GDPR Article 33")
# 클라이언트가 다음 단계 수동 처리
sec_filings = mcp_client.search(query="SEC regulations")
# 계속 수동 조정...

A2A만 사용할 경우:

1
2
3
4
5
6
7
8
9
10
# ❌ 문제점
# 1. 각 도구를 커스텀 통합
# 2. 표준화된 데이터 접근 없음
# 3. 인증을 도구마다 재구현
# 4. 에이전트 로직이 데이터 소스에 강결합

# 각 에이전트가 자체 데이터베이스 연결
agent.connect_to_database(credentials)
agent.connect_to_sec_api(api_key)
# 중복된 통합 로직...

MCP + A2A 통합:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# ✅ 해결책
# A2A로 멀티스텝 워크플로우 오케스트레이션
task = a2a_client.create_task(
    agent="compliance_analyst",
    params={
        "company": "Acme Corp",
        "regulations": ["GDPR Article 33", "SEC Rule 10b-5"]
    }
)

# 실시간 진행 상황 스트리밍
for event in a2a_client.stream_events(task.id):
    print(f"Progress: {event.message}")
    # "문서 검색 중..."
    # "SEC 파일링 분석 중..."
    # "보고서 생성 중..."

# MCP로 표준화된 도구 실행
# (A2A 에이전트 내부에서 자동 사용)
# - hybrid_search 도구: 문서 검색
# - sec_filing 도구: 규제 정보
# - report_generator 도구: 보고서 생성

# 최종 결과와 중간 산출물 모두 접근 가능
result = a2a_client.get_task_result(task.id)

프로덕션의 현실

PoC와 프로덕션의 차이

PoC (Proof of Concept):

1
2
3
4
5
# 간단한 데모
def handle_request(request):
    tool = request["tool"]
    args = request["args"]
    return execute_tool(tool, args)

프로덕션 실제:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 10개 레이어의 프로덕션 고려사항
func (h *MCPHandler) handleToolsCall(ctx context.Context, req *protocol.Request) {
    // 1. 인증 (JWT 검증)
    claims, err := h.auth.ValidateToken(ctx)
    
    // 2. 권한 부여 (권한 확인)
    if !h.authz.CanExecute(claims.UserID, toolName) {
        return errors.New("권한 없음")
    }
    
    // 3. Rate limiting (테넌트별 할당량)
    if !h.rateLimiter.Allow(claims.TenantID) {
        return errors.New("rate limit 초과")
    }
    
    // 4. 입력 검증 (인젝션 방지)
    if err := h.validator.Validate(args); err != nil {
        return err
    }
    
    // 5. 테넌트 컨텍스트 주입 (RLS)
    ctx = context.WithValue(ctx, "tenant_id", claims.TenantID)
    
    // 6. 요청 추적 (관측가능성)
    span := h.tracer.Start(ctx, "tool.execute")
    defer span.End()
    
    // 7. 비용 추적 (예산 시행)
    cost := h.costTracker.EstimateCost(toolName, args)
    if !h.budgetEnforcer.Allow(claims.UserID, cost) {
        return errors.New("예산 초과")
    }
    
    // 8. Circuit breaker (빠른 실패)
    if h.circuitBreaker.IsOpen(toolName) {
        return h.getFallbackResult(toolName)
    }
    
    // 9. 재시도 로직 (일시적 오류 처리)
    result, err := h.retrier.Execute(func() error {
        return h.toolRegistry.Execute(ctx, toolName, args)
    })
    
    // 10. 감사 로그 (컴플라이언스)
    h.auditLog.Record(claims.UserID, toolName, args, result)
    
    return result
}

누락된 10개 레이어

프로토콜 사양서는 다음을 정의하지 않습니다:

  • ❌ 인증 및 권한 부여
  • ❌ 멀티테넌트 격리
  • ❌ Rate limiting 및 비용 제어
  • ❌ 관측가능성 및 추적
  • ❌ Circuit breaker 및 타임아웃
  • ❌ 암호화 및 컴플라이언스
  • ❌ 재해 복구
  • ❌ 확장성 패턴
  • ❌ 모니터링 및 알림
  • ❌ 배포 전략

이것이 바로 이 가이드가 다루는 나머지 90%입니다.

핵심 요약

MCP + A2A = 프로덕션급 AI

1
2
3
✅ MCP: 도구 실행 표준화
✅ A2A: 에이전트 조정 표준화
✅ 둘의 조합: 엔터프라이즈급 AI 시스템

이 가이드가 제공하는 것

  • ✅ 실제 인증 (TODO가 아닌)
  • ✅ 실제 멀티테넌시 (앱 필터링이 아닌 DB RLS)
  • ✅ 실제 관측가능성 (Langfuse 통합)
  • ✅ 실제 테스트 (모의 객체가 아닌 통합 테스트)
  • ✅ 실제 배포 (K8s 매니페스트)

다음 장: MCP 프로토콜의 핵심 개념과 작동 원리를 자세히 살펴봅니다.


참고 자료:

  • Anthropic MCP 발표: https://www.anthropic.com/news/model-context-protocol
  • Google A2A 발표: https://developers.googleblog.com/en/a2a-a-new-era-of-agent-interoperability/
  • Linux Foundation A2A 프로젝트: https://www.linuxfoundation.org/press/linux-foundation-launches-the-agent2agent-protocol-project-to-enable-secure-intelligent-communication-between-ai-agents

작성일: 2024년 12월 13일

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.