에이전트 파이프라인을 8가지 방식으로 망가뜨리는 라이브 데모를 구축한 방법과 MCP 기반의 모든 팀에게 이것이 필요한 이유
요약
LangChain과 MCP(Model Context Protocol)를 활용하여 멀티 에이전트 파이프라인의 8가지 실패 모드를 실시간으로 시뮬레이션하는 오픈 소스 데모 앱 'The Gauntlet'을 소개합니다. 도구 충돌, 네임스페이스 라우팅, 실행 중 발생하는 다양한 오류 상황을 시각화하여 에이전트 시스템의 안정성을 테스트할 수 있습니다.
핵심 포인트
- MCP 서버 연결 시 발생하는 도구 이름 충돌 문제 해결 방법 제시
- 네임스페이스 라우팅을 통한 도구 디스패치 전략 설명
- 에이전트 파이프라인의 실행 과정을 ReactFlow로 시각화
- 실시간 토큰 인플레이션 및 재시도 상태 모니터링 기능 제공
요약 (TL;DR) — The Gauntlet은 LangChain 멀티 에이전트 파이프라인을 통해 7개의 MCP 서버를 연결하고, 실행 중에 8가지 실패 모드 (failure modes)를 실시간으로 전환할 수 있는 오픈 소스 Next.js 앱입니다. 컨퍼런스 데모를 위해 제작되었습니다. 에이전트가 망가지고, 수정되고, 다시 망가지는 과정을 모두 실시간으로 지켜보세요.
문제점
MCP (Model Context Protocol)를 사용하여 무언가를 구축해 보았다면, 다음과 같은 패턴을 알고 있을 것입니다: 몇 개의 서버를 연결하고, 에이전트를 구성한 뒤, 에이전트가 도구 (tools)를 호출하는 것을 지켜보는 것입니다. 잘 작동하다가, 어느 순간 작동하지 않게 됩니다.
실제 운영 중인 MCP 시스템에서 발생하는 실패는
각 단계는 실제 운영 중인 MCP 시스템의 라이프사이클(lifecycle) 단계에 대응합니다:
1. LOAD — 서버를 탐색하고 도구 충돌을 드러냄
앱은 /api/mcp를 통해 7개의 모든 MCP 서버에 동시에 연결합니다. 응답에는 전체 도구 인벤토리(tool inventory)와 이름 충돌(name collisions) 정보가 포함됩니다. search 도구 하나만 해도 4개의 서버에 존재하는데, 이는 즉각적인 위험 신호(red flag)입니다.
// app/api/mcp/route.ts — 단순화된 버전
const client = new MultiServerMCPClient({
mcpServers: { filesystem, calendar, approvals, tavily, ... },
...
2. ROUTE — 네임스페이스 라우팅(namespace routing)으로 충돌 해결
라우트(Route) 단계에서는 자동 네임스페이스 지정(auto-namespacing) 전략을 적용할 수 있습니다. 모든 도구는 server_tool 형식이 되어 모호함이 사라집니다. 또한 첫 번째 일치(first-match), 우선순위(priority), 또는 기능 기반 라우팅(capability-based routing)과 같은 디스패치(dispatch) 전략을 선택할 수 있습니다.
3. RUN — 에이전트 파이프라인(agent pipeline) 실행
여기가 마법이 일어나는 곳입니다. 실행(Run) 단계에서는 다음 항목들이 렌더링됩니다:
- 코디네이터(coordinator) → 리서처(researcher) → 분석가(analyst) → 승인 게이트(approval gate)를 보여주는 ReactFlow 에이전트 파이프라인 그래프
- 실시간 마크다운(markdown)으로 렌더링된 메시지(react-markdown 사용)를 포함하는 코디네이터 로그(coordinator log)
- 서버 접두사(prefix), 재시도 상태(retry status), 소요 시간과 함께 모든 MCP 호출을 보여주는 도구 호출 스트림(tool call stream)
- 재시도를 쌓여있는 점으로 시각화하여 분산(spread)인지 눈사태(avalanche)인지 보여주는 RetryChart SVG
- 토큰 인플레이션(token inflation)을 실시간으로 보여주는 ContextBomb 게이지
- 연속적인 도구 호출을 팩맨(Pac-Man) 애니메이션으로 보여주는 ToolLoopIndicator
백엔드는 수동 ReAct 루프를 사용하는 LangChain의 ChatOpenAI(Groq, OpenAI, Ollama, LM Studio 또는 OpenRouter와 호환 가능)를 사용합니다:
// lib/langchain/multi-runner.ts — 단순화된 LangGraph 파이프라인
const AgentState = Annotation.Root({
messages: Annotation(...),
...
4. CHAOS — 실패 모드(failure modes)를 실시간으로 전환
8개의 토글 카드 그리드가 있으며, 각 카드는 실제 안티 패턴(anti-pattern)을 나타냅니다. 하나를 켜고 파이프라인을 다시 실행하면 정확히 어떤 실패가 나타나는지 관찰할 수 있습니다. 다시 끄면 시스템은 2초 이내에 복구됩니다.
청중의 참여를 위한 Chaos Roulette (카오스 룰렛) 바퀴도 있습니다. 바퀴를 돌리면 2~3개의 플래그(flag)가 동시에 무작위로 활성화됩니다.
5. AUDIT (감사) — 결정 로그 조사
모든 도구 호출(tool call), 상태 전이(state transition), 그리고 인간의 결정은 에이전트, 도구, 입력, 출력 요약, 소요 시간 및 활성화된 카오스 플래그를 포함하는 구조화된 감사 로그(audit log)에 기록됩니다. 필터링이 가능하며 JSON으로 내보낼 수 있습니다.
카오스 래퍼 아키텍처 (The Chaos Wrapper Architecture)
'The Gauntlet'의 핵심은 카오스 래퍼(chaos wrapper)입니다. 이는 모든 MCP 도구가 에이전트에 도달하기 전에 감싸는 미들웨어 계층(middleware layer)입니다:
// lib/langchain/tools.ts — 카오스 래퍼 (개념적)
function wrapToolWithChaos(tool: DynamicStructuredTool, chaosFlags, ctx) {
const wrapped = Object.create(tool);
...
각 카오스 함수는 플래그 확인에 의해 보호되는 단순한 순수 함수(pure function)입니다:
// lib/langchain/chaos.ts — 카오스 함수
export function applyContextWindowBomb(flag, output, ctx): string {
if (!flag["contextWindowBomb"]) return output;
...
핵심 통찰: 카오스 함수는 시스템의 서로 다른 계층에서 작동합니다.
- 도구 이름 충돌 (Tool name collision) — LLM이 확인하기 전, 도구 이름에 작용
- 도구 환각 (Tool hallucination) — 도구 레지스트리(tool registry)에 작용하여 가짜 도구 추가
- 멱등성 / 서킷 브레이커 (Idempotency / Circuit breaker) — 실행 전, 호출 패턴에 작용
- 컨텍스트 폭탄 / 인젝션 / 루프 (Context bomb / Injection / Loop) — 실행 후, 도구 출력에 작용
- 상태 부패 (State rot) — 에이전트 간에 전달되는 컨텍스트 버전 문자열에 작용
- 인간 게이트 / 재시도 백오프 (Human gate / Retry backoff) — 에이전트 제어 흐름(control flow)에 작용
MCP 서버들
기성 제품(off-the-shelf)과 커스텀 구현을 혼합한 7개의 MCP 서버가 데모를 구동합니다:
| 서버 | 구현 방식 |
|---|---|
filesystem | npx @modelcontextprotocol/server-filesystem — public/scenario/ 내에서 읽기/쓰기 수행 |
| ... |
커스텀 서버들은 모두 동일한 패턴인 단순한 MCP stdio 서버 형식을 따릅니다:
// mcp-servers/tavily/index.ts — 단순화된 MCP 서버 예시
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
...
8가지 안티 패턴 (Chaos Toggles)
각 토글은 ELI5(다섯 살 아이에게 설명하듯 쉬운 설명) 이야기를 통해 특정 실패 모드를 보여줍니다:
1. 멱등성 가드 부재 (No Idempotency Guard)
ELI5: 엘리베이터 호출 버튼을 두 번 누릅니다. 이제 엘리베이터 두 대가 도착합니다.
무엇이 망가지는가: 승인 요청이 두 번 실행되어 중복된 캘린더 이벤트가 생성됩니다.
해결책: 도구 입력값(tool inputs)을 해싱(Hash)하고, 하나의 실행(run) 내에서 반복되는 호출을 차단(short-circuit)합니다.
2. 상태 부패 (State Rot)
ELI5: 화이트보드에 메모를 적고 자리를 비웠는데, 누군가 그것을 지워버립니다. 당신은 돌아와서 원래 무엇이 있었는지 기억에 의존해 메모를 작성합니다.
무엇이 망가지는가: 분석가가 이전 실행으로부터 오래된 컨텍스트(stale context)를 전달받습니다 — 메모에 잘못된 수치가 포함됩니다.
해결책: 컨텍스트 버전을 실행 ID(run ID)에 바인딩하고, 분석 전에 이를 검증합니다.
3. 인간 게이트 제거 (Remove Human Gate)
ELI5: 인턴이 아무의 검토도 받지 않고 CEO에게 보고서 초안을 보냅니다.
무엇이 망가지는가: 승인 게이트(approval gate)가 건너뛰어집니다 — 메모가 검토 없이 자동으로 승인됩니다.
해결책: 메모가 확정되기 전에 반드시 명시적인 인간의 승인을 요구합니다.
4. 재시도 백오프 부재 (No Retry Backoff)
ELI5: 문을 두드렸는데 아무도 대답이 없자, 즉시 다시 두드립니다 — 이를 계속 반복합니다.
무엇이 망가지는가: 실패한 도구 호출(tool calls)이 즉시 재시도되어 서버를 계속해서 공격(hammering)합니다.
해결책: 재시도 사이에 지수 백오프 (exponential backoff, 예: 500ms, 1s, 2s)를 적용합니다.
5. 도구 환각 (Tool Hallucination)
ELI5: 계산원이 계산대에 존재하지 않는 "반품 처리"라고 적힌 버튼을 누르려고 손을 뻗습니다.
무엇이 망가지는가: LLM이 존재하지 않는 filesystem_summarize를 호출합니다 — -32601 에러가 발생합니다.
해결책: LLM에 전달하기 전에 실제 매니페스트(manifest)와 대조하여 도구 이름을 검증합니다.
6. 컨텍스트 윈도우 폭탄 (Context Window Bomb)
ELI5 (다섯 살 아이에게 설명하듯): 누군가 당신에게 500페이지짜리 보고서를 건네며 "1분 안에 읽으세요"라고 말하는 것과 같습니다.
무엇이 망가지는가: 도구 (Tool)가 50KB 이상의 스팸을 반환하여 컨텍스트 윈도우 (Context Window)를 초과해 버립니다.
해결책: 도구 응답에 대해 구조화된 절단 (Structured Truncation)을 적용하여 출력 크기 제한을 강제합니다.
7. 도구 호출 루프 (Tool Call Loop)
ELI5: 로봇 청소기가 벽에 부딪히고, 뒤로 물러났다가, 다시 똑같은 벽에 부딪히는 동작을 영원히 반복하는 것과 같습니다.
무엇이 망가지는가: 에이전트 (Agent)가 회로 차단기 (Circuit Breaker) 없이 동일한 도구를 반복해서 호출합니다.
해결책: 최대 반복 횟수 제한, 루프 탐지 (Loop Detection), 그리고 회로 차단기를 설정합니다.
8. 도구 결과 주입 (Tool Result Injection)
ELI5: 사서에게 책을 추천해달라고 요청했는데, 그 책 자체가 당신에게 "내 모든 돈을 내놔"라고 말하는 것과 같습니다.
무엇이 망가지는가: 변조된 도구 출력에 에이전트를 하이재킹 (Hijack)하는 숨겨진 지침이 포함되어 있습니다.
해결책: 도구 출력을 정화 (Sanitize)하고, 신뢰 경계 (Trust Boundaries)를 강제하며, 심층 방어 (Defense-in-depth)를 적용합니다.
실시간 시각화 (Real-Time Visualization)
실행 (Run) 단계는 컨퍼런스 프로젝션용으로 설계되었습니다. 500명 규모의 강당 맨 뒷줄에서도 모든 요소를 읽을 수 있습니다:
- RetryChart: 시간에 따른 도구 호출을 보여주는 SVG 산점도 (Scatter Plot)입니다. 재시도 (Retry)가 수직으로 쌓입니다. 이를 통해 "확산" (건강한 백오프 (Backoff), 시간에 걸쳐 점들이 분포됨)과 "눈사태" (모든 재시도가 동일한 타임스탬프에 쌓임)를 시각적으로 구분할 수 있습니다.
- ContextBomb: 제한 대비 토큰 사용량을 보여주는 진행 바 (Progress Bar)입니다. 오버플로 (Overflow)가 발생하면 빨간색으로 깜빡이며 EXPLODED 애니메이션이 나타납니다.
- ToolLoopIndicator: 점을 먹는 팩맨 (Pac-Man) 애니메이션입니다. 각 점은 연속적인 도구 호출을 나타냅니다. 연쇄 반응이 3회 이상 발생하면 도구 이름과 횟수를 표시합니다.
- ChaosPredictions: 카오스 플래그 (Chaos Flags)가 활성화되면, UI에 예상되는 실패를 보여줍니다 — "Analyst가 filesystem_summarize를 호출할 예정 — -32601 반환."
- MatrixOverlay: 컨텍스트 폭탄 (Context Bomb)이 오버플로되면, 극적인 효과를 위해 초록색 디지털 레인 (Digital Rain) 오버레이가 나타납니다.
기술 스택 (Tech Stack)
| 계층 (Layer) | 선택 (Choice) |
|---|---|
| 프레임워크 (Framework) | Next.js 16 (App Router), TypeScript 6 |
| ... |
시작하기 (Getting Started)
git clone https://github.com/harishkotra/the-gauntlet.git
cd the-gauntlet
npm install
...
http://localhost:3000을 엽니다. 이 앱은 무료 Groq API 키만으로도 작동합니다. 다른 모든 키는 선택 사항입니다.
내가 배운 것들
'The Gauntlet'을 구축하면서 MCP 멀티 에이전트 시스템 (multi-agent systems)에 대해 어렵게 얻은 몇 가지 교훈을 다시 한번 확인할 수 있었습니다.
-
LangChain은 3가지 문제를 무료로 해결해 줍니다 — 도구 이름 충돌 (
prefixToolNameWithServerName을 통해), 구조화된 도구 호출 (structured tool calling,bindTools를 통해), 그리고 멀티 에이전트 오케스트레이션 (multi-agent orchestration,LangGraph를 통해). 남은 안티 패턴 (anti-patterns)들은 여러분이 실제로 설계 단계에서 고려해야 할 것들입니다. -
혼돈 (Chaos)은 계층화되어야 합니다 — 도구 (tool) 수준에서의 래핑 (wrapping)은 데이터 평면 (data-plane) 실패(폭탄, 인젝션)를 잡아냅니다. 에이전트 (agent) 수준에서의 래핑은 제어 평면 (control-plane) 실패(상태 부패, 인간 게이트)를 잡아냅니다. 두 가지 모두가 필요합니다.
-
ReAct 루프는 일부 제공업체에서 취약합니다 — Groq의 Llama 모델은 가끔 잘못된 형식의 함수 호출 (function-call) XML을 생성하여 오류(400 /
tool_use_failed)를 일으킵니다. 우리는 이를 위해 특별히 2회의 재시도를 포함한invokeWithRetry를 추가했습니다. OpenRouter 폴백 (fallback,openai/gpt-oss-120b:free)은 이를 안정적으로 처리합니다. -
MCP 어댑터 (adapter) 명명 규칙이 중요합니다 — 어댑터는 도구에
server__tool(이중 언더스코어) 접두사를 붙이지만, 우리는 이를server_tool(단일 언더스코어)로 정규화합니다. 모든 필터, 프롬프트, 그리고 혼돈 함수 (chaos function)는 동일한 규칙을 사용해야 하며, 그렇지 않으면 시스템이 조용히 고장 납니다. -
컨퍼런스 데모에는 시각적 대비가 필요합니다 — 단순히 작동하는 토글 스위치는 아무것도 가르쳐주지 못합니다. 시스템을 눈에 띄고 극적으로 망가뜨린 다음 즉시 복구하는 토글 스위치 — 그것이 사람들이 기억하는 것입니다.
'The Gauntlet'은 github.com/harishkotra/the-gauntlet에서 오픈 소스로 공개되어 있습니다. 클론(clone)하고, 망가뜨려 보고, 고쳐 보면서 여러분만의 것을 만들어 보세요.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기