LLM 요청 라우팅으로 비용과 품질 동시에 최적화하기
GPT-4o, Claude 3.5 Sonnet, Gemini 1.5 Pro 같은 고성능 모델은 뛰어난 품질을 제공하지만 그만큼 비용이 높습니다. 반면 GPT-4o mini, Claude 3 Haiku, Gemini 1.
목차
- 개요
- LLM 라우팅이 필요한 이유
- 라우팅 전략의 핵심 구조
- 요청 복잡도 분류 구현
- 비용과 품질의 트레이드오프
- 운영 환경 적용 시 고려사항
- 맺음말
개요
문제 배경
GPT-4o, Claude 3.5 Sonnet, Gemini 1.5 Pro 같은 고성능 모델은 뛰어난 품질을 제공하지만 그만큼 비용이 높습니다. 반면 GPT-4o mini, Claude 3 Haiku, Gemini 1.5 Flash 같은 경량 모델은 비용이 낮지만 복잡한 추론이나 긴 컨텍스트 처리에서 한계를 보입니다. 실제 서비스에서는 모든 요청이 동일한 수준의 처리 능력을 필요로 하지 않는데, 단일 모델을 고정 사용하면 단순 요청에 불필요한 비용이 발생하거나 복잡한 요청의 품질이 저하되는 문제가 생깁니다. LLM 요청 라우팅은 들어오는 요청의 특성을 분석해 적합한 모델로 자동 분배함으로써 이 딜레마를 해소하는 아키텍처 전략입니다.
기존 방식의 한계
단일 모델 고정 사용 방식의 가장 큰 문제는 비용 비효율성입니다. "오늘 날씨 어때?"처럼 단순한 질문에 GPT-4급 모델을 사용하는 것은 택시를 타고 100미터를 이동하는 것과 같습니다. 반대로 법률 문서 분석이나 복잡한 코드 리팩토링에 경량 모델만 쓰면 품질 저하와 사용자 이탈로 이어집니다.
LLM 공급자마다 강점이 다르다는 점도 문제입니다. Claude는 긴 문서 분석과 코딩에 강하고, GPT-4o는 멀티모달과 함수 호출에 유리하며, Gemini는 대용량 컨텍스트 처리에 특화되어 있습니다. 이 특성을 활용하지 못하고 단일 공급자에 고착되면 벤더 종속(vendor lock-in) 리스크와 함께 성능 최적화 기회를 잃게 됩니다. 라우팅은 이러한 모델 다양성을 전략적 자산으로 바꾸는 도구입니다.
LLM 라우팅이 필요한 이유
비용 구조의 현실
LLM 비용은 대부분 입출력 토큰 수에 비례합니다. GPT-4o의 입력 토큰 비용은 $2.50/1M tokens인 반면, GPT-4o mini는 $0.15/1M tokens로 약 17배 차이가 납니다. Claude 3.5 Sonnet($3.00/1M)과 Claude 3 Haiku($0.25/1M)도 12배 차이가 납니다. 하루 100만 건의 요청이 발생하는 서비스에서 평균 500토큰 요청 기준으로 경량 모델 전환율 50%만 달성해도 월 수천만 원의 비용 절감이 가능합니다.
그러나 비용만 따라가다 보면 품질 저하라는 함정에 빠집니다. 체감 품질이 떨어지면 사용자 이탈이 발생하고, 그로 인한 매출 손실은 절감한 비용을 초과할 수 있습니다. 라우팅 전략의 목표는 단순 비용 절감이 아니라 요청 유형별 최적 모델 매핑을 통한 전체 서비스 가치 극대화입니다.
라우터가 복잡도를 판단해 경량·고성능 모델로 분기함으로써, 단일 파이프라인 대비 비용 효율이 개선됩니다.
모델 다양성의 전략적 활용
각 LLM 제공자의 모델은 서로 다른 강점을 가집니다. 단순 Q&A, 요약, 번역 같은 작업은 경량 모델로도 충분히 높은 품질을 낼 수 있습니다. 반면 복잡한 추론, 코드 생성, 장문 분석에는 고성능 모델이 필요합니다. 모델별 특성을 잘 파악하면 태스크 유형에 따라 최적 모델을 선택하는 규칙 기반 라우팅이 가능합니다. 코드 관련 요청은 Claude 3.5 Sonnet이나 GPT-4o로, 수학적 추론은 o1이나 Gemini 1.5 Pro로, 단순 텍스트 처리는 Haiku나 GPT-4o mini로 보내는 방식입니다.
| 모델 | 강점 | 약점 | 적합 태스크 | 주의점 |
|---|---|---|---|---|
| GPT-4o | 멀티모달, 함수 호출 | 비용 높음 | 이미지 분석, API 연동 | 토큰 비용 모니터링 필수 |
| Claude 3.5 Sonnet | 코딩, 장문 분석 | 비용 높음 | 코드 리뷰, 문서 분석 | 컨텍스트 윈도우 최대 활용 |
| Gemini 1.5 Pro | 대용량 컨텍스트 | 응답 지연 | 긴 문서 처리 | 실시간 요청에 부적합 |
| GPT-4o mini | 속도, 저비용 | 복잡 추론 약함 | Q&A, 분류 | 임계 복잡도 설정 주의 |
| Claude 3 Haiku | 빠른 응답 | 추론 깊이 제한 | 번역, 요약 | 다단계 추론 시 품질 저하 |
라우팅 필요성의 임계점
라우팅 시스템 도입은 초기 구축 비용이 따릅니다. 월 LLM 비용이 $500을 초과하거나, 서비스 내 요청 복잡도 분포가 명확히 이분화될 때, 또는 응답 지연에 민감한 사용자 인터랙션이 존재할 때 라우팅 도입을 검토하는 것이 좋습니다. 반대로 대부분의 요청이 균일하게 복잡하거나, 서비스가 초기 단계라 트래픽 데이터가 부족하다면 먼저 단일 모델로 패턴을 쌓은 뒤 라우팅을 도입하는 것이 현명합니다.
라우팅 전략의 핵심 구조
규칙 기반 라우팅
가장 단순하고 예측 가능한 방식입니다. 요청의 특정 속성—토큰 길이, 키워드, 태스크 타입 레이블—을 기반으로 미리 정의된 규칙에 따라 모델을 선택합니다. 구현이 쉽고 지연 시간(latency)이 거의 없으며, 라우팅 결과가 결정론적으로 예측 가능하다는 장점이 있습니다. 운영 중에도 규칙을 코드 변경 없이 설정값으로 조정할 수 있어, 사업 요구사항 변화에 빠르게 대응할 수 있습니다.
규칙 기반 방식의 전형적인 구현은 다음과 같습니다. 입력 토큰이 200 미만이면 경량 모델, 200~800이면 중간 모델, 800 이상이면 고성능 모델로 보냅니다. 혹은 요청에 "코드", "분석", "법률"같은 키워드가 포함되면 고성능 모델로 라우팅합니다.
토큰 길이만으로도 1차 라우팅이 가능하지만, 단독으로는 복잡도를 정확히 반영하지 못합니다.
그러나 규칙 기반 방식은 "토큰 수가 적어도 매우 어려운 질문"처럼 규칙이 커버하지 못하는 케이스가 발생합니다. "1+1은?" 같은 단순 질문과 "지구 중력 상수를 이용해 달에서의 탈출 속도를 유도하라"는 짧지만 복잡한 질문을 토큰 수만으로 구분할 수 없습니다. 또한 새로운 유형의 요청이 등장했을 때 규칙 업데이트가 필요하다는 유지보수 부담도 있습니다.
ML 기반 라우팅
ML 기반 라우팅은 요청 텍스트를 임베딩하거나 분류 모델을 통해 복잡도 점수를 예측합니다. 규칙 기반보다 높은 정확도로 복잡도를 판단할 수 있고, 새로운 패턴도 학습을 통해 처리할 수 있습니다. 다만 라우팅 분류 자체에 추가 LLM 호출이나 임베딩 생성 비용이 발생하며, 모델 학습을 위한 레이블 데이터가 필요합니다.
실용적인 ML 기반 접근 중 하나는 소형 분류 모델을 사용하는 것입니다. BERT 계열의 경량 분류기를 파인튜닝하거나, text-embedding-3-small로 벡터화한 뒤 kNN 또는 SVM으로 태스크 유형을 분류합니다. 이 방식은 레이턴시를 수십 밀리초 내로 유지하면서 규칙 기반 대비 높은 정확도를 달성합니다. 또 다른 접근은 라우터 LLM을 활용하는 것으로, 요청을 GPT-4o mini 같은 저렴한 모델에 먼저 보내 "이 요청을 처리하려면 어느 수준의 모델이 필요한가?"를 판단하게 합니다.
임베딩 기반 분류기가 요청을 벡터화한 뒤 복잡도 레벨을 예측하고, 그 결과에 따라 모델을 선택합니다.
하이브리드 라우팅
현업에서 가장 많이 채택되는 방식은 규칙 기반과 ML 기반을 결합한 하이브리드 라우팅입니다. 명확한 경우(토큰 수가 매우 많거나 특정 키워드가 포함된 경우)는 규칙으로 빠르게 처리하고, 모호한 경우만 ML 분류기에 전달합니다. 이를 통해 라우팅 레이턴시를 최소화하면서 정확도도 높게 유지합니다.
하이브리드 방식의 또 다른 형태는 캐스케이드(Cascade) 라우팅입니다. 요청을 먼저 경량 모델에 보내고, 응답 품질을 평가자(evaluator)가 체크한 뒤, 기준 미달이면 고성능 모델로 재시도합니다. 첫 번째 시도에서 품질이 충분하면 비용을 절감하고, 부족하면 자동으로 업그레이드됩니다. 이 방식은 사전 분류 오류에 대한 안전망이 내장되어 있어, 특히 품질 민감도가 높은 서비스에 적합합니다.
요청 복잡도 분류 구현
복잡도 지표 설계
복잡도를 어떤 신호로 측정할 것인지가 라우팅 품질의 핵심입니다. 단일 지표보다는 여러 신호를 조합한 복합 점수가 더 정확합니다. 일반적으로 활용되는 신호에는 토큰 수, 문장 구조 복잡도, 도메인 특수성, 다중 단계 추론 필요 여부, 컨텍스트 의존성 등이 있습니다.
토큰 수는 가장 빠르게 계산할 수 있는 1차 신호이지만 단독으로는 신뢰할 수 없습니다. 효과적인 복잡도 지표를 설계할 때는 다음 요소들을 가중치를 두어 점수화합니다.
| 지표 | 계산 방법 | 가중치 | 주의점 |
|---|---|---|---|
| 토큰 수 | tiktoken으로 직접 측정 | 0.3 | 긴 컨텍스트 ≠ 복잡 요청 |
| 키워드 복잡도 | 도메인 특수 단어 빈도 | 0.2 | 도메인별 사전 필요 |
| 질문 구조 | 하위 질문 수, 조건절 수 | 0.3 | 파싱 비용 발생 |
| 멀티턴 깊이 | 대화 히스토리 길이 | 0.2 | 누적 컨텍스트 고려 |
라우팅 로직 구현
Python으로 복합 복잡도 점수를 계산해 적절한 모델을 선택하는 기본 구조를 구현합니다. tiktoken 라이브러리가 OpenAI 호환 토큰 카운트를 제공하므로 별도 API 호출 없이 빠르게 계산됩니다.
import tiktoken
from dataclasses import dataclass
from enum import Enum
class ModelTier(Enum):
LIGHT = "claude-3-haiku-20240307" # 경량: 단순 Q&A, 번역
BALANCED = "claude-3-5-sonnet-20241022" # 균형: 일반 작업
PREMIUM = "claude-opus-4-5" # 고성능: 복잡 추론
COMPLEX_KEYWORDS = {
"분석", "리팩토링", "최적화", "아키텍처", "설계",
"디버깅", "법률", "의료", "규정", "audit"
}
@dataclass
class RoutingResult:
model: str
tier: ModelTier
score: float
reason: str
def calculate_complexity(prompt: str, history: list[dict] = None) -> float:
"""복합 복잡도 점수 반환 (0.0 ~ 1.0)"""
enc = tiktoken.encoding_for_model("gpt-4o")
# 1. 토큰 수 점수 (최대 0.30)
token_count = len(enc.encode(prompt))
token_score = min(token_count / 1000, 1.0) * 0.30 # 1000토큰 기준
# 2. 복잡 키워드 점수 (최대 0.20)
keyword_hits = sum(1 for kw in COMPLEX_KEYWORDS if kw in prompt)
keyword_score = min(keyword_hits / 3, 1.0) * 0.20
# 3. 질문 구조 점수 (최대 0.30): 하위 질문 수 기반
sub_q = prompt.count("?") + prompt.count("어떻게") + prompt.count("왜")
structure_score = min(sub_q / 4, 1.0) * 0.30
# 4. 멀티턴 깊이 점수 (최대 0.20)
turn_depth = len(history) if history else 0
turn_score = min(turn_depth / 10, 1.0) * 0.20
return token_score + keyword_score + structure_score + turn_score
def route_request(prompt: str, history: list[dict] = None) -> RoutingResult:
score = calculate_complexity(prompt, history)
if score < 0.30:
tier, reason = ModelTier.LIGHT, f"단순 요청 (복잡도 {score:.2f})"
elif score < 0.65:
tier, reason = ModelTier.BALANCED, f"중간 복잡도 (복잡도 {score:.2f})"
else:
tier, reason = ModelTier.PREMIUM, f"고복잡도 요청 (복잡도 {score:.2f})"
return RoutingResult(model=tier.value, tier=tier, score=score, reason=reason)
# 사용 예시
result = route_request("Python 코드 최적화 방법과 아키텍처 개선을 분석해줘")
# result.tier → ModelTier.PREMIUM
# result.score → 0.72 (키워드 "최적화"·"아키텍처"·"분석" 적중, 구조 점수 포함)이 구현의 핵심은 calculate_complexity 함수가 네 가지 신호를 가중 합산해 0~1 범위의 점수를 만들어 낸다는 점입니다. 임계값(0.30, 0.65)은 실제 서비스에서 A/B 테스트를 통해 조정해야 하며, 초기값은 경험치 기반으로 설정합니다.
캐스케이드 패턴 구현
캐스케이드 라우팅은 경량 모델 응답을 품질 평가기로 체크한 뒤 고성능 모델로 에스컬레이션하는 방식입니다. 평가 기준은 태스크에 따라 달라지는데, 아래 예시에서는 경량 평가자 모델이 0~1 점수를 반환하게 합니다.
import anthropic
client = anthropic.Anthropic()
def cascade_route(prompt: str, min_quality: float = 0.70) -> str:
"""경량 모델로 시작, 품질 미달 시 프리미엄 모델로 에스컬레이션"""
# 1단계: 경량 모델 응답 시도
light = client.messages.create(
model="claude-3-haiku-20240307",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}]
)
light_text = light.content[0].text
# 2단계: 소형 평가자로 품질 체크 (경량 모델 재사용 → 추가 비용 최소화)
eval_prompt = (
f"다음 응답의 완성도를 0~1 숫자 하나만 반환하세요.\n"
f"질문: {prompt[:200]}\n응답: {light_text[:500]}\n점수:"
)
eval_resp = client.messages.create(
model="claude-3-haiku-20240307",
max_tokens=10,
messages=[{"role": "user", "content": eval_prompt}]
)
try:
quality = float(eval_resp.content[0].text.strip())
except ValueError:
quality = 0.5 # 파싱 실패 시 중간값으로 보수적 처리
# 3단계: 품질 기준 미달이면 프리미엄 모델로 재시도
if quality < min_quality:
premium = client.messages.create(
model="claude-opus-4-5",
max_tokens=2048,
messages=[{"role": "user", "content": prompt}]
)
return premium.content[0].text # 결과: 고품질 응답 반환
return light_text # 결과: 경량 응답으로 충분캐스케이드 패턴의 장점은 사전 분류 오류에 대한 안전망이 내장되어 있다는 것입니다. 복잡도 분류가 잘못되어 경량 모델로 보냈더라도 품질 평가 단계에서 에스컬레이션이 자동으로 발생합니다. 단, 최악의 경우 세 번의 API 호출이 발생하므로 응답 지연 허용 범위가 넓은 배치 처리나 비동기 작업에 특히 적합합니다.
비용과 품질의 트레이드오프
비용 절감 효과 정량화
라우팅 전략의 효과를 측정하려면 먼저 현재 요청 분포를 파악해야 합니다. 실제 트래픽 로그를 분석하면 대부분의 서비스에서 요청의 60~70%는 단순 작업(분류, 요약, 단순 Q&A)이고, 20~30%는 중간 수준, 10~20%만이 복잡한 추론이 필요한 작업입니다. 이 분포를 기반으로 절감 가능 비용을 사전에 추정할 수 있습니다. 비용 절감의 핵심 공식은 라우팅 전 평균 비용을 기준으로, 경량 모델로 전환된 요청 비율과 각 모델 간 비용 차이를 곱한 뒤, 라우팅 오류율과 라우터 자체 운영 비용을 차감하는 것입니다.
실제 트래픽 분포를 기반으로 한 비용 배분이 라우팅 효과 추정의 출발점입니다.
품질 회귀 방지
비용 절감을 위해 너무 공격적으로 경량 모델로 라우팅하면 품질 회귀(quality regression)가 발생합니다. 이를 방지하기 위해서는 품질 안전망이 필요합니다. 가장 효과적인 방법은 라우팅된 응답의 샘플(보통 5~10%)을 자동화된 LLM 판정자(LLM-as-a-judge)로 품질 점수를 지속적으로 모니터링하는 것입니다.
품질 회귀 감지 시스템을 설계할 때는 **골든 데이터셋(Golden Dataset)**을 구성하는 것이 중요합니다. 각 태스크 유형별로 정답이 알려진 테스트 케이스를 100~500개 준비하고, 라우팅 로직이 변경될 때마다 이 데이터셋으로 회귀 테스트를 돌립니다. 품질 점수가 임계값 이하로 떨어지면 알람을 발생시켜 수동 검토를 트리거합니다.
라우팅 임계값을 1% 낮추면 비용은 5% 절감될 수 있지만, 품질 회귀율이 2배로 올라가는 경우가 있습니다. 임계값 변경은 반드시 A/B 테스트와 함께 진행하세요.
레이턴시와 품질의 균형
고성능 모델은 일반적으로 경량 모델보다 응답 시간이 깁니다. GPT-4o의 평균 첫 토큰 응답 시간(TTFT)은 GPT-4o mini 대비 2~4배 느립니다. 사용자 대면 인터페이스에서는 레이턴시가 UX에 직접 영향을 주므로, 품질과 속도 모두를 고려한 라우팅이 필요합니다. 스트리밍(streaming) 응답과 라우팅을 결합하면 체감 속도를 개선할 수 있습니다. 복잡한 요청도 스트리밍으로 첫 토큰을 빠르게 보여주면, 전체 응답 시간이 길더라도 사용자가 느끼는 대기감이 크게 줄어듭니다.
실시간 여부와 복잡도를 함께 고려해 라우팅 경로를 결정하면 레이턴시와 비용을 동시에 최적화할 수 있습니다.
운영 환경 적용 시 고려사항
흔한 실수와 함정
가장 흔한 실수는 라우팅 임계값을 한 번 설정하고 방치하는 것입니다. 서비스의 사용 패턴은 시간이 지남에 따라 변합니다. 초기에는 단순 질문이 많았던 서비스가 사용자 층이 전문화되면서 복잡한 요청이 늘어날 수 있습니다. 임계값을 주기적으로 재검토하지 않으면 라우팅 정확도가 서서히 저하됩니다. 분기별로 요청 분포를 분석하고 임계값을 재보정하는 프로세스를 정례화하는 것이 좋습니다.
두 번째 함정은 모델 버전 업데이트에 무감각한 것입니다. LLM 제공자는 정기적으로 모델을 업데이트합니다. 경량 모델의 성능이 향상되면 기존에 고성능 모델로 보내던 작업을 경량 모델로 전환할 기회가 생깁니다. 반대로 모델 버전이 변경되면서 특정 유형의 응답 품질이 변동될 수 있어, 정기적인 품질 벤치마킹이 필요합니다.
세 번째는 컨텍스트 윈도우 관리 실패입니다. 멀티턴 대화에서 히스토리가 누적되면 총 토큰 수가 경량 모델의 컨텍스트 한계를 초과할 수 있습니다. 라우팅 로직에서 누적 토큰 수를 반드시 고려해야 하며, 한계에 가까워지면 요약(summarization)을 통해 컨텍스트를 압축하거나 자동으로 상위 모델로 전환해야 합니다.
컨텍스트 누적으로 인한 모델 강제 전환 흐름을 사전에 설계해 두어야 런타임 오류를 방지할 수 있습니다.
모니터링과 디버깅
운영 중인 라우팅 시스템의 건강 상태를 모니터링하기 위해서는 핵심 메트릭을 추적해야 합니다. 라우팅 분포율(각 모델 티어로 보내진 요청 비율)은 예상 분포와 실제 분포의 차이를 보여줍니다. 분포가 갑자기 변했다면 요청 패턴 변화나 라우팅 버그를 의심해야 합니다. 에스컬레이션율은 캐스케이드 패턴에서 특히 중요합니다. 경량 모델 응답이 기준 미달로 재시도되는 비율이 지속적으로 높다면 복잡도 분류 기준이 너무 낮게 설정된 것이고, 에스컬레이션율이 거의 없다면 기준이 너무 높아 비용 절감 효과가 미미한 것입니다.
| 메트릭 | 측정 방법 | 정상 범위 | 주의 신호 |
|---|---|---|---|
| 라우팅 분포율 | 티어별 요청 수 / 전체 | 서비스별 상이 | 갑작스러운 변화 |
| 에스컬레이션율 | 재시도 수 / 전체 | 5~15% | 15% 초과 |
| 평균 복잡도 점수 | 7일 이동평균 | 안정적 유지 | 지속 상승/하락 |
| 비용 효율 지수 | 품질점수 / 토큰비용 | 기준선 이상 | 10% 이상 하락 |
확장과 마이그레이션
라우팅 시스템이 성숙해지면 단순 비용 최적화를 넘어 태스크 전문화(task specialization) 단계로 발전할 수 있습니다. 코드 관련 요청은 코드 특화 모델로, 법률·의료 문서는 전문 파인튜닝 모델로 보내는 세밀한 라우팅이 가능해집니다. 이 단계에서는 요청 분류의 세분화가 핵심으로, 단순 복잡도 점수 대신 다차원 분류가 필요합니다. 신규 모델 도입 시에는 트래픽 쉐도잉(traffic shadowing) 기법이 유용합니다. 실제 요청의 소량(1~5%)을 신규 모델로 동시에 보내 기존 모델 응답과 품질을 비교하고, 충분히 검증되면 해당 태스크 유형의 트래픽을 점진적으로 마이그레이션합니다.
트래픽 쉐도잉으로 실운영 부담 없이 신규 모델의 품질을 검증하고, 통과 시 점진적으로 전환합니다.
맺음말
핵심 요약
LLM 요청 라우팅은 단순한 비용 절감 기법이 아니라 서비스 전체의 비용 효율과 품질을 함께 높이는 아키텍처 전략입니다. 핵심은 세 가지입니다. 첫째, 모든 요청을 동등하게 취급하지 않는 것입니다. 요청의 복잡도와 특성에 따라 최적 모델을 동적으로 선택해야 합니다. 둘째, 라우팅 로직은 단순 규칙에서 시작해 ML 기반으로 점진적으로 발전시킬 수 있습니다. 초기에는 토큰 수와 키워드 기반의 단순 규칙으로도 상당한 효과를 볼 수 있습니다. 셋째, 비용 절감과 품질 유지는 상충하는 목표가 아닙니다. 올바른 라우팅 전략은 두 가지를 동시에 달성할 수 있으며, 지속적인 모니터링과 임계값 재보정이 그 열쇠입니다.
적용 판단 기준
라우팅 도입을 고려할 때는 다음 기준으로 판단하는 것이 좋습니다. 월 LLM API 비용이 $500을 초과하고, 요청 복잡도 분포가 명확히 차별화되며, 단순 요청이 전체의 40% 이상을 차지한다면 라우팅 도입의 ROI가 높습니다. 반면 대부분의 요청이 균일하게 복잡하거나, 서비스 자체가 초기 단계라 트래픽 분포 데이터가 충분하지 않다면 단일 모델로 운영하면서 데이터를 쌓은 뒤 라우팅을 도입하는 것이 현명합니다. 규칙 기반으로 시작해 트래픽 패턴이 명확해지면 ML 기반으로 전환하는 단계적 접근이, 라우팅 시스템을 안정적으로 성장시키는 가장 실용적인 경로입니다.