| name | litellm |
| description | Call 100+ LLMs through a single OpenAI-compatible interface with LiteLLM — use completion/acompletion/embedding with any provider (Anthropic, OpenAI, Google, Groq, Ollama, etc.), run a proxy server for team rate-limiting and cost tracking, load-balance across providers. |
| triggers | ["litellm","lite llm","unified llm api","llm proxy server","multi provider llm","litellm completion","litellm proxy","llm fallback","llm load balancing","litellm budget","litellm router","openai compatible proxy","switch llm provider"] |
| do_not_use_for | ["Fine-tuning — use llamafactory instead","Agent orchestration — use crewai or langgraph instead","Structured output validation — use pydantic-ai or instructor-structured-output instead"] |
| see_also | ["instructor-structured-output","pydantic-ai","vercel-ai-sdk"] |
LiteLLM — Unified LLM API
Source: BerriAI/litellm (MIT) — call 100+ LLMs with a single OpenAI-compatible interface
Why LiteLLM
- One API for OpenAI, Anthropic, Google, Groq, Mistral, Ollama, AWS Bedrock, Azure, etc.
- OpenAI SDK compatible — drop-in replacement, just change
base_url
- Proxy server — centralize API keys, add rate limits, track costs, log requests
- Router — load balance + fallback across multiple models/providers
Install
pip install litellm
pip install 'litellm[proxy]'
Basic Completion
from litellm import completion
response = completion(
model="claude-sonnet-4-5",
messages=[{"role": "user", "content": "Hello"}],
api_key="your-anthropic-key",
)
response = completion(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}],
)
response = completion(
model="gemini/gemini-2.0-flash",
messages=[{"role": "user", "content": "Hello"}],
)
response = completion(
model="groq/llama-3.1-70b-versatile",
messages=[{"role": "user", "content": "Hello"}],
)
response = completion(
model="ollama/llama3",
messages=[{"role": "user", "content": "Hello"}],
api_base="http://localhost:11434",
)
print(response.choices[0].message.content)
print(response.usage.total_tokens)
Async Completion
import asyncio
from litellm import acompletion
async def main():
response = await acompletion(
model="claude-sonnet-4-5",
messages=[{"role": "user", "content": "Explain quantum computing"}],
)
print(response.choices[0].message.content)
asyncio.run(main())
Streaming
from litellm import completion
response = completion(
model="claude-sonnet-4-5",
messages=[{"role": "user", "content": "Write a poem about AI"}],
stream=True,
)
for chunk in response:
content = chunk.choices[0].delta.content or ""
print(content, end="", flush=True)
Function Calling / Tools
from litellm import completion
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]},
},
"required": ["city"],
},
},
}
]
response = completion(
model="claude-sonnet-4-5",
messages=[{"role": "user", "content": "What's the weather in Tokyo?"}],
tools=tools,
tool_choice="auto",
)
if response.choices[0].finish_reason == "tool_calls":
tool_call = response.choices[0].message.tool_calls[0]
print(tool_call.function.name)
print(tool_call.function.arguments)
Embeddings
from litellm import embedding
resp = embedding(model="text-embedding-3-small", input=["Hello world"])
resp = embedding(model="cohere/embed-english-v3.0", input=["Hello world"])
resp = embedding(model="bedrock/amazon.titan-embed-text-v1", input=["Hello world"])
vectors = resp.data[0]["embedding"]
Router — Load Balancing & Fallbacks
from litellm import Router
router = Router(
model_list=[
{
"model_name": "claude-fast",
"litellm_params": {
"model": "claude-haiku-4-5",
"api_key": "your-key",
},
"tpm": 100_000,
},
{
"model_name": "claude-fast",
"litellm_params": {
"model": "claude-sonnet-4-5",
"api_key": "your-key",
},
},
{
"model_name": "fallback-model",
"litellm_params": {"model": "gpt-4o-mini"},
},
],
fallbacks=[{"claude-fast": ["fallback-model"]}],
routing_strategy="least-busy",
retry_after=5,
num_retries=3,
)
response = router.completion(
model="claude-fast",
messages=[{"role": "user", "content": "Hello"}],
)
Proxy Server
litellm --model claude-sonnet-4-5 --port 8000
litellm --config config.yaml
model_list:
- model_name: claude-fast
litellm_params:
model: claude-haiku-4-5
api_key: os.environ/ANTHROPIC_API_KEY
- model_name: gpt4
litellm_params:
model: gpt-4o
api_key: os.environ/OPENAI_API_KEY
litellm_settings:
drop_params: true
request_timeout: 30
max_budget: 100
router_settings:
routing_strategy: least-busy
num_retries: 3
fallbacks: [{"claude-fast": ["gpt4"]}]
from openai import OpenAI
client = OpenAI(
api_key="anything",
base_url="http://localhost:8000",
)
response = client.chat.completions.create(
model="claude-fast",
messages=[{"role": "user", "content": "Hello"}],
)
Cost Tracking
import litellm
litellm.success_callback = ["langfuse"]
from litellm import completion_cost, model_cost
response = completion(model="claude-sonnet-4-5", messages=[...])
cost = completion_cost(completion_response=response)
print(f"Cost: ${cost:.6f}")
pricing = model_cost["claude-sonnet-4-5"]
print(pricing["input_cost_per_token"], pricing["output_cost_per_token"])
Environment Variable Config
export ANTHROPIC_API_KEY="..."
export OPENAI_API_KEY="..."
export GOOGLE_API_KEY="..."
export GROQ_API_KEY="..."
export LITELLM_LOG="DEBUG"
Drop-In for OpenAI SDK
from openai import OpenAI
client = OpenAI()
response = client.chat.completions.create(model="gpt-4o", messages=[...])
from openai import OpenAI
client = OpenAI(base_url="http://localhost:8000", api_key="fake")
response = client.chat.completions.create(model="claude-sonnet-4-5", messages=[...])
Anti-Fake-Pass Checks