SSD Nodes Learn Hosting plans →
Guías Matt ConnorPor Matt Connor

Cómo autohospedar LiteLLM como gateway LLM

Configura un endpoint compatible con OpenAI en un VPS: claves virtuales, presupuestos por clave, fallbacks y versiones de imagen fijadas para evitar sorpresas.

Qué hace un gateway LLM autohospedado

LiteLLM es un gateway LLM de código abierto que aloja usted mismo: un único endpoint HTTP al que llaman todas sus aplicaciones y que reenvía cada petición al proveedor que debe responderla. LLM significa modelo de lenguaje grande. El gateway utiliza la API de completado de chat de OpenAI (interfaz de programación de aplicaciones), por lo que cualquier biblioteca cliente que ya se comunique con OpenAI funciona con él después de cambiar dos valores: la URL base y la clave.

Ese nivel de indirección es el objetivo. Sus aplicaciones dejan de almacenar las credenciales de los proveedores. Cambiar de modelo se reduce a modificar una línea en un archivo de configuración del servidor, en lugar de cambiar el código de cinco servicios. Además, como todas las llamadas pasan por un único proceso, dispone de un lugar donde establecer un presupuesto y conservar un registro de lo gastado.

Una vez en ejecución, dispone de lo siguiente:

  • Un endpoint. Las aplicaciones apuntan a https://gateway.example.com/v1 y solicitan un nombre de modelo que usted ha definido, como bulk o strong.
  • Claves virtuales. Cada aplicación obtiene su propia clave, con su propia lista de modelos permitidos y su propio límite de gasto. Puede revocar una sin afectar a las demás.
  • Alternativas. Una llamada fallida o una petición demasiado grande se reintenta automáticamente con otro modelo.
  • Un registro. Cada petición escribe una fila con su coste, por lo que se puede responder a la pregunta «¿qué aplicación gastó eso?».

Por qué ejecutar el gateway usted mismo

Un router administrado tiene la misma estructura, pero el proceso de otra persona se encuentra en medio de cada solicitud. Si lo ejecuta usted mismo, las claves de su proveedor y el texto de sus prompts permanecen en un equipo que controla. El coste es real: ahora debe operar el componente del que depende cada aplicación. La última sección de esta guía trata ese coste, porque es la parte que la mayoría de los artículos omite.

Qué necesita

  • Un VPS (servidor privado virtual) con Ubuntu 24.04, Docker y el complemento Compose instalados.
  • Un nombre de dominio que apunte al VPS, si máquinas externas accederán a la puerta de enlace mediante TLS (seguridad de la capa de transporte).
  • Al menos una clave de API de un proveedor.

La puerta de enlace no ejecuta inferencias. Reenvía las solicitudes y transmite las respuestas, por lo que su carga de CPU depende del volumen de solicitudes y no del tamaño del modelo. Un servidor con 1 vCPU puede ejecutar varias aplicaciones internas sin problemas. Lo que aumenta es la base de datos, porque la puerta de enlace escribe una fila de gasto por cada solicitud.

Escriba primero config.yaml

El archivo de configuración determina qué modelos puede solicitar un cliente. Importan cuatro secciones de nivel superior: model_list, litellm_settings, router_settings y general_settings.

model_list:
  - model_name: bulk
    litellm_params:
      model: anthropic/claude-haiku-4-5
      api_key: os.environ/ANTHROPIC_API_KEY
  - model_name: strong
    litellm_params:
      model: anthropic/claude-sonnet-5
      api_key: os.environ/ANTHROPIC_API_KEY
  - model_name: strong
    litellm_params:
      model: openai/gpt-5.5
      api_key: os.environ/OPENAI_API_KEY

litellm_settings:
  num_retries: 2
  request_timeout: 120
  json_logs: true
  set_verbose: false

router_settings:
  allowed_fails: 3
  cooldown_time: 30
  fallbacks: [{"bulk": ["strong"]}]
  context_window_fallbacks: [{"bulk": ["strong"]}]

