LiteLLM – Gateway de IA

Saudações.

Esse tutorial é um guia rápido de instalação e uso do LiteLLM.
Site: https://www.litellm.ai/

Descobri esse sistema ao investigar uma maneira de como resolver o LIMITE DE USO DO CLAUDE CODE por meio de balanceamento das requisições em várias chaves de API (contas diferentes obviamente).

De presente eu resolvi um segundo problema: Proteção de chaves de APIs. Antes eu precisava criar uma chave da API Anthropic para cada membro da equipe ou para cada agente de IA para controlar o uso, agora eu libero chaves do LiteLLM!

Pré-requisitos (constam em outros artigos aqui do blog):

  • Instalação do Linux (Debian);
  • Internet no servidor (sua VPS ou host);
  • Docker CE instalado;

1 – O que é o LiteLLM

O LiteLLM é um gateway para APIs de modelos de IA e serve como um midleware entre você e os serviços oficiais.

O conceito mais pontual seria “um proxy-reverso para modelos de IA“.

Ele te fornecerá uma URL de API para chamadas de IA em seus agentes e suas automações mas internamente ele fará o roteamento até os serviços oficiais (OpenAI ChatGPT, Anthropic Claude, OpenRouter, etc).

Recursos:

  • Redundância: Fallback de modelos transparente, se algum serviço sair do ar ele redireciona as chamadas para o próximo serviço disponível;
  • Balanceamento: Distribuir as chamadas entre vários servidores, especialmente útil para balancear custos em chaves de API e em servidores internos locais;
  • Contabilidade: Acompanhar o custo do uso de modelos, contabilizando consumo de tokens e valores ($);
  • Auditoria: Analisar profundamente as chamadas de API e analisar o conteúdo (prompts, contexto, tools, respostas);
  • Trabalho em equipe: Você pode criar chaves para cada membro da equipe e limitar o uso da chave e os serviços finais ela pode usar;
  • Provedor de IA: Você pode ser seu próprio provedor de APIs de IA, pendurando agentes, automações e sistemas no seu site.

Visão geral:

Clientes de modelos de IA se conectam ao LiteLLM em vez de ir direto nos serviços de IA/LLM.

2 – Preparando o Docker

Programas utilitários no HOST:

Bash
# yamllint - analise de sintaxe YAML / YML
which yamllint || apt-get -y install yamllint;

# jq - analise de JSON
which jq || apt-get -y install jq;

Vamos preparar o ambiente docker com a rede (network_public).

Bash
docker network create \
    -d bridge \
    \
    -o "com.docker.network.bridge.name"="br-net-public" \
    -o "com.docker.network.bridge.enable_icc"="true" \
    -o "com.docker.network.driver.mtu"="65495" \
    \
    --subnet 10.249.0.0/16 --gateway 10.249.255.254 \
    \
    network_public;

Vou usar a execução padrão do container Traefik. O container do Traefik se chamará “traefik-app“.

Personalize a variável EMAIL para que o LetsEncrypt funcione corretamente. Vou salvar o email de contato no arquivo /etc/email do host:

Bash
# Email de registro no letsencrypt
EMAIL="voce@seudominio.com.br";

# Gravar no arquivo para consulta
echo "$EMAIL" > /etc/email;

Rodando o Traefik:

Bash
#!/bin/sh

# Variaveis
  # - Nome do container
  NAME=traefik-app;
  
  # - Imagem do software traefik
  IMAGE=traefik:latest;
  
  # - Email de registro no letsencrypt
  EMAIL=$(head -1 /etc/email);

  # - Diretorio do volume (dados persistentes)
  DATADIR=/storage/$NAME;

# Preparar volume:
  mkdir -p $DATADIR/letsencrypt;
  mkdir -p $DATADIR/logs;
  mkdir -p $DATADIR/config;

# Obter imagem atualizada:
  docker pull $IMAGE;

# Remover instância atual:
  docker rm -f $NAME 2>/dev/null;

