개인정보처리방침© 2026 DEV BAK - 기술블로그. All rights reserved.
DEV BAK - 기술블로그
AI

LangGraph Supervisor Pattern: 멀티 에이전트 시스템에서 제어를 잃지 않으려면

멀티 에이전트 시스템을 처음 설계할 때 가장 많이 저지르는 실수가 있습니다. "에이전트끼리 알아서 협력하겠지"라는 막연한 기대 아래 각 에이전트를 느슨하게 연결해두는 것이죠. 저도 처음엔 그렇게 생각했는데, 결과는 언제나 같았습니다. 제어 흐름이 어디 있는지 알 수 없고, 어디서 실패했는지 추적이 안 되고, 디버깅하다가 결국 전체를 다시 설계하게 됩니다.

Supervisor Pattern은 그 반대 방향에서 출발합니다. 단일 오케스트레이터(Supervisor)가 전체 태스크를 분해하고, 전문화된 Worker 에이전트들에게 위임한 뒤 결과를 수집·통합하는 중앙집권형 제어 구조입니다. 2026년 기준으로 이 패턴은 사실상 멀티 에이전트 프로덕션의 기본값으로 자리잡았고, LangGraph·CrewAI·OpenAI Agents SDK 모두 이를 일급 개념으로 지원합니다.

이 글에서는 Supervisor Pattern이 무엇인지, Swarm이나 Pipeline과 무엇이 다른지, 실제로 어떻게 코드를 짜는지, 그리고 운영하면서 어떤 함정을 만나게 되는지를 다룹니다. 읽고 나면 "내 시스템이 Supervisor를 정말 필요로 하는가, 아니면 단순 Pipeline으로 충분한가"를 스스로 판단할 수 있게 됩니다 — 그리고 그 판단을 잘못 내렸을 때 어떤 비용을 치르는지도 미리 피할 수 있게 됩니다.


핵심 개념

Supervisor, Swarm, Pipeline — 제어 흐름이 어디 있느냐의 문제

세 패턴의 차이를 한 문장으로 정리하면 이렇습니다.

  • Swarm: 에이전트끼리 직접 핸드오프. 제어 흐름이 분산되어 있음
  • Pipeline: 선형 순서로 에이전트를 통과. 제어 흐름이 미리 고정됨
  • Supervisor: 모든 제어가 오케스트레이터로 귀환. 제어 흐름이 중앙에 있음
사용자 요청
    │
    ▼
┌─────────────┐
│  Supervisor  │  ← 라우팅·분해·종료 판단
│   (LLM 기반) │
└──────┬──────┘
       │  위임(delegate)
  ┌────┴────────────────┐
  ▼         ▼           ▼
Worker A  Worker B   Worker C
(검색)    (코딩)     (검증)
  │         │           │
  └────┬────┴───────────┘
       ▼
  결과 집계 → Supervisor 복귀 → 최종 응답

Swarm이 편해 보이지만, 막상 에이전트가 4개를 넘어서면 어떤 에이전트가 어디서 무엇을 했는지 추적하기가 매우 어려워집니다. Pipeline은 단계가 명확할 때 좋지만, "다음에 뭘 해야 할지"를 동적으로 결정해야 하는 순간 한계를 드러냅니다.

오케스트레이터(Orchestrator): 여러 에이전트의 실행을 조율하는 상위 컴포넌트. Supervisor는 LLM 기반 오케스트레이터의 대표적인 구현 방식입니다.

왜 규칙 기반이 아니라 LLM 기반 라우팅인가

"어차피 라우팅이면 if-else로 짜면 되지 않나요?"라는 질문을 종종 받습니다. 단순한 경우엔 그게 맞습니다. 하지만 실제 사용자 요청은 대부분 깔끔하게 분류되지 않습니다.

규칙 기반 라우터는 입력이 미리 정의된 카테고리에 딱 맞아떨어질 때만 제대로 동작합니다. LLM 기반 Supervisor는 애매한 요청을 맥락에 따라 해석하고, 중간 결과를 보고 다음 단계를 유동적으로 결정하고, 예상치 못한 입력에도 합리적인 판단을 내릴 수 있습니다. 리서치 에이전트의 결과가 충분하지 않으면 다시 위임하고, 코드 에이전트의 실행이 실패하면 검증 에이전트로 에스컬레이션하는 식의 흐름은 규칙으로 하드코딩하기가 어렵습니다.

