LiteLLM proxy u 2026: Produkcijski LLM gateway s usmjeravanjem, fallback-ovima i budžetima

Praktični vodič kroz postavljanje LiteLLM proxyja kao produkcijskog LLM gatewaya: Docker setup, model groupovi, fallback strategije, virtualni ključevi s budžetima, opservabilnost i semantic caching.

LiteLLM Proxy: LLM Gateway Vodič (2026)

Ažurirano: 20. lipnja 2026.

LiteLLM proxy je open-source LLM gateway koji prevodi pozive iz OpenAI formata u 100+ različitih provajdera (Anthropic, Bedrock, Vertex, Azure, Groq, lokalni vLLM) i centralizira ono što vam u produkciji stvarno treba: routing prema cijeni i latenciji, automatski fallback kad provajder padne, virtualne ključeve po timu, hard budžete i jedinstvene logove. Postavlja se kao Docker kontejner ili Kubernetes deployment, koristi YAML konfiguraciju za modele i Postgres za stanje, a klijenti i dalje koriste običan openai SDK, samo s drugim base_url-om.

  • LiteLLM proxy izlaže OpenAI-kompatibilan /v1/chat/completions endpoint koji rutira na 100+ provajdera bez promjene koda u aplikaciji.
  • Definirate model groupove u config.yaml, a LiteLLM automatski balansira između deploymenata po latenciji, RPM-u ili usage-based shuffleu.
  • Fallback liste se podešavaju na razini grupe. Ako Anthropic padne, sljedeći zahtjev ide na Bedrock Claude bez korisničkog retryja.
  • Virtualni ključevi (sk-...) imaju vlastite budžete, rate limite i listu dopuštenih modela. Idealni su za izolaciju timova i klijenata.
  • Integracija s Langfuse, OpenTelemetry i Prometheus radi out-of-the-box. Jedan callback, i imate per-key trošak, p95 latenciju i error rate po modelu.
  • Verzija 1.74+ donosi semantic caching preko Redisa, što za FAQ-tipske workloadove obara troškove dodatnih 20–40% iznad osnovnog prompt cachinga.

Što je LiteLLM proxy i kada ga koristiti?

LiteLLM proxy je samostalni server koji predstavlja OpenAI-kompatibilan API iznad bilo kojeg LLM provajdera. Aplikacija pošalje obični POST /v1/chat/completions s modelom gpt-4o ili claude-sonnet-4-6, a proxy razrješi gdje taj poziv stvarno ide: direktni OpenAI, Azure OpenAI deployment, Anthropic Messages API, Bedrock Converse, Vertex, lokalni vLLM endpoint, što god ste konfigurirali u config.yaml. Ovo brisanje granice između provajdera je razlog zašto je gateway pattern u 2026. postao default za svaku ozbiljniju LLM aplikaciju.

U svom radu sam vidjela tri jasna trenutka kad tim prelazi s direktnih SDK poziva na proxy. Prvi, drugi provajder ulazi u arhitekturu i copy-paste retry logike postaje neodrživ. Drugi, finance traži per-team alokaciju troškova. Treći, prvi incident u kojem je jedan provajder pao na 40 minuta i nije bilo automatskog routinga na backup. Honestly, sve tri stvari LiteLLM rješava u konfiguraciji, ne u kodu, i to je ono što gateway čini infrastrukturom, a ne bibliotekom.

Treba razlikovati LiteLLM SDK (Python paket litellm koji se importa u kod) od LiteLLM proxyja (samostalni server). SDK je koristan za skripte i prototipove; proxy je ono što ide u Kubernetes. U produkciji uvijek koristim proxy, jer želim da se konfiguracija modela mijenja bez deploymenta aplikacije.

Postavljanje LiteLLM proxyja s Dockerom i Postgresom

Minimalni produkcijski setup je Docker Compose s LiteLLM kontejnerom i Postgres bazom za perzistenciju ključeva, budžeta i logova. Slijedi konfiguracija koja radi out-of-the-box. Kopirate, podesite tri tajne i imate gateway u zraku za pet minuta. Verzija slike koju koristim na novim deploymentima je ghcr.io/berriai/litellm:v1.74-stable, jer main-latest tag ponekad pokupi breaking changeove (u prošlom projektu sam tako izgubila pola popodneva tražeći zašto fallback rutiranje odjednom ne radi).

