AI 모델 라우터 설계법: Claude·Gemini·OpenAI를 한 API 뒤에 묶을 때 필요한 기준
여러 AI 모델을 쓰는 팀은 결국 모델 라우터가 필요해집니다. 처음에는 Claude 하나, Gemini 하나, OpenAI 하나를 각각 직접 호출해도 됩니다. 하지만 제품이 커지면 모델별 엔드포인트, 인증, 비용, 장애 대응, 로그 포맷, 안전 정책이 흩어집니다. 이 상태에서 모델을 바꾸거나 fallback을 넣으려면 코드 여러 곳을 고쳐야 합니다.
Google Cloud API Gateway의 모델 라우팅 Public Preview 같은 흐름은 이 문제를 정면으로 다룹니다. 표준 OpenAI 호환 요청을 받아 Gemini, Claude, OpenAI 계열 모델로 라우팅하고, OpenAPI 명세에서 virtual model name을 backend target에 매핑하는 방식입니다. 특정 제품을 쓰지 않더라도 방향은 분명합니다. 애플리케이션 코드가 모델별 세부 구현을 직접 알지 않게 만드는 것입니다.
왜 모델 라우터가 필요한가
AI 기능을 하나만 만들 때는 라우터가 과해 보입니다. 하지만 다음 상황이 생기면 이야기가 달라집니다.
- 같은 기능에서 저렴한 모델과 강한 모델을 나눠 써야 한다.
- 특정 모델 장애 시 다른 모델로 fallback해야 한다.
- 고객사별로 허용 모델이 다르다.
- 개인정보가 포함된 요청은 특정 리전에만 보내야 한다.
- 팀별 비용 한도를 걸어야 한다.
- 모델별 응답 포맷 차이를 애플리케이션에서 숨기고 싶다.
이 문제를 각 서비스 코드에서 처리하면 중복이 쌓입니다. 라우터는 이 중복을 한 곳으로 모읍니다. 프론트엔드나 백엔드는 model: support-fast, model: code-review-strong 같은 가상 모델명만 보내고, 실제 backend는 라우터가 결정합니다.
기본 구조
모델 라우터는 최소 5개 역할을 해야 합니다.
첫째, 인증을 중앙화합니다. 클라이언트나 여러 서버에 모델 API key를 흩뿌리지 않습니다. 라우터만 외부 모델 provider와 통신합니다.
둘째, virtual model name을 실제 모델로 매핑합니다. 예를 들어 fast-summary는 저렴한 Gemini 계열, deep-code-review는 Claude Opus 계열, realtime-helper는 OpenAI realtime 계열로 보낼 수 있습니다.
셋째, 요청과 응답 스키마를 정규화합니다. provider마다 tool call, system prompt, JSON mode, streaming 이벤트 형식이 다릅니다. 애플리케이션이 이 차이를 모두 알면 유지보수가 어려워집니다.
넷째, 정책을 적용합니다. PII 감지, 최대 토큰, 허용 tool, 고객별 모델 제한, 리전 제한, rate limit이 여기에 들어갑니다.
다섯째, 관측성을 제공합니다. 비용, 지연시간, 에러율, fallback 횟수, 모델별 품질 지표를 남겨야 합니다.
라우팅 기준 정하기
좋은 라우터는 단순히 랜덤으로 모델을 고르지 않습니다. 기준이 있어야 합니다. 가장 기본적인 기준은 작업 유형입니다. 요약, 번역, 코드 리뷰, SQL 생성, 장애 분석, 고객지원 답변처럼 작업을 나눕니다.
두 번째 기준은 위험도입니다. 권한, 결제, 개인정보, 보안, 배포 관련 요청은 강한 모델이나 더 엄격한 검증 경로로 보냅니다.
세 번째 기준은 비용과 지연시간입니다. 사용자 인터랙션 중 즉시 답해야 하는 요청은 빠른 모델이 낫고, 백그라운드 리포트처럼 시간이 있는 작업은 더 깊은 모델을 쓸 수 있습니다.
네 번째 기준은 고객 정책입니다. 엔터프라이즈 고객은 특정 모델 사용을 금지하거나, 데이터가 특정 지역 밖으로 나가지 않기를 원할 수 있습니다. 이 조건은 애플리케이션 코드가 아니라 라우터 정책에 있어야 합니다.
구현 시 피해야 할 함정
가장 흔한 함정은 모든 provider를 OpenAI 호환 스키마로 억지 변환하는 것입니다. 기본 chat completion은 가능하지만, 고급 tool call, reasoning control, multimodal input, realtime streaming은 provider별 차이가 큽니다. 공통 인터페이스를 만들되, provider 특화 기능을 완전히 지우면 강점도 같이 사라집니다.
현실적인 방식은 공통 필드와 확장 필드를 나누는 것입니다. messages, tools, temperature, max_tokens 같은 기본 필드는 공통으로 두고, provider별 기능은 provider_options 같은 영역에 둡니다. 애플리케이션 대부분은 공통 필드만 쓰고, 특정 기능이 필요한 서비스만 확장 필드를 사용합니다.
두 번째 함정은 fallback을 품질 검증 없이 넣는 것입니다. A 모델이 실패하면 B 모델로 보내는 것은 쉽습니다. 문제는 B 모델의 응답이 같은 품질 기준을 만족하는지입니다. 특히 JSON schema, tool call, 안전 정책이 다를 수 있습니다. fallback 후에는 응답 검증을 반드시 해야 합니다.
세 번째 함정은 로그에 원문을 모두 저장하는 것입니다. 디버깅은 쉬워지지만 개인정보와 소스코드 유출 위험이 커집니다. 라우터는 민감 데이터가 가장 많이 지나가는 지점이므로 로그 최소화, 마스킹, 보존 기간 설정이 필요합니다.
운영 지표
모델 라우터를 만들었다면 다음 지표를 봐야 합니다.
- 모델별 요청 수
- 모델별 입력·출력 토큰
- 모델별 비용
- p50·p95 지연시간
- 에러율과 timeout율
- fallback 발생률
- fallback 후 성공률
- policy block 횟수
- 고객·팀별 사용량
- 작업 유형별 품질 지표
여기서 fallback 발생률은 특히 중요합니다. 장애 때문에 fallback이 자주 발생한다면 provider 안정성 문제일 수 있습니다. 품질 실패 때문에 fallback이 많다면 초기 라우팅 기준이 틀렸을 수 있습니다. 비용이 특정 팀이나 고객에게 몰린다면 quota 정책이 필요합니다.
작은 팀을 위한 시작 방법
처음부터 거대한 gateway를 만들 필요는 없습니다. 작은 팀은 서버 내부 모듈로 시작해도 됩니다. callModel(taskType, payload, policy) 같은 함수를 만들고, 그 안에서 모델 선택, 토큰 제한, 로그 기록, 에러 처리를 중앙화합니다. 이후 트래픽이 커지면 별도 서비스나 API Gateway로 분리하면 됩니다.
초기 virtual model name은 5개면 충분합니다.
summary-fastsupport-balancedcode-review-strongincident-deepcreative-draft
이름은 실제 모델명이 아니라 제품 의도를 나타내야 합니다. 그래야 내부에서 provider를 바꿔도 애플리케이션 코드를 덜 고칩니다.
실행 체크리스트
- 애플리케이션 코드에서 실제 모델명을 직접 쓰는 위치를 찾는다.
- 작업 유형별 virtual model name을 정의한다.
- 인증, 토큰 제한, 로그 기록을 라우터로 모은다.
- 공통 스키마와 provider별 확장 필드를 분리한다.
- fallback 후 응답 검증을 넣는다.
- PII 마스킹과 로그 보존 기간을 정한다.
- 모델별 비용·지연시간·fallback 지표를 대시보드화한다.
AI 모델 라우터의 목적은 provider를 추상화하는 데서 끝나지 않습니다. 비용, 장애, 보안, 품질 정책을 한 곳에서 운영할 수 있게 만드는 것입니다. Claude, Gemini, OpenAI를 모두 쓰는 팀이라면 모델 라우터는 선택 기능이 아니라 운영 기반으로 봐야 합니다.