블로그가이드 & 튜토리얼태스크별 모델 선택 전략: 접미사·provider 옵션으로 비용/속도/추론 라우팅하기
가이드 & 튜토리얼

태스크별 모델 선택 전략: 접미사·provider 옵션으로 비용/속도/추론 라우팅하기

특정 모델을 '추천'하는 대신, 태스크 성격(비용 민감/응답속도 민감/추론 난이도)에 따라 :floor·:nitro·:thinking 접미사와 provider.s

---
title: "쇼핑몰 에이전트가 문의 하나에 모델 하나씩 쓰지 않는 이유"
slug: task-based-model-routing-cafe24-agent
dek: "배송 조회와 상품 설명 생성, 같은 모델로 처리하면 안 되는 이유"
excerpt: "카페24 쇼핑몰에 연결한 에이전트가 처리하는 요청은 성격이 제각각이다. 비용 민감한 반복 응답과 추론이 필요한 판단 작업을 같은 경로로 몰면 비용도 속도도 손해다. :floor·:nitro·:thinking 접미사와 provider.sort·max_price로 태스크별 라우팅 규칙을 짜는 법을 정리했다."
category: guides
tags: ["LLM Router", "카페24", "OpenClaw", "Hermes Agent", "라우팅 전략"]
readingTime: "8분"
---

에이전트를 쇼핑몰에 연결하고 며칠 지나 로그를 들여다보다가 이상한 숫자를 봤다. 배송 조회 문의 하나를 처리하는 데 든 비용과 상품 설명 문구를 새로 생성하는 작업 하나에 든 비용 차이가 열 배 가까이 벌어져 있었다. 표로 옮기면 아래와 같다.

| 요청 유형 | 상대 비용 | 상대 지연 | 비고 |
|---|---|---|---|
| 배송 조회(반복 응대) | 낮음 | 낮음 | 답이 정형화돼 있어 고가 모델이 불필요하다 |
| 상품 설명 생성 | 높음 | 중간 | 판단과 창작 요소가 섞여 있다 |
| 실시간 채팅 문의 | 중간 | 최소화 필수 | 답의 품질보다 속도가 우선이다 |

*(실측 로그 기반 비용·지연 차트는 추후 업데이트 예정)*

두 요청 모두 같은 모델을 거쳐 나온 결과였다.

원인은 모델이 아니라 라우팅 규칙에 있었다. 요청 성격을 구분하지 않고 전부 같은 경로, 같은 모델로 밀어 넣은 탓이었다. 반복적인 단순 응대에는 추론 모델을 연결하고 판단이 필요한 작업에는 저렴한 모델을 연결하는, 배치가 뒤바뀐 경우도 섞여 있었다.

카페24 쇼핑몰 스킬팩을 에이전트에 연결하고 나면(쇼핑몰도 에이전트가 자동으로 관리한다), 그 에이전트가 받는 요청은 성격이 제각각이다. 배송 상태를 확인해 달라는 문의가 있는가 하면, 교환 절차를 안내해 달라는 요청도 들어오고, 재고 유무를 판단해 응답을 조합해야 하는 작업까지 같은 창구로 몰린다.

OpenClaw든 Hermes Agent든 에이전트를 LLM Router에 연결하는 절차는 이미 다뤘다(OpenClaw에 LLM Router 연결하기). 연결 자체는 주소와 키를 바꾸는 선에서 끝난다. 문제는 그다음부터다. 성격이 다른 요청을 하나의 경로로 흘려보내면, 비용과 속도 모두 요청 성격에 맞지 않는 만큼 낭비된다.

세 갈래로 나누면 규칙이 보인다

로그에 쌓인 요청을 다시 들여다보면 패턴은 사실 단순하다. 하나는 반복적이고 정형화된 응대다. 배송 조회, 주문 상태 확인, 자주 묻는 교환 절차 안내가 여기 속한다. 정답이 거의 고정돼 있고 하루에도 수십 번씩 같은 형태로 들어오니, 이런 요청에 값비싼 모델을 연결할 이유는 없다.

다른 하나는 응답 속도가 곧 경험인 요청이다. 실시간 채팅창에서 오가는 짧은 문의가 그렇다. 답의 품질보다 몇 초 안에 뭔가 나오는 순간이 더 중요하다.

나머지 하나는 판단이 들어가는 작업이다. 재고가 애매한 상황에서 교환 가능 여부를 조합해 답해야 하거나, 환불 규정과 개별 사정을 같이 봐야 하는 문의가 여기 속한다. 저렴한 모델을 쓰면 오답이 나올 확률이 올라가고, 오답 하나가 재문의를 부르니 결국 비용은 더 커진다.

이 세 갈래에 맞춰 접미사와 provider 옵션을 다르게 건다. LLM Router는 모델 ID 뒤에 붙는 접미사로 같은 모델 풀 안에서도 다른 정렬 기준을 적용한다. :floor는 가장 저렴한 프로바이더를 우선 선택하고, :nitro는 응답 속도가 가장 빠른 프로바이더를 우선한다. :thinking은 추론 과정을 거치는 경로로 보낸다. 여기에 provider 객체의 sort(price, throughput, latency 중 선택), max_price(상한선 지정)를 얹으면 같은 모델이라도 요청 성격에 맞는 프로바이더가 선택된다.