세 단계 메커니즘: 분해 → 위임 → 집계

Supervisor가 하는 일은 크게 세 단계로 나뉩니다. 설명하면 간단해 보이는데, 이게 순환 구조라는 점이 핵심입니다.

  • 분해(Decomposition): 사용자 요청을 의미 단위의 서브태스크로 나눕니다
  • 위임(Delegation): 각 서브태스크를 도메인 전문 Worker에게 라우팅합니다
  • 집계(Aggregation): Worker 결과를 받아 "이걸로 충분한가, 아니면 다시 위임해야 하는가"를 판단합니다

이 마지막 판단 루프가 Supervisor를 Pipeline과 다르게 만드는 지점입니다. Pipeline은 A→B→C 순서가 고정되어 있지만, Supervisor는 B의 결과를 보고 C 대신 다시 A를 호출할 수도 있습니다.

계층적 확장: 에이전트가 6개를 넘으면

Worker가 너무 많아지면 Supervisor 하나로 감당하기 어렵습니다. 그때는 2레벨 계층 구조를 고려해볼 수 있습니다. 리서치 서브팀·라이팅 서브팀처럼 도메인별로 Sub-Supervisor를 두고, 최상위 Supervisor가 이들을 조율하는 방식입니다.

최상위 Supervisor
  ├── 리서치 Sub-Supervisor
  │     ├── 검색 Worker
  │     └── 데이터 추출 Worker
  └── 라이팅 Sub-Supervisor
        ├── 초안 작성 Worker
        └── 검증 Worker

다만 Worker가 3개 이하라면 이 구조는 과도한 추상화입니다. 순차 Pipeline이 더 단순하고 빠릅니다. Supervisor 도입 전에 Worker 수 임계값을 먼저 확인해보시면 좋습니다.


실전 적용

예시 1: LangGraph로 기본 Supervisor 구성하기

LangGraph는 2024년 말부터 langgraph-supervisor 패키지를 공식 지원합니다. create_supervisor() 팩토리 함수가 토폴로지 배선을 자동화해줘서, 예전처럼 직접 그래프 엣지를 하나하나 연결하지 않아도 됩니다.

아래 코드에서 search_tool은 langchain_community.tools의 DuckDuckGoSearchRun으로, python_repl_tool은 langchain_experimental.tools의 PythonREPLTool로 대체해 사용할 수 있습니다. 전체 실행 가능한 예제 코드는 langchain-ai/langgraph-supervisor-py 레포지토리에서 확인할 수 있습니다.

python
from langchain_openai import ChatOpenAI
from langchain_community.tools import DuckDuckGoSearchRun
from langchain_experimental.tools import PythonREPLTool
from langgraph_supervisor import create_supervisor
from langgraph.prebuilt import create_react_agent
 
search_tool = DuckDuckGoSearchRun()
python_repl_tool = PythonREPLTool()
 
# Worker 에이전트 정의
search_agent = create_react_agent(
    model=ChatOpenAI(model="gpt-4o-mini"),
    tools=[search_tool],
    name="search_agent",
    prompt="웹 검색을 수행하는 에이전트입니다. 검색 결과를 JSON 형식으로 반환하세요."
)
 
code_agent = create_react_agent(
    model=ChatOpenAI(model="gpt-4o-mini"),
    tools=[python_repl_tool],
    name="code_agent",
    prompt="코드 작성 및 실행 에이전트입니다. 코드와 실행 결과를 반환하세요."
)
 
# Supervisor 생성 — Worker보다 강력한 모델을 사용하는 것을 권장
supervisor = create_supervisor(
    agents=[search_agent, code_agent],
    model=ChatOpenAI(model="gpt-4o"),
    prompt=(
        "당신은 팀을 조율하는 Supervisor입니다. "
        "검색이 필요하면 search_agent에, 코드 작성이 필요하면 code_agent에 위임하세요. "
        "작업이 완료되면 FINISH를 반환하세요."
    )
)
 
app = supervisor.compile()
 