# Renovar/criar/rodar:
docker run \
    -d --restart=unless-stopped --name $NAME -h $NAME.intranet.br \
    \
    --network network_public \
    \
    -p 80:80 \
    -p 443:443 \
    \
    -v /var/run/docker.sock:/var/run/docker.sock:ro \
    -v $DATADIR/letsencrypt:/etc/letsencrypt \
    -v $DATADIR/config:/etc/traefik \
    -v $DATADIR/logs:/logs \
    \
    --tmpfs /run:rw,noexec,nosuid,size=16m \
    --tmpfs /tmp:rw,noexec,nosuid,size=16m \
    --read-only \
    \
    $IMAGE \
      \
      --global.checkNewVersion=false \
      --global.sendAnonymousUsage=false \
      \
      --api.insecure=true \
      \
      --log.level=INFO \
      --log.filePath=/logs/error.log \
      \
      --accessLog.filePath=/logs/access.log \
      \
      --entrypoints.web.address=:80 \
      --entrypoints.web.http.redirections.entryPoint.to=websecure \
      --entrypoints.web.http.redirections.entryPoint.scheme=https \
      --entrypoints.web.http.redirections.entryPoint.permanent=true \
      \
      --entrypoints.websecure.address=:443 \
      \
      --providers.docker=true \
      --providers.file.directory=/etc/traefik \
      \
      --certificatesresolvers.letsencrypt.acme.email=$EMAIL \
      --certificatesresolvers.letsencrypt.acme.storage=/etc/letsencrypt/acme.json \
      --certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web;

3 – Banco de dados

O LiteLLM requer um banco de dados PostgreSQL para armazenamento de tarefas, logs, contabilidade, chaves e demais informações persistentes, o Redis é usado para cache e aceleração de operações.

3.1 – Postgres

Bash
# Variaveis
    NAME=pgvector-main;
    LOCAL=$NAME.intranet.br;

    # Argumentos do postgres
    POSTGRES_USER="postgres";
    POSTGRES_PASSWORD="tulipasql";
    POSTGRES_DB="admin";

# Imagem
    IMAGE="pgvector/pgvector:pg18-trixie";
    docker pull $IMAGE;

# Volume
    DATADIR=/storage/$NAME;
    mkdir -p $DATADIR;
    chown -R 999:999 $DATADIR;

# Renovar/rodar:
    docker rm -f $NAME 2>/dev/null;
    docker run \
        -d --restart=always \
        --name $NAME -h $LOCAL \
        --cpus="4.0" --memory=2g --memory-swap=2g --shm-size=1g \
        \
        --network network_public \
        \
        --tmpfs /run:rw,noexec,nosuid,size=64m \
        --tmpfs /tmp:rw,noexec,nosuid,size=64m \
        \
        -v $DATADIR:/var/lib/postgresql/data \
        \
        -e POSTGRES_USER=$POSTGRES_USER \
        -e POSTGRES_PASSWORD=$POSTGRES_PASSWORD \
        -e POSTGRES_DB=$POSTGRES_DB \
        -e PGDATA=/var/lib/postgresql/data/pgdata \
        \
        --health-cmd="pg_isready -U postgres" \
        --health-interval=5s \
        --health-timeout=5s \
        --health-retries=10 \
        \
        --entrypoint "docker-entrypoint.sh" \
        \
        $IMAGE \
            postgres \
                --max_connections=8192 \
                --wal_level=minimal \
                --max_wal_senders=0 \
                --port=5432;

# Acesso:
# docker exec -it pgvector-main psql -U postgres
#   \c  admin

Para instruir o LiteLLM a acessar o PostgreSQL será necessário informar o acesso completo por meio da variável DATABASE_URL, exemplo:

Bash
export DATABASE_URL="postgresql://postgres:tulipasql@pgvector-main:5432/admin";

3.2 – Redis

Bash
# Pasta de persistencia
    mkdir  -p /storage/redis-db;

