사내 LLM 요청을 한곳으로 모은 AI Gateway 구축기
안녕하세요, 데브옵스 엔지니어 포카입니다.
인프랩에서는 자막 번역, 강의 상세 생성, 학습 에이전트, 커뮤니티 답변 등 꽤 많은 곳에서 LLM API를 쓰고 있습니다.
처음에는 각 서비스가 필요한 제공 업체에서 API 키를 발급받아 직접 호출하는 방식이었는데요.
사용처가 서른 곳을 넘어가면서 이 방식이 슬슬 버티기 어려워졌습니다.
이번 글에서는 사내 LLM 라우팅 서비스인 AI Gateway를 만들게 된 배경과 구축 과정을 공유해보려고 합니다.
배경
모델이 너무 빨리 바뀝니다
GPT, Claude, Gemini, Qwen 같은 제공 업체들이 거의 매주 더 싸고 좋은 모델을 내놓고 있습니다.
한 업체 안에서도 길어야 3개월 주기로 새 버전이 나오고, 오래된 모델은 은퇴시켜서 더는 호출할 수 없게 만듭니다.
여기서 두 가지가 동시에 문제가 됩니다.
- “지금 가장 가성비 좋은 모델”의 수명이 매우 짧음 - 할인 정책까지 겹치면 더 짧아집니다.
- 모델 업데이트를 놓치면 서비스가 멈춤 - 은퇴 시점까지 교체를 못 하면 그대로 장애입니다.
모델을 바꾸실 때는 기존 모델과 새 모델이 둘 다 만족스러운 결과를 내는지 검증이 필요하실 텐데요.
이 검증을 서비스마다 담당자분이 짧은 주기로 반복하시면 시간이 상당히 들어갑니다.
바쁘시면 교체가 계속 밀리고, 밀리다 보면 위의 두 번째 문제로 이어지게 됩니다.
비용도 무시하기 어려운 수준까지 올라왔습니다.
2026년 6월 기준 인프랩의 LLM API 비용은 AWS 비용의 23% 정도였는데요.
같은 성능을 더 싸게 쓰는 일이 전체 인프라 비용 효율에서 차지하는 비중이 그만큼 커졌다고 볼 수 있겠습니다.
키와 사용량이 흩어져 있습니다
각 서비스가 제공 업체를 직접 호출하면 서비스 수만큼 키가 늘어납니다.
키가 늘어나면 회수와 교체가 어려워지고, 유출됐을 때 영향 범위를 파악하기도 어려워집니다.
사용량 확인도 번거로웠습니다.
어떤 기능이 토큰을 얼마나 쓰는지 보려면 제공 업체 대시보드를 하나씩 열어봐야 했고,
그렇게 봐도 “어느 서비스의 어느 기능이 쓴 건지”는 구분되지 않았습니다.
정리하면 모델 선택, 키 관리, 사용량 관측 세 가지를 한곳으로 모으는 게 목표였습니다.
그래서 어떤 게이트웨이를 써야 할까?
LiteLLM Proxy, Portkey AI Gateway, Envoy AI Gateway를 비교했습니다.
세 후보 모두 여러 LLM으로의 통합 라우팅과 fallback은 지원해서, 판단은 나머지 항목에서 갈렸습니다.
처음 비교한 건 2025년 11월이고, 이 글을 쓰면서 2026년 9월 기준으로 다시 확인했습니다.
모두 셀프 호스팅 + 무료 플랜에서 쓸 수 있는지를 기준으로 적었습니다.
세 제품 모두 빠르게 바뀌고 있어서 도입을 검토하신다면 최신 문서를 다시 보시는 편이 좋습니다.
| 기능 | Envoy AI Gateway | LiteLLM Proxy | Portkey AI Gateway |
|---|---|---|---|
| 예산/rate limit(비용/토큰 기반) | 가능(정책 구성) | 유료 전용 | 유료 전용 |
| 관측성(로그/메트릭/트레이스) | 가능(OpenTelemetry) | 로깅만 가능 메트릭 내보내기는 유료 |
기본 대시보드만 제공 |
| 비용 트래킹 | 가능(구성 필요) | 기본 집계만 가능 키/팀별은 유료 |
유료 전용 |
| 가드레일 | 가능 | 유료 전용 | 가능 |
| 프롬프트 관리 | 없음 | 가능 | 유료 전용 |
결정적이었던 건 CNCF라는 점이었습니다
표를 다시 보시면 유료 전용이라고 적힌 칸이 Envoy AI Gateway 열에만 없습니다.
프롬프트 관리는 아예 없지만, 돈을 안 내서 막힌 기능은 하나도 없습니다.
Envoy AI Gateway는 CNCF에서 관리하는 Envoy 프로젝트의 일부라서 기능이 상용 플랜 뒤에 잠기지 않습니다.
이게 지금 당장 얼마를 내느냐의 문제는 아니었습니다.
게이트웨이를 두는 목적 자체가 예산 정책, rate limit, 사용량 추적, 인증 같은 통제 장치를 한곳에 모으는 것인데요.
하필 이 통제 장치들이 대체로 상용 플랜의 판매 포인트입니다.
사용처가 늘어나서 정책을 조여야 하는 시점에 기능마다 플랜 협상을 다시 하는 상황은 피하고 싶었습니다.
관측성이 딱 그 사례였습니다.
저희는 이미 메트릭과 트레이스를 Prometheus, OpenTelemetry 기반 스택으로 모아 보고 있었는데,
LiteLLM Proxy는 사용량을 자체 UI 안에서만 볼 수 있어서 기존 대시보드에 합칠 방법이 없었습니다.
사내 대시보드 한 곳에서 사용량을 보는 게 이번 작업의 주요 목표였으니 그대로 탈락 사유가 되었습니다.
감수한 부분
물론 공짜로 얻은 건 아니고, 딸려오는 비용이 있었습니다.
- Envoy Gateway를 같이 도입해야 함 - Envoy AI Gateway는 Envoy Gateway 위에서 동작합니다. 당시 저희는 Envoy Gateway를 쓰고 있지 않았기 때문에, AI Gateway를 도입하면서 함께 가져왔습니다.
- 프롬프트 관리 기능이 약함 - 프롬프트는 각 서비스 저장소에서 관리하시는 편이 자연스럽다고 봐서 넘어갔습니다.
대신 라우팅과 인증 정책을 전부 쿠버네티스 커스텀 리소스로 선언할 수 있다는 점은 잘 맞았습니다.
사내 인프라 설정은 모두 GitOps로 관리하고 있어서, 새 제공 업체를 붙이는 작업이 콘솔 클릭이 아니라 코드 리뷰가 붙는 Pull Request 한 건으로 끝나게 되었습니다.
구조
먼저 쓰는 쪽 이야기부터 하면, 알아야 할 게 거의 없습니다.
게이트웨이가 OpenAI API 스펙을 받아서 각 제공 업체 스펙으로 변환해주기 때문에,
대부분의 경우 OpenAI 라이브러리 하나로 Claude와 Gemini와 Qwen을 전부 호출하실 수 있습니다.
인프랩 구성에서는 게이트웨이 하나가 진입 경로 세 가지를 받고, 뒤로 제공 업체 다섯 곳이 붙어 있습니다.
사용에 필요한 건 여기까지입니다.
아래는 이 게이트웨이가 어떻게 구성되는지에 대한 이야기라, 궁금하신 분만 보셔도 됩니다.
Envoy AI Gateway는 설정을 관리하는 Control Plane과 실제 요청이 흐르는 Data Plane으로 나뉩니다.
Envoy Gateway 위에 얹는 확장이라, 라우팅과 인증을 쿠버네티스 리소스로 선언하면
컨트롤러가 그걸 프록시 설정으로 옮겨주는 구조입니다.
AIGatewayRoute- 어떤 모델 요청을 어느 백엔드로 보낼지 정합니다AIServiceBackend- 제공 업체 엔드포인트와 API 스펙을 정합니다BackendSecurityPolicy- 그 백엔드에 쓸 자격증명을 정합니다
이 리소스를 적용하면 요런 흐름으로 반영됩니다.
AIGatewayRoute 적용
-> AI Gateway Controller가 HTTPRoute, 설정 시크릿 생성
-> Envoy Gateway Controller가 xDS 설정 생성
-> AI Gateway Extension Server가 xDS에 LLM 처리 필터를 얹음
-> Envoy Proxy + ExtProc sidecar가 요청 처리모델 이름을 지우고 등급만 남기기
모델 교체를 중앙에서 처리하려면 서비스가 모델 이름을 직접 지정하면 안 됩니다.
서비스 코드에 gemini-2.5-flash가 박혀 있으면 그 모델이 은퇴할 때 결국 서비스 코드를 고쳐야 하는데요.
그러면 게이트웨이를 둔 이유가 없어집니다.
그래서 모델 이름 대신 low, medium, high 세 등급만 노출하기로 했습니다.
| 이름 | 100만 입력 토큰당 최대 비용 | 권장 용도 |
|---|---|---|
| high | $2 | 환각에 매우 취약하거나 복잡한 사고가 필요한 경우 사용 |
| medium | $1 | 사용자가 텍스트를 직접 보거나, 후가공에 활용되는 데이터 생성에 사용 |
| low | $0.3 | 간단한 논리, 짧은 답변, 분류, 구조적 데이터 생성에 사용 |
각 등급에 실제로 연결되는 모델은 시간이 지나면 바뀝니다.
다만 표에 적은 최대 비용은 계약처럼 고정됩니다.
어떤 모델이 붙을지는 모르셔도 상한선은 아실 수 있으니,
월간 예상 입력 토큰 x 상한 비용으로 입력 토큰 비용을 미리 추정하실 수 있습니다.
예를 들어 한 달에 1억 입력 토큰을 쓸 것으로 예상되는 기능에서
low를 선택하시는 경우
100만 토큰 단위로 100이니100 x $0.3 = $30입니다. 출력 토큰 비용은 여기에 별도로 붙습니다.
실제로 호출하실 때는 model 자리에 등급 이름만 넣어주시면 됩니다.
curl -s '<사내 AI Gateway 주소>/v1/chat/completions' \
-H 'Content-Type: application/json' \
-H 'Authorization: Bearer <서비스 이름>' \
-H 'X-Service-Feature: onboarding-chat' \
-d '{"model":"low","messages":[{"role":"user","content":"hi"}]}'
# -> 응답의 model 필드에는 실제로 라우팅된 모델명이 담겨서 돌아옵니다라우팅 구성
게이트웨이 설정에서 등급을 실제 모델로 치환합니다.
같은 모델을 여러 제공 업체에서 살 수 있는 경우에는 우선순위를 붙여서 fallback을 걸어두었습니다.
# medium: 할인 중인 경로를 먼저 때리고, rate limit에 걸리면 정가 경로로 넘김
- matches:
- headers:
- type: Exact
name: x-ai-eg-model
value: medium
backendRefs:
- name: envoy-ai-gateway-openrouter
modelNameOverride: openai/gpt-5.6-luna
priority: 0
- name: envoy-ai-gateway-openai
modelNameOverride: gpt-5.6-luna
priority: 1여기에 429 응답과 커넥션 실패에 대한 재시도 정책을 붙였습니다.
같은 모델을 더 싸게 파는 경로가 생기면 그쪽을 1순위로 두고, 한도에 걸릴 때만 정가 경로로 넘어가게 됩니다.
이 판단이 서비스 코드가 아니라 게이트웨이 설정에 있다는 게 핵심입니다.
모델 바꿀 때 절차
모델이 바뀌면 모델 특성에 따라 응답 형태가 달라지거나 기존에 잘 동작하던 패턴이 더는 동작하지 않는 등
부작용이 나타나서 서비스에 영향을 드릴 수 있습니다.
이걸 중앙에서 최대한 억제하는 것도 게이트웨이의 역할이라고 보고, 아래 절차를 정해두었습니다.
- 등급별로 최소 품질 기준을 자동 검증할 수 있는 테스트 세트를 준비합니다.
- 상한 비용을 넘지 않으면서 가성비가 더 좋아 보이는 모델이 나오면 후보로 올립니다.
- 기존 모델과 후보 모델에 같은 테스트 세트를 돌립니다. 하나라도 실패하면 탈락 처리합니다.
- 통과하면 개발 파트 전체에 변경 예정일을 공지하고 관련 기능 모니터링을 요청드립니다.
- 변경 후에 해당 등급을 쓰는 기능이 정상적으로 동작하는지 집중 확인하고, 새로 발견한 품질 기준은 테스트 세트에 추가합니다.
그런데 이거 좀 답답하지 않나요?
네, 기능마다 딱 맞는 모델을 고르는 자유가 줄어듭니다.
그럼에도 이 방향으로 간 이유는, 특정 시점에 완벽하게 최적화된 선택을 하는 것보다
변화를 빠르게 따라가는 능력이 더 오래 이득을 준다고 봤기 때문입니다.
모델 하나가 크게 인하됐을 때 서른 개 서비스가 각자 반응하는 구조와
게이트웨이가 한 번 반응하는 구조는 시간이 갈수록 차이가 벌어질 것 같습니다.
누가 얼마나 쓴 건지 어떻게 알지?
키를 게이트웨이가 독점하면 제공 업체 대시보드에서는 모든 요청이 한 덩어리로 보입니다.
그래서 게이트웨이가 직접 “누가 호출했는지”를 남겨야 했습니다.
처음에는 서비스마다 게이트웨이용 API 키를 발급하는 방안을 봤는데요.
없애려던 키가 다시 늘어나는 게 걸려서, 발급 대신 명명 규칙과 검증을 쓰는 쪽으로 방향을 틀었습니다.
배포 애플리케이션 이름을 API 키 자리에 넣어주시면
게이트웨이가 허용된 형식인지 확인한 뒤 서비스 식별 헤더로 옮겨 담습니다.
여기에 앞의 예시에서 보신 X-Service-Feature 헤더로 기능 이름을 하나 더 받습니다.
덕분에 “어느 서비스의 어느 기능이 어떤 모델을 얼마나 호출했는지”를 사내 대시보드 한 곳에서 보실 수 있게 되었습니다.
성과
- 사내 서른 곳이 넘는 서비스가 게이트웨이를 경유해서 LLM을 호출하고 있습니다. 서비스 코드에서 제공 업체 키가 사라졌습니다.
- 새 제공 업체를 붙이는 작업이 GitOps Pull Request 한 건으로 수렴했습니다.
- 서비스와 기능 두 축으로 토큰 사용량과 비용을 보실 수 있게 되었습니다.
- 모델 교체가 게이트웨이 설정 변경 한 번으로 끝납니다. 크게 인하된 모델이 나오면 등급 연결만 바꿔서 전 서비스에 한 번에 반영합니다.
그래서 비용은 얼마나 줄었을까요?
인프랩의 LLM 비용이 가장 높았던 달은 6월이었습니다.
등급 라우팅을 운영 환경에 적용한 건 8월 초라, 적용 후 첫 온전한 달인 8월을 지금 상태로 놓고 비교했습니다.
전체 LLM 비용이 최고치 대비 약 78% 줄었습니다.
여기에는 두 가지가 함께 작용했습니다.
하나는 등급 라우팅입니다.
medium 등급의 실제 blended 단가는 100만 토큰당 $0.18이었는데요.
등급 표에 적어둔 medium 상한 $1의 5분의 1 수준입니다.
캐시 히트율이 80%를 넘긴 것도 단가를 끌어내리는 데 한몫했습니다.
다른 하나는 사용량이 보이기 시작한 것입니다.
그전에는 제공 업체 대시보드에 요청이 한 덩어리로 찍혀서 어느 기능이 얼마를 쓰는지 알 수 없었습니다.
서비스와 기능 두 축으로 쪼개놓고 나니 예상보다 훨씬 많이 쓰던 기능,
굳이 비싼 모델일 필요가 없던 기능이 드러났습니다.
라우팅을 바꾸지 않아도 보이는 것만으로 고쳐지는 몫이 있었습니다.
마무리
빠르게 변하는 영역에서는 최적의 선택을 유지하는 것보다 선택을 바꾸는 비용을 낮추는 게 낫습니다.
모델 이름을 등급으로 감춘 결정은 개별 기능의 최적화를 조금 포기하는 대신 조직 전체의 반응 속도를 산 셈입니다.
관리할 것을 늘리지 않고 푸는 방법이 있는지 먼저 찾아보는 게 좋습니다.
서비스를 구분하려고 게이트웨이용 키를 새로 발급하려 했다가, 명명 규칙과 검증으로 방향을 틀었던 것처럼요.
애초에 키를 줄이려고 시작한 작업이었으니 키를 다시 늘리지 않는 쪽이 맞았다고 보고 있습니다.
앞으로는 등급별 테스트 세트를 더 촘촘하게 만들어서 모델 교체 판단을 자동화하는 쪽에 집중해보려고 합니다.
비슷한 고민 하고 계신 분들께 도움이 되었으면 좋겠습니다. 읽어주셔서 감사합니다!
