LiteLLM Proxy와 AI Gateway 운영
LiteLLM SDK와 Router는 애플리케이션 프로세스 안에서도 사용할 수 있습니다. 서비스가 하나라면 이 구조가 단순하지만, 여러 팀과 여러 서비스가 같은 모델 인프라를 사용하기 시작하면 다른 문제가 생깁니다. Provider credential, routing policy, budget, rate limit, logging 설정을 각 애플리케이션이 따로 가지고 있으면 모델 호출보다 운영 정책을 일관되게 관리하는 일이 더 어려워집니다.
LiteLLM Proxy는 모델 호출 방식을 새로 만드는 계층이라기보다 SDK와 Router를 중앙 서비스 뒤에 두고 인증·비용·트래픽·관측 정책을 한곳에서 적용하는 AI Gateway입니다. 클라이언트는 Proxy가 제공하는 공통 API와 Virtual Key 같은 gateway credential을 사용하고, 실제 provider credential과 deployment 정보, routing policy는 gateway 쪽에서 관리할 수 있습니다.
이 구조에서는 애플리케이션이 직접 가지고 있던 운영 상태도 gateway 쪽으로 이동합니다. Virtual Key를 team과 user에 연결하고 각 단위에 budget과 rate limit을 적용하며, 사용량과 비용을 중앙에서 추적할 수 있습니다. Postgres는 이런 key·team·user·budget 같은 관리 정보를 지속하는 데 사용되고, 여러 Proxy instance를 운영할 때 Redis는 rate limit과 spend counter, pod coordination 같은 공유 상태를 맞추는 데 사용할 수 있습니다.
Observability도 같은 이유로 gateway에 모을 수 있습니다. 모든 서비스의 LLM 요청이 한 지점을 지나므로 provider별 호출량, latency, cost, error를 공통 기준으로 기록하고 외부 logging·tracing 시스템에 전달하기 쉬워집니다.
Proxy가 단순한 HTTP 중계 서버를 넘어 AI Gateway가 되는 이유부터 살펴보고, Virtual Key와 team·user가 접근 권한을 어떻게 나누는지, budget과 rate limit이 어디에 적용되는지 연결해서 봅니다. 이어서 Postgres와 Redis가 각각 어떤 상태를 담당하는지, 여러 Proxy instance를 운영할 때 coordination이 왜 필요한지, 마지막으로 logging과 observability가 중앙 gateway에 모였을 때 무엇이 달라지는지까지 살펴봅니다.
1장. SDK를 서버로 세우면 무엇이 달라지나
SDK 방식에서는 각 애플리케이션 프로세스가 직접 LiteLLM을 import합니다.
서비스 A ── LiteLLM SDK ──► 모델 API
서비스 B ── LiteLLM SDK ──► 모델 API
서비스 C ── LiteLLM SDK ──► 모델 API
이 구조에서는 서비스마다 제공자 키와 설정을 가지고 있어야 합니다. 정책을 바꾸려면 여러 서비스의 배포를 함께 고쳐야 할 수도 있습니다.
Proxy를 세우면 경계가 바뀝니다.
서비스 A ──┐
서비스 B ──┼──► LiteLLM Proxy ──► Router/SDK ──► 모델 API
서비스 C ──┘
애플리케이션은 Proxy만 호출하고 실제 모델 연결은 게이트웨이 뒤로 숨깁니다. 그래서 제공자 키를 교체하거나 폴백 정책을 바꿔도 클라이언트 코드는 그대로 둘 수 있습니다.
2장. OpenAI 호환 API로 호출한다
Proxy의 장점은 클라이언트도 특별한 SDK를 배울 필요가 적다는 점입니다. OpenAI SDK의 base_url을 LiteLLM Proxy로 바꿔 호출할 수 있습니다.
from openai import OpenAI
client = OpenAI(
api_key="sk-virtual-key",
base_url="http://localhost:4000",
)
response = client.chat.completions.create(
model="chat-model",
messages=[
{"role": "user", "content": "안녕하세요"}
],
)
클라이언트가 지정한 chat-model은 실제 제공자 모델 이름일 필요가 없습니다. Proxy 설정에서 정의한 논리 모델 이름이고, 뒤에서 Router가 실제 배포를 선택할 수 있습니다.
Responses API를 쓰는 클라이언트도 같은 원리입니다.
response = client.responses.create(
model="reasoning-model",
input="이 문제를 분석해줘",
)
Proxy는 /chat/completions뿐 아니라 /responses, Anthropic Messages, 이미지·오디오·rerank·vector store 같은 여러 API 표면을 함께 제공하고, 필요하면 제공자 고유 API를 passthrough로 통과시키기도 합니다.
3장. 가상 키가 제공자 키를 가린다
팀 운영에서 가장 먼저 얻는 이득은 Virtual Key입니다.
애플리케이션에 OpenAI·Anthropic·Bedrock 키를 직접 나눠 주는 대신, Proxy가 자체 키를 발급합니다.
애플리케이션
│
│ sk-virtual-key
▼
LiteLLM Proxy
│
├── OpenAI API key
├── Anthropic API key
└── AWS credentials
가상 키를 쓰면 제공자 키를 애플리케이션에서 감출 수 있고, 특정 서비스의 키만 회수하거나 예산·허용 모델을 따로 걸 수 있습니다.
Proxy 관리용 master_key와 가상 키는 역할이 다릅니다.
master_key 관리자 권한. 키·팀·정책 관리
virtual key 실제 애플리케이션 호출용
운영 코드에서 master key를 일반 서비스 키처럼 사용하지 않습니다.
4장. 사용자·팀·키를 어떻게 묶나
조직 구조를 단순한 한 줄 트리로만 보면 오해가 생깁니다. LiteLLM에서는 사용자와 팀이 있고, 가상 키가 사용자·팀 중 하나 또는 둘 모두에 연결될 수 있습니다.
user-123 ───────┐
├── virtual key
team-backend ───┘
대표적인 형태는 다음과 같습니다.
| 키 형태 | 사용 예 |
|---|---|
| 사용자 키 | 개발자 개인 테스트 |
| 팀 키 | 운영 서비스, CI/CD, 공용 백엔드 |
| 사용자 + 팀 키 | 팀 예산 안에서 개인 사용량까지 추적 |
팀 키는 특정 구성원이 퇴사해도 서비스가 끊기지 않아야 하는 운영 워크로드에 적합합니다. 반대로 사용자 키는 개인별 사용량과 수명을 관리하기 쉽습니다.
Organization은 여러 팀을 묶는 상위 관리 단위로 사용할 수 있습니다. 다만 조직·팀 수준의 일부 역할과 고급 권한 기능은 Enterprise 범위가 있으므로, 실제 도입 시 사용하는 기능의 라이선스와 권한 범위를 별도로 확인해야 합니다.
5장. 예산과 레이트리밋을 중앙에서 건다
가상 키를 쓰는 이유는 인증만이 아닙니다. 키와 팀에 지출 한도와 처리량 한도를 붙일 수 있습니다.
예를 들어 팀을 만들면서 예산을 설정할 수 있습니다.
curl -X POST 'http://localhost:4000/team/new' \
-H 'Authorization: Bearer sk-admin-key' \
-H 'Content-Type: application/json' \
-d '{
"team_alias": "backend-team",
"max_budget": 100,
"budget_duration": "30d"
}'
가상 키에도 max_budget, TPM, RPM 같은 제한을 둘 수 있습니다. 이 정책이 게이트웨이에 있으면 애플리케이션이 실수로 제한 코드를 빼더라도 중앙 정책은 남습니다.
여기서 중요한 운영 조건이 하나 있습니다. 예산과 가상 키를 실제로 집행하려면 PostgreSQL 같은 데이터베이스가 필요합니다. 공식 문서도 DB가 없는 배포에서는 spend를 읽을 수 없어 예산을 강제로 막을 수 없다고 설명합니다.
따라서 "설정 파일에 max_budget을 적었다"와 "실제로 예산이 집행된다"는 같은 말이 아닙니다. 데이터 저장 계층까지 연결돼 있어야 합니다.
6장. Postgres와 Redis의 역할을 구분한다
기존 설명에서 자주 섞이는 부분이 Postgres와 Redis입니다. 둘 다 운영에서 자주 쓰이지만 항상 같은 이유로 필수인 것은 아닙니다.
Postgres는 영구 데이터의 중심입니다.
Postgres
가상 키
사용자·팀
예산
지출 이력
관리 설정
예산·가상 키·팀별 spend tracking을 쓰려면 데이터베이스가 필요합니다.
Redis는 주로 빠르게 공유해야 하는 상태와 분산 라우팅에 유용합니다.
Redis
레이트리밋 카운터
Router 상태 공유
쿨다운/캐시
여러 인스턴스 간 빠른 coordination
단일 Proxy를 간단히 띄우는 데 Redis가 무조건 필요한 것은 아닙니다. 하지만 여러 Proxy/Router 인스턴스가 같은 레이트리밋과 라우팅 상태를 정확히 공유해야 한다면 공용 Redis의 중요성이 커집니다.
이 차이를 이해하면 "Proxy를 쓰려면 Redis와 Postgres가 항상 둘 다 필수"라는 식의 과도한 결론을 피할 수 있습니다.
7장. 가장 작은 Proxy 구성
모델과 관리자 키, 데이터베이스를 설정하는 기본 형태는 다음과 같습니다.
model_list:
- model_name: chat-model
litellm_params:
model: openai/gpt-5
api_key: os.environ/OPENAI_API_KEY
router_settings:
routing_strategy: simple-shuffle
litellm_settings:
drop_params: true
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
database_url: os.environ/DATABASE_URL
실행합니다.
litellm --config config.yaml
이 설정에서 model_list는 실제 모델 연결, router_settings는 2편에서 본 배포 선택, general_settings는 Proxy 자체의 인증·데이터베이스 같은 운영 설정을 맡습니다.
drop_params: true는 모델 교체 시 지원되지 않는 파라미터를 버리도록 하는 설정입니다. 편해 보이지만 무시된 파라미터를 놓칠 수 있으므로, 4편에서 내부 동작을 보고 다시 판단합니다.
8장. Router 정책도 키와 팀에 내려갈 수 있다
초기에는 Router 설정을 Proxy 전체에 하나 두는 방식이 중심이었습니다. 지금은 키와 팀 단위로 라우팅 설정을 다르게 적용할 수 있는 기능도 제공됩니다.
예를 들어 개발용 키는 단순한 simple-shuffle을 쓰고, 비용 민감 팀은 cost 기반 라우팅을 적용하거나, 특정 팀만 다른 폴백과 타임아웃을 사용할 수 있습니다.
이 구조가 중요한 이유는 모델 정책과 조직 정책이 만나는 지점이기 때문입니다.
팀 A
└── 낮은 비용 우선 Router 정책
팀 B
└── 낮은 지연 우선 Router 정책
라우팅 정책을 코드에 박아 두면 이런 차이를 적용하려고 애플리케이션을 분기해야 합니다. Proxy에 두면 호출부는 그대로 두고 정책 계층에서 조정할 수 있습니다.
9장. 관측과 Guardrail도 게이트웨이에 모인다
모든 호출이 한 게이트웨이를 지나면 관측 지점도 하나로 모입니다.
LiteLLM은 callback과 Proxy 통합을 통해 Langfuse, OpenTelemetry, Prometheus 같은 관측 도구와 연결할 수 있습니다. 비용과 지연, 실패율을 서비스마다 따로 구현하지 않고 중앙에서 수집하기 쉬워집니다.
Proxy hook은 요청 전후에 정책을 적용하는 자리입니다. 예산과 레이트리밋뿐 아니라 guardrail, cache 검사, 응답 ID 검증 같은 기능이 이 계층에 들어갑니다.
요청
│
▼
인증
│
▼
예산·레이트리밋·Guardrail
│
▼
Router
│
▼
모델 호출
│
▼
비용·로그·관측
이 구조의 장점은 애플리케이션이 정책을 매번 직접 구현하지 않아도 된다는 것입니다. 반대로 게이트웨이에 정책이 너무 많이 몰리면 장애 영향도 커지므로 운영 설계가 필요합니다.
10장. 패스스루가 필요한 이유
공통 형식으로 모든 제공자 기능을 완벽하게 표현할 수는 없습니다. 특정 제공자의 새 API나 고유 기능을 바로 사용해야 할 때는 passthrough endpoint가 필요합니다.
패스스루에서는 제공자 고유 요청 형식을 그대로 통과시키되, 게이트웨이의 인증·관측·정책 경계를 유지할 수 있습니다.
공통 API 사용
장점: 모델 교체와 통합이 쉬움
단점: 제공자 고유 기능을 모두 표현하기 어려움
passthrough 사용
장점: 제공자 기능을 그대로 사용
단점: 호출 코드가 그 제공자에 종속됨
통합성을 위해 모든 기능을 억지로 공통 API에 맞추기보다, 필요한 곳만 제공자 고유 경로를 쓰는 절충입니다.
11장. Proxy를 도입할 시점
Proxy는 중앙화의 이득과 운영 부담을 동시에 가져옵니다.
다음 상황이면 Proxy의 가치가 커집니다.
- 여러 서비스가 같은 모델과 정책을 사용한다.
- 제공자 키를 애플리케이션에서 제거하고 싶다.
- 팀·사용자별 예산과 레이트리밋이 필요하다.
- 라우팅과 폴백을 중앙에서 바꾸고 싶다.
- 모든 LLM 호출을 한 곳에서 관측하고 싶다.
반대로 애플리케이션 하나가 모델 몇 개를 호출하는 수준이면 SDK와 Router가 더 단순할 수 있습니다.
Proxy를 도입하면 그 자체가 중요한 인프라가 됩니다. 모든 호출이 Proxy를 지나기 때문에 다중 인스턴스, 데이터베이스 가용성, 헬스체크, 배포 버전 고정과 회귀 테스트를 함께 설계해야 합니다.
12장. 정리
LiteLLM Proxy는 SDK를 HTTP 서버로 바꾼 것 이상의 의미가 있습니다. 모델 호출 정책의 소유권을 애플리케이션에서 플랫폼 계층으로 옮기는 것이 핵심입니다.
애플리케이션
│
│ virtual key + 공통 API
▼
LiteLLM Proxy
├── 인증
├── 사용자·팀 정책
├── 예산·레이트리밋
├── Router
├── Guardrail
└── 관측
│
▼
모델 제공자
Postgres는 키·예산·지출 같은 영구 상태의 중심이고, Redis는 분산 레이트리밋과 Router 상태처럼 빠르게 공유해야 하는 영역에 주로 쓰입니다.
다음 편에서는 이 게이트웨이와 SDK 아래에서 실제로 제공자 차이를 흡수하는 Translation Layer를 봅니다.
용어 정리
| 용어 | 뜻 |
|---|---|
| LiteLLM Proxy | LiteLLM SDK와 Router 위에 인증·정책·관측을 더한 중앙 AI Gateway |
| Virtual Key | Proxy가 발급해 애플리케이션이 사용하는 키 |
master_key |
Proxy 관리 권한에 사용하는 관리자 키 |
| Team | 여러 사용자·서비스의 예산과 접근 정책을 묶는 단위 |
| Postgres | 가상 키, 팀, 예산, 지출 이력 등 영구 상태 저장소 |
| Redis | 분산 레이트리밋·라우팅·캐시 같은 빠른 공유 상태에 사용하는 저장소 |
| Router settings | 배포 선택·재시도·폴백 정책 |
| Proxy hook | 요청 전후에 예산·한도·보안 정책을 적용하는 확장 지점 |
| passthrough | 제공자 고유 API를 공통 형식으로 번역하지 않고 통과시키는 경로 |
참고자료
'AI Agent > Frameworks' 카테고리의 다른 글
| LangChain (5) - 흐름 제어 (0) | 2024.11.22 |
|---|---|
| LiteLLM (4) - 내부 구조와 Translation Layer (0) | 2024.11.11 |
| LiteLLM (2) - 폴백과 라우팅 (0) | 2024.10.21 |
| LangGraph (4) - 에이전트와 커스텀 그래프 (0) | 2024.10.10 |
| LiteLLM (1) - 전체 구조와 SDK (0) | 2024.08.29 |
댓글