result = app.invoke({
    "messages": [{"role": "user", "content": "파이썬으로 피보나치 수열 10개를 출력하는 코드를 작성하고 실행해줘"}]
})
부분 설명
create_react_agent 추론→행동→관찰을 반복하는 ReAct 패턴으로 Tool을 사용할 수 있는 Worker 에이전트를 생성합니다
create_supervisor Worker 목록을 받아 라우팅 로직을 가진 Supervisor 그래프를 생성합니다
model 분리 Supervisor는 gpt-4o, Worker는 gpt-4o-mini — 비용 분산의 핵심입니다
FINISH Supervisor 프롬프트에 명시하는 종료 신호입니다. create_supervisor가 이 문자열을 감지해 라우팅 루프를 종료합니다

예시 2: CrewAI로 계층적 Supervisor 구성하기

CrewAI는 Process.hierarchical 모드와 manager_llm 설정만으로 Supervisor 동작을 구현할 수 있습니다. 역할 기반 에이전트 설계에 익숙하다면 LangGraph보다 진입 장벽이 낮은 편입니다.

LangGraph가 "그래프 구조를 직접 설계하는" 방식이라면, CrewAI는 "역할(role)과 목표(goal)를 선언하면 프레임워크가 협업 방식을 정한다"는 선언적 접근에 가깝습니다. 어느 쪽이 낫다기보다, 팀이 어떤 추상화 수준에 더 익숙한지에 따라 선택하면 됩니다.

python
from crewai import Agent, Task, Crew, Process
from langchain_openai import ChatOpenAI
from langchain_community.tools import DuckDuckGoSearchRun
 
search_tool = DuckDuckGoSearchRun()
 
# Worker 에이전트 정의
researcher = Agent(
    role="리서치 전문가",
    goal="주어진 주제에 대한 최신 정보를 수집합니다",
    backstory="데이터 수집과 분석에 특화된 에이전트입니다.",
    llm=ChatOpenAI(model="gpt-4o-mini"),
    tools=[search_tool]
)
 
writer = Agent(
    role="콘텐츠 작성 전문가",
    goal="수집된 정보를 기반으로 명확한 보고서를 작성합니다",
    backstory="기술 문서 작성에 특화된 에이전트입니다.",
    llm=ChatOpenAI(model="gpt-4o-mini")
)
 
# 태스크 정의
research_task = Task(
    description="AI 에이전트 트렌드에 대한 최신 정보를 수집하세요",
    expected_output="5가지 핵심 트렌드를 포함한 리서치 결과",
    agent=researcher
)
 
write_task = Task(
    description="리서치 결과를 바탕으로 500자 요약 보고서를 작성하세요",
    expected_output="완성된 요약 보고서",
    agent=writer
)
 
# hierarchical 모드로 Supervisor 활성화
crew = Crew(
    agents=[researcher, writer],
    tasks=[research_task, write_task],
    process=Process.hierarchical,   # Manager LLM이 Supervisor 역할 수행
    manager_llm=ChatOpenAI(model="gpt-4o"),
    verbose=True
)
 
result = crew.kickoff()
부분 설명
Process.hierarchical Supervisor(manager)가 태스크 순서와 위임을 동적으로 결정합니다. Process.sequential과 달리 흐름이 고정되지 않습니다
manager_llm Supervisor로 동작하는 Manager LLM입니다. Worker와 분리해 고성능 모델을 할당하는 것을 권장합니다
verbose=True 라우팅 결정 과정을 콘솔에 출력합니다. 초기 설계 검증에 유용합니다

예시 3: 컨텍스트 압축으로 토큰 폭발 막기

실무에서 자주 맞닥뜨리는 상황인데, 서브에이전트 왕복이 10회를 넘어서면 Supervisor의 컨텍스트가 Worker 결과 메시지로 포화되기 시작합니다. 저 역시 리서치 파이프라인을 운영하면서 10회 왕복 전후로 Supervisor의 응답 품질이 눈에 띄게 달라지는 걸 직접 경험했습니다. 그 이후로 각 핸드오프 지점에서 전체 트랜스크립트 대신 요약본을 전달하는 방식을 쓰기 시작했습니다.

python
from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage
 
summarizer_llm = ChatOpenAI(model="gpt-4o-mini")
 
