Como usar o LiteLLM para unificar chamadas a diferentes provedores de LLM

1. Introdução ao LiteLLM e o problema da fragmentação de APIs

O ecossistema de Large Language Models (LLMs) cresceu exponencialmente, criando um problema significativo para desenvolvedores: cada provedor — OpenAI, Anthropic, Google, Microsoft Azure, Cohere, Mistral AI — expõe sua própria API com formatos de requisição, parâmetros e tratamentos de erro distintos. Manter integrações separadas para cada provedor resulta em código duplicado, maior superfície de bugs e dificuldade de migração entre modelos.

O LiteLLM surge como uma solução elegante para esse problema. Trata-se de uma biblioteca Python leve e open-source que abstrai as diferenças entre dezenas de provedores de LLM em uma interface unificada. Com menos de 10KB de código central, o LiteLLM permite que você troque de modelo ou provedor alterando apenas uma string — o nome do modelo.

Os benefícios principais incluem:
- Interface única: mesma sintaxe para OpenAI, Anthropic, Google, Azure e dezenas de outros
- Fallback automático: redirecionamento inteligente quando um provedor falha
- Roteamento flexível: distribuição de carga entre múltiplos provedores
- Custo controlado: seleção dinâmica do modelo mais barato disponível

2. Instalação e configuração básica do LiteLLM

A instalação é direta via pip:

pip install litellm

Para ambientes de produção, recomenda-se instalar com dependências extras para provedores específicos:

pip install "litellm[proxy]"  # Para usar o servidor proxy integrado
pip install "litellm[all]"    # Todas as dependências opcionais

Configure suas chaves de API como variáveis de ambiente:

export OPENAI_API_KEY="sk-..."
export ANTHROPIC_API_KEY="sk-ant-..."
export GEMINI_API_KEY="AIza..."

Agora, uma chamada básica unificada:

import litellm

# A mesma função funciona para qualquer provedor
resposta = litellm.completion(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "Explique o que é LiteLLM em uma frase"}]
)
print(resposta.choices[0].message.content)

3. Unificando chamadas a diferentes provedores com uma sintaxe comum

O poder do LiteLLM está no mapeamento inteligente de modelos. Você pode usar nomes padronizados ou os nomes específicos de cada provedor:

# OpenAI
model="gpt-4"
model="gpt-3.5-turbo"

# Anthropic
model="claude-3-opus-20240229"
model="claude-3-sonnet-20240229"

# Google
model="gemini-pro"
model="gemini-1.5-pro"

# Azure
model="azure/gpt-4"  # Prefixo azure/

Exemplo prático: chamar três provedores diferentes com exatamente o mesmo código:

import litellm

mensagens = [
    {"role": "system", "content": "Você é um assistente útil."},
    {"role": "user", "content": "Qual é a capital do Brasil?"}
]

# Chamada para OpenAI
resp_openai = litellm.completion(
    model="gpt-3.5-turbo",
    messages=mensagens,
    temperature=0.7,
    max_tokens=100
)

# Chamada para Anthropic
resp_anthropic = litellm.completion(
    model="claude-3-haiku-20240307",
    messages=mensagens,
    temperature=0.7,
    max_tokens=100
)

# Chamada para Google
resp_google = litellm.completion(
    model="gemini-pro",
    messages=mensagens,
    temperature=0.7,
    max_tokens=100
)

print("OpenAI:", resp_openai.choices[0].message.content)
print("Anthropic:", resp_anthropic.choices[0].message.content)
print("Google:", resp_google.choices[0].message.content)

4. Gerenciamento de fallback e balanceamento de carga

Um dos recursos mais valiosos do LiteLLM é o fallback automático. Você pode definir uma lista de modelos para tentar em ordem:

import litellm

# Fallback: tenta GPT-4 primeiro, se falhar usa Claude-3, depois Gemini
resposta = litellm.completion(
    model="gpt-4",
    fallbacks=["claude-3-opus-20240229", "gemini-1.5-pro"],
    messages=[{"role": "user", "content": "Explique a teoria da relatividade"}]
)

Para balanceamento de carga com estratégia round-robin:

from litellm import Router

# Configura múltiplos deployments
model_list = [
    {
        "model_name": "gpt-4",  # Nome lógico
        "litellm_params": {
            "model": "gpt-4",
            "api_key": "sk-openai-1"
        }
    },
    {
        "model_name": "gpt-4",
        "litellm_params": {
            "model": "gpt-4",
            "api_key": "sk-openai-2"  # Segunda chave
        }
    }
]

router = Router(model_list=model_list)