# Renovar/rodar
    docker pull redis:latest;
    docker rm -f redis-db 2>/dev/null;
    docker run \
        -d --restart=always \
        --name redis-db -h redis-db.intranet.br \
        --read-only \
        --cpus="4.0" --memory=2g --memory-swap=2g --shm-size=1g \
        \
        --network network_public \
        \
        -v /storage/redis-db:/data \
        -w /data \
        \
        --health-cmd="redis-cli ping" \
        --health-interval=1s \
        --health-timeout=3s \
        \
        redis:latest \
            redis-server \
                --dir /data \
                --save 30 1 --save 20 10 --save 10 10000 \
                --rdbcompression no --rdbchecksum yes \
                --dbfilename "redis-db.rdb" \
                --appendonly yes --appendfsync everysec \
                --appendfilename "redis-db.aof";

4 – Implementando o LiteLLM no Docker

Para começar a usar plenamente, vamos definir as chaves de acesso para serviços de IA na nuvem.

4.1 – Diretório do volume

Pasta de volume do LiteLLM para armazenar as chaves:

Bash
# Pasta de volume do LiteLLM
DATADIR=/storage/litellm;

# Criar diretorio
mkdir -p $DATADIR;

# Sub-diretorio para logs:
mkdir -p $DATADIR/logs;

4.2 – Acesso ao banco de dados

Bash
# Pasta de volume do LiteLLM
DATADIR=/storage/litellm;

# URL de acesso ao banco de dados:
DATABASE_URL="postgresql://postgres:tulipasql@pgvector-main:5432/admin";

# Colocar em arquivo dentro do volume:
echo "$DATABASE_URL" > $DATADIR/database_url;

# Ajustar permissoes:
chmod 600 $DATADIR/database_url;

# Visualizar url de acesso ao PG
echo "Acesso postgres.: $(head -1 $DATADIR/database_url)";

4.3 – Chaves de gestão

Para gerir o LiteLLM, precisamos de uma chave mestra:

Bash
# Pasta de volume do LiteLLM
DATADIR=/storage/litellm;


# Chave Mestra
#----------------------------------------------------------------

# Gravar:
if [ -f $DATADIR/litellm_master_key ]; then
    # Ja existe, nao alterar:
    echo "Chave mastra ja existe";
else
    # Gerar chave:
    echo "Craindo Chave mastra";
    MKEY="sk-$(head -1 /proc/sys/kernel/random/uuid)";
    echo "$MKEY" > $DATADIR/litellm_master_key;
fi;


# Chave Salt
#----------------------------------------------------------------

# Gravar:
if [ -f $DATADIR/litellm_salt_key ]; then
    # Ja existe, nao alterar:
    echo "Chave salt ja existe";
else
    # Gerar chave:
    echo "Craindo Chave salt";
    SKEY="sk-$(head -1 /proc/sys/kernel/random/uuid)";
    echo "$SKEY" > $DATADIR/litellm_salt_key;
fi;

# Ajustar permissoes:
chmod 600 $DATADIR/litellm_master_key;
chmod 600 $DATADIR/litellm_salt_key;


# Visualizar chaves
#----------------------------------------------------------------

echo "Chave mestra.: $(head -1 $DATADIR/litellm_master_key)";
echo "Chave salt...: $(head -1 $DATADIR/litellm_salt_key)";

4.4 – Arquivos com as chaves de API

Vou criar os arquivos dentro da pasta do volume contendo as chaves de API que iremos usar:

Obtenha as chaves desses serviços, se não possuir todos comece pelo OpenRouter.

Criando arquivos dentro do volume para puxar as chaves para o LiteLLM:

Bash
# Pasta de volume do LiteLLM
DATADIR=/storage/litellm;