def compress_worker_result(worker_output: str, max_chars: int = 500) -> str:
    """Worker 결과를 Supervisor에 전달하기 전에 압축합니다."""
    if len(worker_output) <= max_chars:
        return worker_output
 
    summary_prompt = f"""
다음 에이전트 실행 결과를 핵심만 남겨 {max_chars}자 이내로 요약하세요.
수치, 결론, 다음 단계에 필요한 정보만 포함하세요.
 
결과:
{worker_output}
"""
    response = summarizer_llm.invoke([SystemMessage(content=summary_prompt)])
    return response.content

compress_worker_result는 독립적인 유틸리티 함수라, Supervisor 노드에 붙이기 전에 단독으로 동작을 확인해볼 수 있습니다. Supervisor 노드 내부에서는 Worker 메시지를 순회하며 이 함수를 거쳐 압축한 뒤 LLM에 전달하면 됩니다.

검색 결과나 코드 실행 로그처럼 원문이 수천 자를 넘는 Worker 출력이 많은 파이프라인에서는 이 방식으로 토큰 소비를 크게 줄일 수 있습니다. 조건에 따라 차이는 있지만 7090% 절감도 가능한 구조입니다. 다만 요약 단계에서 0.51.5초 정도의 지연이 추가되는 트레이드오프는 감안해야 합니다.


장단점 분석

장점

실무에서는 "추론 가능성"과 "품질 게이트"가 압도적으로 중요하게 작용합니다. Supervisor 없이 Swarm으로 운영해본 팀이라면 "어디서 왜 실패했는지" 추적이 얼마나 고통스러운지 이미 알고 계실 겁니다. 아래 항목들이 바로 그 고통을 구조적으로 해소해주는 이점들입니다.

항목 내용
추론 가능성 모든 라우팅 결정이 Supervisor를 통과하므로 LangSmith·OpenTelemetry로 전체 실행 경로를 추적하기 쉽습니다
품질 게이트 Supervisor가 Worker 결과를 검토한 후 재위임 여부를 결정해, 중간 결과의 품질을 제어하는 지점이 명확합니다
도메인 격리 각 Worker는 자신의 도메인에만 집중하므로 프롬프트가 단순해지고 개별 교체가 쉽습니다
디버깅 용이성 Swarm 대비 제어 흐름이 단순해 오류 발생 위치를 특정하기 쉽습니다

단점 및 주의사항

수치로만 보면 단점이 꽤 많아 보이는데, 실무에서는 "병목"과 "컨텍스트 누적"이 압도적으로 자주 터집니다. 나머지 항목들은 초기 설계 단계에서 한 번 대응해두면 이후엔 거의 신경 쓸 일이 없습니다.

항목 내용 대응 방안
병목(Bottleneck) Supervisor가 프론티어 모델을 사용하면 모든 라우팅 결정마다 풀 인퍼런스 비용과 지연이 발생합니다 Worker에 저렴한 모델 사용, 라우팅 결정을 배치 처리
단일 장애 지점 Supervisor가 다운되면 전체 워크플로가 멈춥니다 재시도 로직과 상태 체크포인트로 복구 경로 확보
컨텍스트 누적 열화 서브에이전트 왕복 8~12회 초과 시 라우팅 정확도가 눈에 띄게 저하됩니다 핸드오프마다 Worker 결과를 요약해 전달
토큰 비용 증가 모든 Worker 결과가 Supervisor를 경유하므로 Swarm 대비 LLM 호출 횟수가 많습니다 컨텍스트 압축 + Worker 모델 경량화로 비용 분산

단일 장애 지점(Single Point of Failure): 시스템 내 한 컴포넌트가 실패했을 때 전체 시스템이 동작을 멈추는 구조적 취약점. Supervisor 패턴에서 Supervisor 자체가 이에 해당합니다. 재시도 로직과 상태 체크포인트를 설계 초기부터 고려하는 것을 권장합니다.