# docker-compose.yml
services:
  litellm:
    image: ghcr.io/berriai/litellm:v1.74-stable
    ports:
      - "4000:4000"
    environment:
      DATABASE_URL: postgresql://litellm:${POSTGRES_PASSWORD}@db:5432/litellm
      LITELLM_MASTER_KEY: ${LITELLM_MASTER_KEY}    # mora počinjati sa sk-
      LITELLM_SALT_KEY: ${LITELLM_SALT_KEY}        # za enkripciju ključeva u bazi
      OPENAI_API_KEY: ${OPENAI_API_KEY}
      ANTHROPIC_API_KEY: ${ANTHROPIC_API_KEY}
      AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
      AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
      AWS_REGION_NAME: eu-central-1
    volumes:
      - ./config.yaml:/app/config.yaml:ro
    command: --config /app/config.yaml --port 4000 --num_workers 4
    depends_on:
      db:
        condition: service_healthy

  db:
    image: postgres:16-alpine
    environment:
      POSTGRES_USER: litellm
      POSTGRES_DB: litellm
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - pg_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U litellm"]
      interval: 5s
      timeout: 5s
      retries: 10

volumes:
  pg_data:

Provajderski API ključevi se prosljeđuju kroz environment varijable, jer ih LiteLLM resolva u runtimeu. Referencirate ih u config.yaml sa sintaksom os.environ/OPENAI_API_KEY i nikad ne završavaju zapisani u plain textu. Master key je root credential proxyja. Čuvajte ga u sekret store-u (Vault, AWS Secrets Manager, SOPS) i nikad ga ne distribuirajte aplikacijama. Aplikacije dobivaju virtualne ključeve, a ne master key.

Konfiguracija model groupova i routing strategija

Srce LiteLLM-a je config.yaml. U njemu se model imena (ono što aplikacija šalje) mapiraju na jedan ili više stvarnih deploymenata. Kad više deploymenata dijeli isto ime, dobivate model group, odnosno kandidate između kojih proxy bira po definiranoj strategiji. Ovo je primarni mehanizam za load balancing i regional failover.

# config.yaml
model_list:
  # Group "smart" - koristi Anthropic primarno, Bedrock kao kapacitet
  - model_name: smart
    litellm_params:
      model: anthropic/claude-sonnet-4-6
      api_key: os.environ/ANTHROPIC_API_KEY
      rpm: 4000
    model_info:
      input_cost_per_token: 0.000003
      output_cost_per_token: 0.000015

  - model_name: smart
    litellm_params:
      model: bedrock/anthropic.claude-sonnet-4-6-v1:0
      aws_region_name: eu-central-1
      rpm: 2000

  # Group "fast" - Haiku za jeftine batch poslove
  - model_name: fast
    litellm_params:
      model: anthropic/claude-haiku-4-5-20251001
      api_key: os.environ/ANTHROPIC_API_KEY

  # Group "embed"
  - model_name: embed
    litellm_params:
      model: openai/text-embedding-3-small
      api_key: os.environ/OPENAI_API_KEY

router_settings:
  routing_strategy: usage-based-routing-v2   # gleda RPM/TPM headroom
  num_retries: 2
  timeout: 30
  redis_host: redis
  redis_port: 6379

general_settings:
  master_key: os.environ/LITELLM_MASTER_KEY
  database_url: os.environ/DATABASE_URL

U produkciji preporučujem usage-based-routing-v2, jer gleda preostali RPM/TPM headroom na svakom deploymentu prije nego donese odluku. Kvotni 429-ovi tako praktički nestaju. Alternative koje vrijedi znati: simple-shuffle (uniform random), least-busy (gleda broj otvorenih connectiona) i latency-based-routing (rutira na deployment s najnižim trenutnim p95-om). Redis je potreban za sve strategije koje dijele stanje između proxy workera. Bez njega svaki worker proces donosi svoju odluku i load balancing degradira. Više o samim strategijama imate u službenoj router dokumentaciji.