# Distribui automaticamente as requisições
for _ in range(4):
    resposta = router.completion(
        model="gpt-4",
        messages=[{"role": "user", "content": "Teste"}]
    )

5. Customização com modelos locais e provedores não oficiais

O LiteLLM suporta modelos locais executados via Ollama, vLLM ou Hugging Face:

# Ollama (modelo local)
model="ollama/llama3"

# vLLM (servidor próprio)
model="vllm/meta-llama/Meta-Llama-3-8B-Instruct"

# Hugging Face
model="huggingface/mistralai/Mistral-7B-Instruct-v0.2"

Exemplo prático unificando modelo local e remoto:

import litellm

# Primeiro, inicia um modelo local com Ollama
# $ ollama run llama3

# Agora, usa o mesmo código para ambos
modelos = ["ollama/llama3", "gpt-3.5-turbo"]

for modelo in modelos:
    resposta = litellm.completion(
        model=modelo,
        messages=[{"role": "user", "content": "O que é Python?"}]
    )
    print(f"{modelo}: {resposta.choices[0].message.content[:50]}...")

Para provedores personalizados, use o formato custom/:

litellm.completion(
    model="custom/minha-api",
    api_base="https://meu-servidor.com/v1",
    api_key="minha-chave",
    messages=[{"role": "user", "content": "Olá"}]
)

6. Tratamento de erros, logging e monitoramento

O LiteLLM normaliza exceções de diferentes provedores:

import litellm
from litellm import RateLimitError, AuthenticationError, APIError

try:
    resposta = litellm.completion(
        model="gpt-4",
        messages=[{"role": "user", "content": "Teste"}]
    )
except RateLimitError as e:
    print(f"Rate limit excedido: {e}")
    # Implementar lógica de backoff
except AuthenticationError as e:
    print(f"Erro de autenticação: {e}")
except APIError as e:
    print(f"Erro na API: {e}")

Para logging estruturado:

import logging
import litellm

# Configura logging
litellm.set_verbose = True
logging.basicConfig(level=logging.INFO)

# Callbacks para métricas
def log_metrics(model, response, start_time, end_time, **kwargs):
    custo = litellm.cost_per_token(model, response.usage.prompt_tokens, response.usage.completion_tokens)
    latencia = end_time - start_time
    print(f"Modelo: {model}, Custo: ${custo:.4f}, Latência: {latencia:.2f}s")

litellm.success_callback = [log_metrics]
litellm.failure_callback = [lambda e: print(f"Falha: {e}")]

7. Boas práticas de segurança e otimização de custos

Armazenamento seguro de chaves com variáveis de ambiente ou serviços como AWS Secrets Manager:

import os
from dotenv import load_dotenv
load_dotenv()

# As chaves são carregadas automaticamente das variáveis de ambiente
# Nunca hardcode chaves no código

Estratégias para otimizar custos com cache e roteamento inteligente:

import litellm
from functools import lru_cache

@lru_cache(maxsize=100)
def consulta_custosa(pergunta: str) -> str:
    """Cache para perguntas repetidas"""
    resposta = litellm.completion(
        model="gpt-4",  # Modelo caro para respostas complexas
        messages=[{"role": "user", "content": pergunta}]
    )
    return resposta.choices[0].message.content

def roteamento_inteligente(pergunta: str, complexidade: str):
    """Roteia para modelo barato ou caro baseado na complexidade"""
    if complexidade == "simples":
        modelo = "gpt-3.5-turbo"  # Barato
    else:
        modelo = "claude-3-opus-20240229"  # Caro, mas preciso

    return litellm.completion(
        model=modelo,
        messages=[{"role": "user", "content": pergunta}],
        max_tokens=500  # Limita tokens para controlar custo
    )

8. Considerações finais e cenários de uso avançados

O LiteLLM, embora poderoso, possui limitações:
- Nem todos os parâmetros específicos de cada provedor são suportados
- Modelos muito novos podem levar alguns dias para serem mapeados
- Para provedores não oficiais, pode ser necessário configurar manualmente

Casos de uso avançados incluem:
- Chatbots multi-provedor: sistema que usa Claude para respostas criativas e GPT-4 para análises técnicas
- Pipelines de avaliação: comparar respostas de diferentes modelos para o mesmo prompt
- Agentes autônomos: agentes que escolhem dinamicamente o melhor modelo baseado no custo e na tarefa
- Proxy de API: usar o servidor proxy do LiteLLM para expor uma API unificada para sua equipe

Para contribuir com a comunidade, explore o repositório oficial no GitHub, reporte issues e submeta pull requests para adicionar suporte a novos provedores.

Referências