general_settings:
  background_health_checks: true
  health_check_interval: 300

model_name es el nombre que envían sus clientes. litellm_params.model es el modelo real, escrito como provider/model. Asigne nombres a los modelos según la tarea y no según el proveedor. Una aplicación que solicita bulk seguirá funcionando si el próximo mes decide que bulk debe ser otro modelo.

api_key: os.environ/ANTHROPIC_API_KEY indica a LiteLLM que lea esa variable durante la ejecución. La clave literal nunca aparece en el archivo. Esto es importante porque config.yaml es el archivo que confirma en el repositorio.

Dos entradas comparten el nombre strong, de forma intencionada. Cuando más de una implementación tiene el mismo model_name, el router las trata como intercambiables y distribuye entre ellas las solicitudes con ese nombre. Así es como strong sigue funcionando cuando un proveedor tiene problemas durante un periodo: una vez que una implementación entra en periodo de enfriamiento (más abajo), las nuevas solicitudes para strong se envían a la otra.

num_retries: 2 reintenta un error recuperable hasta dos veces. Esos reintentos pueden seleccionar otra implementación disponible del mismo grupo de modelos: la documentación de arquitectura de LiteLLM, comprobada el 2026-10-29, describe los reintentos dentro del grupo y las alternativas entre grupos como pasos independientes. Por tanto, un reintento para strong puede terminar en el otro proveedor sin activar la conmutación por error ponderada. Una alternativa sólo se activa después de agotar esos reintentos.

allowed_fails y cooldown_time son opciones del router, por lo que se encuentran dentro de router_settings. El proxy construye su router a partir de esa sección. En v1.95.0, un cooldown_time escrito dentro de litellm_settings nunca llega al router, por lo que los periodos de enfriamiento permanecen silenciosamente en el valor predeterminado de 5 segundos. cooldown_time: 30 establece cuánto tiempo permanece una implementación fuera de la rotación después de entrar en enfriamiento. La referencia de configuración describe allowed_fails como el número de fallos que una implementación debe superar dentro de cooldown_time para entrar en enfriamiento. En el código fuente de v1.95.0, allowed_fails: 3 es el valor predeterminado. Con ese valor, el router utiliza los activadores integrados; el recuento de fallos sólo se aplica cuando se establece otro número. Estos activadores incluyen el enfriamiento inmediato tras una respuesta 429 para un grupo con más de una implementación, más de un 50% de fallos durante el minuto actual después de al menos 5 solicitudes para ese grupo y errores que el router no reintentará, como un 401 debido a una clave incorrecta. Otro activador pone en enfriamiento una implementación única cuando fallan todas las solicitudes del minuto actual y el tráfico alcanza SINGLE_DEPLOYMENT_TRAFFIC_FAILURE_THRESHOLD, cuyo valor predeterminado es 1000 solicitudes. Un proveedor que devuelve respuestas 500 en una ráfaga deja de recibir intentos en cada solicitud, mientras que un 500 aislado cada pocos minutos nunca activa el enfriamiento.

fallbacks y context_window_fallbacks tienen activadores distintos. El segundo es el útil y suele omitirse.

  • fallbacks se activa cuando falla la llamada principal.
  • context_window_fallbacks se activa cuando el proveedor rechaza la solicitud porque supera la ventana de contexto de ese modelo. Así, una solicitud demasiado grande se envía a un modelo con capacidad suficiente en lugar de devolver un error al cliente.

También existe content_policy_fallbacks, para los casos en que un proveedor rechaza la solicitud por motivos de política de contenido. Configúrelo sólo si tiene un destino adecuado al que enviar esas solicitudes.

Implementar LiteLLM en un VPS con Docker Compose

Cree un directorio que contenga tres archivos: config.yaml, docker-compose.yml y .env. El inicio rápido oficial descarga la etiqueta latest. Fije una etiqueta de versión en su lugar. Así, docker compose up -d el mes que viene le proporcionará la misma puerta de enlace que hoy, y una reversión se reduce a una sola línea.

