상세 컨텐츠

본문 제목

# 라우팅(Routing) 워크플로우 — 입력에 따라 다른 길로 보내는 "교통 정리" 패턴

AI

by Robert_ 2026. 6. 11. 00:18

본문

라우팅(Routing) 워크플로우 — 입력에 따라 다른 길로 보내는 "교통 정리" 패턴

체이닝(Chaining)이 "하나씩 순서대로" 였다면, 라우팅(Routing)은 "입력 종류에 따라 다른 길로" 보내는 패턴입니다. 🛤️

오늘 글의 핵심 질문은 이거예요. "같은 챗봇 / 같은 도구라도, 사용자 요청 유형이 너무 달라서 하나의 프롬프트로 다 잘 처리할 수 없을 때 어떻게 할까?" 답은 의외로 단순합니다 — 입력을 먼저 분류한 다음, 그에 맞는 전문 파이프라인으로 보낸다. 우리가 평소에 병원 접수처에서 진료과별로 흩어지는 것과 똑같은 아이디어예요. 🏥


🤔 왜 라우팅이 필요한가? — 일반 프롬프트의 한계

원문 강의의 시나리오로 시작해봅시다. 사용자 주제 → 영상 스크립트 자동 생성 마케팅 도구.

사용자 입력 적합한 콘텐츠 톤
"Python 함수" 📚 교육적, 명확한 정의·예제
"서핑" 🎉 엔터테인먼트, 흥분과 시각적 매력
"최신 노트북 리뷰" ⚖️ 분석적, 장단점 위주
"내 첫 마라톤 후기" 💬 친근한 vlog 톤

이 모두에 같은 프롬프트를 쓰면 어떻게 될까요?

> 다음 주제로 영상 스크립트를 만들어줘: <topic>

결과:

  • 🥱 Python 강의가 슬랩스틱 톤으로 나오거나
  • 🤓 서핑 영상이 학술 발표처럼 됨
  • ⚖️ 리뷰가 정보 없이 감성만 잔뜩

🎯 문제의 본질: 같은 모델·같은 프롬프트가 모든 도메인에 최적이긴 어렵습니다. 모델은 만능이지만, 프롬프트는 도메인 종속적이거든요.


🧭 라우팅의 핵심 아이디어

[사용자 입력]
       ▼
[Router] — 입력 종류를 분류
       ▼
   ┌────┬────┬────┬────┐
   ▼    ▼    ▼    ▼    ▼
 [Pipe A] [Pipe B] [Pipe C] [Pipe D] ...
   각 파이프라인 = 특정 카테고리 전용 프롬프트/도구

핵심 규칙: 입력은 단 하나의 파이프라인에만 흘러갑니다. 모든 파이프라인을 거치지 않아요.

일반 프롬프트 라우팅 워크플로우
1개의 만능 프롬프트 N개의 전문 프롬프트
한 번 호출 분류 1회 + 처리 1회 = 2회
결과 품질 평균 카테고리별 고품질
새 도메인 추가 어려움 새 파이프라인만 추가

💡 트레이드오프: 호출 횟수가 늘어 비용·지연이 약간 증가하지만, 품질 향상이 훨씬 큽니다. 다양한 도메인을 다루는 앱에선 거의 필수.


🏗️ 단계별 구현 — SNS 영상 도구 예시

1단계: 카테고리 정의

먼저 앱이 다룰 콘텐츠 종류를 명확히 분류합니다.

카테고리 특징
🎉 Entertainment 트렌드 언어, 문화적 맥락 고에너지
📚 Educational 명확한 설명, 친근한 예시 차분하고 친절
🎭 Comedy 의외의 전개, 타이밍 위트
📹 Personal vlog 진솔한 스토리텔링 대화체
⚖️ Reviews 장단점 비교, 경험 기반 단호하고 분석적
📖 Storytelling 생생한 디테일, 감정 연결 몰입형

📌 카테고리 설계 팁: 너무 많으면 분류가 헷갈리고, 너무 적으면 차별화가 없습니다. 5~8개 사이가 보통 sweet spot 이에요.

2단계: 카테고리별 프롬프트 템플릿

각 카테고리 전용 프롬프트를 미리 작성해둡니다.