실무에서 가장 흔한 실수

  1. Worker가 3개 이하인데 Supervisor를 도입하는 것 — 이 경우 오버엔지니어링입니다. 순차 Pipeline이 더 단순하고 빠릅니다. Worker 수 임계값을 먼저 확인해보시면 좋습니다.
  2. Supervisor와 Worker에 같은 모델을 쓰는 것 — Supervisor는 라우팅 판단이 목적이므로 고성능 모델이 유리하지만, Worker는 도메인 특화 작업에 경량 모델을 사용해 비용을 분산하는 것이 효과적입니다.
  3. Worker 결과를 압축 없이 그대로 Supervisor에 전달하는 것 — 솔직히 이 실수는 처음 구축할 때 거의 모두가 한 번씩 겪습니다. 10회 왕복 전후로 Supervisor의 응답 품질이 눈에 띄게 달라지기 시작하는 걸 보고 나서야 컨텍스트 압축의 필요성을 체감하게 됩니다.

마치며

Supervisor Pattern은 "에이전트들이 알아서 협력하겠지"라는 막연한 설계를, "제어 흐름이 항상 한 곳으로 귀환한다"는 명확한 구조로 바꿔줍니다. 추적 가능성, 품질 게이트, 도메인 격리라는 세 가지 이점이 이 패턴을 프로덕션 기본값으로 만든 이유입니다.

지금 바로 시작해볼 수 있는 3단계:

  1. 패키지 설치부터 시작해볼 수 있습니다 — pip install langgraph-supervisor langchain-openai로 설치한 뒤, LangGraph 공식 문서에서 "Hierarchical Agent Teams" 튜토리얼을 검색해 예제 코드를 실행해보시면 전체 흐름을 빠르게 파악할 수 있습니다.
  2. 기존 단일 에이전트를 Supervisor + Worker 2개로 분리해볼 수 있습니다 — 이미 만들어둔 에이전트가 있다면, 태스크를 "정보 수집"과 "결과 생성" 두 단계로 나눠서 각각 Worker로 분리하고, Supervisor가 그 사이를 조율하도록 구조를 바꿔보시면 패턴의 이점을 직접 체감할 수 있습니다.
  3. LangSmith를 연결해 실행 트레이스를 확인해볼 수 있습니다 — LANGCHAIN_TRACING_V2=true 환경 변수 설정만으로 Supervisor의 라우팅 결정과 각 Worker 호출이 시각적으로 추적됩니다. 처음 트레이스를 보면 "이렇게 흐르고 있었구나" 하는 감이 확 오는데, 그게 이 패턴을 제대로 이해하는 순간입니다.

참고 자료

  • LangGraph Supervisor Pattern: Orchestrating Multi-Agent Teams in 2026 | CallSphere Blog
  • GitHub - langchain-ai/langgraph-supervisor-py
  • Hierarchical Agent Teams | LangGraph 공식 튜토리얼
  • langgraph-supervisor · PyPI
  • How to Use the Supervisor Pattern for Multi-Agent Voice AI Systems | LiveKit
  • Supervisor pattern | LiveKit Documentation
  • Multi-Agent AI Orchestration Patterns: Production Guide | Lushbinary
  • Multi-Agent Orchestration in LangGraph: Supervisor vs Swarm, Tradeoffs and Architecture
  • Swarm vs. Supervisor: Multi-Agent Architecture Guide | Augment Code
  • Agent system design patterns | Databricks on AWS
  • Multi-Agent collaboration patterns with Strands Agents and Amazon Nova | AWS Blog
  • Multi-Agent in Production 2026: 3 Patterns That Survived
  • Architecting efficient context-aware multi-agent framework for production | Google Developers Blog
  • LangGraph Multi-Agent Collaboration in Practice: Supervisor Pattern and Task Dispatch
  • The Multi-Agent Trap | Towards Data Science
#LangGraph#멀티에이전트#SupervisorPattern#CrewAI#LLM오케스트레이션#ReAct#Python#LangChain#컨텍스트압축#OpenAI
공유하기

목차

핵심 개념Supervisor, Swarm, Pipeline — 제어 흐름이 어디 있느냐의 문제왜 규칙 기반이 아니라 LLM 기반 라우팅인가세 단계 메커니즘: 분해 → 위임 → 집계계층적 확장: 에이전트가 6개를 넘으면실전 적용예시 1: LangGraph로 기본 Supervisor 구성하기예시 2: CrewAI로 계층적 Supervisor 구성하기예시 3: 컨텍스트 압축으로 토큰 폭발 막기장단점 분석장점단점 및 주의사항실무에서 가장 흔한 실수마치며참고 자료