services:
  litellm:
    image: ghcr.io/berriai/litellm:v1.95.0
    restart: unless-stopped
    command: ["--config", "/app/config.yaml", "--num_workers", "1"]
    ports:
      - "127.0.0.1:4000:4000"
    volumes:
      - ./config.yaml:/app/config.yaml:ro
    env_file: .env
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16
    restart: unless-stopped
    environment:
      POSTGRES_USER: litellm
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set POSTGRES_PASSWORD in .env}
      POSTGRES_DB: litellm
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U litellm"]
      interval: 5s
      timeout: 5s
      retries: 10
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Compose lee .env dos veces aquí. Una vez para sustituir ${POSTGRES_PASSWORD} dentro del propio archivo Compose y otra mediante env_file para pasar todas las variables al contenedor.

v1.95.0 era la versión actual en agosto de 2026. Consulte la página de versiones del proyecto y fije la versión que esté vigente cuando realice el despliegue. Cada versión publica una firma, por lo que puede comprobar la imagen antes de confiar en ella:

cosign verify --key https://raw.githubusercontent.com/BerriAI/litellm/v1.95.0/cosign.pub ghcr.io/berriai/litellm:v1.95.0

La línea del puerto es 127.0.0.1:4000:4000, que publica el puerto sólo en la interfaz de loopback. Escriba 4000:4000 en su lugar y la puerta de enlace será accesible desde toda Internet, porque Docker añade sus propias reglas a la cadena FORWARD de iptables y estas se evalúan antes que las de ufw, por lo que ufw deny 4000 no lo detiene. Es la forma más habitual de que una puerta de enlace autohospedada quede expuesta: consulte cómo Docker publica un puerto de contenedor directamente fuera del control de ufw. El tráfico externo llega a través del reverse proxy.

Mantenga las claves de los proveedores fuera de la imagen

El archivo .env contiene todos los secretos. Se proporciona como variable de entorno en tiempo de ejecución, por lo que nunca se incluye en la imagen ni se confirma en el repositorio.

LITELLM_MASTER_KEY=sk-REPLACE_ME
LITELLM_SALT_KEY=sk-REPLACE_ME_TOO
POSTGRES_PASSWORD=REPLACE_ME_AS_WELL
DATABASE_URL=postgresql://litellm:REPLACE_ME_AS_WELL@db:5432/litellm
STORE_MODEL_IN_DB=True
LITELLM_MODE=PRODUCTION
LITELLM_LOG=ERROR
ANTHROPIC_API_KEY=sk-ant-...
OPENAI_API_KEY=sk-proj-...

Genere las dos claves de LiteLLM con aleatoriedad real y restrinja los permisos del archivo:

printf 'sk-%s\n' "$(openssl rand -hex 32)"
chmod 600 .env

LITELLM_MASTER_KEY es la credencial de administrador. Autentica la API de gestión y es la contraseña de la interfaz de administración en /ui. Ninguna aplicación debe tenerla.

LITELLM_SALT_KEY cifra las credenciales de los proveedores almacenadas en la base de datos. Establézcala una vez y no la cambie. Si la cambia más adelante, las credenciales almacenadas ya no se podrán descifrar. En ese caso, la puerta de enlace se inicia con normalidad, pero todas las llamadas a esos proveedores fallan durante la autenticación.

STORE_MODEL_IN_DB=True permite añadir y editar modelos desde la interfaz de administración sin modificar config.yaml. Es práctico, pero divide la fuente de verdad en dos. Decida cuál es la fuente autoritativa y documente la decisión junto a la configuración.

El motivo para mantener las claves fuera del archivo de configuración es el mismo que para mantenerlas fuera de las herramientas que se entregan a un agente. Mantener los secretos de los proveedores fuera de los agentes de IA explica este patrón, y archivos env y secretos en Docker Compose explica los aspectos operativos.

