LiteLLM proxy para agentes: un gateway OpenAI frente a 100+ modelos
Resumen
Guía práctica de LiteLLM como AI Gateway self-hosted para agentes: SDK completion(), proxy en :4000, config.yaml, virtual keys con Postgres, load balancing, fallbacks y Docker Compose. Distinto de Vercel/Cloudflare AI Gateway (managed) y del fallback en el código del agente.

Qué resuelve
Esta pieza se queda en la decisión práctica: qué instalar, qué riesgo agrega y cómo aplicarlo sin romper operación.
LiteLLM es la librería open source que habla OpenAI Chat Completions con 100+ proveedores, y el AI Gateway (proxy) que pone esa interfaz delante de tu agente: un base_url, una virtual key, spend tracking y failover. No es un coding agent. No es Vercel AI Gateway ni Cloudflare AI Gateway (managed). Es tuyo: corre en :4000, guarda keys en Postgres y enruta Azure, Bedrock, Anthropic, Ollama o vLLM con el mismo SDK.
Esta guía cubre el recorte que un agente en producción necesita: SDK vs proxy, arranque local, config.yaml, virtual keys, balanceo, fallbacks y el mínimo de producción. Vive en el hub de seguridad, coste y operación. Si el agente todavía no existe, parte de construir agentes o del curso.
Qué es (y qué no es)
LiteLLM 1.100.0 en PyPI (verificado 2026-09-07) pide Python ≥3.10 y <3.15. Desde 1.84.0 el suelo es 3.10: un pip install 'litellm[proxy]' en 3.9 no falla ruidoso; pip resuelve hacia atrás hasta 1.83.9. Usa uv tool install 'litellm[proxy]' o sube el intérprete.
Dos superficies, un contrato OpenAI:
| Superficie | Para qué | Qué no hace |
|---|---|---|
SDK from litellm import completion | Una llamada unificada en Python | No emite keys ni presupuestos por tenant |
Proxy / AI Gateway litellm --config | Endpoint :4000 para cualquier cliente OpenAI | No sustituye el retry del agente |
El SDK sirve si el runtime es Python. El proxy sirve si el agente es Node, un CLI o varios servicios: todos apuntan a http://host:4000/v1 con una virtual key. Las keys de proveedor no viajan al proceso del agente.
Arranque local: CLI o Compose
La CLI Quick Start (docs, 2026-09-07) arranca un gateway mínimo:
uv tool install 'litellm[proxy]'
export OPENAI_API_KEY=sk-...
litellm --model gpt-4o
El proceso escucha en http://0.0.0.0:4000. Eso es bind público, no 127.0.0.1: en un VPS el puerto queda expuesto. Cierra con firewall o pon un reverse proxy; el detalle está en bind 0.0.0.0. --detailed_debug solo en diagnóstico.
El Quickstart con Docker (docs, 2026-09-07) levanta gateway + Postgres:
curl -sSLO https://docs.litellm.ai/docker-compose.yml
docker compose up -d
Admin UI: http://localhost:4000/ui. Usuario admin. Password = LITELLM_MASTER_KEY (sk-1234 en el compose de ejemplo). Cámbiala antes de añadir modelos reales. LITELLM_SALT_KEY cifra las API keys de proveedor en la DB: genérala larga, no la rotes después de guardar modelos — las credenciales quedan ilegibles.
El compose oficial usa tag móvil. En algo que vaya a vivir, pin digest. Imagen canónica: ghcr.io/berriai/litellm (bundle Prisma para Postgres); no latest.
config.yaml: alias de cara, modelo de verdad
El overview de config.yaml (docs, 2026-09-07) separa dos nombres:
model_name: lo que el agente manda enmodel=litellm_params.model: lo que LiteLLM manda al proveedor (openai/…,azure/…,bedrock/…,ollama/…)
model_list:
- model_name: gpt-4o
litellm_params:
model: openai/gpt-4o
api_key: os.environ/OPENAI_API_KEY
rpm: 60
- model_name: claude-sonnet
litellm_params:
model: anthropic/claude-sonnet-4-5
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: local-llama
litellm_params:
model: ollama/llama3
api_base: http://ollama:11434
general_settings:
master_key: os.environ/LITELLM_MASTER_KEY
os.environ/NOMBRE hace getenv al arrancar. No pongas sk- en el YAML. Eso es el mismo contrato de secretos fuera del repo. Un segundo bloque con el mismo model_name y otro api_base es load balancing, no un alias nuevo.
Arranque: litellm --config /path/to/config.yaml. El cliente:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:4000", api_key="sk-virt-...")
print(client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "ping"}],
).choices[0].message.content)
El agente no importa litellm. Importa openai y cambia base_url.