추천 포스트

AI 에이전트 장기 메모리 비교: Mem0 vs Letta vs Zep — 세 가지 철학과 실전 선택 기준
AI

AI 에이전트 장기 메모리 비교: Mem0 vs Letta vs Zep — 세 가지 철학과 실전 선택 기준

LLM 기반 앱을 한 번이라도 만들어봤다면 반드시 이 벽에 부딪힌다. "지난 대화를 어떻게 기억하게 할까?" 컨텍스트 윈도우에 전체 대화를 욱여넣으면 되겠지 싶지만, 현실은 그렇지 않다. 토큰 비용이 폭발하고, 대화가 길어질수록 LLM의 집중력은 흐트러지며, 세션이 끊기면 모든 것이 사...

2026년 05월 30일읽는 데 29분
멀티모달 RAG 파이프라인 구축: 이미지·표를 LLM이 이해하게 만드는 법
AI

멀티모달 RAG 파이프라인 구축: 이미지·표를 LLM이 이해하게 만드는 법

RAG를 처음 도입했을 때 저도 비슷한 경험을 했습니다. PDF 몇 백 개를 파싱해서 벡터 DB에 넣고 검색해보니, 텍스트로 잘 설명된 내용은 꽤 잘 뽑아왔는데, 문서 중간에 끼어있던 차트나 제품 사진, 회로 다이어그램은 완전히 무시되더군요. 그 시각 정보가 사실상 문서의 핵심인 경우가...

2026년 05월 30일읽는 데 20분
OpenTelemetry로 LLM 트레이싱 구축하기: RAG·멀티에이전트 흐름을 gen_ai 표준으로 추적하는 법
AI

OpenTelemetry로 LLM 트레이싱 구축하기: RAG·멀티에이전트 흐름을 gen_ai 표준으로 추적하는 법

GPT-4를 붙여놓은 서비스가 갑자기 엉뚱한 답을 내놓기 시작했다. 로그를 뒤져봐도 에러는 없다. HTTP 응답코드도 200이다. 근데 사용자는 화가 났다. 이 상황, 한 번쯤 겪어보셨을 것 같다. 전통적인 APM으로는 "LLM 호출에 1.2초 걸렸음"까지만 알 수 있고, 정작 중요한 ...

2026년 05월 30일읽는 데 25분
AI 에이전트 88%가 프로덕션에 실패하는 이유: 5계층 하네스 아키텍처가 그 답이다
AI

AI 에이전트 88%가 프로덕션에 실패하는 이유: 5계층 하네스 아키텍처가 그 답이다

GPT-4가 처음 나왔을 때, 저도 그랬고 주변 개발자들도 다들 비슷한 착각을 했습니다. "모델만 좋으면 되는 거 아닌가?" 프롬프트 몇 줄 붙여서 프로토타입 만들고, 그럴싸하게 돌아가는 것 같으니 프로덕션 배포. 그리고 얼마 지나지 않아 에이전트가 엉뚱한 파일을 삭제하거나, 컨텍스트를...

2026년 05월 29일읽는 데 28분
FP4 양자화 + Blackwell GPU: H100 대비 4배 처리량이 가능한 조건과 쓰면 안 되는 상황
AI

FP4 양자화 + Blackwell GPU: H100 대비 4배 처리량이 가능한 조건과 쓰면 안 되는 상황

llm-compressorscheme="NVFP4"ignore=["lm_head"]num_calibration_samplespip install llmcompressornvfp4_experts_onlynvfp4_experts_onlytorch.cuda.get_device_capabili...

2026년 05월 29일읽는 데 22분
XGrammar-2: 구조화 출력을 80배 빠르게 만든 설계 원리
AI

XGrammar-2: 구조화 출력을 80배 빠르게 만든 설계 원리

LLM이 툴을 호출하거나 JSON을 반환할 때, 사실 꽤 무거운 작업이 뒤에서 돌아가고 있습니다. 모델이 토큰을 하나 뱉을 때마다 "이 토큰이 현재 문법 상태에서 유효한가?"를 실시간으로 판단해야 하고, 툴이 수백 개로 늘어나면 요청이 들어올 때마다 문법을 새로 컴파일하는 비용이 조용히...

2026년 05월 28일읽는 데 23분