Inícielo y supervise el primer arranque:

docker compose up -d
docker compose logs -f litellm

Compruebe que realmente funciona

Hay dos comprobaciones sin autenticación y una con autenticación. Fallan por motivos diferentes.

curl -s http://127.0.0.1:4000/health/liveliness
curl -s http://127.0.0.1:4000/health/readiness

/health/liveliness no requiere autenticación y responde con "I'm alive!" mientras el proceso está en ejecución. /health/readiness tampoco requiere autenticación. Devuelve un objeto JSON con "status": "healthy" y un campo db, o devuelve 503 cuando no se puede acceder a la base de datos. Configure la monitorización sobre readiness, porque liveliness permanece en verde en un gateway que no puede resolver ninguna clave virtual.

La comprobación con autenticación es la que se comunica con los proveedores:

curl -s http://127.0.0.1:4000/health \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY"

Responde con matrices healthy_endpoints y unhealthy_endpoints. Si un modelo aparece en unhealthy_endpoints con un error de autenticación, la clave del proveedor en .env es incorrecta o falta. Ese es el fallo que debe localizar ahora. Como background_health_checks: true está configurado, el proxy ejecuta estas comprobaciones automáticamente cada health_check_interval segundos y /health devuelve el último resultado. Por tanto, consultarlo no envía una solicitud de prueba a los proveedores en cada consulta.

Claves virtuales y presupuestos por clave

Cada aplicación obtiene su propia clave, generada a partir de la clave maestra.

curl -s http://127.0.0.1:4000/key/generate \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
    "key_alias": "nightly-summariser",
    "models": ["bulk"],
    "max_budget": 5,
    "budget_duration": "30d",
    "rpm_limit": 60,
    "tpm_limit": 200000
  }'

La respuesta incluye un campo key que empieza por sk-. Esa cadena es lo que recibe la aplicación y es lo único que recibe.

  • models es una lista de permitidos de lo que esta clave puede solicitar. La clave anterior puede solicitar bulk y nada más.
  • max_budget: 5 con budget_duration: "30d" equivale a cinco dólares estadounidenses por mes natural. LiteLLM restablece el presupuesto 30d el día 1 de cada mes a medianoche, en UTC salvo que defina timezone en litellm_settings, en lugar de calcularlo sobre una ventana móvil de 30 días. Por tanto, cuando la clave ha gastado cinco dólares, deja de funcionar hasta el siguiente día 1.
  • rpm_limit y tpm_limit limitan las solicitudes por minuto y los tokens por minuto exclusivamente para esta clave.
  • key_alias es el valor que reconocerá en el registro de gasto seis semanas después. Defínalo siempre.

Cuando se agota el presupuesto, la llamada falla con un error de tipo budget_exceeded y un mensaje con esta estructura:

Budget has been exceeded! Key=<key> Current cost: <spend>, Max budget: <max_budget>

El código de estado depende de la versión. En la v1.95.0 fijada, es HTTP 429. A partir de la v1.104.0, el valor predeterminado es HTTP 422. Si define budget_exceeded_status_code: 429 en litellm_settings, recupera el código anterior. Los límites reales de rpm_limit y tpm_limit siguen devolviendo 429 en ambas versiones. Compruebe cuál recibe después de cada actualización.

El código de estado es lo que causa la confusión, porque ninguno de los dos indica "presupuesto". Una biblioteca cliente interpreta 429 como un límite de tasa y puede reintentarlo con espera progresiva contra un presupuesto que no volverá a estar disponible hasta el restablecimiento. También interpreta 422 como una solicitud que no se pudo procesar. Registre el cuerpo de la respuesta junto al código de estado. De lo contrario, el agotamiento del presupuesto parecerá otra cosa cada vez.

Consulte y ajuste las claves mediante la misma API de administración:

curl -s "http://127.0.0.1:4000/key/info?key=sk-..." \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY"