# Troque o xxxx pela chave de API:
echo "xxxxxxxxxxxxx" > $DATADIR/openai_key;
echo "xxxxxxxxxxxxx" > $DATADIR/anthropic_key;
echo "xxxxxxxxxxxxx" > $DATADIR/ollama_key;
echo "xxxxxxxxxxxxx" > $DATADIR/openrouter_key;
echo "xxxxxxxxxxxxx" > $DATADIR/gemini_key;
echo "xxxxxxxxxxxxx" > $DATADIR/deepseek_key;
echo "xxxxxxxxxxxxx" > $DATADIR/xai_key;

# (eu uso as chaves gerais do meu servidor)
#	cat /etc/openai-key     > $DATADIR/openai_key;
#	cat /etc/anthropic-key  > $DATADIR/anthropic_key;
#	cat /etc/ollama-key     > $DATADIR/ollama_key;
#	cat /etc/openrouter-key > $DATADIR/openrouter_key;
#	cat /etc/gemini-key     > $DATADIR/gemini_key;
#	cat /etc/deepseek-key   > $DATADIR/deepseek_key;
#	cat /etc/xai-key        > $DATADIR/xai_key;

# Ajustar permissoes:
chmod 600 $DATADIR/*key;

4.5 – Configuração principal

A configuração principal orienta o LiteLLM de como prover modelos aos seus clientes e para quais serviços externos as chamadas de API devem ser encaminhadas.

Vou começar com uma configuração ampla que reune todos os serviços e todos os modelos, ideal para ambiente de testes e desenvolvimento de agentes.

Crie o arquivo dentro do volume (/storage/litellm) com o nome “config.yaml“.

Conteúdo:

YAML
general_settings:
  master_key: os.environ/LITELLM_MASTER_KEY
  database_url: os.environ/DATABASE_URL
  log_file_dir: "/data/logs"
  admin_ui_access_limit: 1000
  proxy_batch_write_at: 60

litellm_settings:
  num_retries: 2
  request_timeout: 20
  allowed_fails: 3
  check_provider_endpoint: true
  enable_cache: true
  cache:
    type: redis
    host: redis-db
    port: 6379

# opcional
router_settings:
  # simple-shuffle, least-busy, usage-based-routing,latency-based-routing
  routing_strategy: simple-shuffle
  # routing_strategy: "least-busy"
  # modelos gpt-4 redirecionados para gpt-4o
  model_group_alias: {"gpt-4": "gpt-4o"}
  num_retries: 2
  timeout: 30
  # Fallbacks entre provedores
  # fallbacks:
  #  - model_name: "openai/*"
  #    fallback_models: ["anthropic/*", "openrouter/*", "gemini/*"]
  #  - model_name: "anthropic/*"
  #    fallback_models: ["openai/*", "openrouter/*", "gemini/*"]
  #  - model_name: "gemini/*"
  #    fallback_models: ["openai/*", "anthropic/*", "openrouter/*"]
  redis_host: "redis-db"
  #redis_password: "tulipa"
  redis_port: 6379
  ttl: 3600

# lista de modelos
model_list:
  # ======================== OPENAI (Wildcard)
  - model_name: "openai/*"
    litellm_params:
      model: "openai/*"
      api_key: os.environ/OPENAI_API_KEY
    model_info:
      access_groups: ["default-models"]
      description: "OpenAI - GPT models"

  # ======================== ANTHROPIC (Wildcard)
  - model_name: "anthropic/*"
    litellm_params:
      model: "anthropic/*"
      api_key: os.environ/ANTHROPIC_API_KEY
    model_info:
      access_groups: ["default-models"]
      description: "Anthropic - Claude models"

  # ======================== GOOGLE GEMINI (Wildcard)
  - model_name: "gemini/*"
    litellm_params:
      model: "gemini/*"
      api_key: os.environ/GEMINI_API_KEY
    model_info:
      access_groups: ["default-models"]
      description: "Google Gemini models"

  # ======================== DEEPSEEK (Wildcard)
  - model_name: "deepseek/*"
    litellm_params:
      model: "deepseek/*"
      api_key: os.environ/DEEPSEEK_API_KEY
    model_info:
      access_groups: ["default-models"]
      description: "DeepSeek models"

  # ======================== XAI GROK (Wildcard)
  - model_name: "xai/*"
    litellm_params:
      model: "xai/*"
      api_key: os.environ/XAI_API_KEY
    model_info:
      access_groups: ["default-models"]
      description: "XAI - Grok models"

  # ======================== OPENROUTER (Wildcard)
  - model_name: "openrouter/*"
    litellm_params:
      model: "openrouter/*"
      api_key: os.environ/OPENROUTER_API_KEY
    model_info:
      access_groups: ["default-models"]
      description: "OpenRouter - 300+ models"

  # ======================== OLLAMA Cloud (Wildcard)
  - model_name: "ollama/*"
    litellm_params:
      model: "openai/*"
      api_base: "https://ollama.com/api"
      api_key: os.environ/OLLAMA_API_KEY
      extra_headers:
        Authorization: "Bearer ${OLLAMA_API_KEY}"

  # ======================== MODELOS ESPECÍFICOS COM CONFIGURAÇÃO CUSTOMIZADA
  # OpenAI Premium
  - model_name: gpt-4o-premium
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY
      temperature: 0.3
      max_tokens: 4096
    model_info:
      access_groups: ["premium"]

  # Anthropic Premium
  - model_name: claude-3.5-sonnet-premium
    litellm_params:
      model: anthropic/claude-3-5-sonnet-20241022
      api_key: os.environ/ANTHROPIC_API_KEY
      temperature: 0.3
      max_tokens: 4096
    model_info:
      access_groups: ["premium"]

  # Gemini Premium
  - model_name: gemini-2.5-pro-premium
    litellm_params:
      model: gemini/gemini-2.5-pro
      api_key: os.environ/GEMINI_API_KEY
    model_info:
      access_groups: ["premium"]

  # DeepSeek R1 (Reasoning)
  - model_name: deepseek-r1
    litellm_params:
      model: deepseek/deepseek-r1
      api_key: os.environ/DEEPSEEK_API_KEY
    model_info:
      access_groups: ["reasoning"]
      description: "DeepSeek R1 - Modelo de reasoning"

  # Grok 4.1 (Reasoning)
  - model_name: grok-4.1-fast-reasoning
    litellm_params:
      model: xai/grok-4-1-fast-reasoning
      api_key: os.environ/XAI_API_KEY
    model_info:
      access_groups: ["reasoning"]
      description: "Grok 4.1 Fast - Com reasoning"

  # Ollama Local Llama3.1
  - model_name: llama3.1-local
    litellm_params:
      model: ollama/llama3.1
      api_base: os.environ/OLLAMA_HOST
    model_info:
      access_groups: ["local-models"]
      description: "Llama 3.1 - Local via Ollama"

  # Ollama Local DeepSeek
  - model_name: deepseek-local
    litellm_params:
      model: ollama/deepseek-r1
      api_base: os.environ/OLLAMA_HOST
    model_info:
      access_groups: ["local-models"]
      description: "DeepSeek R1 - Local via Ollama"

Verifique erros de sintaxe YML no arquivo antes de continuar:

Bash
# Garantir instalacao do comando yamllint
which yamllint || apt-get -y install yamllint;

# Verificar configuracao sintaticamente:
yamllint /storage/litellm/litellm_config.yaml;

4.6 – DNS e URL pública

Você precisará criar um nome de DNS (FQDN) para seu container. Vou usar o nome litellm.seudominio.com.br como exemplo. Troque pelo nome que você criou.

4.7 – Criando o serviço

Um pré-requisito vital

Bash
# Variaveis
#----------------------------------------------------------------

    # Nome do container
    NAME=litellm;
    
    # Nome de DNS para acesso HTTPs (altere)
    FQDN="litellm.seudominio.com.br";

    IMAGE="docker.litellm.ai/berriai/litellm:main-latest";

  	# Pasta de volume
  	DATADIR=/storage/litellm;

    # URL de acesso do postgres
    DATABASE_URL=$(head -1 $DATADIR/database_url);


# Carregar chaves de API
#----------------------------------------------------------------

    # LiteLLM:
    LITELLM_MASTER_KEY=$(head -1 $DATADIR/litellm_master_key);
    LITELLM_SALT_KEY=$(head -1 $DATADIR/litellm_salt_key);

    # Provedores:
    XAI_API_KEY=$(head -1 $DATADIR/xai_key);
    OLLAMA_API_KEY=$(head -1 $DATADIR/ollama_key);
    GEMINI_API_KEY=$(head -1 $DATADIR/gemini_key);
    OPENAI_API_KEY=$(head -1 $DATADIR/openai_key);
    DEEPSEEK_API_KEY=$(head -1 $DATADIR/deepseek_key);
    ANTHROPIC_API_KEY=$(head -1 $DATADIR/anthropic_key);
    OPENROUTER_API_KEY=$(head -1 $DATADIR/openrouter_key);


  # Exibir chaves de acesso para conferir se faltou alguma:
#----------------------------------------------------------------

    echo;
    echo "LITELLM_MASTER_KEY....: $LITELLM_MASTER_KEY";
    echo "LITELLM_SALT_KEY......: $LITELLM_SALT_KEY";
    echo;
    echo "XAI_API_KEY...........: $XAI_API_KEY";
    echo "OLLAMA_API_KEY........: $OLLAMA_API_KEY";
    echo "GEMINI_API_KEY........: $GEMINI_API_KEY";
    echo "OPENAI_API_KEY........: $OPENAI_API_KEY";
    echo "DEEPSEEK_API_KEY......: $DEEPSEEK_API_KEY";
    echo "ANTHROPIC_API_KEY.....: $ANTHROPIC_API_KEY";
    echo "OPENROUTER_API_KEY....: $OPENROUTER_API_KEY";
    echo;


# Rodar/renovar/reiniciar
#----------------------------------------------------------------

    # Baixar imagem atualizada
    docker pull $IMAGE;

    # Renovar/rodar:
    docker rm -f $NAME 2>/dev/null;
    docker run \
        -d --restart=always \
        --name $NAME -h $NAME.intranet.br \
        --cpus=4.0 --memory=2g --memory-swap=2g --shm-size=1g \
        \
        --network network_public \
        -p 4000:4000 \
        \
        --tmpfs "/run:rw,noexec,nosuid,size=64m" \
        --tmpfs "/tmp:rw,noexec,nosuid,size=64m" \
        \
        -v "$DATADIR:/data" \
        -w "/data" \
        \
        -e LITELLM_MASTER_KEY="$LITELLM_MASTER_KEY" \
        -e LITELLM_SALT_KEY="$LITELLM_SALT_KEY" \
        -e LITELLM_LOG="INFO" \
        -e STORE_MODEL_IN_DB="True" \
        -e DATABASE_URL="$DATABASE_URL" \
        \
        -e XAI_API_KEY="$XAI_API_KEY" \
        -e OLLAMA_API_KEY="$OLLAMA_API_KEY" \
        -e GEMINI_API_KEY="$GEMINI_API_KEY" \
        -e OPENAI_API_KEY="$OPENAI_API_KEY" \
        -e DEEPSEEK_API_KEY="$DEEPSEEK_API_KEY" \
        -e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
        -e OPENROUTER_API_KEY="$OPENROUTER_API_KEY" \
        \
        --label "traefik.enable=true" \
        --label "traefik.http.routers.$NAME.rule=Host(\`$FQDN\`)" \
        --label "traefik.http.routers.$NAME.entrypoints=websecure" \
        --label "traefik.http.routers.$NAME.tls=true" \
        --label "traefik.http.routers.$NAME.tls.certresolver=letsencrypt" \
        --label "traefik.http.services.$NAME.loadbalancer.server.port=4000" \
        \
        --entrypoint /app/docker/prod_entrypoint.sh \
        $IMAGE --config /data/config.yaml --port 4000 --num_workers 4;

    # debug, adicionar:
    # -e LITELLM_LOG="DEBUG"
    # CMD += --detailed_debug

4.8 – Acesso web

A porta HTTP do container é 4000/tcp.

Acesse pelo nome usando HTTPs (via Traefik) ou pelo IP ou nome na porta HTTP 4000.

Endereços:

6 – Usando a API

Exemplos de uso da API:

Bash
curl -X POST http://localhost:4000/v1/chat/completions \
  -H "Authorization: Bearer sk-1234" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "Olá, quem é você?"}],
    "temperature": 0.7
  }'

curl -X POST http://localhost:4000/v1/chat/completions \
  -H "Authorization: Bearer sk-1234" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-3.5-sonnet",
    "messages": [{"role": "user", "content": "Olá, quem é você?"}]
  }'

curl -X POST http://localhost:4000/v1/chat/completions \
  -H "Authorization: Bearer sk-1234" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-2.0-flash-exp",
    "messages": [{"role": "user", "content": "Olá, quem é você?"}]
  }'

curl -X GET http://localhost:4000/v1/models \
  -H "Authorization: Bearer sk-1234"

curl http://localhost:4000/metrics


# OpenAI - Qualquer modelo novo é automaticamente suportado
curl -X POST http://localhost:4000/v1/chat/completions \
  -H "Authorization: Bearer sk-1234" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5",  # Novo modelo? Funciona automaticamente!
    "messages": [{"role": "user", "content": "Olá"}]
  }'

# Anthropic - Mesmo com wildcard
curl -X POST http://localhost:4000/v1/chat/completions \
  -H "Authorization: Bearer sk-1234" \
  -d '{
    "model": "anthropic/claude-4",  # Novo? Funciona!
    "messages": [{"role": "user", "content": "Olá"}]
  }'

# Gemini
curl -X POST http://localhost:4000/v1/chat/completions \
  -H "Authorization: Bearer sk-1234" \
  -d '{
    "model": "gemini/gemini-3.0-ultra",  # Funciona automaticamente!
    "messages": [{"role": "user", "content": "Olá"}]
  }'
  

curl -X GET http://localhost:4000/v1/models \
  -H "Authorization: Bearer sk-1234"

# Sincronizar manualmente (a qualquer momento)
curl -X POST http://localhost:4000/reload/model_cost_map \
  -H "Authorization: Bearer sk-1234" \
  -H "Content-Type: application/json"

curl -X POST "http://localhost:4000/schedule/model_cost_map_reload?hours=6" \
  -H "Authorization: Bearer sk-1234" \
  -H "Content-Type: application/json"


python sync_models.py &

# ou em Docker
docker run -d \
  --name litellm-sync \
  -e PROXY_URL="http://litellm-proxy:4000" \
  -e ADMIN_TOKEN="sk-1234" \
  python:3.11 \
  python sync_models.py


curl -X POST http://localhost:4000/model/new \
  -H "Authorization: Bearer sk-1234" \
  -H "Content-Type: application/json" \
  -d '{
    "model_name": "gpt-5-turbo",
    "litellm_params": {
      "model": "openai/gpt-5-turbo",
      "api_key": "sk-proj-xxx"
    },
    "model_info": {
      "description": "GPT-5 Turbo - Novo modelo lançado",
      "input_cost_per_token": 0.00001,
      "output_cost_per_token": 0.00003
    }
  }'
  
curl -X GET http://localhost:4000/model/list \
  -H "Authorization: Bearer sk-1234"

curl -X DELETE http://localhost:4000/model/delete \
  -H "Authorization: Bearer sk-1234" \
  -H "Content-Type: application/json" \
  -d '{
    "model_name": "gpt-5-turbo"
  }'

Um erro da largura de um fio de cabelo pode causar um desvio de mil quilômetros.
Provérbio Chinês

Terminamos por hoje!

Patrick Brandão, patrickbrandao@gmail.com