대부분의 AI 에이전트는 모든 작업에 단일 모델을 사용합니다. 계획 수립, 도구 호출, 요약, 오류 복구까지 말이죠. 데모용으로는 괜찮지만, 실제 운영 환경에서는 낭비입니다.
깊은 추론이 필요한 계획 수립 단계와 JSON 추출 단계에 동일한 모델을 사용할 필요는 없습니다. 코드 생성 작업은 분류 작업과 요구 사항이 다릅니다. 날짜 문자열 형식을 맞추기 위해 Claude Opus 4.6(출력 1M token당 $25)을 사용하는 것은 벽을 칠하기 위해 수석 건축가를 고용하는 것과 같습니다.
각 단계를 최적의 모델로 라우팅하는 에이전트를 구축하는 방법을 소개합니다.
에이전트 레이어가 아닌 API 레이어에서 작업 중이라면, 이 페이지와 함께 Agent-First API Design 및 Why Teams Switch from Direct Model APIs to a Unified AI API를 읽어보세요. 멀티 모델 에이전트는 오케스트레이션 코드를 다시 작성하지 않고도 모델을 교체할 수 있을 만큼 기본 API 인터페이스가 안정적일 때 가장 효과적입니다.
멀티 모델 에이전트 아키텍처
사용자 요청
│
▼
┌─────────────┐
│ 라우터 │ ← 작업 복잡도 분류
│ (빠른 모델) │
└──────┬──────┘
│
┌───┴───┐
▼ ▼
┌──────┐ ┌──────┐
│ 단순 │ │ 복잡 │
│ 모델 │ │ 모델 │
└──┬───┘ └──┬───┘
│ │
▼ ▼
┌─────────────┐
│ 애그리게이터 │ ← 결과 결합
│ (빠른 모델) │
└─────────────┘
세 가지 구성 요소:
- 유입되는 작업을 복잡도에 따라 분류하는 라우터
- 다양한 작업 유형에 맞춰진 모델 풀
- 필요 시 결과를 결합하는 애그리게이터
실제 운영 환경에서는 보통 두 가지 요소가 더 필요합니다:
- 기본 모델이 실패하거나 느려질 때를 대비한 fallback 정책
- 단계별 모델 선택, latency, 비용을 기록하는 telemetry 레이어
이 두 가지가 없으면 멀티 모델 에이전트는 예측 불가능한 동작을 하는 블랙박스로 변하기 쉽습니다.
OpenAI SDK를 이용한 구현
애그리게이터를 통해 단일 API key를 사용하면 여러 SDK를 관리할 필요 없이 모든 모델에 액세스할 수 있습니다:
from openai import OpenAI
client = OpenAI(
api_key="sk-lemon-xxx",
base_url="https://api.lemondata.cc/v1"
)
# Model pool with cost/capability tiers
MODELS = {
"router": "gpt-4.1-mini", # $0.40/1M in - fast classification
"simple": "gpt-4.1-mini", # $0.40/1M in - extraction, formatting
"reasoning": "claude-sonnet-4-6", # $3.00/1M in - planning, analysis
"complex": "gpt-4.1", # $2.00/1M in - code gen, multi-step
"budget": "deepseek-chat", # $0.28/1M in - bulk processing
}
def route_task(task: str) -> str:
"""Use a cheap model to classify task complexity."""
response = client.chat.completions.create(
model=MODELS["router"],
messages=[
{"role": "system", "content": """Classify this task into one category:
- simple: data extraction, formatting, translation
- reasoning: analysis, planning, comparison
- complex: code generation, multi-step problem solving
- budget: bulk processing, non-critical tasks
Reply with just the category name."""},
{"role": "user", "content": task}
],
max_tokens=10
)
category = response.choices[0].message.content.strip().lower()
return MODELS.get(category, MODELS["simple"])
def execute_task(task: str, context: str = "") -> str:
"""Route task to appropriate model and execute."""
model = route_task(task)
messages = []
if context:
messages.append({"role": "system", "content": context})
messages.append({"role": "user", "content": task})
response = client.chat.completions.create(
model=model,
messages=messages
)
return response.choices[0].message.content
실전 에이전트: 코드 리뷰 파이프라인
다음은 Pull Request를 리뷰하는 실용적인 멀티 모델 에이전트 예시입니다:
def review_pr(diff: str) -> dict:
"""Multi-model PR review pipeline."""
# Step 1: Classify changes (cheap model)
classification = client.chat.completions.create(
model="gpt-4.1-mini",
messages=[{
"role": "user",
"content": f"Classify these code changes: {diff[:2000]}\n"
"Categories: bugfix, feature, refactor, docs, test"
}],
max_tokens=20
).choices[0].message.content
# Step 2: Security scan (reasoning model)
security = client.chat.completions.create(
model="claude-sonnet-4-6",
messages=[{
"role": "system",
"content": "You are a security reviewer. Check for: "
"SQL injection, XSS, auth bypass, secrets in code, "
"unsafe deserialization. Be specific about line numbers."
}, {
"role": "user",
"content": f"Review this diff for security issues:\n{diff}"
}]
).choices[0].message.content
# Step 3: Code quality (general model)
quality = client.chat.completions.create(
model="gpt-4.1",
messages=[{
"role": "user",
"content": f"Review code quality: naming, structure, "
f"error handling, test coverage.\n{diff}"
}]
).choices[0].message.content
# Step 4: Summary (cheap model)
summary = client.chat.completions.create(
model="gpt-4.1-mini",
messages=[{
"role": "user",
"content": f"Summarize this PR review in 3 bullet points:\n"
f"Type: {classification}\n"
f"Security: {security[:500]}\n"
f"Quality: {quality[:500]}"
}]
).choices[0].message.content
return {
"classification": classification,
"security": security,
"quality": quality,
"summary": summary
}
일반적인 PR 리뷰(2K token diff) 비용 분석:
| 단계 | 모델 | 입력 토큰 | 비용 |
|---|---|---|---|
| 분류 | GPT-4.1-mini | ~2,100 | $0.0008 |
| 보안 | Claude Sonnet 4.6 | ~2,500 | $0.0075 |
| 품질 | GPT-4.1 | ~2,500 | $0.0050 |
| 요약 | GPT-4.1-mini | ~1,200 | $0.0005 |
| 합계 | ~$0.014 |
모든 네 단계를 Claude Sonnet 4.6으로 처리하면 약 $0.028가 듭니다. 멀티 모델 방식을 사용하면 가장 중요한 부분(보안 리뷰)에 가장 강력한 모델을 사용하면서도 비용을 50% 절감할 수 있습니다.
가격뿐만 아니라 성능에 따른 라우팅
많은 팀이 "비싼 작업은 비싼 모델에, 저렴한 작업은 저렴한 모델에"라는 단순한 규칙으로 멀티 모델 라우팅을 시작합니다.
이는 좋은 첫걸음이지만 충분하지 않습니다.
더 강력한 라우팅 정책은 다음 네 가지 차원을 고려합니다:
- 추론 깊이 (reasoning depth)
- 컨텍스트 길이 (context length)
- tool-use 신뢰도
- latency 민감도
이를 통해 더 나은 규칙을 만들 수 있습니다:
- 계획 수립 및 분해는 추론 능력이 뛰어난 모델로
- 추출 및 형식 지정은 저렴하고 빠른 모델로
- 코드 리뷰는 버그 탐지 능력이 가장 좋은 모델로
- 저장소 전체 분석은 컨텍스트 윈도우가 가장 큰 모델로
이것이 coding model comparison과 pricing comparison을 별도의 연구 폴더에 두지 말고 라우터 설계에 반영해야 하는 이유입니다.
LangChain 연동
from langchain_openai import ChatOpenAI
# Create model instances with different configs
fast = ChatOpenAI(
model="gpt-4.1-mini",
api_key="sk-lemon-xxx",
base_url="https://api.lemondata.cc/v1"
)
reasoning = ChatOpenAI(
model="claude-sonnet-4-6",
api_key="sk-lemon-xxx",
base_url="https://api.lemondata.cc/v1"
)
# Use in LangChain chains
from langchain_core.prompts import ChatPromptTemplate
classify_chain = ChatPromptTemplate.from_template(
"Classify: {input}"
) | fast
analyze_chain = ChatPromptTemplate.from_template(
"Analyze in depth: {input}"
) | reasoning
멀티 모델 에이전트를 사용해야 하는 경우
멀티 모델 라우팅은 복잡성을 가중시킵니다. 다음과 같은 경우에 가치가 있습니다:
- 에이전트가 다양한 작업 유형을 처리할 때 (단순 채팅뿐만 아니라)
- 월간 API 비용이 $100를 초과할 때 (절감 효과가 유의미해짐)
- 특정 모델의 강점이 필요할 때 (코드의 경우 Claude, 긴 컨텍스트의 경우 Gemini, 속도의 경우 GPT)
- 일부 단계에서는 latency가 중요하지만 다른 단계에서는 그렇지 않을 때
단순한 챗봇이나 단일 목적 에이전트의 경우 단일 모델로도 충분합니다. 모든 요청에 동일한 성능이 필요할 때 라우팅 오버헤드를 감수할 이유는 없습니다.
전환점은 보통 다음과 같습니다:
- 가치가 낮은 작업에 고성능 추론 비용을 지불하고 있을 때
- 특정 제공업체의 장애가 실제 비즈니스 리스크가 될 때
- 워크플로우 전반에 걸쳐 컨텍스트 요구 사항이 크게 다를 때
- 하나의 비싼 핵심 단계 전후로 저렴한 리뷰 / 추출 / 요약 단계가 필요할 때
이 중 해당하는 사항이 없다면 단일 모델이 여전히 정답입니다.
흔한 실패 사례
멀티 모델 시스템은 예측 가능한 방식으로 실패하곤 합니다:
1. 라우터가 너무 복잡함
라우터 프롬프트가 거대한 분류 체계가 되어버리면, 무엇을 할지 결정하는 데 너무 많은 비용을 쓰게 됩니다. 라우터는 저렴하고 단순하게 유지하세요.
2. 출력 계약의 변동
한 모델은 깔끔한 JSON을 반환하고, 다른 모델은 JSON 블록이 포함된 텍스트를 반환하면 다운스트림 파서가 깨집니다. 모든 전달 단계에서 명시적인 스키마와 검증을 사용하세요.
3. Fallback이 품질을 소리 없이 변화시킴
제공업체 부하 시 저렴한 모델로 라우팅하면 사용자가 전혀 다른 품질을 경험하게 되어 에이전트가 불안정해 보일 수 있습니다. 이것이 rate limiting strategy가 사후 고려 사항이 아닌 설계 내부에 포함되어야 하는 이유입니다.
4. 비용 보고 누락
단계별 모델 선택, 비용, latency를 기록하지 않으면 멀티 모델 설계가 실제로 비용을 절감하고 있는지 알 수 없습니다.
최소한의 평가 루프
멀티 모델 에이전트를 책임감 있게 운영하기 위해 거대한 평가 플랫폼이 필요한 것은 아닙니다.
실행당 하나의 시트나 데이터베이스 테이블로 시작하세요:
- 사용자 작업 카테고리
- 라우터의 결정
- 단계별 최종 사용 모델
- 단계별 latency
- 총 토큰 비용
- fallback 발생 여부
- 사용자의 답변 수락 여부
이를 통해 다음과 같은 중요한 질문에 답할 수 있는 신호를 얻을 수 있습니다:
- 라우터가 비싼 모델을 충분히 적절하게 선택하고 있는가?
- 어떤 단계에서 예산이 가장 많이 소비되는가?
- fallback이 실행을 성공적으로 구제하고 있는가, 아니면 단순히 불안정성을 숨기고 있는가?
- 반복적인 작업에 저렴한 경로가 충분히 효과적인가?
이것이 통합 게이트웨이가 도움이 되는 이유이기도 합니다. 모델 사용량이 여러 제공업체에 분산되어 있으면 비교 가능한 실행 로그를 구성하기 어렵습니다. 모든 것이 하나의 API 레이어를 통하면 모니터링 부담이 줄어듭니다.
아키텍처를 단순하게 유지하기
최고의 멀티 모델 에이전트는 이국적이지 않고 운영상 '지루하게' 느껴집니다.
이는 다음을 의미합니다:
- 오케스트레이션 레이어로 들어오는 안정적인 요청 형태
- 라우팅 규칙을 정의하는 단일 장소
- 비용과 latency를 점검하는 단일 장소
- 작업군별 하나의 fallback 정책
- 모델 allowlist를 위한 단일 소스
에이전트 그래프는 똑똑해 보이는데 운영자가 왜 특정 요청이 다른 모델로 갔는지 설명할 수 없다면, 그 설계는 완성된 것이 아닙니다.
멀티 모델 에이전트를 사용하지 말아야 할 때
단순한 설계가 승리하는 명확한 사례들도 있습니다.
단순히 모델 카탈로그가 방대하다고 해서 라우팅을 추가하지 마세요.
다음과 같은 경우 단일 모델을 고수하세요:
- 제품이 하나의 좁은 작업을 반복적으로 수행할 때
- 모델 간의 품질 차이가 사용자에게 무의미할 때
- 트래픽이 너무 적어 비용 최적화가 중요하지 않을 때
- 운영 모니터링 체계가 아직 부족할 때
- 라우팅이 도움이 되었는지 해가 되었는지 판단할 만큼 평가(evals)가 강력하지 않을 때
잘 선택된 단일 모델에 좋은 재시도 로직, 프롬프트 관리, 관측성을 결합하는 것이 아무도 신뢰하지 않는 화려한 멀티 모델 그래프보다 나은 경우가 많습니다.
올바른 질문은 "라우팅을 할 수 있는가?"가 아니라 "라우팅이 이 워크플로우에서 더 나은 품질, 낮은 비용, 혹은 더 안전한 실패 동작을 만들어내는가?"입니다.
답이 모호하다면 워크플로우 자체가 더 다양해질 때까지 아키텍처를 단순하게 유지하세요.
핵심 요약
- 각 단계를 잘 처리하는 가장 저렴한 모델을 사용하세요.
- 비싼 모델은 정말로 필요한 작업에만 아껴두세요.
- 분류/라우팅 단계에는 항상 사용 가능한 가장 저렴한 모델을 사용하세요.
- 토큰당 가격뿐만 아니라 에이전트 실행당 실제 비용을 측정하세요.
- 하나의 키를 사용하는 API 애그리게이터는 멀티 모델 접근을 크게 단순화합니다.
멀티 모델 에이전트가 본질적으로 더 우수한 것은 아닙니다. 워크플로우에 진정으로 서로 다른 종류의 작업이 포함되어 있을 때 비로소 더 우수해집니다.
하나의 API로 모든 모델에 액세스하세요: LemonData는 단일 API key로 300개 이상의 모델을 제공합니다. 여러 제공업체 계정을 관리하거나 모델 조합마다 라우팅을 새로 만들 필요 없이 멀티 모델 에이전트를 구축하세요.