curl -s -X POST http://127.0.0.1:4000/key/update \
  -H "Authorization: Bearer $LITELLM_MASTER_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"key": "sk-...", "max_budget": 25}'

Un presupuesto aplicado en la puerta de enlace se mantiene incluso cuando el problema está en el propio agente. Por eso es la base del control de costes de agentes de IA en un VPS.

Enviar trabajo masivo a un modelo económico

Apunte el cliente a la puerta de enlace. URL base, clave y nombre del modelo:

curl -s http://127.0.0.1:4000/v1/chat/completions \
  -H "Authorization: Bearer sk-<the virtual key>" \
  -H 'Content-Type: application/json' \
  -d '{
    "model": "bulk",
    "messages": [{"role": "user", "content": "Say hello in five words."}]
  }'

Cualquier biblioteca cliente de OpenAI funciona igual: establezca base_url en https://gateway.example.com/v1 y api_key en la clave virtual.

La política de enrutamiento de config.yaml se aplica ahora sin que el cliente tenga que conocerla. Una solicitud para bulk se envía al modelo económico. Si esa llamada falla después de sus reintentos, la solicitud se reintenta contra strong. Si el prompt es demasiado largo para bulk, context_window_fallbacks lo envía a strong en lugar de devolver un error. El trabajo masivo, como una pasada de clasificación o la generación de resúmenes de una cola pendiente, se ejecuta con el modelo económico de forma predeterminada. Sólo las solicitudes complejas tienen un coste mayor.

Aquí también se aprecia la utilidad de una puerta de enlace con agentes que usan herramientas. Un servidor MCP (protocolo de contexto del modelo) en el mismo VPS y el agente que lo controla pueden apuntar al mismo endpoint. Así, el modelo que hay detrás puede cambiar sin volver a desplegar ninguno de los dos.

¿Cómo saber si se produjo un fallback?

Este es el modo de fallo que genera costes porque nada parece estar roto. Un fallback correcto devuelve HTTP 200 con un cuerpo de respuesta normal. El modelo barato puede estar caído durante un día y todas las llamadas pueden ser atendidas silenciosamente por el modelo caro. La primera evidencia será la factura.

La evidencia sí existe, en las cabeceras de respuesta. Solicítelas:

curl -s -D - -o /dev/null http://127.0.0.1:4000/v1/chat/completions \
  -H "Authorization: Bearer sk-<the virtual key>" \
  -H 'Content-Type: application/json' \
  -d '{"model":"bulk","messages":[{"role":"user","content":"ping"}]}' \
  | grep -i '^x-litellm'
  • x-litellm-model-group es el nombre del modelo con el que se enrutó la solicitud, como bulk. x-litellm-model-id es el ID del deployment que respondió. Puede consultarlo con /v1/model/info?litellm_model_id=.... Si ese ID no corresponde a uno de sus deployments de bulk, se produjo un fallback.
  • x-litellm-attempted-fallbacks y x-litellm-attempted-retries cuentan estos eventos. En una llamada correcta, ninguno muestra un valor superior a 0.
  • x-litellm-response-cost es el coste de esa llamada en dólares estadounidenses.
  • x-litellm-call-id es el identificador que se usa para encontrar la misma llamada en los logs.

Registre x-litellm-attempted-fallbacks en cada solicitud y genere una alerta cuando sea superior a 0. Ese único número distingue una política de enrutamiento funcional de una política que se ha convertido silenciosamente en «usar siempre el modelo caro».

La versión completa de este enfoque es el tracing y merece una configuración independiente: Langfuse autohospedado para el tracing de llamadas de agentes. LiteLLM incluye el callback, por lo que configurarlo requiere dos líneas y las credenciales.

litellm_settings:
  success_callback: ["langfuse"]
  failure_callback: ["langfuse"]
LANGFUSE_PUBLIC_KEY=pk-lf-...
LANGFUSE_SECRET_KEY=sk-lf-...
LANGFUSE_HOST=https://langfuse.example.com

