우와한 개발자

[LangGraph] A2A 멀티에이전트란? — Agent-to-Agent 프로토콜과 오케스트레이터 패턴

by 우와한개발자

 

1. 멀티에이전트

1) 개념

  • 멀티에이전트는 여러 개의 AI 에이전트가 역할을 나누어 협력하는 아키텍처다.
  • 하나의 에이전트가 모든 작업을 처리하는 것이 아니라, 문서 검색·웹 조사·파일 관리·보고서 작성처럼 역할별 에이전트가 각자 맡은 작업을 수행한다.
  • 오케스트레이터가 사용자 요청을 분석하고 어떤 에이전트에게 어떤 작업을 맡길지 결정한 뒤, 각 에이전트의 결과를 모아 최종 응답을 만든다.

 

2) 사용하는 이유

  • 복잡한 작업을 역할별로 나누어 처리할 수 있다
  • 각 에이전트의 책임이 명확해져 시스템 프롬프트와 로직을 설계하기 쉽다
  • 성격이 다른 작업(검색, 작성, 검토)을 각 에이전트에 최적화할 수 있다
  • 새 에이전트를 추가해도 기존 에이전트에 영향을 주지 않는다

 

2. 기존 방식과의 차이

1) 단일 프로세스 멀티에이전트

  • 이전 블로그에서 구현한 Supervisor 패턴은 모든 에이전트가 하나의 프로세스 내에서 LangGraph 노드로 연결되는 구조다.
하나의 Python 프로세스
  ├── planner_node()
  ├── researcher_node()
  ├── writer_node()
  └── reviewer_node()
  • 에이전트 간 데이터는 LangGraph State 객체로 전달된다
  • 에이전트를 추가하려면 같은 프로세스 코드를 수정해야 한다
  • 하나의 에이전트가 다운되면 전체 시스템이 영향을 받는다

 

2) A2A 방식 (독립 서버 구조)

  • A2A(Agent-to-Agent) 방식은 각 에이전트가 독립된 HTTP 서버로 실행된다.
오케스트레이터 서버 (port 10010)
  │ HTTP 요청
  ├── RAG 에이전트 서버     (port 10012)
  ├── Web 에이전트 서버     (port 10011)
  ├── File 에이전트 서버    (port 10013)
  └── Report 에이전트 서버  (port 10014)
  • 에이전트 간 데이터는 HTTP 요청과 응답으로 전달된다
  • 에이전트를 추가할 때 새 서버만 실행하면 된다
  • 특정 에이전트가 다운되어도 다른 에이전트는 정상 동작한다
  • 에이전트별로 독립적인 배포와 확장이 가능하다

 

3) 비교

구분 단일 프로세스 A2A
실행 방식 하나의 프로세스 내 노드 독립된 HTTP 서버
데이터 전달 LangGraph State HTTP 요청/응답
에이전트 추가 코드 수정 필요 새 서버 실행으로 추가
장애 영향 전체 시스템 영향 해당 에이전트만 영향
적합한 규모 소규모 워크플로우 확장 가능한 서비스

 

3. A2A 프로토콜

1) 개념

  • A2A(Agent-to-Agent)는 에이전트 간 통신을 위한 HTTP 기반 표준 프로토콜이다.
  • 각 에이전트는 A2A 스펙에 맞는 HTTP 서버를 구현하고, 오케스트레이터는 A2A SDK를 통해 에이전트를 호출한다. 에이전트 내부 구현이 어떻게 되어 있든 A2A 인터페이스만 맞추면 오케스트레이터와 통신할 수 있다.

 

2) 통신 방식

  • A2A에서 오케스트레이터가 에이전트를 호출하는 방식은 두 가지다.

(1) 일반 HTTP 요청

  • 오케스트레이터가 에이전트에게 작업을 요청하고 완료된 결과를 한 번에 받는다
  • 처리 시간이 짧은 작업에 적합하다

(2) SSE 스트리밍

  • 에이전트가 작업 중간 결과를 실시간으로 스트리밍한다
  • Server-Sent Events(SSE) 방식으로 응답을 청크 단위로 전송한다
  • 처리 시간이 길거나 LLM 답변을 실시간으로 보여줄 때 사용한다
오케스트레이터                    RAG 에이전트
     │                               │
     │── POST /run (작업 요청) ──────>│
     │                               │ (검색 중...)
     │<── data: 검색 완료 ────────────│  SSE 스트림
     │<── data: 답변 생성 중... ──────│
     │<── data: 최종 답변 ────────────│
     │<── data: [DONE] ──────────────│

 

3) Agent Card

  • A2A 에이전트는 자신의 능력과 엔드포인트를 설명하는 Agent Card를 제공한다.
- 에이전트 이름, 설명, 버전 정보
- 지원하는 작업 목록과 입출력 형식
- 엔드포인트 URL
  • 오케스트레이터는 Agent Card를 읽어 어떤 에이전트가 어떤 작업을 처리할 수 있는지 파악한다.

 

4. 오케스트레이터 패턴

1) 개념

  • 오케스트레이터는 사용자 요청을 분석하고 어떤 에이전트를 어떤 순서로 호출할지 계획을 세우는 상위 에이전트다.
  • 각 에이전트의 실행 결과를 수집하고, 필요하면 결과를 다음 에이전트에게 전달하며, 최종 결과를 사용자에게 반환한다.

 

