LiteLLM în Python: Un Singur API pentru Claude, OpenAI și 100+ LLM-uri (2026)

LiteLLM abstrahează 100+ furnizori de LLM într-un singur API compatibil OpenAI. Vezi cum îl integrezi în Python cu fallback automat, load balancing, cost tracking și proxy server pentru echipe.

LiteLLM Python: 100+ LLM-uri, un API (2026)

Actualizat: 18 septembrie 2026

LiteLLM este o bibliotecă Python open-source care traduce apelurile către peste 100 de furnizori de LLM-uri (Claude, OpenAI, Gemini, Bedrock, Vertex AI, Ollama, Groq) într-un singur format compatibil cu API-ul openai.chat.completions. În loc să scrii un client separat pentru fiecare provider, apelezi litellm.completion(model="...", messages=[...]) și schimbi modelul printr-un string. În ghidul ăsta îți arăt cum îl integrez într-un pipeline real, cu fallback automat, router pentru load balancing, tracking de costuri și proxy server pentru echipe.

  • LiteLLM 1.7x expune un singur SDK compatibil cu openai pentru 100+ modele; schimbi providerul printr-un string precum anthropic/claude-sonnet-4-5 sau gemini/gemini-2.5-pro.
  • Funcția completion() este sincronă, acompletion() este async, iar ambele suportă stream=True cu format identic pentru toți providerii.
  • Clasa Router face load balancing între mai multe chei API și adaugă fallback-uri când un model dă rate limit sau eroare tranzitorie.
  • Callback-urile pentru cost și tokens (litellm.success_callback = ["langfuse"]) permit observability fără cod suplimentar în handler.
  • LiteLLM Proxy Server rulează ca serviciu HTTP și centralizează chei, budget-uri și guardrails pentru toată echipa, iar clienții tăi rămân cu SDK-ul OpenAI standard.

Ce este LiteLLM și când merită folosit

LiteLLM (proiect BerriAI, licență MIT) rezolvă o problemă mică, dar enervantă: fiecare furnizor de LLM are propriul SDK, propriile chei, propriile formate de răspuns și propriile particularități la streaming. Când vrei să compari două modele pe același prompt, ajungi să scrii două integrări. Când vrei fallback de la Claude la GPT-4o pentru că Anthropic a returnat 529, ajungi să scrii orchestrare manuală. LiteLLM abstractizează exact acest strat.

Din experiența mea de „recovering ops engineer", merită introdus în trei situații concrete: (1) trebuie să evaluezi mai multe modele pe același dataset fără să dublezi codul, (2) construiești un serviciu multi-tenant care oferă „LLM as a feature" și vrei să comuți providerul fără să atingi codul aplicației, (3) ai nevoie de failover între providere pentru SLA. Dacă folosești un singur model, cu un singur cont, fără cerințe de failover, SDK-ul oficial e suficient. LiteLLM adaugă complexitate care nu se plătește.

Piesa cheie e că formatul de răspuns este identic cu openai.chat.completions. Dacă mâine adaugi un model Bedrock, codul din aval (parserul de răspuns, structured outputs, function calling) nu se schimbă. Complementar, când vrei să reduci facturile pentru mesaje repetitive, urmărește ghidul nostru despre prompt caching cu Claude și OpenAI. LiteLLM propagă header-ele de caching către provider fără intervenție manuală.

Instalare și primul apel unificat

Instalarea e standard, dar îți recomand să fixezi versiunea în producție. LiteLLM iterează rapid și API-ul de router s-a schimbat între minor releases. La momentul scrierii, versiunea stabilă este 1.75.x.

pip install "litellm==1.75.*" python-dotenv

Cheia sub care se aleargă modelul se ia din variabile de mediu specifice fiecărui provider: OPENAI_API_KEY, ANTHROPIC_API_KEY, GEMINI_API_KEY, GROQ_API_KEY etc. LiteLLM le citește automat, așa că nu trebuie să le pasezi manual la fiecare apel.

import os
from dotenv import load_dotenv
from litellm import completion

load_dotenv()  # încarcă OPENAI_API_KEY și ANTHROPIC_API_KEY din .env

messages = [
    {"role": "system", "content": "Ești un asistent tehnic concis."},
    {"role": "user", "content": "Rezumă în 2 propoziții ce face LiteLLM."},
]

# Același apel, doi provideri diferiți: schimbi doar stringul de model.
gpt = completion(model="openai/gpt-4o-mini", messages=messages, temperature=0.2)
claude = completion(model="anthropic/claude-haiku-4-5", messages=messages, temperature=0.2)

print("GPT:", gpt.choices[0].message.content)
print("Claude:", claude.choices[0].message.content)
print("Cost GPT (USD):", gpt._hidden_params["response_cost"])

