멀티 에이전트 아키텍처 설계: MCP·이벤트 버스·검증 레이어 운영법
멀티 에이전트라는 말은 쉽게 붙는다. 하지만 실제로는 에이전트 이름만 여러 개이고 내부는 단일 프롬프트 체인인 경우가 많다. 이런 구조는 데모에서는 그럴듯하지만 운영에서는 병목과 오류가 빠르게 드러난다. 진짜 멀티 에이전트 시스템을 만들려면 모델을 여러 번 부르는 것보다 통신 방식, 병렬 처리, fallback 검증, 비용 라우팅을 먼저 설계해야 한다.
Google for Startups AI Agents Challenge를 정리한 Google Developers Blog 글은 상위 제출작에서 반복된 4가지 패턴을 소개했다. 양방향 MCP, 이벤트 기반 동시성, 같은 기준을 통과하는 fallback, 비싼 모델 호출 전 tiered routing이다. 이 네 가지는 특정 프레임워크보다 중요한 운영 패턴이다. 지금 에이전트 제품을 만드는 팀이라면 그대로 체크리스트로 써도 된다.
패턴 1: MCP를 내부 도구가 아니라 인프라로 본다
많은 에이전트는 MCP를 한 방향으로만 쓴다. 에이전트가 데이터베이스나 파일 시스템 같은 도구 서버를 호출하는 방식이다. 상위 사례에서는 한 단계 더 나아가, 에이전트가 내부적으로 MCP 도구를 쓰면서 동시에 다른 에이전트가 호출할 수 있는 MCP 서버로도 노출됐다. 이 차이는 크다. 사람용 채팅 UI를 하나 더 만드는 것이 아니라, 다른 에이전트와 IDE, 터미널 도구가 같은 reasoning layer를 직접 부를 수 있게 된다.
예를 들어 성능 분석 에이전트가 telemetry DB 전체를 모델 컨텍스트에 넣으면 토큰 비용과 정보 유출 위험이 커진다. 대신 MCP 도구가 특정 job의 실행 계획, 특정 trace, 특정 error group만 반환하게 만들면 컨텍스트가 작아지고 결과도 재사용 가능해진다. 외부 에이전트는 원시 DB가 아니라 제한된 도구 표면만 호출하므로 접근 제어도 쉬워진다.
단, 외부로 노출하는 순간 보안 요구가 달라진다. 내부 에이전트만 부르던 도구에는 느슨한 권한이 있어도 버틸 수 있다. 다른 에이전트와 사용자가 호출할 수 있는 MCP 서버에는 인증, rate limit, 입력 검증, 감사 로그가 필요하다. MCP는 편한 연결 방식이 아니라 API surface다.
패턴 2: 이벤트 버스로 병렬성을 만든다
단순한 멀티 에이전트 데모는 Agent A가 B를 부르고, B가 C를 부르고, C가 D를 부른다. 문제는 총 지연 시간이 모두 더해진다는 점이다. A가 2초, B가 3초, C가 5초 걸리면 사용자는 10초 이상 기다린다. 더 나쁜 것은 A와 B가 사실 독립적으로 같은 신호에 반응해도 되는 경우에도 줄을 세운다는 것이다.
이벤트 버스 구조는 다르다. 특정 신호가 발생하면 관련 에이전트가 각자 subscribe한 topic을 보고 동시에 움직인다. 예를 들어 ORDER.RISK_DETECTED 이벤트가 뜨면 결제 위험 에이전트, 고객 알림 에이전트, 운영자 티켓 에이전트가 병렬로 반응할 수 있다. 서로의 결과가 필요한 단계만 downstream 이벤트로 이어진다. 이렇게 하면 실제 병목이 어디인지 보이고, 독립 작업은 동시에 처리된다.
운영 기준도 명확해진다. 이벤트 스키마를 버전 관리하고, 각 에이전트가 어떤 topic을 consume·publish하는지 문서화한다. 실패한 이벤트는 dead letter queue로 보내고 재처리 정책을 둔다. 에이전트를 함수 호출 체인으로만 만들면 이런 운영 장치를 붙이기 어렵다.
패턴 3: fallback 모델도 같은 검증을 통과해야 한다
운영 환경에서는 고성능 모델이 503을 내거나 rate limit에 걸릴 수 있다. 그래서 fallback 모델을 둔다. 문제는 fallback이 품질 기준을 낮추는 우회로가 되는 경우다. 기본 모델은 인용 검증을 통과해야 하는데 fallback은 그냥 답하게 한다면, 장애 상황에서 가장 위험한 답변이 사용자에게 나간다.
해결책은 검증 함수를 모델 경로 밖에 두는 것이다. Pro 모델이든 Flash 모델이든 결과는 같은 validate_response()를 통과해야 한다. 의료, 법률, 금융, 보안처럼 위험한 도메인에서는 특히 중요하다. 예를 들어 “근거 문서 링크가 있어야 한다”, “금액과 계좌번호는 원문에서 추출된 값이어야 한다”, “권고 조치는 승인 도구 호출 전에는 실행되지 않아야 한다” 같은 검증은 모델 종류와 무관하게 적용돼야 한다.
좋은 fallback은 “아무 답이나 빨리 주기”가 아니라 “같은 기준을 만족하면 대체하고, 아니면 제한된 답을 주기”다. 실패했을 때는 사용자에게 더 좁은 범위의 답변이나 재시도 안내를 주는 편이 잘못된 확신보다 낫다.
패턴 4: 비싼 추론 전에 tiered routing을 둔다
AI 비용은 어려운 질문보다 쉬운 질문에서 새는 경우가 많다. “주문 어디 있어요”, “예약 취소해 주세요”, “비밀번호 재설정 링크 보내 주세요” 같은 요청이 매번 가장 비싼 reasoning model로 가면 비용 구조가 망가진다. 상위 사례 중 하나는 local regex, 작은 모델 분류, 큰 모델 추론의 3단계를 둬서 40% 넘는 메시지를 모델 호출 전에 처리했다고 설명했다.
이 구조는 고객지원뿐 아니라 개발 도구에도 적용된다. “파일 열어 줘”, “테스트 실행해 줘”는 deterministic command로 충분할 수 있다. “이 flaky test의 원인을 찾아 줘”는 더 큰 모델이 필요하다. “프로덕션 배포해 줘”는 큰 모델보다 승인 정책이 먼저다. 라우팅은 비용 절감 도구이면서 안전 장치다.
설계 체크리스트
- 에이전트 간 통신이 사람용 채팅 UI에 묶여 있는지 확인한다.
- 내부 도구 중 다른 에이전트가 재사용할 만한 것을 MCP 서버 후보로 분리한다.
- 같은 신호에 여러 에이전트가 반응한다면 이벤트 버스를 고려한다.
- 이벤트 스키마, topic, 재처리 정책, dead letter queue를 설계한다.
- primary와 fallback 결과가 같은 검증 함수를 통과하게 만든다.
- 쉬운 요청을 regex나 작은 모델로 먼저 분류한다.
- 비싼 모델 호출률, fallback 발생률, 검증 실패율을 지표로 본다.
결론
멀티 에이전트 시스템의 품질은 에이전트 수가 아니라 연결 방식에서 나온다. MCP를 재사용 가능한 도구 표면으로 만들고, 이벤트 버스로 병렬성을 확보하고, fallback을 같은 검증 기준에 묶고, 비싼 추론 전에 라우팅을 두면 데모가 아니라 운영 가능한 구조가 된다. 반대로 이 네 가지가 없다면 에이전트 이름이 10개여도 단일 프롬프트 체인과 크게 다르지 않다.
핵심 출처
- Google Developers Blog, 4 engineering patterns behind the strongest AI Agents Challenge submissions