Skip to content

LiteLLM

Write once, call any LLM. LiteLLM gives you a single Python SDK and OpenAI-compatible proxy server that works with 100+ providers — OpenAI, Anthropic, Gemini, Ollama, Azure, AWS Bedrock, and more. Swap models by changing a string, not your code.

Table of Contents

Installation / Setup

pip install litellm                       # or: uv add litellm
import litellm

# set API keys (litellm reads from env by default)
# OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, etc.

Core Syntax

The unified completion API

import litellm

# OpenAI
response = litellm.completion(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
)

# Anthropic
response = litellm.completion(
    model="anthropic/claude-sonnet-4-20250514",
    messages=[{"role": "user", "content": "Hello!"}],
)

# Gemini
response = litellm.completion(
    model="gemini/gemini-2.0-flash",
    messages=[{"role": "user", "content": "Hello!"}],
)

# Ollama (local)
response = litellm.completion(
    model="ollama/llama3.1",
    messages=[{"role": "user", "content": "Hello!"}],
)

# same response format for all — standard OpenAI-style
print(response.choices[0].message.content)

Model naming convention

provider/model-name

openai/gpt-4o
openai/gpt-4o-mini
anthropic/claude-sonnet-4-20250514
anthropic/claude-haiku-4-20250414
gemini/gemini-2.0-flash
gemini/gemini-2.5-pro
ollama/llama3.1
bedrock/anthropic.claude-3-5-sonnet-20241022-v2:0
azure/gpt-4o

Streaming

response = litellm.completion(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "Write a story"}],
    stream=True,
)
for chunk in response:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="", flush=True)

Function calling

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Get weather for a city",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    },
}]

response = litellm.completion(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "Weather in London?"}],
    tools=tools,
)

Cost tracking

import litellm

response = litellm.completion(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
)

# litellm automatically tracks cost
print(response._hidden_params.get("cost"))
print(f"Tokens: {response.usage.prompt_tokens} in, {response.usage.completion_tokens} out")

Common Operations

Available models

Provider Models Prefix
OpenAI GPT-4o, GPT-4o-mini, o3 openai/
Anthropic Claude 3.5, Claude 4 anthropic/
Google Gemini 2.0, 2.5 gemini/
Ollama Llama, Mistral, Qwen ollama/
Azure OpenAI models via Azure azure/
AWS Bedrock Claude, Llama, Mistral bedrock/
Groq Fast inference groq/
Together Open models together/

Model fallbacks

import litellm

# if primary fails, try fallbacks
response = litellm.completion(
    model="openai/gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
    fallbacks=["anthropic/claude-sonnet-4-20250514", "gemini/gemini-2.0-flash"],
)

Router — load balancing across models

from litellm import Router

router = Router(
    model_list=[
        {"model_name": "gpt", "litellm_params": {"model": "openai/gpt-4o", "api_key": "YOUR_API_KEY"}},
        {"model_name": "gpt", "litellm_params": {"model": "openai/gpt-4o-mini", "api_key": "YOUR_API_KEY"}},
    ],
    routing_strategy="simple-shuffle",    # or "least-busy", "latency-based"
)

response = router.completion(
    model="gpt",
    messages=[{"role": "user", "content": "Hello!"}],
)

LiteLLM Proxy Server

# start a proxy server (OpenAI-compatible)
litellm --model openai/gpt-4o --port 4000

# use it like OpenAI
curl http://localhost:4000/v1/chat/completions -d '{
  "model": "gpt-4o",
  "messages": [{"role": "user", "content": "Hello!"}]
}'
# connect to the proxy with any OpenAI SDK
from openai import OpenAI

client = OpenAI(base_url="http://localhost:4000/v1", api_key="any-key")
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Hello!"}],
)

YAML config for the proxy

# config.yaml
model_list:
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY
  - model_name: claude
    litellm_params:
      model: anthropic/claude-sonnet-4-20250514
      api_key: os.environ/ANTHROPIC_API_KEY

litellm_settings:
  drop_params: true                    # drop unsupported params
  num_retries: 3
  fallbacks: [{"gpt-4o": ["claude"]}]  # fallback chain
litellm --config config.yaml --port 4000

Practical Examples

Example 1 — Multi-provider with fallback

import litellm

