자동화 생산성

멀티 에이전트 워크플로우 실전 가이드

temver 2026. 5. 27. 16:18
SMALL
멀티 에이전트 워크플로우 실전 가이드
AI 엔지니어링 멀티 에이전트 실전 가이드

LLM 단독 호출을 넘어서
멀티 에이전트 워크플로우 실전 가이드

단순 프롬프트 엔지니어링의 한계를 어떻게 극복할까요? 오케스트레이터-에이전트 패턴으로 복잡한 작업을 자동화하는 방법을 코드와 함께 단계별로 살펴봅니다.

2025 · 06 · 01 읽는 시간 약 12분 난이도 중급

왜 지금 멀티 에이전트인가

GPT-4, Claude, Gemini 같은 강력한 모델이 등장하면서 처음에는 "프롬프트만 잘 짜면 된다"는 기대가 높았습니다. 실제로 단순한 Q&A나 요약, 번역 같은 작업은 단일 LLM 호출로도 충분합니다. 하지만 현실의 업무는 다릅니다.

수십 개의 파일을 분석해 보고서를 쓰거나, 외부 API를 조합해 데이터를 수집하고, 그 결과를 검증하고 다시 처리하는 파이프라인—이런 작업에서는 단일 LLM 호출이 컨텍스트 한계신뢰성 한계에 금방 부딪힙니다.

핵심 통찰

멀티 에이전트 워크플로우는 "모델을 더 스마트하게 만드는 것"이 아닙니다. 복잡한 작업을 검증 가능한 작은 단계로 분해하여 각 단계에서 모델이 집중할 수 있도록 설계하는 시스템 엔지니어링입니다.

핵심 패턴 세 가지

실무에서 반복적으로 등장하는 패턴이 있습니다. 모든 복잡한 에이전트 시스템은 결국 이 세 가지를 조합한 것입니다.

01
오케스트레이터 / 서브에이전트

계획을 수립하는 LLM이 전문화된 에이전트에게 작업을 위임합니다. 가장 일반적이고 확장성이 높은 패턴입니다.

02
파이프라인 체인

각 단계의 출력이 다음 단계의 입력이 됩니다. 예측 가능한 순서가 있는 ETL, 문서 처리에 적합합니다.

03
평가자-최적화 루프

에이전트 A가 생성하고, 에이전트 B가 평가하고, 결과가 기준을 통과할 때까지 반복합니다. 고품질 출력이 필요할 때 사용합니다.

아키텍처 설계하기

오케스트레이터-에이전트 패턴의 실제 구조를 살펴봅시다. 아래 다이어그램은 "경쟁사 분석 리포트 자동 생성" 시스템의 예입니다.

// architecture — competitor analysis pipeline
🧠 Orchestrator LLM
🔍 Research Agent
📊 Analysis Agent
✍️ Writer Agent
Web Search
DB Query
Chart API
Markdown Export

오케스트레이터는 목표를 받아 계획을 세우고 서브 에이전트를 호출합니다. 각 에이전트는 자신에게 필요한 도구(Tool)만 갖습니다. 이 분리 덕분에 각 에이전트를 독립적으로 테스트하고 교체할 수 있습니다.

파이썬으로 직접 구현하기

기본 에이전트 루프

복잡한 프레임워크 없이도 핵심 로직은 단순합니다. 에이전트의 본질은 생각 → 행동 → 관찰의 반복입니다.

import anthropic
from typing import Callable

client = anthropic.Anthropic()

def run_agent(
    task: str,
    tools: list[dict],
    tool_handlers: dict[str, Callable],
    max_steps: int = 10
) -> str:
    messages = [{"role": "user", "content": task}]

    for _ in range(max_steps):
        response = client.messages.create(
            model="claude-sonnet-4-20250514",
            max_tokens=4096,
            tools=tools,
            messages=messages
        )

        # 도구 호출이 없으면 최종 답변 반환
        if response.stop_reason == "end_turn":
            return response.content[0].text

        # 도구 호출 처리
        tool_results = []
        for block in response.content:
            if block.type == "tool_use":
                handler = tool_handlers[block.name]
                result = handler(**block.input)
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": block.id,
                    "content": str(result)
                })

        # 대화 히스토리 업데이트
        messages += [
            {"role": "assistant", "content": response.content},
            {"role": "user", "content": tool_results}
        ]

    raise RuntimeError("Max steps exceeded")

오케스트레이터 구현

오케스트레이터는 서브 에이전트 자체를 도구로 등록합니다. 이렇게 하면 LLM이 어떤 에이전트를 언제 호출할지 스스로 결정합니다.

def create_orchestrator():
    # 서브 에이전트를 도구로 래핑
    agent_tools = [
        {
            "name": "research_agent",
            "description": "웹에서 정보를 수집하고 요약합니다",
            "input_schema": {
                "type": "object",
                "properties": {
                    "query": {"type": "string"},
                    "depth": {"type": "integer", "default": 3}
                }
            }
        },
        {
            "name": "analysis_agent",
            "description": "데이터를 분석하고 인사이트를 추출합니다",
            "input_schema": {
                "type": "object",
                "properties": {
                    "data": {"type": "string"},
                    "focus": {"type": "string"}
                }
            }
        }
    ]

    handlers = {
        "research_agent": lambda **kw: run_agent(
            kw["query"], research_tools, research_handlers
        ),
        "analysis_agent": lambda **kw: run_agent(
            kw["data"], analysis_tools, analysis_handlers
        )
    }

    return lambda task: run_agent(task, agent_tools, handlers)

실전에서 마주치는 함정들

⚠ 경고

멀티 에이전트 시스템은 실패 지점이 여러 개입니다. 단일 에이전트 오류는 쉽게 디버깅할 수 있지만, 에이전트 A의 잘못된 출력이 에이전트 B와 C까지 오염시킬 수 있습니다. 검증 레이어를 반드시 추가하세요.

흔한 실수 증상 해결책
에이전트 컨텍스트 비대화 응답 품질 저하, 지연 증가 단계마다 컨텍스트 요약 후 전달
무한 루프 max_tokens 초과, 비용 폭증 max_steps + 타임아웃 필수 설정
도구 오류 미처리 에이전트가 멈추거나 환각 발생 try/except + 폴백 메시지 반환
병렬 호출 미활용 불필요한 순차 실행, 느린 파이프라인 asyncio.gather로 독립 에이전트 병렬화

단일 LLM vs 멀티 에이전트: 언제 무엇을?

모든 작업에 멀티 에이전트가 정답은 아닙니다. 아래 기준으로 판단해 보세요.

기준 단일 LLM 호출 멀티 에이전트
작업 복잡도 단순, 명확한 단일 질의 다단계, 조건 분기 포함
외부 도구 의존 없거나 1~2개 3개 이상, 동적 선택 필요
응답 시간 빠름 (초 이하) 느림 (수십 초 ~ 분)
비용 저렴 LLM 호출 횟수 비례 증가
디버깅 용이성 입출력 추적 간단 중간 상태 로깅 필수

다음 단계

멀티 에이전트 시스템의 진입 장벽은 낮아졌습니다. LangGraph, LlamaIndex Workflows, 혹은 직접 구현한 루프— 어떤 방식이든 작은 단위부터 검증하는 것이 핵심입니다.

다음 글에서는 에이전트 간 공유 메모리와 장기 실행 작업에서의 체크포인트 패턴을 다룰 예정입니다.

LIST