PROMPT_TEMPLATES = {
    "Educational": """
당신은 친근한 IT 강사입니다. 복잡한 개념을 일상 비유로 풀어주세요.
주제: {topic}
다음을 포함하세요:
- 한 줄 핵심 정의
- 일상에서 본 적 있을 비유 1개
- 코드 또는 실습 예시 1개
- 시청자에게 던지는 질문 1개로 마무리
""",
    "Entertainment": """
당신은 SNS 트렌드를 잘 아는 크리에이터입니다.
주제: {topic}
- 후킹 강한 첫 5초
- 시각적 임팩트 가능한 표현 다수
- 트렌디한 표현·밈 적극 활용
- 공유하고 싶게 만드는 마무리
""",
    "Reviews": """...""",
    # ... 나머지 카테고리
}

🎯 각 템플릿이 그 도메인의 베테랑처럼 작동하게 만드는 게 핵심. 일반 프롬프트보다 훨씬 강한 페르소나·제약을 박아도 됩니다.

3단계: Router — 입력을 분류

def classify_topic(topic: str) -> str:
    messages = []
    add_user_message(messages, f"""
다음 주제를 한 카테고리로 분류해. 정확히 카테고리명만 출력.

<topic>{topic}</topic>

<categories>
- Educational
- Entertainment
- Comedy
- Personal vlog
- Reviews
- Storytelling
</categories>
""")
    return chat(messages, temperature=0).strip()

💡 분류는 temperature=0 으로 결정성을 극대화하세요. 같은 입력에 같은 카테고리가 나와야 디버깅이 쉬워집니다.

4단계: Routing — 분류 결과로 분기

def generate_video_script(topic: str) -> str:
    category = classify_topic(topic)
    template = PROMPT_TEMPLATES.get(category, PROMPT_TEMPLATES["Educational"])

    messages = []
    add_user_message(messages, template.format(topic=topic))
    return chat(messages, temperature=0.7)
사용자 입력 classify_topic 결과 사용된 템플릿
"Python 함수" Educational educational_prompt
"서핑" Entertainment entertainment_prompt
"M3 Max 노트북 리뷰" Reviews reviews_prompt
"유럽 여행 후기" Personal vlog vlog_prompt

🎯 사용자는 카테고리 존재를 모릅니다. 그저 더 자기 입력에 어울리는 결과를 받아볼 뿐이에요. UX 매끄럽게 유지하면서 품질만 올라가는 패턴.


🛡️ Router 의 견고성 — 흔한 함정과 방어

함정 1: 분류 결과가 카테고리 밖

# Claude 가 가끔 이렇게 답할 수 있음:
"Educational/Entertainment 혼합" 
"Educational - because it's about programming"

방어:

VALID_CATEGORIES = {"Educational", "Entertainment", "Comedy",
                    "Personal vlog", "Reviews", "Storytelling"}

def classify_topic(topic: str) -> str:
    raw = chat(...).strip()
    # 카테고리명만 추출
    for cat in VALID_CATEGORIES:
        if cat.lower() in raw.lower():
            return cat
    return "Educational"  # 안전한 기본값

📌 post 09 에서 배운 prefill + stop_sequences 패턴을 적용하면 더 안전합니다.

add_assistant_message(messages, "<category>")
raw = chat(messages, stop_sequences=["</category>"])

함정 2: 모호한 입력

> "AI"  ← 너무 광범위
> "음... 뭔가"  ← 무의미

방어:

def classify_with_fallback(topic: str) -> str:
    if len(topic) < 3 or topic.isspace():
        return "Educational"  # 기본값
    if not is_meaningful(topic):  # 추가 검증
        return ask_user_to_clarify()
    return classify_topic(topic)

함정 3: 새 카테고리가 자주 추가되는 경우

# 동적 카테고리 — 코드 변경 없이 카테고리 추가
CATEGORIES = load_from_yaml("categories.yaml")

def build_categorize_prompt(topic, categories):
    cat_list = "\n".join(f"- {c['name']}: {c['description']}" for c in categories)
    return f"""주제: <topic>{topic}</topic>\n카테고리:\n{cat_list}\n..."""

💡 카테고리 정의를 YAML/DB 등으로 외부화하면 운영 중 추가가 쉬워집니다. 비즈니스 변화에 빠르게 적응 가능.