요청 유형접미사provider 설정
비용 민감 반복 응대:floorsort: price, max_price 상한 지정
응답속도 민감 요청:nitrosort: throughput
추론 필요 판단 작업:thinkingorder로 신뢰 프로바이더 지정

하나 짚고 넘어갈 지점이 있다. provider 설정은 계정 기본값, 프리셋, 요청 단위 순으로 우선순위가 정해진다. 계정에 걸어둔 기본 규칙이 있어도 프리셋이 있으면 그 값이 앞서고, 요청에 직접 넣은 값이 최종적으로 이긴다. 태스크별 라우팅은 이 우선순위 구조를 활용할 뿐이다. 요청을 보내는 시점에 태스크 태그에 맞는 provider 값을 얹으면 된다.

태스크부터 가려낸다

태스크 태그를 붙이려면 요청이 어느 갈래인지부터 가려야 한다. 에이전트 쪽에서 다음 순서로 판별하도록 짜면 된다.

요청에 주문번호나 배송 관련 키워드가 있고 답변 템플릿이 이미 정해져 있으면 반복 응대로 분류한다. 실시간 채팅 세션에서 들어왔고 응답 지연이 곧 품질로 이어지는 경우라면 응답속도 민감 요청이다. 두 조건 어디에도 해당하지 않고 재고, 환불 규정, 개별 사정처럼 여러 조건을 함께 봐야 답이 나오는 경우는 판단 작업으로 분류한다.

의사코드로 옮기면 이렇다.

if 주문번호_또는_배송키워드 in 요청 and 답변_템플릿_존재:
    분류 = "반복응대"
elif 요청_출처 == "실시간채팅" and 응답지연_민감:
    분류 = "응답속도민감"
else:
    분류 = "판단작업"
분류판별 조건접미사
반복 응대주문번호·배송 키워드 + 템플릿 존재:floor
응답속도 민감실시간채팅 출처 + 지연 민감:nitro
판단 작업두 조건 미해당, 조건 조합 필요:thinking

요청 하나에 분류 결과를 실어 보낸다

코드에 반영할 때는 에이전트가 먼저 이 분류를 처리하고, 그 결과에 따라 요청 바디의 model과 provider 값을 바꿔서 보낸다. 판단 작업 하나를 예로 들면 이렇다.

{
  "model": "deepseek-ai/DeepSeek-V3.1:thinking",
  "models": [
    "deepseek-ai/DeepSeek-V3.1:thinking",
    "qwen/qwen3-max"
  ],
  "provider": {
    "order": ["fireworks", "together"],
    "sort": "latency",
    "max_price": 0.02
  },
  "messages": [
    {"role": "user", "content": "재고 1개 남은 상품, 교환 요청 접수 가능한지 판단해줘"}
  ]
}

폴백은 네 단계를 거친다

요청이 들어가면 서킷브레이커가 먼저 장애가 발생한 프로바이더를 걸러낸다. 재시도 단계에서는 일시적 오류를 한 번 더 시도하고, 프로바이더 계층에서는 order와 sort 값에 따라 순서가 정해진다. primary 모델이 끝내 응답하지 않을 때 비로소 models 배열의 다음 모델로 넘어간다. provider 옵션이 관여하는 지점은 이 중 프로바이더 계층, 즉 어떤 프로바이더를 먼저 시도할지 정하는 필터 역할이다.

max_price를 판단 작업에도 걸었다가 생긴 문제

처음엔 비용 민감 요청뿐 아니라 판단 작업에도 max_price를 낮게 걸어두었다. 그랬더니 상한을 넘는 프로바이더가 반복적으로 걸러지면서 정상 응답이 가능한 프로바이더까지 폴백 체인에서 함께 빠지는 문제가 생겼다. 불필요한 재시도만 늘었고 지연은 오히려 커졌다. 결국 max_price는 반복 응대처럼 정답 품질 편차가 크지 않은 요청에만 걸고, 판단이 들어가는 작업은 order로 신뢰할 프로바이더를 직접 지정하는 쪽으로 바꾸니 그제야 안정을 찾았다.

규칙을 걸어둔 다음에는 응답에 실제로 반영됐는지 확인해야 한다. 응답 본문의 extra_fields에는 latency, provider, resolved_model_used가 함께 내려온다. 판단 작업 요청에 :thinking을 걸었는데 resolved_model_used에 다른 모델이 표시된다면, provider 설정이 우선순위 어딘가에서 덮어써진 것이다. 이 필드를 대시보드 로그와 함께 보면 태스크별로 어떤 경로를 탔는지, 비용이 어디서 새는지 파악된다.

정리

배송 조회 하나와 교환 판단 하나는 같은 문의창에서 들어오지만 같은 경로로 보낼 이유가 없다. 반복 응대는 :floor로 비용을 눌러 두고, 실시간성이 중요한 응답은 :nitro로 속도를 잡는다. 판단이 들어가는 작업만 :thinking과 지정된 프로바이더로 넘긴다.

코드 몇 줄이면 이 구분을 걸어둘 수 있다. 같은 에이전트가 처리하는 요청이라도 이렇게 나눠두면 비용 구조와 응답 품질이 각자 제자리를 찾는다. 태스크 분류와 라우팅 규칙은 LLM Router에서 카페24 쇼핑몰 에이전트에 바로 적용해볼 수 있다.

관련 글