Trei detalii care contează: prefixul openai/ sau anthropic/ e opțional pentru modele „canonice", dar te scutește de ambiguități când adaugi Bedrock (care are propriile ID-uri pentru Claude). Apoi, response_cost apare deja calculat în _hidden_params pe baza tabelei interne de prețuri. Și choices[0].message.content funcționează identic indiferent de provider.

Ce furnizori LLM suportă LiteLLM

La 100+ integrări active, o listă completă e inutilă, dar categoriile mari și modul de identificare al modelului sunt lucrurile utile în practică. Tabelul de mai jos rezumă providerii pe care îi întâlnesc cel mai des în workflow-uri reale.

CategorieExemple de string de modelVariabile de mediuNote
OpenAI / Azureopenai/gpt-4o, azure/deployment-nameOPENAI_API_KEY, AZURE_API_BASEAzure cere și api_version.
Anthropic directanthropic/claude-sonnet-4-5ANTHROPIC_API_KEYSuportă prompt caching prin flag-uri.
Googlegemini/gemini-2.5-pro, vertex_ai/gemini-2.5-flashGEMINI_API_KEY sau credentials JSONVertex AI trece prin ADC.
AWS Bedrockbedrock/anthropic.claude-sonnet-4-5-v1:0AWS credentials + AWS_REGIONBun pentru compliance/VPC.
Groq / together / Fireworksgroq/llama-3.3-70b, together_ai/...Cheia provideruluiLatență foarte mică (Groq).
Local (Ollama, vLLM)ollama/llama3.1, openai/<model> + api_baseIdeal pentru dev fără cost.

Sursa oficială pentru string-urile exacte și feature-urile pe provider este lista de providers din documentația LiteLLM, actualizată aproape zilnic. Îți recomand să o verifici înainte să adaugi un provider nou. De exemplu, function calling și structured outputs nu sunt suportate uniform, iar poți vedea codul sursă direct în repo-ul BerriAI/litellm de pe GitHub dacă vrei să înțelegi cum se face translația între providere.

Streaming și apeluri async

Când construiesc UI-uri care afișează token cu token, folosesc acompletion() cu stream=True. Formatul chunk-urilor imită SSE-ul de la OpenAI, așa că același parser funcționează pentru Claude, Gemini sau Groq. Câmpul relevant este chunk.choices[0].delta.content, care poate fi None la primul chunk (rol) și la ultimul (finish reason), deci verificarea e obligatorie.

import asyncio
from litellm import acompletion

async def stream_answer(model: str, prompt: str) -> str:
    buffer = []
    response = await acompletion(
        model=model,
        messages=[{"role": "user", "content": prompt}],
        stream=True,
        max_tokens=400,
    )
    async for chunk in response:
        piece = chunk.choices[0].delta.content
        if piece:
            buffer.append(piece)
            print(piece, end="", flush=True)
    return "".join(buffer)

asyncio.run(stream_answer(
    "anthropic/claude-sonnet-4-5",
    "Explică diferența dintre RAG și fine-tuning în 3 fraze.",
))

Un lucru care mă prinde des pe picior greșit: pe Gemini, chunk-urile pot conține blocuri mari deodată (Gemini flush-uiește pe propoziție, nu pe token), deci UI-ul poate să pară „stroboscopic". Nu e un bug LiteLLM, e comportament nativ. Dacă vrei o experiență granulară uniformă, plafonează dimensiunea chunk-ului în UI printr-un scheduler propriu, nu forța din LiteLLM.

Router: load balancing între chei și modele

Când ai două chei OpenAI (una pe „org A", una pe „org B") sau vrei să distribui traficul între GPT-4o și un Llama pe Groq în funcție de latență, folosești Router. Fiecare intrare este un model deployment, adică un mapping între un nume logic și un provider concret cu cheia lui.

from litellm import Router

router = Router(
    model_list=[
        {
            "model_name": "chat-fast",  # nume logic
            "litellm_params": {
                "model": "groq/llama-3.3-70b-versatile",
                "api_key": os.environ["GROQ_API_KEY"],
                "rpm": 30,   # rate limit local (opțional)
            },
        },
        {
            "model_name": "chat-fast",
            "litellm_params": {
                "model": "openai/gpt-4o-mini",
                "api_key": os.environ["OPENAI_API_KEY"],
                "rpm": 500,
            },
        },
    ],
    routing_strategy="simple-shuffle",  # sau "least-busy", "latency-based-routing"
)

resp = router.completion(
    model="chat-fast",
    messages=[{"role": "user", "content": "Salut!"}],
)
print(resp.choices[0].message.content)

Strategiile disponibile (simple-shuffle, least-busy, usage-based-routing-v2, latency-based-routing) sunt utile în ordine crescătoare a complexității. Pentru trafic mic pornesc cu simple-shuffle. Când începi să vezi rate limits (429), treci pe usage-based-routing-v2, care ține evidența token-urilor per minut per deployment.