Ako ste već prošli kroz prompt caching u Claude API-ju 2026., znate koliko cache miss košta. LiteLLM automatski prosljeđuje cache_control blokove kroz proxy do Anthropica i bilježi cache hit ratio u svoj log, što vam daje per-team metriku iskorištenja cachea.

Fallback strategije i obrada provajderskih grešaka

Fallback je razlog zašto većina ozbiljnih timova uopće prelazi na gateway. Pravilo iz iskustva: retry pokušava isti deployment ponovo (mreža je flapnula), a fallback ide na drugi model ili provajdera (provajder ne radi). LiteLLM razlikuje oboje i konfigurira ih odvojeno.

# Dodajte u router_settings
router_settings:
  routing_strategy: usage-based-routing-v2
  num_retries: 2
  retry_after: 5
  allowed_fails: 3
  cooldown_time: 60
  fallbacks:
    - smart: ["smart-bedrock", "smart-openai"]
    - fast: ["fast-openai"]
  context_window_fallbacks:
    - smart: ["smart-200k"]   # za pozive koji prelaze context limit
  content_policy_fallbacks:
    - smart: ["smart-openai"] # kad Anthropic odbije zbog content policyja

Tri vrste fallbacka koje LiteLLM razlikuje su semantički različite. Generički fallbacks pokreće se na 5xx greške, timeoute i rate limite. context_window_fallbacks hvata ContextWindowExceededError i šalje zahtjev na model s većim contextom. Koristim ovo da Sonnet pošaljem na model s 1M tokena umjesto da aplikacija dobije 400 grešku. content_policy_fallbacks pokreće se kad jedan provajder odbije content (npr. Anthropic safety), ali drugi bi prošao. Ovu opciju koristite oprezno i samo gdje business case to opravdava.

Virtualni ključevi, timovi i hard budžeti

Virtualni ključevi su način da aplikacije dobiju vlastiti sk-... credential bez pristupa stvarnim provajderskim ključevima. Svaki virtualni ključ ima vlastiti budžet, rate limite, listu dopuštenih modela i metadata tagove za billing. Generiraju se preko /key/generate endpointa ili kroz Admin UI.

# Python: generiranje virtualnog ključa za "rag-tim"
import httpx

PROXY = "http://litellm:4000"
MASTER = "sk-..."   # samo platforma tim ovo ima

resp = httpx.post(
    f"{PROXY}/key/generate",
    headers={"Authorization": f"Bearer {MASTER}"},
    json={
        "key_alias": "rag-tim-prod",
        "models": ["smart", "fast", "embed"],
        "max_budget": 500.00,            # tvrdi limit u USD
        "budget_duration": "30d",        # resetira se mjesečno
        "tpm_limit": 200000,             # tokens per minute
        "rpm_limit": 500,                # requests per minute
        "metadata": {"team": "rag", "env": "prod"},
    },
    timeout=10,
)
new_key = resp.json()["key"]
print(new_key)   # sk-... dajte ovo aplikaciji

Kad ključ prijeđe max_budget, proxy vraća BudgetExceededError sa 429 statusom i zahtjevi se zaustavljaju do isteka budget_duration. Ovo je hard limit. Nije alert, nije warning, doslovno blokira pozive. Za softer kontrolu koristite soft_budget, koji okida webhook umjesto blokade. U svom radu imam pravilo: production ključevi imaju samo soft budget s alertom na PagerDuty, dok staging ključevi imaju hard budget, jer ne želim da pijani deploy nekog test cikla podzemno potroši mjesečni budžet (jednom sam preko noći skupila $1200 u stagingu zbog beskonačne petlje koja je zvala model svake sekunde).

Timovi (/team/new) su sloj iznad ključeva. Više ključeva može pripadati istom timu i budžet se može aggregateati. Korisno za organizacije s 10+ aplikacija gdje finance želi jednu fakturu po timu, a ne po aplikaciji.

Opservabilnost: Langfuse, Prometheus i strukturirani logovi

Bez opservabilnosti gateway je samo crna kutija s nizom YAML pravila. Tri stvari koje uvijek konfiguriram dan jedan su Langfuse za trace-level uvid u svaki poziv, Prometheus za time-series metrike i strukturirani JSON log u stdout za agregaciju u Lokiju ili Datadogu.

