시리즈 1번에서 Model Router 라는 한 단어가 두 계층을 덮고 있다고 적었다. 공개 사례를 그 경계로 늘어놓으면 다른 사실이 하나 더 드러난다. 같은 문제를 회사마다 서로 다른 층에서 풀고 있고, 어느 층에서 풀지가 그 조직에 이미 있던 것과 요건에 따라 갈렸다. Netflix 는 기존 계층을 재사용했고 Uber 는 단일 지점을 새로 만들었다. 빈...
Model Router 시리즈 8번이고 마지막 글이다. 앞 글 vLLM 지표를 라우팅 판단에 쓰는 방법까지 계층과 판단 방식과 설정을 다뤘다. 이 글은 공개된 사례를 그 계층 경계에 늘어놓는다.
시리즈 1번에서 Model Router 라는 한 단어가 두 계층을 덮고 있다고 적었다. 공개 사례를 그 경계로 늘어놓으면 다른 사실이 하나 더 드러난다. 같은 문제를 회사마다 서로 다른 층에서 풀고 있고, 어느 층에서 풀지가 그 조직에 이미 있던 것과 요건에 따라 갈렸다. Netflix 는 기존 계층을 재사용했고 Uber 는 단일 지점을 새로 만들었다.
| 사례 | 서빙 계층 | 라우팅 계층 | 특징 |
|---|---|---|---|
| 토스증권 | vLLM, Triton, KServe | 공개 글에 없다 | 서빙 표준화에 집중했다 |
| Netflix | Triton, vLLM | 기존 JVM 서빙 계층 위에 얹었다 | 라우팅을 새로 만들지 않고 있던 것을 재사용했다 |
| Uber | Uber 자체 호스팅 stack | Go 기반 GenAI Gateway 를 따로 만들었다 | 모든 호출이 한 지점을 지난다 |
| KT | 공개 글에 언급이 없다 | LiteLLM 을 도입했다 | 라우팅 정책만 직접 만들었다 |
빈칸이 정보다. 토스증권 공개 글에 라우팅 계층이 없다는 것은 그 조직에 없다는 뜻이 아니라, 그 글이 다루는 문제가 아래 계층이었다는 뜻이다. KT 공개 글에 서빙 계층 언급이 없는 것도 같다.
네 사례를 하나의 발전 단계로 읽으면 잘못 읽는다. 각각 다른 문제를 풀고 있었고, 그 문제가 어느 층에 있었는지가 선택을 정했다.
Machine Learning 팀이 공개한 글이다. 문제와 판정 기준이 분명해 가장 먼저 읽을 만하다.
문제는 둘이었다.
두 번째 문제가 라우팅 계층과 성격이 다르다. 비용도 품질도 아니고, 모델을 만든 사람이 그것을 서빙까지 보내는 데 필요한 지식의 양이 문제였다.
판정 기준을 셋으로 세웠다.
| 기준 | 무엇을 봤나 |
|---|---|
| 정량 지표 | Token per Second 와 Time to First Token |
| 사용성 | 학습한 모델을 몇 단계로 서빙까지 보낼 수 있는지 |
| 모델 지원 | Llama, Gemma, Mixtral, Qwen 호환성 |
선택은 vLLM 과 Triton 과 KServe 조합이었다. vLLM 은 성능과 사용성이 균형을 이루고 컴파일이 필요하지 않았다. Triton 은 dynamic batching 과 continuous batching 을 제공한다. KServe 는 yaml 하나로 서빙하게 해 배포 단계를 줄였다.
운영에서 얻은 것으로 정형화된 로그를 들었다. KServe 와 Triton 이 정해진 형태로 로그를 남기므로, 새 서버가 뜨면 대시보드에 자동으로 붙었다.
얻을 판단은 판정 기준을 먼저 세운 순서다. 프레임워크를 고르기 전에 무엇을 재서 고를지 정했다. 라우팅 계층에서도 같은 순서가 필요하다. 어느 모델로 보낼지 무엇으로 정하는가에서 효과성과 효율성을 따로 재야 한다고 적은 것이 이 순서에 해당한다.
모델 배포부터 추론까지 전부 자체 운영한다. 별도 ML 환경을 두지 않고 기존 프로덕션 환경 안에 넣었다.
라우팅 계층을 새로 만들지 않았다. 기존 JVM 기반 서빙 계층이 라우팅, 기능 검색, 후보 생성, 후처리, 로깅을 이미 담당하고 있었고 그 위에 LLM 호출을 얹었다.
이 결정이 자바 백엔드 개발자에게 직접 닿는다. 추천 시스템의 라우팅과 A/B 테스트 로직을 담던 계층이 이미 있었다. 그 계층은 요청을 여러 후보로 보내고 결과를 모으고 로그를 남기는 일을 하고 있었으므로, 모델 호출이 하나 더 붙는 것을 감당할 수 있었다.
"라우팅 계층을 만들어야 하는가" 라는 질문 앞에서 먼저 확인할 것이 여기 있다. 지금 요청을 분기하고 결과를 로깅하는 계층이 이미 있는지, 그 계층에 모델 선택 판단을 넣을 수 있는지다. 있으면 새 계층을 세우는 것보다 싸게 끝난다.
세 번째 항목도 눈에 남는다. 작은 요청은 로컬에서, 큰 요청은 별도 서빙으로 보낸다. 같은 애플리케이션 안에서 요청 크기로 실행 위치를 가른 것이고, 이것도 라우팅 판단의 한 형태다.
모든 모델 호출이 지나는 단일 지점을 Go 로 만들었다. 규모는 공개 시점 기준으로 약 30개 팀, 월 1,600만 쿼리, 피크 25 QPS 이고 LLM 활용 사례는 60개가 넘는다.
담당하는 것이 다섯이다.
이 사례에서 얻을 판단이 가장 큰 곳이 여기다.
PII redactor 가 입력을 훑어 개인정보를 익명 자리표시자로 바꾼다.
이름은 ANONYMIZED_NAME_0, ANONYMIZED_NAME_1 처럼 순서대로 치환하고, 응답을 돌려줄 때 원래 값으로 복원한다.
그런데 이 처리가 지연과 결과 품질을 함께 해친다고 적혀 있다. 같은 단어가 위치에 따라 다른 번호로 치환돼 LLM 성능이 떨어질 수 있다. 공개 글은 문제를 밝히는 데까지만 가고 해결책은 제시하지 않는다.
보안 요건이 품질과 충돌하는 실제 사례다. "비용과 지연과 품질과 보안을 함께 맞춘다" 는 문장이 실제로 어떤 충돌을 뜻하는지 보여준다.
라우터 설계에서 이 충돌이 생기는 자리가 어디인지도 드러난다. PII 처리는 모델을 고르기 전에 입력을 바꾸는 단계이므로, 라우팅 판단이 보는 텍스트도 이미 바뀐 텍스트다. 모델을 골라주는 계층이 대신 가져오는 제약에서 라우터가 요청의 일부만 읽고 판단한다고 적었는데, 이 사례에서는 읽는 것 자체가 원본이 아니다.
Netflix 와 갈린 지점을 공개 글로 완전히 설명할 수는 없다. 다만 요건 목록에서 짐작할 수 있는 것이 있다.
| 요건 | 기존 계층에 넣기 어려운 이유 |
|---|---|
| 30개 팀의 비용 귀속 | 팀 경계를 넘는 집계가 필요하다. 한 서비스의 서빙 계층에는 그 경계가 없다 |
| PII 제거 | 외부로 나가는 모든 호출이 이 처리를 거쳐야 한다. 놓치는 경로가 있으면 요건이 성립하지 않는다 |
| 외부 제공자와 자체 호스팅을 한 인터페이스로 | 제공자별 차이를 흡수하는 층이 따로 필요하다 |
두 번째가 단일 지점을 강제한다. "모든 호출이 반드시 이 지점을 지난다" 를 보장해야 하는 요건이 있으면 선택지가 좁아진다.
Agentic AI Lab 이 LiteLLM 을 도입하고 그 위에 라우팅 정책을 만들었다. 인증과 로깅과 모니터링은 LiteLLM 에 맡겼다.
얻을 판단은 분류 축을 넷으로 나눈 방식이다. 요청을 Task 와 Domain 과 Level 과 Capability 네 축으로 분류해 모델을 고른다. 공개 글은 축의 이름까지만 밝히고 각 축을 무엇으로 판정하는지는 적지 않는다.
난이도 하나로 고르지 않고 축을 나눈 것이 읽을 지점이다. 어느 모델로 보낼지 무엇으로 정하는가에서 다룬 판단 방식 넷은 각각 하나의 판정을 내놓는데, 축을 나누면 판정이 넷이 되고 그 조합으로 모델을 고른다.
축을 나누는 대가는 판단 비용이다. 축이 넷이면 각 축을 판정할 방법이 넷 필요하고, 그중 어느 축이 판정에 실패하면 전체 판단이 어긋난다. 축을 몇 개까지 둘 수 있는지, 각 축의 판정에 얼마가 드는지는 공개 글에 없다.
| 사례 | 읽을 지점 |
|---|---|
| 카페24 LLM 라우터 | 120여 개 모델을 하나로 묶은 규모 |
| 한화솔루션 사내 LLM Gateway | 거버넌스와 통제 관점에서 Gateway 를 세운 사례 |
| Uber MCP Gateway | agentic coding 을 위해 MCP 서버들을 한 지점에 모은 사례 |
| DigitalOcean inference router | 캐시를 보는 라우팅. 가장 싼 모델이 가장 싸지 않은 이유 |
앞의 둘은 규모와 통제 관점이고, 뒤의 둘은 이 시리즈에서 다룬 두 주제의 구현 사례다. MCP 게이트웨이는 LiteLLM 로 라우팅 정책을 설정하는 방법, 캐시 기준 라우팅은 캐시를 보고 인스턴스를 고른다에서 다뤘다.
네 사례를 읽고도 답이 나오지 않은 것들이다. 공개 글이 다루지 않았거나, 조직마다 답이 다를 문제다.
여덟 편에서 정리한 것을 한 줄씩 남긴다.
| 편 | 글 | 남는 한 줄 |
|---|---|---|
| 1 | Model Router 란 무엇인가 | 한 단어가 두 계층을 덮고 있다. 어느 모델인가와 어느 인스턴스인가는 다른 판단이다 |
| 2 | 어느 모델로 보낼지 무엇으로 정하는가 | 판단 지연은 대부분 병목이 아니다. 비용을 정하는 것은 그 판단이 고른 모델이다 |
| 3 | 모델을 골라주는 계층이 대신 가져오는 제약 | 어느 모델로 갈지 모른다는 상태가 컨텍스트 한도와 캐시 적중으로 돌아온다 |
| 4 | 캐시를 보고 인스턴스를 고른다 | 위 계층의 캐시는 비용 문제이고 아래 계층의 캐시는 지연 문제다 |
| 5 | 첫 토큰이 나간 뒤에는 재시도할 수 없다 | 그 경계가 HTTP 와 모델 두 층에서 온다. 경계 뒤에 남는 것은 셋이다 |
| 6 | LiteLLM 로 라우팅 정책을 설정하는 방법 | 오류 종류마다 옮겨갈 곳이 다르므로 fallback 키가 셋으로 나뉘어 있다 |
| 7 | vLLM 지표를 라우팅 판단에 쓰는 방법 | 요청 경로에서는 gauge 를 보고 histogram 은 사후 진단에 쓴다 |
| 8 | 같은 문제를 회사마다 다른 층에서 푼다 | 어느 층에서 풀지가 그 조직에 이미 있던 것과 요건에 따라 갈렸다 |
시리즈 전체를 관통하는 것이 하나 있다.
정밀도를 올리는 판단이 요청 경로에 무언가를 얹는다.
usage-based-routing 이 Redis 를 읽고, KV cache aware 가 인스턴스 상태를 조회하고, 계단식이 모델을 두 번 부르고, PII 처리가 입력을 다시 쓴다.
라우팅 계층을 설계하는 일은 무엇을 더 정확히 판단할지가 아니라, 어느 정확도를 어느 지연으로 살지를 정하는 일이다.