def ask(question, preferred="openai/gpt-4o"):
    try:
        response = litellm.completion(
            model=preferred,
            messages=[
                {"role": "system", "content": "Be concise."},
                {"role": "user", "content": question},
            ],
            temperature=0.7,
            max_tokens=500,
        )
        return response.choices[0].message.content
    except Exception:
        # fallback to cheaper model
        response = litellm.completion(
            model="openai/gpt-4o-mini",
            messages=[{"role": "user", "content": question}],
            temperature=0.7,
        )
        return response.choices[0].message.content

Example 2 — Compare models side-by-side

import litellm

models = [
    "openai/gpt-4o-mini",
    "anthropic/claude-haiku-4-20250414",
    "gemini/gemini-2.0-flash",
    "ollama/llama3.1",
]

question = "What is 2+2? Explain in one sentence."
for model in models:
    try:
        response = litellm.completion(
            model=model,
            messages=[{"role": "user", "content": question}],
            temperature=0.0,
        )
        cost = getattr(response, "_hidden_params", {}).get("cost", "N/A")
        print(f"{model:40s} | {response.choices[0].message.content[:60]}")
    except Exception as e:
        print(f"{model:40s} | ERROR: {e}")

Example 3 — Proxy server with spending limits

# config.yaml with budget controls
model_list:
  - model_name: gpt-4o
    litellm_params:
      model: openai/gpt-4o
      api_key: os.environ/OPENAI_API_KEY

general_settings:
  master_key: "sk-your-master-key"     # proxy auth

litellm_settings:
  num_retries: 3
  drop_params: true
  success_callback: ["langfuse"]        # log to Langfuse
litellm --config config.yaml --port 4000 --detailed_debug

Common Patterns

Pattern: provider-agnostic code

import litellm
import os

# define model by env var — swap providers by changing env
MODEL = os.getenv("LLM_MODEL", "openai/gpt-4o-mini")

def generate(prompt, system="You are a helpful assistant."):
    response = litellm.completion(
        model=MODEL,
        messages=[
            {"role": "system", "content": system},
            {"role": "user", "content": prompt},
        ],
        temperature=0.7,
    )
    return response.choices[0].message.content

Pattern: batch with cost tracking

import litellm

total_cost = 0
results = []
for text in texts:
    response = litellm.completion(
        model="openai/gpt-4o-mini",
        messages=[{"role": "user", "content": f"Classify: {text}"}],
        temperature=0.0,
    )
    cost = getattr(response, "_hidden_params", {}).get("cost", 0)
    total_cost += cost
    results.append(response.choices[0].message.content)

print(f"Total cost: ${total_cost:.4f}")

Pattern: A/B testing models

import litellm, random

def ab_test(question, model_a="openai/gpt-4o", model_b="anthropic/claude-sonnet-4-20250514"):
    model = random.choice([model_a, model_b])
    response = litellm.completion(
        model=model,
        messages=[{"role": "user", "content": question}],
    )
    return {"model": model, "response": response.choices[0].message.content}

Best Practices

  • Use litellm.completion() instead of provider-specific SDKs — same code, any provider.
  • Always set API keys via environment variables — never hard-code.
  • Use fallbacks for reliability — if one provider is down, try another.
  • The proxy server is great for teams — one endpoint, many providers.
  • cost tracking is automatic — use it to monitor spending.
  • drop_params: true in config prevents errors from unsupported parameters.
  • Use Router for load balancing across multiple instances of the same model.
  • Set max_tokens explicitly — different providers have different defaults.

Common Mistakes

Mistake Fix
Not setting API keys for each provider Each provider needs its own env var (OPENAI_API_KEY, etc.)
Ignoring cost tracking Use response._hidden_params.get("cost") to monitor
Not using fallbacks Add fallbacks for production reliability
Hard-coding model names Use env vars or config files to swap models
Forgetting max_tokens Set it explicitly to avoid surprise truncation
Using the wrong model prefix Always prefix with provider: openai/gpt-4o
Proxy server has no auth Set master_key in config for production

Troubleshooting

Symptom Cause / Fix
AuthenticationError Missing API key for that provider — set the env var
Model not found Check model name and prefix (e.g. openai/gpt-4o)
Unsupported parameter error Add drop_params: true or remove the parameter
High latency Use a faster model or check provider status
Cost unexpectedly high Check token usage; switch to cheaper model
Proxy returns 500 Check proxy logs; usually an auth or model issue
Fallback chain not working Ensure fallback models are valid and keys are set

Official Documentation

Last Updated

2026-09-06 — Initial version.