🧪 Router 의 신뢰성 검증 — eval 적용

라우터의 분류 정확도가 떨어지면 이후 모든 파이프라인의 품질이 무의미해집니다. 그래서 라우터는 반드시 챕터 2 의 eval 워크플로우로 측정하세요.

test_cases = [
    {"topic": "Python 함수", "expected": "Educational"},
    {"topic": "서핑", "expected": "Entertainment"},
    {"topic": "M3 Max 후기", "expected": "Reviews"},
    {"topic": "오늘 점심 먹은 가게", "expected": "Personal vlog"},
    # ...
]

correct = sum(
    classify_topic(c["topic"]) == c["expected"]
    for c in test_cases
)
print(f"정확도: {correct}/{len(test_cases)}")

🎯 운영 환경에서 카테고리별 호출 수와 정확도를 추적하면 어느 카테고리가 자주 오분류되는지 보입니다. 거기에 더 명확한 카테고리 description 을 주거나 키워드 힌트를 추가하면 정확도가 점프해요.


🏛️ 라우팅 아키텍처 다이어그램

                    [사용자 입력]
                          │
                          ▼
                    ┌──────────┐
                    │  Router  │ ← Claude (temp=0, 분류만)
                    └────┬─────┘
                         │ category
              ┌──────────┼──────────┐
              ▼          ▼          ▼
        ┌──────────┐ ┌──────────┐ ┌──────────┐
        │ Pipe A   │ │ Pipe B   │ │ Pipe C   │
        │ Edu 전용 │ │ Ent 전용 │ │ Rev 전용 │
        └────┬─────┘ └────┬─────┘ └────┬─────┘
             ▼            ▼            ▼
                     [최종 결과]

🔧 각 Pipe 는 자체 프롬프트, 자체 도구, 자체 후처리를 가질 수 있습니다. 한 라인은 RAG 를, 다른 라인은 단일 호출만, 또 다른 라인은 Evaluator-Optimizer 를 쓸 수도 있죠.


⏰ 라우팅을 언제 쓸까?

원문이 짚은 4가지 적합 조건을 확장해봅니다.

✅ 라우팅이 빛나는 상황

  1. 다양한 요청 유형이 섞여 들어옴
    • 고객 응대 봇 (환불/문의/기술지원/칭찬...)
  2. 유형별로 처리 방식이 명확히 다름
    • 환불은 빠른 검증, 기술지원은 깊은 진단
  3. 카테고리 정의가 가능
    • "잘 모르겠는 회색지대" 가 적음
  4. 분류 단계의 비용 < 전문 처리의 이득
    • 작은 모델(Haiku) 로 분류 → 큰 모델(Opus) 로 처리 같은 최적화도 가능

❌ 라우팅이 과한 상황

상황 추천
모든 입력이 비슷한 성격 단일 프롬프트
카테고리 경계가 너무 모호 단일 + Evaluator-Optimizer
이미 도구 사용으로 자율 분기 가능 에이전트

⚠️ 카테고리 ≠ 본질적 차이. 라우팅은 다른 처리 전략이 정말 필요할 때만 도입하세요. 같은 프롬프트에 약간의 변수만 다른 거라면 체이닝의 변수 주입으로 해결할 수 있어요.


💼 한국 개발자를 위한 실전 팁

1️⃣ 라우터에 작은 모델 활용 — 비용 절감

분류는 단순 작업이라 Haiku 같은 작은 모델로 충분합니다.

def classify_topic(topic: str) -> str:
    return chat(
        messages,
        model="claude-haiku-4-5",  # 작은 모델
        temperature=0
    ).strip()

def generate_content(topic, category) -> str:
    return chat(
        messages,
        model="claude-sonnet-4-6",  # 큰 모델
        temperature=0.7
    )

💰 혼합 모델 전략: 분류는 빠르고 싸게, 본 처리는 강력하게. Anthropic 도 이 패턴을 권장합니다.

2️⃣ 한국어 입력 — 영어 카테고리 매핑

사용자 입력은 한국어, 카테고리 라벨은 영어인 경우가 많습니다.

