Guía10 min

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.

OpenAIDocker
Gateway LiteLLM unificando varios proveedores LLM detrás de un endpoint OpenAI para un 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:

SuperficiePara quéQué no hace
SDK from litellm import completionUna llamada unificada en PythonNo emite keys ni presupuestos por tenant
Proxy / AI Gateway litellm --configEndpoint :4000 para cualquier cliente OpenAINo 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 en model=
  • 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.

Diagrama de flujo del proxy LiteLLM entre el agente y varios proveedores

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:

  1. DATABASE_URL=postgresql://…
  2. master_key que empiece por sk- (general_settings.master_key o LITELLM_MASTER_KEY)
  3. POST /key/generate con Authorization: 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.

Llaves virtuales y techos de presupuesto frente a las API keys de proveedor

Producción: Postgres, Redis, salt, réplicas

La guía de Production Deployment (docs, 2026-09-07) es Helm/Terraform. El recorte mínimo:

PiezaPara quéTrampa
Postgreskeys, teams, spendsin DB no hay virtual keys
RedisRPM compartido, router stateobligatorio con 2+ réplicas
LITELLM_SALT_KEYcifra keys de proveedorno se rota
DISABLE_SCHEMA_UPDATE=trueréplicas no migranun job de migraciones por upgrade
2+ réplicas statelessel gateway no guarda sesiónhealth 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:4000 no es “local”: firewall o reverse proxy.
  • model_name estable para el agente; litellm_params.model es 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_KEY fuerte 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.