Para Langfuse v3 y posteriores, la página de Langfuse de LiteLLM recomienda ahora su preset langfuse_otel; el callback langfuse anterior sigue estando documentado. Configure failure_callback además de success_callback. Si lo omite, los únicos traces que conservará serán los de las solicitudes en las que no se produjo ningún problema. De forma independiente, LiteLLM escribe una fila de gasto por solicitud en Postgres, y la interfaz de administración de /ui lee esa tabla. La tabla crece con el tráfico, así que contrólela si el disco es pequeño.

Pon el gateway detrás de un reverse proxy

Nada fuera del servidor debe poder acceder al puerto 4000. Termina TLS en nginx o Caddy y reenvía las conexiones a la dirección de loopback.

location / {
    proxy_pass http://127.0.0.1:4000;
    proxy_http_version 1.1;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_buffering off;
    proxy_read_timeout 600s;
}

Esas dos líneas son las que se suelen omitir. proxy_buffering off es importante porque una respuesta de streaming está formada por una serie de eventos enviados por el servidor, y con el almacenamiento en búfer activado nginx acumula los fragmentos en búferes antes de reenviarlos, lo que retrasa la entrega al cliente. proxy_read_timeout 600s es importante porque el valor predeterminado de nginx, 60 segundos, es el tiempo máximo que espera entre dos lecturas del gateway, no un límite para toda la respuesta. Una respuesta sin streaming no envía nada hasta que termina la generación, por lo que una respuesta larga supera los 60 segundos sin que llegue ningún byte y el cliente recibe un 504, mientras el registro de errores registra upstream timed out (110: Connection timed out) while reading response header from upstream. Una respuesta con streaming que sigue enviando fragmentos puede ejecutarse durante mucho más de 60 segundos; sólo activa el tiempo de espera si el modelo permanece en silencio durante ese tiempo.

Para el certificado, Certbot con Let's Encrypt en nginx es la opción más directa. Si el servidor ya ejecuta varios contenedores, Traefik delante de varias aplicaciones de Compose gestiona el enrutamiento y los certificados desde un único lugar.

La puerta de enlace es ahora un punto único de fallo

Sea honesto sobre lo que ha construido. Todas las aplicaciones que administra dependen ahora de un contenedor en un VPS. Mientras está caído, nada puede llamar a ningún modelo, incluidos los proveedores que funcionan correctamente. De esto se derivan cuatro consecuencias.

  • Una configuración incorrecta lo detiene todo de una vez. restart: unless-stopped reinicia un proceso que se bloquea, y reinicia una y otra vez un contenedor que no puede analizar config.yaml. Lea docker compose logs litellm después de cada cambio de configuración y haga estos cambios cuando tenga tiempo de supervisarlos.
  • Postgres forma parte de la ruta de las peticiones cuando falla la caché. La búsqueda de la clave virtual usa Postgres cuando la clave no está en la caché; el registro del consumo se ejecuta de forma asíncrona después de la respuesta. Que /health/readiness devuelva 503 es el aviso de que la puerta de enlace está funcionando, pero no puede hacer ninguna de las dos cosas.
  • Use primero los núcleos y después añada instancias. La recomendación de producción del proyecto de usar un worker por instancia (--num_workers 1) está pensada para Kubernetes u otro autoscalador de pods que añada instancias automáticamente. En una VM única o un contenedor independiente como este indica lo contrario: establezca el número de workers según el número de vCPU de la máquina. En la máquina de 1 vCPU anterior sigue siendo --num_workers 1; en una máquina más grande, auméntelo y recuerde que cada worker consume su propia memoria. Una segunda puerta de enlace detrás de un balanceador de carga elimina el contenedor único como punto de fallo. No elimina la base de datos.
  • Haga copias de seguridad de lo que no pueda regenerar. Se trata de config.yaml y .env, junto con un pg_dump de la base de datos. Perder LITELLM_SALT_KEY hace inútiles las credenciales cifradas de los proveedores que contiene ese volcado, por lo que el archivo de entorno y el volcado deben formar parte del mismo trabajo de copia de seguridad: copias de seguridad de restic en almacenamiento externo.