Virtual keys: el techo que el agente sí puede romper
Sin Postgres, el proxy enruta. No emite keys ni presupuestos. La página de Virtual Keys (docs, 2026-09-07) exige:
DATABASE_URL=postgresql://…master_keyque empiece porsk-(general_settings.master_keyoLITELLM_MASTER_KEY)POST /key/generateconAuthorization: Bearer <master>
La master es admin. La virtual es lo que recibe el agente: modelos permitidos, RPM/TPM, budget. Un admin que crea una key sin user_id no hereda dueño: no asumas que “la hizo el admin, hereda al admin”. Service accounts (user_id null) tampoco.
Esto es la pieza de infraestructura de presupuestos por tenant: el techo vive en la key, no en un if spend > X dentro del prompt. Si el agente ve un 429 de LiteLLM con retry-after, respeta el header; no reintentes a ciegas contra el mismo techo.
Load balancing y fallbacks: en el proxy, no en el tool loop
Misma model_name, varios litellm_params: el router reparte. Default simple-shuffle. Otras estrategias oficiales (load balancing, 2026-09-07): least-busy, usage-based-routing, latency-based-routing, cost-based-routing. rpm/tpm en el deployment son señal de routing por defecto. Hard limit (429 antes de tocar al proveedor) solo con router_settings.optional_pre_call_checks: [enforce_model_rate_limits]. RPM es exacto; TPM es best-effort porque los tokens salen después de la respuesta.
Varias réplicas del proxy: Redis. Sin Redis cada instancia cuenta RPM sola y te pasas del cupo del proveedor.
Fallbacks (provider failover, 2026-09-07) son otro model_name, en orden, después de num_retries del primario:
router_settings:
num_retries: 2
timeout: 30
fallbacks:
- gpt-4o: ["claude-sonnet", "local-llama"]
Eso no sustituye el fallback de modelos en el agente: el proxy cubre 5xx/timeout/429 del proveedor. 401/403 y spend limit no deben saltar a un modelo más caro. Desde Proxy v1.85.0, mock_testing_fallbacks en el request se ignora; prueba con un error real en staging.
Ollama como último eslabón encaja con agente local: degradar a casa cuando OpenAI/Anthropic no contestan, no al revés.

Producción: Postgres, Redis, salt, réplicas
La guía de Production Deployment (docs, 2026-09-07) es Helm/Terraform. El recorte mínimo:
| Pieza | Para qué | Trampa |
|---|---|---|
| Postgres | keys, teams, spend | sin DB no hay virtual keys |
| Redis | RPM compartido, router state | obligatorio con 2+ réplicas |
LITELLM_SALT_KEY | cifra keys de proveedor | no se rota |
DISABLE_SCHEMA_UPDATE=true | réplicas no migran | un job de migraciones por upgrade |
| 2+ réplicas stateless | el gateway no guarda sesión | health en el load balancer |
Monolítico: una imagen sirve tráfico + UI. Microservicios: gateway :4000, backend :4001, UI :3000. Empieza monolítico. Pin tag. Master key en el secret manager, no en el compose commiteado.
Checklist
- Python ≥3.10 (o
uv tool install); no te quedes en 1.83.9 por pip silencioso. - SDK solo si el runtime es Python; si hay más de un cliente, proxy.
-
0.0.0.0:4000no es “local”: firewall o reverse proxy. -
model_nameestable para el agente;litellm_params.modeles el proveedor. - Keys de proveedor en env /
os.environ/…, nunca en YAML ni en el prompt. - Virtual keys con Postgres; el agente nunca ve la master (
sk-admin). -
LITELLM_SALT_KEYfuerte y fija antes de guardar modelos. - Fallbacks 2–3 grupos; 401/403/spend no caen al backup.
- Redis si hay más de una réplica; pin de imagen, no
latest. - Loguea el modelo efectivo (headers / spend), no lo reescribas en el system prompt.
FAQ
¿LiteLLM reemplaza Vercel o Cloudflare AI Gateway? No. Esos son managed. LiteLLM es self-hosted: más control, más Postgres/Redis/ops. Úsalo cuando las keys y el spend tienen que vivir en tu VPC.
¿El agente tiene que hablar LiteLLM? No. Habla OpenAI (/v1/chat/completions). Cambia base_url y la key.
¿Puedo mezclar Azure, Anthropic y Ollama detrás del mismo alias? Sí: varios bloques con el mismo model_name (balanceo) o fallbacks hacia otro model_name. El backup tiene que poder ejecutar las tools de esa llamada.
¿Hace falta Admin UI? No. CLI + config.yaml bastan. La UI acelera keys y test de modelos; la fuente de verdad en prod suele ser el YAML versionado o STORE_MODEL_IN_DB.
¿Dónde va el retry: LiteLLM o el agente? Ambos, con techo. num_retries + timeout en el proxy; el agente reintenta idempotente y corta en 401/403. No multipliques 3 modelos × 5 retries contra un webhook de 3 s.
Lecturas relacionadas
Sigue explorando AgentOps y otras piezas para builders.

Timeouts y cancelación de llamadas LLM: AbortSignal, no un setTimeout decorativo

CoT vs thinking models: no pidas ‘piensa paso a paso’ al modelo que ya piensa

Idempotencia en tools de agentes: una clave, un efecto