Fallback-uri și retry între providere

Ăsta e feature-ul care mi-a salvat cel mai des noaptea. Când Anthropic dă 529 („overloaded") sau OpenAI cade pentru 4 minute, vrei ca cererea să treacă automat la alt provider. LiteLLM permite fallback-uri la nivel de router și retry-uri exponențiale cu jitter.

router = Router(
    model_list=[
        {"model_name": "primary", "litellm_params": {"model": "anthropic/claude-sonnet-4-5"}},
        {"model_name": "backup",  "litellm_params": {"model": "openai/gpt-4o"}},
    ],
    fallbacks=[{"primary": ["backup"]}],   # dacă „primary" eșuează, încearcă „backup"
    num_retries=2,                          # 2 retry-uri pe fiecare deployment
    retry_after=2,                          # backoff de bază în secunde
    allowed_fails=3,                        # circuit breaker: după 3 fail-uri, deployment-ul e „cooldown"
    cooldown_time=30,
)

try:
    r = router.completion(
        model="primary",
        messages=[{"role": "user", "content": "test failover"}],
    )
except Exception as e:
    # ambele providere au eșuat definitiv
    print("Eșec total:", e)

Trei recomandări din experiență. Nu seta num_retries mai mare de 2 pe deployment (multiplicat cu fallback, ajungi la 6-8 apeluri per cerere și poți amplifica un incident). Folosește allowed_fails plus cooldown_time ca circuit breaker, altfel trimiți trafic într-un provider degradat. Și logează întotdeauna hop-urile de fallback, pentru că altfel debugging-ul devine ghicit. Pentru un cadru mai defensiv la nivel de payload, articolul despre guardrails pentru agenți AI în Python arată cum să oprești răspunsurile toxice sau off-topic înainte să iasă în UI.

Cost tracking și observability

Fiecare răspuns include _hidden_params["response_cost"], un float în USD calculat pe baza tabelei interne de prețuri din LiteLLM. Pentru o vizualizare centralizată, LiteLLM emite callback-uri către Langfuse, Helicone, Datadog, S3 și fișiere JSON.

import litellm

litellm.success_callback = ["langfuse"]  # emite trace-uri automat
litellm.failure_callback = ["langfuse"]

# Configurabile prin env:
# LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, LANGFUSE_HOST

resp = litellm.completion(
    model="anthropic/claude-sonnet-4-5",
    messages=[{"role": "user", "content": "Explică vector search."}],
    metadata={"trace_name": "explain-vector-search", "user_id": "u_42"},
)
print("Cost:", resp._hidden_params["response_cost"])

Când construiesc pipeline-uri de evaluare (să spunem, rulând același prompt pe 5 modele), folosesc un callback custom care scrie într-un CSV: model, tokens_in, tokens_out, cost, latency. Așa pot decide pe date reale dacă merită să înlocuiesc GPT-4o cu Claude Haiku 4.5 pentru un anumit workload. Am pățit-o cu un client care avea 40% din trafic pe un model scump degeaba; datele din CSV au fost suficient argument. Pentru evaluări structurate ale calității răspunsurilor (nu doar cost), am scris separat despre evaluarea agenților AI cu DeepEval, care se combină natural cu callback-urile din LiteLLM.

LiteLLM Proxy Server pentru echipe

Când mai mult de 2-3 developeri lovesc aceleași modele, îmi mut logica în LiteLLM Proxy Server. Rulează ca un serviciu HTTP (compatibil cu API-ul OpenAI) și centralizează cheile, budget-urile, rate-limit-urile per user, guardrails și logging. Aplicațiile client rămân cu SDK-ul OpenAI standard, doar cu base_url îndreptat spre proxy.

# config.yaml
model_list:
  - model_name: chat-cheap
    litellm_params:
      model: openai/gpt-4o-mini
      api_key: os.environ/OPENAI_API_KEY
  - model_name: chat-smart
    litellm_params:
      model: anthropic/claude-sonnet-4-5
      api_key: os.environ/ANTHROPIC_API_KEY

router_settings:
  routing_strategy: usage-based-routing-v2
  fallbacks:
    - chat-smart: ["chat-cheap"]

general_settings:
  master_key: sk-master-xxx
  database_url: postgres://litellm:pass@db:5432/litellm
# pornire
litellm --config config.yaml --port 4000

# apel din client, cu SDK OpenAI standard:
from openai import OpenAI
client = OpenAI(base_url="http://localhost:4000", api_key="sk-team-alpha")
r = client.chat.completions.create(
    model="chat-smart",
    messages=[{"role": "user", "content": "salut"}],
)

Câștigul real e că poți emite chei virtuale per echipă (sk-team-alpha), setezi max_budget: 20 USD/lună pe fiecare și blochezi automat abuzul. Documentația oficială pentru configurare avansată este la LiteLLM Proxy Quick Start. Merită citită înainte să deployezi în producție.

LiteLLM vs LangChain: când alegi ce

Este o întrebare pe care o primesc săptămânal. Răspunsul scurt: LiteLLM este un abstraction layer peste API-uri de LLM, iar LangChain este un framework pentru orchestrare de agenți și chains. Nu concurează direct; ba chiar LangChain folosește LiteLLM în spate în unele integrări.

AspectLiteLLMLangChain
Scop principalUn singur API pentru 100+ modeleOrchestrare de chains, agenți, tools
Suprafață APIMică: completion(), Router, callbacksMare: LCEL, agents, retrievers, tools, memory
Learning curveOreZile-săptămâni
Overhead runtimeMinim (thin wrapper)Semnificativ pe chains complexe
Fallback / load balancingNativ (Router)Prin cod custom sau LangSmith
Când îl alegiVrei portabilitate între provideriVrei orchestrare declarativă

În practică, le combin: LiteLLM face apelul de model (cu fallback plus cost tracking), iar LangChain sau LangGraph construiesc grafuri de decizii deasupra. Când vezi un tutorial care importă from langchain_openai import ChatOpenAI și tu ai nevoie de 3 provideri diferiți, îl înlocuiești cu ChatLiteLLM și continui.

Greșeli comune și cum le eviți

Am adunat cinci greșeli care apar la echipele care adoptă LiteLLM pentru prima dată. Le pun în ordinea în care mușcă cel mai tare.

  1. Chei pierdute în cod. Nu pasa api_key literal în cod versionat. Folosește os.environ sau, pentru proxy, sintaxa api_key: os.environ/OPENAI_API_KEY în YAML.
  2. Fallback fără logging. Dacă nu emiți un event când happen fallback-ul, n-o să știi niciodată că providerul primar era jos 4 ore. Setează un callback pe failure_callback și trimite un warning în Slack/Sentry.
  3. Retry-uri agresive care amplifică incidente. Cu num_retries=5 pe 3 deployment-uri ajungi la 15 apeluri per cerere pentru o singură eroare. Pornește de la 1-2 și crește doar dacă e nevoie.
  4. Prețuri incorecte după update. Vezi callout-ul din secțiunea de cost tracking. Pin la versiune și verifică litellm.model_cost după fiecare upgrade.
  5. Formate diferite la function calling. Deși completion e uniform, tool calling are subtilități între provideri (Claude cere tool_choice într-un format ușor diferit de OpenAI). Testează pe fiecare provider înainte de producție.

Întrebări frecvente

Este LiteLLM gratuit?

Da. Biblioteca Python și serverul Proxy sunt open-source sub licență MIT. BerriAI (compania din spate) oferă și o versiune Enterprise cu SSO, audit logs și support, dar pentru majoritatea echipelor versiunea gratuită acoperă tot ce ai nevoie inclusiv în producție.

Cum apelezi Claude prin LiteLLM?

Setezi ANTHROPIC_API_KEY și apelezi litellm.completion(model="anthropic/claude-sonnet-4-5", messages=[...]). Formatul răspunsului e identic cu OpenAI, deci resp.choices[0].message.content funcționează la fel. Pentru Bedrock, folosești bedrock/anthropic.claude-sonnet-4-5-v1:0 cu credentials AWS.

Ce diferență e între LiteLLM SDK și LiteLLM Proxy?

SDK-ul este o bibliotecă pe care o importezi în aplicația ta Python. Proxy-ul este un serviciu HTTP separat (deploy-uit ca container) care expune un API compatibil OpenAI și centralizează chei, budget-uri și logging pentru toată echipa. Poți folosi SDK direct sau prin proxy; proxy-ul devine util când mai mulți developeri sau microservicii lovesc aceleași modele.

Suportă LiteLLM streaming și async?

Da, ambele. Folosești litellm.completion(..., stream=True) pentru sync sau litellm.acompletion(..., stream=True) pentru async. Chunk-urile respectă formatul SSE al OpenAI, ceea ce înseamnă că același cod de parsare funcționează pentru Claude, Gemini, Groq și restul provider-ilor suportați.

Cum urmăresc costurile LLM cu LiteLLM?

Fiecare răspuns are _hidden_params["response_cost"], un float USD calculat automat. Pentru dashboarding centralizat, activezi callback-uri: litellm.success_callback = ["langfuse"] trimite trace-urile în Langfuse, iar Proxy Server-ul agregă costurile per cheie virtuală și le expune în UI.

Emma Bergstrom
Despre Autor Emma Bergstrom

Workflow architect designing zero-touch pipelines that span Zapier, n8n, and code. Calls herself a recovering ops engineer.