# Proširenje general_settings u config.yaml
litellm_settings:
  success_callback: ["langfuse", "prometheus"]
  failure_callback: ["langfuse", "prometheus"]
  json_logs: true

environment_variables:
  LANGFUSE_PUBLIC_KEY: os.environ/LANGFUSE_PUBLIC_KEY
  LANGFUSE_SECRET_KEY: os.environ/LANGFUSE_SECRET_KEY
  LANGFUSE_HOST: https://cloud.langfuse.com

Prometheus endpoint je dostupan na /metrics i izlaže litellm_requests_total, litellm_request_duration_seconds, litellm_spend_metric i još tridesetak metrika sa labelima model, team, key_alias i status_code. Iz tih labela napravite Grafana dashboard sa per-team troškom, per-model p95 latencijom i fallback rate-om. Sve stvari koje vam trebaju kad netko dođe i kaže "skupo je, ne znam zašto".

Langfuse pruža trace-level perspektivu. Vidite cijeli prompt, response, latenciju i trošak za svaki poziv. Detaljnije sam ovo pokrila u tekstu o eval cjevovodima s DeepEval, RAGAS i Langfuseom. Ovdje samo napominjem da kad oboje teku kroz isti gateway, debugging incidentnog poziva traje minute umjesto sati. Za referentnu dokumentaciju callbackova pogledajte LiteLLM logging dokumentaciju.

Semantic caching s Redisom za dodatne uštede

Od verzije 1.74 LiteLLM ima ugrađen semantic cache koji embeddira upit i koristi Redis vector search da pronađe semantički slične prošle pozive. Za workloadove gdje se ista pitanja vraćaju u različitim parafrazama (interni FAQ chatbotovi, podrška, dokumentacijski asistenti) hit ratio može biti 30-50%, što direktno briše toliki postotak troška.

litellm_settings:
  cache: true
  cache_params:
    type: redis-semantic
    host: redis
    port: 6379
    similarity_threshold: 0.92
    ttl: 86400
    redis_semantic_cache_embedding_model: embed

Threshold od 0.92 je konzervativan i to je razlog zašto ga koristim u produkciji. Ide na sigurniju stranu false negativea (cache miss kad bismo mogli pogoditi) prije nego false positivea (vraćamo krivi odgovor). Za niskorizične workloadove kao FAQ search možete spustiti na 0.88, ali za sve što ulazi u customer-facing kanal držite se 0.92+. Cache key uvijek uključuje virtualni ključ, tako da timovi ne dijele cache. To bi bilo i security i privacy issue.

LiteLLM proxy vs OpenRouter vs Portkey

Tri alata se najčešće dovode u istu rečenicu, ali rješavaju različite probleme. OpenRouter je hosted aggregator. Ne hostate ništa, ali plaćate markup i nemate kontrolu nad routing pravilima. Portkey je hosted gateway s naprednim AI guardrails featureima. LiteLLM proxy je self-hosted i open-source, najfleksibilniji, ali zahtijeva da vi vodite infrastrukturu.

KarakteristikaLiteLLM proxyOpenRouterPortkey
Model deploymentaSelf-hosted (Docker/K8s)Hosted (SaaS)Hosted ili self-hosted (Enterprise)
CijenaBesplatno + infraMarkup ~5% iznad provajderaFree tier + paid plans
Broj podržanih modela100+300+200+
Custom routing pravilaDa, YAML i Python hooksOgraničenoDa, kroz UI
Virtualni ključevi i budžetiDa, ugrađenoDaDa
Semantic cacheDa (Redis)NeDa
Data ostaje na vašoj infrastrukturiDaNeSamo Enterprise
Najprikladnije zaRegulirane industrije, kontrola troškovaBrzi prototipi, hobi projektiTimovi koji ne žele DevOps

U svom radu LiteLLM biram kad postoji compliance zahtjev (financije, zdravstvo, podaci ne smiju van EU) ili kad očekivani spend prelazi $5k mjesečno. Markup OpenRoutera u tom trenutku počinje smetati. Za interni prototip ili weekend projekt OpenRouter je brži start. Portkey je razuman izbor za timove koji žele hosted, ali sa enterprise featureima i guardrailsima. Detaljne specifikacije proxyja nalaze se u službenoj dokumentaciji, a izvorni kod je dostupan na GitHubu.

