콘텐츠로 이동

Handoff와 Dispatch: 두 가지 협업 모델

멀티에이전트 시스템에서 에이전트들이 어떻게 협력하는지는 크게 두 가지 패턴으로 나뉜다. **디스패치(dispatch)**는 중앙의 오케스트레이터가 모든 작업을 조율한다. 오케스트레이터가 서브태스크를 만들고, 어떤 워커에게 할당할지 결정하고, 결과를 수집한다. 오케스트레이터는 항상 제어권을 유지한다. **핸드오프(handoff)**는 에이전트가 피어(peer)에게 직접 제어권을 넘긴다. 에이전트 A가 작업을 처리하다가 에이전트 B가 더 적합하다고 판단하면, 전체 실행 컨텍스트를 B에게 넘기고 스스로 종료된다.

┌─────────────────────────────────────────────────────────────────┐
│ 디스패치(Dispatch) vs 핸드오프(Handoff) 제어 흐름 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ 디스패치: │
│ 사용자 ─→ 오케스트레이터 ─→ 워커 A (결과 반환) │
│ ─→ 워커 B (결과 반환) │
│ ─→ 워커 C (결과 반환) │
│ ← 오케스트레이터가 종합 │
│ │
│ 핸드오프: │
│ 사용자 ─→ 에이전트 A ─→ 에이전트 B ─→ 에이전트 C ─→ 최종 답변 │
│ (제어권 완전 이양) (제어권 완전 이양) │
│ A는 이후 관여 없음 B는 이후 관여 없음 │
└─────────────────────────────────────────────────────────────────┘

OpenAI Agents SDK는 핸드오프 패턴을 일급(first-class) 프리미티브로 지원한다. 세 가지 핵심 개념이 있다.

Agent: 특정 역할과 도구, 지시를 가진 LLM 실행 단위다. 자체 루프를 가지며 handoffs 목록에 다른 에이전트를 지정해 피어 위임을 선언할 수 있다.

Handoff: 에이전트가 다른 에이전트에게 제어권을 넘기는 메커니즘이다. 단순히 결과를 반환하는 것이 아니라 실행 컨텍스트 자체를 이양한다. 수신 에이전트는 이전 에이전트의 컨텍스트(대화 히스토리)를 이어받아 작업을 계속한다.

Guardrail: 에이전트의 입출력을 검증하는 레이어다. 모델 실행과 병렬로 동작하며, 유해한 출력이나 범위를 벗어난 요청을 차단한다. Guardrail은 에이전트 외부에서 결정론적(deterministic)으로 동작하므로, LLM이 안전 제약을 추론으로 우회하지 못한다.

개념 이해용 의사 코드이며 실제 API와 다를 수 있습니다.

# OpenAI Agents SDK 스타일 개념 예시
from agents import Agent, Handoff, Runner
# 전문화된 에이전트 정의
code_agent = Agent(
name="CodeAgent",
instructions="코드 작성 및 디버깅을 담당합니다.",
tools=[read_file, write_file, run_tests],
)
research_agent = Agent(
name="ResearchAgent",
instructions="기술 문서 검색 및 분석을 담당합니다.",
tools=[web_search, read_url],
# 코드 작성이 필요한 경우 CodeAgent로 핸드오프
handoffs=[Handoff(agent=code_agent)],
)
triage_agent = Agent(
name="TriageAgent",
instructions="사용자 요청을 분석해 적합한 에이전트로 라우팅합니다.",
handoffs=[
Handoff(agent=research_agent),
Handoff(agent=code_agent),
],
)
# 실행: TriageAgent가 시작하고, 필요에 따라 핸드오프
result = Runner.run(triage_agent, user_message)

핸드오프 모델은 다음 조건에서 빛난다.

전문화가 명확할 때: 에이전트 A가 특정 도메인 경계를 만났을 때 즉시 그 도메인 전문 에이전트로 넘기는 것이 자연스럽다. 고객 서비스 봇이 기술 지원 질문을 받으면 기술 에이전트로, 환불 요청이면 결제 에이전트로 핸드오프하는 시나리오가 전형적이다.

결과 집계가 필요 없을 때: 핸드오프는 선형 체인이다. 최종 에이전트가 사용자에게 직접 응답하고 중간 결과를 종합하는 별도 단계가 없다. 작업이 선형적으로 처리될 수 있는 경우에 적합하다.

컨텍스트 연속성이 중요할 때: 이전 에이전트가 수집한 정보를 다음 에이전트가 그대로 이어받아야 할 때, 핸드오프는 컨텍스트를 완전히 전달한다.

결과 종합이 필요할 때: 여러 워커의 결과를 모아 하나의 일관된 답변을 만들어야 한다면 오케스트레이터가 필요하다. 핸드오프는 이 종합 단계를 자연스럽게 표현하기 어렵다.

병렬 실행이 핵심일 때: 10개의 서브태스크를 동시에 실행해야 한다면 오케스트레이터가 모든 워커를 동시에 시작해야 한다. 핸드오프는 본질적으로 순차적이다.

작업 계획이 동적으로 변할 때: 오케스트레이터는 워커 결과를 받아볼 때마다 다음 서브태스크를 조정할 수 있다. 핸드오프 체인은 이런 동적 계획 수정이 어렵다.

핸드오프와 디스패치는 한 시스템 안의 제어 흐름 패턴이다. A2A는 서로 다른 팀·런타임에 배포된 독립 에이전트가 능력을 알리고 태스크·상태·산출물을 교환해야 할 때 쓰는 상호운용성 계약이다. MCP가 도구·데이터 연결을 다룬다면 A2A는 에이전트 간 위임을 다룬다. 내부 함수 호출을 A2A로 바꿀 필요는 없다.

Agent Skills는 특정 업무의 지침·스크립트·참조 자료를 재사용 가능한 묶음으로 만든다. A2A가 “어느 에이전트에게 위임할지”라면 Skills는 “수신 에이전트가 어떤 절차와 자원을 사용할지”다. 두 경우 모두 권한, 입력·출력 형식, 버전을 명시해야 한다.

실제 시스템에서는 두 패턴을 조합하는 경우가 많다. 최상위 레이어에서는 오케스트레이터가 병렬 디스패치를 관리하고, 각 워커 내부에서는 핸드오프를 통해 세부 전문 에이전트로 위임하는 구조다.

기준 핸드오프 디스패치
제어 흐름 선형 이양 (A→B→C) 중앙 집중 (O→A, O→B)
결과 종합 불필요 (마지막 에이전트가 직접 답) 오케스트레이터가 종합
병렬성 본질적으로 순차 자연스러운 병렬 실행
컨텍스트 전달 전체 이양 태스크 스펙만 전달
실패 처리 체인이 끊기면 복구 어려움 워커별 독립 재시도 가능

다음 챕터에서는 멀티에이전트 시스템과 롱호라이즌(long-horizon) 작업에서 가장 중요한 과학적 질문인 METR의 시간 지평선(time horizon) 연구를 살펴본다.

참고 자료