06. 고급: LangGraph Supervisor
개요
순차적 체인(A → B → C)을 넘어 Supervisor 패턴을 탐구합니다. 단일 "Supervisor Node" (LLM)가 상태를 보고 다음에 누가 행동할지(Researcher vs Coder) 또는 작업이 완료되었는지 결정합니다.
이는 실제 팀 구조를 모방하며, 개방형 작업을 처리할 수 있는 "Deep Agents"를 구축하는 데 필수적입니다.
Supervisor 패턴
핵심 개념
| 개념 | 설명 |
|---|---|
| Supervisor | 라우팅과 작업 완료를 결정하는 LLM |
| Worker Nodes | 전문화된 에이전트 (리서치, 코드, 검토) |
| State | 모든 노드 간에 전달되는 공유 컨텍스트 |
| Routing | 현재 상태 기반 동적 결정 |
LangGraph 구현
from langgraph.graph import StateGraph, END
from typing import TypedDict, Literal
class AgentState(TypedDict):
messages: list
next: str
def supervisor_node(state: AgentState) -> AgentState:
"""Supervisor가 다음 행동자 결정"""
response = llm.invoke([
SystemMessage(content="""당신은 팀을 관리하는 supervisor입니다.
대화 내용을 바탕으로 다음에 누가 행동할지 결정하세요:
- 'researcher': 정보 수집
- 'coder': 구현
- 'FINISH': 작업 완료"""),
*state["messages"]
])
return {"next": response.content}
def researcher_node(state: AgentState) -> AgentState:
"""리서치 에이전트가 정보 수집"""
# ... 리서치 로직
return {"messages": state["messages"] + [result]}
def coder_node(state: AgentState) -> AgentState:
"""코더 에이전트가 코드 작성"""
# ... 코딩 로직
return {"messages": state["messages"] + [result]}그래프 구축
workflow = StateGraph(AgentState)
# 노드 추가
workflow.add_node("supervisor", supervisor_node)
workflow.add_node("researcher", researcher_node)
workflow.add_node("coder", coder_node)
# 엣지 추가
workflow.add_conditional_edges(
"supervisor",
lambda x: x["next"],
{
"researcher": "researcher",
"coder": "coder",
"FINISH": END
}
)
workflow.add_edge("researcher", "supervisor")
workflow.add_edge("coder", "supervisor")
workflow.set_entry_point("supervisor")
app = workflow.compile()Supervisor 패턴을 사용하는 이유
동적 라우팅: Supervisor가 작업에 맞게 적응하여 필요에 따라 전문가 호출
| Sequential | Supervisor |
|---|---|
| 고정된 순서 A→B→C | 동적 라우팅 |
| 모든 단계 항상 실행 | 불필요한 단계 건너뛰기 |
| 단순한 작업 | 복잡한 개방형 작업 |
실습
Worker 에이전트 정의
researcher와 coder 노드 생성
Supervisor 로직 구축
라우팅 결정 구현
그래프 연결
조건부 엣지로 노드 연결
작업으로 테스트
다른 쿼리 실행 및 라우팅 관찰