Produkcijski checklist prije puštanja u promet

Sljedeća lista je destilat svega što sam zaboravila ili krivo postavila prvi put i što sada radim po reduku. Ako sve odgovorite s "da", proxy je spreman za produkcijski traffic.

  1. Master key u sekret storeu, Vault, AWS Secrets Manager ili SOPS. Nikad u Git repou, nikad u environment fileu na disku bez enkripcije.
  2. SALT key generiran jednom i backupiran. Gubitak znači rotaciju svih virtualnih ključeva i prekid usluge.
  3. Postgres ima backupe i replication. Ako baza ode, izgubili ste sve ključeve, budžete i logove.
  4. Redis je odvojen od proxyja. Ne dijelite Redis s drugim aplikacijama, jer cache trash ide u istu memoriju.
  5. Fallback liste su testirane chaos testom. Privremeno blokirajte primarni provajder na firewall razini i potvrdite da requests teku kroz fallback bez korisničkog impacta.
  6. Prometheus alerting za budžete i error rate. Alert na 80% budgeta, alert na >1% 5xx rate u 5-minutnom prozoru.
  7. Health check endpoint /health u load balancer probesu. Proxy zna javiti je li Postgres dostupan i jesu li ključni provajderi reachable.
  8. Rate limit na razini ingressa. Defense in depth: virtualni ključevi imaju svoje limite, ali ingress limit štiti od DDoS-a.
  9. Dokumentirana procedura rotacije virtualnih ključeva. Kome dajete novi sk-... kad current procuri, kako revokirate stari, kako mjerite blast radius.
  10. Verzija proxyja je pinned. Koristite konkretan stable tag, nikad main-latest. Upgrade ide kroz staging prvo.

S ovih deset stavki imate produkcijski LLM gateway koji preživljava provajderske outage-e, drži troškove pod kontrolom po timu i daje vam jedinstveni audit log za sve LLM pozive u organizaciji. To je razlog zašto u 2026. niti jedan ozbiljan multi-LLM projekt više ne ide bez ovog sloja.

Često postavljana pitanja

Koja je razlika između LiteLLM SDK-a i LiteLLM proxyja?

SDK je Python paket litellm koji se importa u kod aplikacije i prevodi pozive lokalno. Proxy je samostalni server koji se deploya kao Docker kontejner i izlaže OpenAI-kompatibilan REST API. Proxy ima dodatne featureove (virtualni ključevi, budžeti, Admin UI, semantic cache) koje SDK nema i preporučuje se za sve produkcijske upotrebe.

Može li LiteLLM proxy raditi bez Postgres baze?

Može, ali u in-memory modu se gube virtualni ključevi, budžeti i spend tracking pri svakom restartu. Bez Postgresa proxy se ponaša kao thin routing layer. Za bilo što ozbiljnije od demo setupa Postgres je obavezan.

Kako pratiti trošak po korisniku kad više korisnika dijeli istu aplikaciju?

Šaljite user field u headeru x-litellm-user-id ili u request bodyju. LiteLLM bilježi spend per user u Postgresu i izlaže ga kroz /spend/users endpoint i Prometheus metrike. Možete kombinirati sa virtualnim ključem po timu i dobiti hijerarhijski view (tim, korisnik, poziv).

Podržava li LiteLLM streaming odgovore?

Da, server-sent events streaming radi out-of-the-box za sve podržane provajdere. Klijent šalje stream: true u zahtjevu i proxy prosljeđuje SSE tokove kroz, normalizirajući formate (Anthropic content_block_delta, OpenAI delta) u jedinstveni OpenAI format.

Što se događa s aktivnim zahtjevima tijekom restarta proxyja?

Proxy ima graceful shutdown koji čeka SIGTERM, prestaje primati nove zahtjeve i čeka da postojeći završe (default 30 sekundi grace period, podesivo kroz --graceful_timeout). Za zero-downtime upgrade koristite Kubernetes rolling deployment s minimalno dvije replike i readiness probeom na /health/readiness.

Emma Bergstrom
O Autoru Emma Bergstrom

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