add_user_message(messages, f"""
한국어 주제를 영어 카테고리로 분류해. 카테고리명만 출력.

<topic>{topic}</topic>

<categories>
- Educational (교육·강의)
- Entertainment (오락·트렌드)
- Reviews (리뷰·비교)
- ...
</categories>
""")

💡 카테고리 옆에 한국어 설명을 붙여주면 다국어 입력에서도 정확도가 안정적입니다.

3️⃣ 라우터 결과 캐싱

같은 입력은 같은 카테고리. 프로덕션에선 캐싱하세요.

@lru_cache(maxsize=10000)
def classify_topic_cached(topic: str) -> str:
    return classify_topic(topic)

📌 또는 Redis·Memcached 같은 분산 캐시 사용. 인기 키워드의 분류 결과는 거의 무한 재사용 가능.

4️⃣ Fallback 카테고리는 가장 만능인 것

분류 실패 시 어디로 보내냐가 중요합니다.

DEFAULT_CATEGORY = "Educational"  # 무난한 톤
# 또는
DEFAULT_CATEGORY = "Generic"  # 별도의 만능 파이프라인

⚠️ Fallback 을 가장 좁은 카테고리로 두면 큰 사고가 납니다. 가장 부작용이 작은 파이프라인으로 라우팅하세요.

5️⃣ 한국형 도메인 카테고리 예시

도메인별 추천 카테고리 셋업:

도메인 추천 카테고리
🛍️ 쇼핑 챗봇 환불 / 배송 / 상품문의 / 일반문의
🏥 헬스케어 증상문의 / 예약 / 처방 / 일반
🏦 금융 거래조회 / 송금 / 투자상담 / 사고신고
📚 교육 플랫폼 강의문의 / 학습질문 / 진로상담 / 결제
🍔 배달 앱 주문 / 환불 / 라이더 문의 / 일반

🎯 고객 응대 로그를 클러스터링해서 자주 나오는 의도를 카테고리로 뽑으면 정확도가 매우 높아집니다.


🧠 핵심 정리

  • 🛤️ 라우팅(Routing) = 입력을 분류 후, 카테고리별 전문 파이프라인으로 분기.
  • 🤔 일반 프롬프트의 한계 — 도메인이 다른 입력에 동일 처리 → 품질 평균화.
  • 🏗️ 구현 4단계: 카테고리 정의 → 카테고리별 프롬프트 → Router 분류 → 분기 처리.
  • 🛡️ Router 견고성: 출력 검증, 모호한 입력 fallback, 동적 카테고리 외부화.
  • 🧪 Router 정확도는 챕터 2 eval 로 정량 측정 → 운영 모니터링 필수.
  • 🏛️ 각 Pipe 는 자체 프롬프트·도구·후처리 가능 — 다른 워크플로우(체이닝, evaluator-optimizer 등)도 내부에 포함 가능.
  • ⏰ 도입 시점: 다양한 요청 유형 + 명확한 카테고리 + 분류 비용 < 전문화 이득.
  • 💼 한국 운영 팁: Haiku 로 분류·Sonnet 으로 처리, 다국어 카테고리 매핑, 결과 캐싱, 안전한 Fallback, 고객 로그 기반 카테고리 추출.

📚 출처 (Source)

본 글은 Anthropic Academy"Building with the Claude API" 코스 중 'Routing workflows' 강의 내용을 한국어로 정리·요약한 것입니다.

  • 원문 출처: Anthropic Academy
  • 강의 챕터: Agents and workflows → Routing workflows
  • 저작권: © Anthropic. All rights reserved.

⚠️ 본 글은 학습 목적의 요약본이며, 정확하고 최신화된 내용은 반드시 Anthropic 공식 가이드 — Building effective agents 를 참고해주세요.


📝 이 글이 도움이 되셨다면 공감 ♥ 과 구독 부탁드립니다!
실제 프로젝트에서 어떤 카테고리 셋으로 라우팅을 설계하셨는지, 혹은 분류 정확도를 끌어올린 노하우가 있다면 댓글로 공유해 주세요. 다음 강의는 "Agents and tools — 에이전트와 도구의 결합" 입니다. 🤖

#Workflow #RoutingWorkflow #AnthropicAcademy #ClaudeAI #LLM #AgentDesign #SystemDesign #PromptEngineering #AI개발 #API개발 #챗봇 #ClaudeAPI

관련글 더보기