Curso
Mudar entre diferentes provedores de LLM não deveria exigir a reescrita de toda a sua base de código. Mas é exatamente isso que rola quando você trabalha com vários serviços de IA hoje em dia. Cada provedor tem seu próprio SDK, método de autenticação e formato de resposta. O LiteLLM resolve isso com uma interface unificada.
Neste tutorial, vou explicar as principais partes do LiteLLM e mostrar como começar com chamadas básicas de API e avançar para respostas de streaming, saídas estruturadas e acompanhamento de custos.
O que é LiteLLM?
LiteLLM é uma biblioteca Python de código aberto que funciona como um tradutor universal para modelos de IA. Em vez de aprender diferentes APIs para cada provedor, você usa uma interface que se conecta a mais de 100 serviços LLM.
A estrutura tem duas partes principais. O SDK Python permite que você escreva o código uma vez e o execute com qualquer provedor. O servidor proxy funciona como um gateway central para equipes e empresas que precisam gerenciar serviços de IA em grande escala.
O LiteLLM oferece estes benefícios adicionais:
- Rastreamento de custos integrado: Veja os gastos de todos os fornecedores em um único painel, em vez de ficar checando vários sistemas de faturamento.
- Failovers automáticos: Quando um provedor fica fora do ar ou atinge os limites de taxa, o LiteLLM tenta automaticamente suas opções de backup.
- Opção de hospedagem própria: Execute tudo nos seus próprios servidores se precisar de privacidade de dados ou conformidade.
Observe que o OpenRouter oferece acesso unificado parecido a vários LLMs, mas com preços e recursos diferentes.
O servidor proxy adiciona limites de gastos por equipe, acompanhamento de uso em todos os projetos e gerenciamento centralizado de chaves API. Toda a configuração é feita por meio de arquivos YAML simples.
O LiteLLM funciona bem para diferentes tipos de usuários:
- Desenvolvedores individuais que querem testar vários modelos sem precisar criar contas em todos os lugares
- Equipes pequenas que precisam de visibilidade dos custos e não querem ficar presas a um único fornecedor
- Grandes empresas que precisam de gerenciamento centralizado, controle de orçamento e análises detalhadas de uso
A biblioteca tem licença MIT e é totalmente de código aberto. Você pode dar uma olhada no código, ajustar como quiser ou até ajudar no projeto.
Agora que você já sabe o que o LiteLLM pode fazer, veja como configurar seu ambiente.
Pré-requisitos
Antes de começar a usar o LiteLLM, você precisa configurar algumas coisas. Provavelmente, a maior parte disso já está pronta se você já trabalhou com modelos de IA antes.
Ambiente Python
Você precisa do Python 3.7 ou mais recente. A maioria dos sistemas hoje tem isso, mas você pode conferir sua versão com:
import sys
print(f"Python version: {sys.version_info.major}.{sys.version_info.minor}")
Instalação do pacote
Instale o LiteLLM e o python-dotenv para gerenciar variáveis de ambiente:
uv add litellm python-dotenv
# or with pip: pip install litellm python-dotenv
Chaves API
Você vai precisar das chaves API dos provedores que deseja usar. Neste tutorial, vamos trabalhar com dois modelos:
- Chave API da OpenAI: Você pode pegar uma chave em platform.openai.com (para GPT-5).
- Chave API da Anthropic: Você pode pegar uma chave em console.anthropic.com (para Claude Sonnet 4).
Guarde isso num arquivo .env no diretório do seu projeto:
OPENAI_API_KEY=your_openai_key_here
ANTHROPIC_API_KEY=your_anthropic_key_here
Verificação do ambiente
Execute este script para verificar sua configuração:
import os
import sys
from dotenv import load_dotenv
# Load environment variables
load_dotenv()
# Check Python version
print(f"Python version: {sys.version_info.major}.{sys.version_info.minor}")
# Check LiteLLM
try:
import litellm
print("✓ LiteLLM installed")
except ImportError:
print("✗ LiteLLM not installed")
# Check API keys
openai_key = os.getenv("OPENAI_API_KEY")
anthropic_key = os.getenv("ANTHROPIC_API_KEY")
if openai_key:
print(f"✓ OpenAI API key found")
else:
print("✗ OpenAI API key not found")
if anthropic_key:
print(f"✓ Anthropic API key found")
else:
print("✗ Anthropic API key not found")
Python version: 3.11
✓ LiteLLM installed
✓ OpenAI API key found
✓ Anthropic API key found
Se você vir todas as marcas de verificação verdes, está tudo pronto. Se alguma verificação falhar, certifique-se de que instalou os pacotes e adicionou suas chaves API ao arquivo .env.
Fazendo sua primeira chamada de API com o LiteLLM
O LiteLLM usa a mesma interface que você já conhece do OpenAI, mas funciona com qualquer provedor.
Configuração básica
Comece com estas importações:
import litellm
from dotenv import load_dotenv
# Load your API keys
load_dotenv()
Uma solicitação básica ao GPT-5 segue este padrão: defina suas mensagens, chame litellm.completion() e obtenha a resposta.
messages = [
{"role": "user", "content": "Write a simple Python function that adds two numbers"}
]
response = litellm.completion(
model="gpt-5",
messages=messages
)
print(response.choices[0].message.content)
def add(a, b):
"""Return the sum of a and b."""
return a + b
Você acabou de chamar o GPT-5 pelo LiteLLM. O objeto de resposta segue o formato da OpenAI, então, se você já usou a API deles antes, isso vai parecer familiar. Você pode querer dar uma olhada em qual modelo realmente respondeu e conferir o uso do token:
print(f"Model used: {response.model}")
print(f"Response ID: {response.id}")
print(f"Total tokens: {response.usage.total_tokens}")
Model used: gpt-5-2025-08-07
Response ID: chatcmpl-CIbZWUDE1amW2vHtHDmieTX6hnZUq
Total tokens: 557
Mudança de provedor
O verdadeiro poder do LiteLLM aparece quando você troca de provedor. Quer experimentar o Claude Sonnet 4? Mude um parâmetro:
response = litellm.completion(
model="anthropic/claude-sonnet-4-20250514",
messages=messages
)
print(response.choices[0].message.content)
Here's a simple Python function that adds two numbers:
def add_numbers(a, b):
"""
Adds two numbers and returns the result.
Args:
a: First number
b: Second number
Returns:
The sum of a and b
"""
return a + b
# Example usage:
result = add_numbers(5, 3)
print(result) # Output: 8
This function:
- Takes two parameters a and b
- Returns their sum using the + operator
- Works with integers, floats, and even negative numbers
- Includes a docstring to explain what the function does
A mesma estrutura de código, mas um provedor diferente. Claude dá uma resposta bem mais detalhada, com documentação e exemplos, enquanto o GPT-5 foi mais direto.
Tratamento básico de erros
Adicione um pouco de tratamento de erros para quando as coisas derem errado:
try:
response = litellm.completion(
model="gpt-5",
messages=messages
)
print(response.choices[0].message.content)
except Exception as e:
print(f"API call failed: {e}")
Esse padrão detecta problemas comuns, como chaves API inválidas, problemas de rede ou indisponibilidade do modelo.
E agora, o que vem a seguir?
Agora você já sabe o básico pra usar o LiteLLM com qualquer provedor. A documentação Introdução traz mais detalhes sobre os modelos e parâmetros compatíveis, e a referência da função Completion mostra todas as opções disponíveis.
Para criar aplicativos de produção, você também vai querer seguir as melhores práticas de design de API para criar sistemas confiáveis e de alto desempenho.
Troca de provedor e alternativas
O sistema de fallback do LiteLLM lida automaticamente com falhas do provedor para que seus usuários nunca vejam mensagens de erro. Quando você está criando aplicativos reais, precisa de planos de backup que funcionem sem precisar escrever nenhum código extra.
Configuração básica de fallback
Para configurar um fallback, adicione uma lista fallbacks à sua chamada de conclusão:
messages = [
{"role": "user", "content": "Explain what a Python decorator is in one sentence"}
]
response = litellm.completion(
model="gpt-5",
messages=messages,
fallbacks=["anthropic/claude-sonnet-4-20250514"]
)
print(f"Response: {response.choices[0].message.content}")
print(f"Model used: {response.model}")
Response: A Python decorator is a callable that wraps another function or class to augment its behavior and returns it, applied with the @ syntax so you can add reusable functionality without changing the original code.
Model used: gpt-5-2025-08-07
Se o GPT-5 não funcionar, o LiteLLM tenta automaticamente o Claude Sonnet 4. Os usuários recebem uma resposta de qualquer maneira.
Criando cadeias de fallback
Você pode conectar vários provedores para ter mais segurança. Usando as mesmas mensagens de antes:
response = litellm.completion(
model="gpt-5",
messages=messages,
fallbacks=["anthropic/claude-sonnet-4-20250514", "gpt-3.5-turbo"]
)
print(f"Model used: {response.model}")
Model used: gpt-5-2025-08-07
O LiteLLM testa os modelos na ordem. Se o primário falhar, ele tenta o primeiro fallback. Se isso não der certo, ele tenta o segundo. Várias camadas de proteção.
Adicionando novas tentativas
Combine fallbacks com novas tentativas para obter uma confiabilidade ainda maior:
response = litellm.completion(
model="gpt-5",
messages=messages, # Same messages as before
num_retries=2
)
Tenta o mesmo modelo duas vezes antes de passar para os planos alternativos. Ótimo pra problemas temporários de rede ou picos de limite de taxa.
Os fallbacks cuidam da maioria das falhas automaticamente, mas você ainda deve pegar os casos em que todos os modelos falham:
try:
response = litellm.completion(
model="gpt-5",
messages=messages, # Same messages as before
fallbacks=["anthropic/claude-sonnet-4-20250514"],
num_retries=2
)
return response.choices[0].message.content
except Exception as e:
# All models failed - handle gracefully
return "Sorry, I'm having trouble right now. Please try again."
Mesmo quando os provedores funcionam perfeitamente, os usuários ainda enfrentam outro problema: o tempo de espera frustrante. Alguém clica em enviar no seu aplicativo e não vê nada por alguns segundos. Eles ficam pensando se alguma coisa quebrou.
Streaming para respostas em tempo real
A maioria das respostas da API de IA chega como um bloco completo, tipo quando você baixa um arquivo. Os usuários ficam esperando sem saber de nada até que a resposta esteja pronta. O streaming muda isso mostrando o texto conforme ele é gerado, palavra por palavra.
Por que o streaming muda a experiência do usuário
Em vez de esperar pela resposta completa, o streaming mostra o texto à medida que a IA o gera. Veja a diferença:
import litellm
from dotenv import load_dotenv
load_dotenv()
messages = [{"role": "user", "content": "What is Python in one sentence?"}]
response = litellm.completion(
model="gpt-5",
messages=messages,
stream=True
)
for chunk in response:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
Python is a high-level, interpreted, dynamically typed, general-purpose programming language known for its readability and vast ecosystem, used across web development, data science, automation, scripting, and more.
O texto aparece aos poucos, em vez de todo de uma vez (quando você executa o trecho acima na sua máquina). Os usuários veem o progresso na hora, o que é bem mais legal do que ficar olhando pra um ícone girando.
Como o streaming realmente funciona
Isso funciona no nível do bloco. Em vez de uma resposta grande, você recebe várias pequenas partes, chamadas deltas. Às vezes, os blocos estão vazios, então você deve lidar com eles corretamente por segurança:
response = litellm.completion(
model="anthropic/claude-sonnet-4-20250514",
messages=[{"role": "user", "content": "Define JavaScript in exactly two sentences"}],
stream=True
)
for chunk in response:
if hasattr(chunk.choices[0].delta, 'content') and chunk.choices[0].delta.content:
print(f"'{chunk.choices[0].delta.content}'", end=" ")
'JavaScript is a high' '-level, interpreted programming language primarily used for creating' ' interactive and dynamic content on web pages, running' ' in web browsers to manip' 'ulate HTML elements, handle user events' ', and communicate with servers.' ' Originally designed for client-side web development, JavaScript has evolve' 'd into a versatile language that can also' ' be used for server-side development, mobile applications' ', and desktop software through various runtime' ' environments like Node.js.'
Tornando o streaming reutilizável
Para aplicações reais, você vai querer capturar a resposta completa enquanto ainda mostra a saída de streaming. Aqui está uma função para fazer isso:
def stream_and_capture(model, messages):
"""Stream response while capturing the complete text"""
response = litellm.completion(
model=model,
messages=messages,
stream=True
)
full_response = ""
for chunk in response:
if chunk.choices[0].delta.content:
content = chunk.choices[0].delta.content
print(content, end="", flush=True)
full_response += content
print() # New line after response
return full_response
# Test it
messages = [{"role": "user", "content": "Define APIs in 2 sentences max"}]
result = stream_and_capture("gpt-5", messages)
APIs (Application Programming Interfaces) are standardized contracts, often exposed as endpoints, that specify how software components or services can communicate, including the allowed operations, inputs, and outputs. They let developers access functionality or data without knowing the underlying implementation, enabling modular, interoperable systems.
O parâmetro ` end="" ` evita quebras de linha entre os blocos. ` flush=True ` força a exibição imediata em vez do armazenamento em buffer.
Streaming com fallbacks
Você também pode juntar o streaming com o sistema de backup pra ter mais segurança:
response = litellm.completion(
model="gpt-5",
messages=[{"role": "user", "content": "Define machine learning in one sentence"}],
fallbacks=["anthropic/claude-sonnet-4-20250514"],
stream=True
)
for chunk in response:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
Machine learning is a branch of artificial intelligence where algorithms learn patterns from data to make predictions or decisions without being explicitly programmed.
Feedback imediato e troca automática de provedor se o modelo principal falhar.
O streaming dá feedback imediato aos usuários, mas você ainda enfrenta outro problema ao criar aplicativos reais. Quando esse texto chegar, seu código precisa funcionar com ele. Você pode extrair dados, guardar informações em bancos de dados ou passar valores para outras funções. Mas analisar respostas de texto é complicado e dá errado facilmente quando o formato muda.
Usando saídas estruturadas
Eis o que realmente acontece: Você cria um aplicativo que analisa o feedback dos clientes. Sua IA mostra um texto tipo “O sentimento é positivo com confiança 0,85 e as principais palavras-chave são: responsivo, útil, rápido.” Você escreve padrões regex para extrair a pontuação de confiança e as palavras-chave. Tudo funciona nos testes.
Então, a IA muda um pouco o formato da resposta para “Sentimento: positivo (confiança: 0,85). Palavras-chave incluem responsivo, prestativo e rápido. Sua expressão regular não funciona. Seu pipeline de dados para de funcionar. Os relatórios de opinião dos clientes mostram valores em branco em vez de pontuações. Seu painel de controle trava. Você passa horas consertando o código de análise que funcionava ontem.
As saídas estruturadas evitam esse problema, devolvendo dados em formatos previsíveis desde o início.
Recebendo JSON em vez de texto
O LiteLLM pode devolver JSON em vez de texto simples. Você diz qual estrutura quer através do seu prompt, e ele volta formatado corretamente:
import litellm
from dotenv import load_dotenv
load_dotenv()
messages = [{"role": "user", "content": "Describe Python as a programming language. Return as JSON with fields: language, difficulty, description"}]
response = litellm.completion(
model="gpt-5",
messages=messages,
response_format={"type": "json_object"}
)
print(response.choices[0].message.content)
{
"language": "Python",
"difficulty": "Beginner-friendly (easy to learn, moderate to master)",
"description": "Python is a high-level, interpreted, dynamically typed, general-purpose programming language focused on readability and developer productivity. It supports multiple paradigms (object-oriented, functional, procedural), uses indentation for block structure, and includes a large standard library with an extensive third-party ecosystem (PyPI). Common uses include web development, data science, machine learning, automation/scripting, scientific computing, and DevOps. While not the fastest for CPU-bound tasks, it integrates well with C/C++ and accelerators, and runs cross-platform."
}
Essa abordagem estruturada elimina os problemas comuns de análise sintática. Em vez de procurar no texto, você recebe um JSON válido com exatamente os campos que você pediu. Sem dores de cabeça com análise sintática, sem surpresas com formatos.
Trabalhando com os dados JSON
As strings JSON brutas não são úteis até você transformá-las em objetos Python com os quais seu aplicativo possa trabalhar. Você precisa transformar essa string em objetos Python que você possa realmente usar:
import json
messages = [{"role": "user", "content": "Describe JavaScript in 2 sentences. Return as JSON with fields: name, paradigm, use_cases (array of exactly 3 items)"}]
response = litellm.completion(
model="anthropic/claude-sonnet-4-20250514",
messages=messages,
response_format={"type": "json_object"}
)
# Parse the JSON response
data = json.loads(response.choices[0].message.content)
print(f"Language: {data['name']}")
print(f"Paradigm: {data['paradigm']}")
print(f"Use cases: {', '.join(data['use_cases'])}")
Language: JavaScript
Paradigm: multi-paradigm (object-oriented, functional, event-driven)
Use cases: web development and browser scripting, server-side development with Node.js, mobile app development with frameworks like React Native
Agora que você tem dados estruturados, pode passar eles direto para outras funções, guardar em bancos de dados ou mostrar na sua interface do usuário sem precisar mexer no texto. Para fluxos de trabalho de análise de dados, ferramentas como o Pandas AI podem trabalhar diretamente com essa saída estruturada para gerar insights.
Adicionando segurança de tipos com o Pydantic
A análise JSON detecta erros de sintaxe, mas tipos de dados errados ou campos ausentes são problemas diferentes. Os modelos Pydantic resolvem isso validando sua estrutura de dados e detectando problemas antes que eles danifiquem seu aplicativo:
from pydantic import BaseModel
import json
class ProgrammingLanguage(BaseModel):
name: str
paradigm: str
use_cases: list[str]
messages = [{"role": "user", "content": "Describe CSS briefly. Return as JSON with fields: name, paradigm, use_cases (array of 3 items)"}]
response = litellm.completion(
model="gpt-5",
messages=messages,
response_format={"type": "json_object"}
)
# Parse and validate with Pydantic
data = json.loads(response.choices[0].message.content)
language = ProgrammingLanguage(**data)
print(f"Validated data: {language.name} - {language.paradigm}")
print(f"Use cases: {language.use_cases}")
Validated data: CSS (Cascading Style Sheets) - Declarative, rule-based stylesheet language for describing the presentation of structured documents.
Use cases: ['Styling layout, colors, and typography of web pages', 'Responsive design across devices and viewports', 'Animations, transitions, and visual effects']
O Pydantic automaticamente verifica se name e paradigm são strings, e se use_cases é uma lista de strings. Se a IA devolver os tipos errados ou esquecer um campo obrigatório, você vai receber um erro claro em vez de bugs misteriosos mais tarde.
Lidando com erros JSON
A análise JSON pode falhar se a IA retornar JSON malformado ou texto que não seja JSON. Adicione o tratamento básico de erros:
import json
messages = [{"role": "user", "content": "Summarize machine learning in 1 sentence. Return as JSON with topic and summary fields"}]
try:
response = litellm.completion(
model="anthropic/claude-sonnet-4-20250514",
messages=messages,
response_format={"type": "json_object"}
)
data = json.loads(response.choices[0].message.content)
print(f"Topic: {data['topic']}")
print(f"Summary: {data['summary']}")
except json.JSONDecodeError:
print("Invalid JSON returned")
except Exception as e:
print(f"Request failed: {e}")
Topic: machine learning
Summary: Machine learning is a subset of artificial intelligence that allows computers to learn and make predictions or decisions from data without being explicitly programmed for each specific task.
Saídas estruturadas trocam a análise confusa de texto por estruturas de dados organizadas. Você pode juntar o modo JSON com fallbacks, assim como as conclusões normais.
Saídas estruturadas fornecem dados limpos e previsíveis que não prejudicam sua lógica de análise. Mas tem outro problema que aparece quando você passa do protótipo para a produção: as contas. Cada chamada de API custa dinheiro, e esses custos podem te surpreender.
Acompanhamento de custos
Eis o que rola: Seu protótipo funciona muito bem nos testes com 50 chamadas de API por dia. Você está gastando cerca de US$ 2 por semana. Tudo parece estar bem. Você lança a produção e consegue 500 usuários. Agora você está fazendo 5.000 chamadas de API por dia. Sua conta mensal passa de R$ 8 para R$ 800.
Sem acompanhar os custos, você não tinha como saber. Você não consegue saber quais recursos custam mais, quais modelos são mais caros ou como fazer um orçamento para o crescimento. Você descobre o aumento na conta semanas depois, quando recebe o extrato do cartão de crédito.
O LiteLLM programa exatamente o que você gasta com todos os provedores.
Entendendo o uso de tokens
Cada resposta da IA inclui informações detalhadas de uso que mostram exatamente o que você está pagando:
import litellm
from dotenv import load_dotenv
load_dotenv()
messages = [{"role": "user", "content": "Explain what a REST API is in two sentences"}]
response = litellm.completion(
model="gpt-5",
messages=messages
)
print(f"Response: {response.choices[0].message.content}")
print(f"Prompt tokens: {response.usage.prompt_tokens}")
print(f"Completion tokens: {response.usage.completion_tokens}")
print(f"Total tokens: {response.usage.total_tokens}")
Response: A REST API is a web service that follows the Representational State Transfer architectural style, exposing resources identified by URLs and manipulated with HTTP methods like GET, POST, PUT, and DELETE. It uses stateless client-server communication, cacheability, and uniform representations (often JSON) to support scalable, decoupled interactions.
Prompt tokens: 15
Completion tokens: 201
Total tokens: 216
Os tokens de entrada são o seu prompt, os tokens de saída são a resposta da IA. Diferentes provedores cobram taxas diferentes para cada tipo.
Cálculo automático de custos
A contagem bruta de tokens não mostra o valor em dólares. O LiteLLM calcula o custo real para você:
# Get the cost for a completed response
cost = litellm.completion_cost(completion_response=response)
print(f"Total cost: ${cost:.4f}")
Total cost: $0.0020
O banco de dados de preços do LiteLLM transforma tokens em dólares com base no seu modelo.
Cálculos manuais de custos
Às vezes, você quer estimar os custos antes de fazer uma chamada ou calcular os custos de um texto que já tem:
# Calculate cost without making an API call
prompt_text = "Explain machine learning"
completion_text = "Machine learning is a method of data analysis that automates analytical model building."
estimated_cost = litellm.completion_cost(
model="anthropic/claude-sonnet-4-20250514",
prompt=prompt_text,
completion=completion_text
)
print(f"Estimated cost: ${estimated_cost:.4f}")
Estimated cost: $0.0002
Isso é útil para fazer orçamentos e comparar modelos.
Programando várias chamadas de API
Para aplicativos que fazem muitas chamadas de API, você pode programar os custos acumulados:
total_cost = 0.0
conversation = [
"What is Python?",
"How do you install Python packages?",
"What are virtual environments?"
]
for i, question in enumerate(conversation):
response = litellm.completion(
model="gpt-5",
messages=[{"role": "user", "content": question}]
)
call_cost = litellm.completion_cost(completion_response=response)
total_cost += call_cost
print(f"Call {i+1}: ${call_cost:.4f}")
print(f"Total cost: ${total_cost:.4f}")
Call 1: $0.0057
Call 2: $0.0134
Call 3: $0.0102
Total cost: $0.0292
O acompanhamento dos custos ajuda você a tomar decisões informadas sobre quais modelos usar e evitar contas inesperadas. Veja exatamente quanto custa cada chamada de API e compare os fornecedores.
Conclusão
Agora você tem as ferramentas para criar aplicativos de IA sem ficar preso a um único fornecedor. Você aprendeu chamadas básicas de API, fallbacks automáticos, respostas de streaming, saídas estruturadas e acompanhamento de custos.
Isso te dá a liberdade de escolher os melhores modelos para cada tarefa. Troque de provedor facilmente, configure fallbacks automáticos e programa os custos. Quando surgirem modelos melhores, você poderá adotá-los sem precisar reescrever o código.

Sou um criador de conteúdo de ciência de dados com mais de 2 anos de experiência e um dos maiores seguidores no Medium. Gosto de escrever artigos detalhados sobre IA e ML com um estilo um pouco sarcástico, porque você precisa fazer algo para torná-los um pouco menos monótonos. Produzi mais de 130 artigos e um curso DataCamp, e estou preparando outro. Meu conteúdo foi visto por mais de 5 milhões de pessoas, das quais 20 mil se tornaram seguidores no Medium e no LinkedIn.

