요구사항: Chapter 2 - Routing
출처
- PDF:
Agentic_Design_Patterns.pdf - 섹션:
Chapter 2: Routing - 페이지 범위:
docs/agentic-design-patterns-toc.md의 논리 페이지 30-42 - 추출 참고: Chapter 2는 PDF 페이지 인덱스 35, 파일 페이지 36에서 시작하고 Chapter 3는 PDF 페이지 인덱스 49, 파일 페이지 50에서 시작한다. 따라서 추출된 Chapter 2 범위는 PDF 인덱스 35-48, 파일 페이지 36-49, 챕터 내부 페이지 카운터 1-14로 보인다. 이는 TOC의 논리 범위 30-42가 13페이지인 점과 모호성이 있다.
패턴 요약
Routing은 에이전트 시스템에 조건부 제어 흐름을 추가한다. 고정된 프롬프트 체인으로 모든 요청을 동일하게 처리하는 대신, 시스템이 요청, 현재 상태, 또는 이전 결과를 먼저 평가하여 가장 적합한 다음 워크플로우, 도구, 또는 전문 에이전트 경로를 선택한다.
이 패턴은 주문 상태 조회, 제품 정보 조회, 기술 지원 처리, 사람에게 위임, 의도가 불명확할 때의 명확화 등 서로 다른 입력을 구분해 처리 경로를 바꿔야 하는 경우에 사용한다. 라우팅 판정은 LLM 분류기, 임베딩 유사도, 규칙 기반 판단, 감독 학습 분류기 등으로 구현할 수 있다. 초기 LangGraph 구현에서는 라우터를 테스트 가능한 인터페이스로 두어, 실제 운영에서는 LLM을 사용하되 테스트에서는 결정적 라우팅 결정을 주입할 수 있어야 한다.
예상 동작:
- 전문 핸들러를 실행하기 전에 들어오는 사용자 요청을 분석한다.
- 자유 텍스트가 아닌 제한된 라우트 라벨을 출력한다.
- 초기 예제에서는 정확히 하나의 라우트로만 분기한다.
- 라우트 결정, 근거, 신뢰도, 핸들러 출력은 그래프 상태에 보존한다.
- 불명확/지원되지 않음/저신뢰도/형식 오류 라우트는 clarifying 혹은 폴백 경로로 보낸다.
패턴 설명
개념 개요
Routing은 에이전트가 본 작업을 수행하기 전 요청에 맞는 경로를 골라가는 방식이다. 라우터는 입력 또는 현재 상태를 검사해 제한된 목적지로 분류하고, 해당 처리기로 워크플로우를 전달한다.
단일 프롬프트 체인과 다른 점은 다음 단계가 고정되지 않는다는 것이다. 다음 단계는 intent, 신뢰도, 요청 유형, 정책 제약에 따라 달라진다.
문제
많은 에이전트 애플리케이션은 혼합된 요청을 받는다. 고객 지원 도구는 주문 질문, 제품 질문, 기술 이슈, 모호한 문의를 한 화면에서 받는 경우가 많다. 모든 요청을 하나의 범용 핸들러로 처리하면 취약하고 평가하기 어렵다. Routing은 분류를 별도 처리함으로써 전문 핸들링과 분리한다.
사용해야 할 때
- 입력이 알려진 카테고리로 나눠질 때 사용한다.
- 카테고리마다 도구/프롬프트/정책/전문가가 다를 때 사용한다.
- 불명확하거나 신뢰도가 낮은 입력은 액션 전에 명확화가 필요한 경우 사용한다.
- 의사결정 경로 추적이 중요할 때 사용한다.
사용하지 말아야 할 때
- 모든 요청이 동일한 워크플로우를 따라야 하는 경우 피한다.
- 카테고리가 불안정하거나 정의가 불명확한 경우 피한다.
- 잘못된 라우트가 명확화 질문보다 더 위험한 경우 과도한 라우팅을 피한다.
- 제약 없는 자유 텍스트 라우트 출력에 의존하는 것은 피한다.
작동 방식
- 워크플로가 사용자 입력을 정규화하고 검증한다.
- 라우터가 제한된 라우트 라벨 세트 중 하나로 분류한다.
- 라우터는 라벨, 신뢰도, 폴백 정책을 검증한다.
- 조건부 엣지가 선택된 전문 핸들러로 상태를 전달한다.
- 선택된 핸들러가 도메인별 응답을 생성하고 formatter가 최종 답변을 반환한다.
트레이드오프
| 이점 | 비용 또는 위험 |
|---|---|
| 전문 프롬프트와 도구의 책임이 명확해진다. | 잘못된 라우팅은 사용자를 잘못된 워크플로로 보낼 수 있다. |
| 라우트별로 동작을 테스트하기 쉽다. | 라우트 라벨, 신뢰도 임계값, 폴백 정책이 필요하다. |
| 다중 처리기 시스템 확장성이 좋아진다. | 브랜치가 늘면 유지보수와 관측성 요구가 커진다. |
최소 예시
고객 요청
-> 라우트 분류
-> 라우트 검증
-> order_status | product_info | technical_support | clarify
-> 최종 응답
LangGraph 매핑
| 패턴 개념 | LangGraph 요소 |
|---|---|
| 라우트 결정 | 상태 필드 route, route_reason, route_confidence |
| 라우터 | 노드 classify_route |
| 라우트 검증 | 노드 validate_route |
| 브랜치 선택 | route를 읽는 조건부 엣지 |
| 전문 워크플로 | order_status_handler 등의 핸들러 노드 |
| 폴백 | clarification_handler 브랜치 |
LangGraph 구현 목표
입력 요청을 분류하여 다음 네 가지 전문 노드 중 하나로 분기하는 고객 문의 라우터를 구현한다.
- 주문 추적이나 계정/주문 조회를 위한
order_status_handler - 제품 카탈로그, 기능, 가격, 호환성, 가용성 질문을 위한
product_info_handler - 문제 해결 및 지원 요청을 위한
technical_support_handler - 불명확/지원되지 않음/저신뢰도 요청을 위한
clarification_handler
예제는 선형 체인이 아니라 LangGraph의 조건부 엣지를 보여야 한다. 라우터 노드는 LLM 프롬프트로 구조화된 결정을 만들 수 있지만, 그래프는 테스트에서 그 라우터를 결정적 규칙 기반/가짜 분류기로 교체할 수 있어야 한다.
상태 형태
그래프가 필요로 하는 상태 필드를 정리한다.
| 필드 | 타입 | 목적 |
|---|---|---|
input | str | 원본 사용자 요청. |
normalized_input | str | 분류에 쓰이는 정규화된 요청 문자열. |
route | Literal["order_status", "product_info", "technical_support", "clarify"] \| None | 라우터가 선택한 제한된 목적지. |
route_reason | str \| None | 관측성 및 디버깅용 짧은 설명. |
route_confidence | float \| None | 라우터/분류기의 선택 신뢰도. |
handler_output | str \| None | 선택된 전문 핸들러가 만든 출력. |
final_output | str \| None | 사용자에게 반환되는 최종 응답. |
errors | list[str] | 실행 중 파싱/분류/핸들링 과정의 복구 가능한 오류. |
retry_count | int | 잘못된 출력이나 일시적 실패 후 재시도한 라우팅 횟수. |
requires_human_review | bool | 자동 응답 대신 Escalation이 필요한지 여부. |
metadata | dict[str, Any] | 요청 ID, 계정 ID, 라우터 모델명, 추적 데이터 등. |
노드
| 노드 | 책임 |
|---|---|
preprocess_input | input 존재 여부를 검사하고 공백을 정규화하며 기본 상태 필드를 초기화한다. |
classify_route | normalized_input을 분석해 라우트 결정, 이유, 신뢰도를 생성한다. |
validate_route | 라우터 출력을 정규화하고 알 수 없는 라벨을 거부, 신뢰도 임계값을 적용해 유효하지 않으면 clarify로 매핑한다. |
order_status_handler | 주문 조회 요청을 시뮬레이션/조회한다. |
product_info_handler | 제품 관련 질문에 대한 카탈로그 조회를 시뮬레이션/실행한다. |
technical_support_handler | 문제 해결 가이드를 시뮬레이션/실행한다. 복잡하거나 위험한 지원 건은 requires_human_review를 설정한다. |
clarification_handler | 모호하거나 지원되지 않은 요청일 때 타깃형 추가 질문을 한다. |
format_response | 선택된 핸들러 결과를 final_output으로 정리하며 추적 필드를 유지한다. |
엣지
그래프 흐름을 조건부 분기 포함해 설명한다.
START
-> preprocess_input
-> classify_route
-> validate_route
-> route_by_decision
route_by_decision:
order_status -> order_status_handler
product_info -> product_info_handler
technical_support -> technical_support_handler
clarify -> clarification_handler
order_status_handler -> format_response -> END
product_info_handler -> format_response -> END
technical_support_handler -> format_response -> END
clarification_handler -> format_response -> END
조건부 엣지 요구사항:
- 조건부 엣지는 검증된 정규 상태(
route같은)만 읽어야 한다. - 알 수 없거나 비어 있거나 잘못된 라벨은 기본적으로 예외를 발생시키지 말고
clarification_handler로 보내고 오류를 추가해야 한다. classify_route가 일시적으로 실패하면 최대retry_count한도까지 재시도한 뒤 폴백한다.technical_support_handler가 인간 검토가 필요하다고 판단하면finalize를 통과해 최종 응답에 승격 상태를 명시한다.
입력과 출력
- 입력: 단일 자연어 고객 요청. 선택적으로 사용자 ID, 계정 ID, 테스트용 라우트 오버라이드 같은 메타데이터.
- 출력:
final_output, 선택된route, 경로 검증을 위한 진단 필드. - 중간 산출물: 정규화 입력, 라우터 raw 출력, 라우트 이유, 신뢰도, 핸들러 출력, 오류, 인간 검토 플래그.
예시 입력 형태:
{
"input": "Where is order 12345?",
"user_id": "user-123",
"metadata": {
"channel": "chat"
}
}
예시 입력 카테고리:
- 주문 상태:
"Where is order 12345?" - 제품 정보:
"Does this laptop support two external monitors?" - 기술 지원:
"My device will not connect to Wi-Fi." - 명확화:
"Can you help me with that thing from yesterday?"
실패 사례
예상 실패, 재시도, 폴백 동작, 인간 검토 포인트를 기록한다.
- 입력이 없거나 공백이면 전처리 단계에서 중단하고 명확화 응답 및 오류 항목을 남긴다.
- LLM 라우터가 허용 라벨이 아닌 문장을 반환하면 검증 후 오류를 추가하고 선택적으로 재시도한 뒤 명확화로 이동한다.
- 라우트가 유효하나 신뢰도가 임계값 미만이면 잘못된 핸들러 호출 대신 명확화로 이동한다.
- 주문 조회와 트러블슈팅 같은 다중 의도가 섞인 요청은 우선도 높은 의도 하나를 고르거나 초기 구현에서는 명확화로 전환한다.
- 핸들러가 복구 가능한 예외를 발생하면 오류를 추가하고
format_response에서 폴백 응답을 반환한다. - 고위험, 계정 전용, 권한이 필요한 기술 지원은
requires_human_review = true로 설정하고 에스컬레이션 응답을 만든다. - 임베딩 기반 또는 ML 기반 라우터를 사용할 수 없으면 규칙 기반/LLM 기반 라우팅으로 대체하고, 구성되지 않으면 명확화한다.
테스트 아이디어
- 각 라우트(주문 상태, 제품 정보, 기술 지원, 명확화)의 정상 경로를 검증한다.
- 각 정상 경로 입력에서 정확히 하나의 전문 핸들러만 실행되는지 검증한다.
- 잘못된 라우터 출력이
clarification_handler로 이동하고 오류가 기록되는지 검증한다. - 저신뢰도 라우팅이 전문 핸들러를 호출하지 않음을 검증한다.
- 빈 입력이
classify_route를 호출하지 않고 명확화 응답을 만드는지 검증한다. - 핸들러 예외가
errors에 캡처되고final_output이 생성되는지 검증한다. technical_support_handler가requires_human_review를 설정할 수 있는지 검증한다.- 최종 상태에
input,normalized_input,route,handler_output,final_output,errors가 있는지 검증한다. - 테스트에서 네트워크에 의존하지 않도록 가짜 분류기와 fake classifier를 사용한다.
열린 질문
- TOC에서는 Chapter 2를 논리 페이지 30-42로 표시하지만 추출 경계는 PDF 인덱스 35~48이며, Chapter 3은 인덱스 49에서 시작한다. 이로 인해 14페이지 추출과 13페이지 논리 범위의 불일치가 생긴다.
- 본 장에서는 LLM 기반, 임베딩 기반, 규칙 기반, 감독 학습 분류기 기반 라우팅을 모두 다룬다. 첫 LangGraph 예제는 테스트에서 결정론적 fake를 쓰기 쉽게 LLM 기반 라우팅을 택하는 것이 적절해 보이지만, 현재 저장소에는 모델 제공자/픽스처가 표준화되어 있지 않다.
- 장의 예시에는 고객 지원 카테고리와 booking/info/unclear 코디네이터 예제가 모두 있으나, 범용성과 LangGraph 브랜치 매핑을 위해 고객 지원 카테고리를 사용한다.