2) 역할

  • 사용자 요청 분석 및 인텐트 분류
  • 실행할 에이전트와 순서 결정 (Plan 생성)
  • 독립적인 단계 병렬 실행, 의존 단계 순차 실행
  • 에이전트 결과 수집 및 최종 응답 구성

 

3) 인텐트 분류

  • 오케스트레이터는 사용자 질문을 분석하여 적합한 에이전트를 선택한다.
사용자 요청
  │
  ▼
오케스트레이터 (인텐트 분류)
  │
  ├── 사내 문서 질문    → RAG 에이전트
  ├── 웹 검색 요청      → Web Research 에이전트
  ├── 파일 관리 요청    → File Management 에이전트
  ├── 보고서 작성 요청  → Report Writing 에이전트
  └── 복합 작업         → 여러 에이전트 순차/병렬 실행

 

4) 실행 흐름

(1) 순차 실행

  • 의존 관계가 있는 작업은 순서대로 실행한다. 앞 단계의 결과를 다음 단계의 입력으로 사용한다.
웹 조사 후 보고서 작성
  → 1단계: Web Research 에이전트 (조사 수행)
  → 2단계: Report Writing 에이전트 (조사 결과로 보고서 작성)

(2) 병렬 실행

  • 의존 관계가 없는 작업은 동시에 실행하여 응답 시간을 줄인다.
여러 정보를 동시에 조회
  → RAG 에이전트 실행 ──┐
  → Web 에이전트 실행 ──┤ (동시 실행)
                         │
                         ▼
                    결과 합산 후 반환

 

5. 에이전트별 역할

1) RAG 에이전트 (Internal RAG Agent)

사내 문서를 벡터 검색하여 근거 있는 답변을 생성한다.

  • 업로드된 문서를 청크로 분할하고 임베딩 벡터로 변환하여 저장한다
  • 사용자 질문과 유사한 청크를 검색하고 해당 내용을 바탕으로 답변을 생성한다
  • 출처 파일명과 페이지 번호를 함께 반환한다

 

2) Web Research 에이전트

Tavily Search API를 사용하여 실시간 웹 검색을 수행한다.

  • 사내 문서에 없는 최신 정보나 외부 정보가 필요할 때 호출된다
  • 검색 결과의 관련성 점수를 기준으로 낮은 품질의 결과는 반환하지 않는다
  • 출처 URL을 함께 반환한다

 

3) File Management 에이전트

Google Drive 파일 목록 조회, 검색, 업로드를 처리한다.

  • RAG 인덱싱 워크플로우에서 파일 목록을 조회한 후 RAG 에이전트로 연계된다
  • Google Drive API v3와 OAuth2 인증을 사용한다

 

4) Report Writing 에이전트

조사 결과나 내용을 정해진 양식의 마크다운 보고서로 작성한다.

  • 임원 요약, 조사 보고서, 기술 보고서, 회의록 등 양식을 자동으로 감지한다
  • 웹 조사 결과를 입력받아 구조화된 보고서를 생성한다

 

6. RAG → 웹 자동 폴백

1) 개념

  • 사내 문서에서 답변을 찾지 못했을 때 자동으로 웹 검색으로 전환하는 흐름이다.
  • 사용자가 매번 "사내 문서에서 찾아봐, 없으면 웹에서 찾아봐"라고 지시하지 않아도 오케스트레이터가 자동으로 처리한다.

 

2) 흐름

사실 질문
  │
  ▼
RAG 에이전트 검색
  │
  ├── 결과 있음 → 📄 [사내 문서 기반] 답변 반환
  │
  └── 결과 없음 → "사내 문서에서 찾지 못했습니다. 웹에서 검색합니다..."
                    │
                    ▼
                  Web 에이전트 검색
                    │
                    ├── 관련성 높음 (score ≥ 0.5) → [웹 검색 기반] 답변 반환
                    └── 관련성 낮음 (score < 0.5) → "관련 정보를 찾을 수 없습니다."

 

3) 답변 출처 배지

  • 사용자가 답변이 어디서 왔는지 알 수 있도록 경로별로 구분된 출처 배지를 답변 앞에 표시한다.
  • [사내 문서 기반]: RAG 에이전트가 문서에서 답변을 찾은 경우
  • [웹 검색 기반]: 사내 문서 미발견 후 웹에서 찾은 경우
  • [AI 직접 답변]: 인사말 등 문서 검색 없이 직접 응답하는 경우

 

7. 채팅 이력 설계

1) 이력을 오케스트레이터에 전달하지 않는 이유

일반적인 챗봇은 이전 대화 이력을 LLM에 함께 전달하여 맥락을 유지한다.

멀티에이전트에서 이력을 그대로 오케스트레이터에 전달하면 두 가지 문제가 생긴다.

  • 이력 텍스트가 RAG 벡터 검색 쿼리에 섞여 임베딩 품질이 저하된다
  • 오케스트레이터 LLM이 이력과 현재 질문을 혼동하여 잘못된 에이전트를 선택한다

 

2) 해결 방법

  • 현재 질문만 오케스트레이터로 전달하고, 이력은 DB에만 저장한다.
  • 맥락 의존 질문("그것의 조건은?")은 RAG 에이전트 내부의 contextualize_question 노드가 감지하여 "더 구체적으로 질문해 주세요." 형태로 재질문을 유도한다.

블로그의 정보

우와한개발자 님의 블로그

우와한개발자

활동하기