Actualizar consiste en editar la etiqueta de la imagen y ejecutar docker compose up -d. LiteLLM ejecuta prisma migrate deploy durante el arranque de forma predeterminada, por lo que el contenedor nuevo migra el esquema de la base de datos en su primer arranque. Haga el volcado antes de cambiar la etiqueta, porque volver a poner la imagen anterior no deshace una migración que ya se haya ejecutado.

Lea las notas de la versión de todas las versiones que omita, no sólo de la versión a la que llegue. Pasar de v1.95.0 a v1.104.0 o posterior implica varios cambios incompatibles: el código de estado de presupuesto indicado arriba, una proxy que se niega a arrancar si la clave maestra no está definida, está vacía o es conocida públicamente, y una proxy que termina si la configuración de la base de datos falla durante el arranque, lo que con restart: unless-stopped aparece como un bucle de reinicios. Si parte de v1.102.x o anterior, las notas de v1.104.0 también le piden que cree por su cuenta dos índices LiteLLM_SpendLogs.

FAQ

¿Añade LiteLLM una latencia apreciable a cada llamada?

El proyecto publica 8 ms en el percentil 95 con 1000 solicitudes por segundo, según su README de octubre de 2026. Considere ese dato una cifra del proveedor. El factor que realmente aumenta la latencia es la distancia de red entre sus aplicaciones y el gateway, porque ha añadido un viaje de ida y vuelta a cada llamada. Ejecute el gateway en la misma región que las aplicaciones que lo llaman y mida después su propia sobrecarga con la cabecera x-litellm-overhead-duration-ms en una respuesta real.

¿Por qué dejó de funcionar el streaming después de poner nginx delante?

Porque nginx almacena en búfer las respuestas del upstream de forma predeterminada y una respuesta de streaming es una serie de eventos enviados por el servidor. Con proxy_buffering activado, nginx acumula los fragmentos en búferes antes de reenviarlos, lo que retrasa su entrega al cliente. Configure proxy_buffering off; en el bloque location. Aumente también proxy_read_timeout en el mismo bloque. De forma predeterminada, nginx abandona la conexión después de 60 segundos sin recibir datos del gateway, un plazo que una generación larga sin streaming alcanza fácilmente, y el cliente recibe un 504.

¿Qué ocurre cuando una clave virtual agota el presupuesto?

La llamada falla con un error de tipo budget_exceeded y un mensaje con el formato Budget has been exceeded! Key=<key> Current cost: <spend>, Max budget: <max_budget>. En la v1.95.0 fijada, el estado es HTTP 429; desde la v1.104.0, el valor predeterminado es HTTP 422. Ninguno de los dos códigos indica que se haya agotado el presupuesto. Esa es la trampa: una biblioteca cliente interpreta 429 como un límite de tasa y puede reintentarlo, por lo que se empieza a investigar una limitación de tasa en lugar de leer el mensaje. Registre el cuerpo de la respuesta junto con el código de estado. Confirme la posición real de la clave con /key/info?key=sk-... usando la clave maestra y aumente el límite con /key/update si el presupuesto era demasiado bajo.

¿Puede el gateway dirigir solicitudes a un modelo local y a modelos alojados?

Sí, y es otra entrada en model_list. Use el prefijo ollama_chat/ con un api_base, por ejemplo model: ollama_chat/llama3.1 junto con api_base: http://ollama:11434. En la red predeterminada de Compose, localhost dentro de un contenedor hace referencia a ese mismo contenedor. Use el nombre del servicio de Compose o la dirección del host en la red de Docker, nunca 127.0.0.1. La excepción es el uso de la red del host, donde el contenedor comparte la pila de red del host. Poner en ejecución el modelo local es una tarea independiente: consulte alojar un LLM con Ollama en un VPS.

¿Te resultó útil este artículo?