OpenRouter + LiteLLM + Langfuse ile Üretken Yapay Zekâ (LLM) Uygulama Mimarisi

Featured image

Neden bu üçlü?

Bu kombinasyonun özü: Uygulama → (isteğe göre) LiteLLM ProxyOpenRouter/diğer sağlayıcılar ve tüm çağrılar Langfuse’a izlenir/değerlendirilir.


Yüksek Seviyeli Akış (ASCII Diyagram)

[Client/App/API] 
      │  (OpenAI-compatible)
      ▼
[LiteLLM Proxy - optional] ──► Policy/limits, per-key budgets, caching, fallbacks
      │
      ▼
[OpenRouter Gateway] ──► model routing / provider routing / fallbacks
      │
      ▼
[Model Providers] ──► OpenAI, Anthropic, Google, Mistral, Local (Ollama)…
      │
      └──► Responses + Usage
                    │
                    ▼
                [Langfuse]
   traces, spans, tokens, latency, evals, dashboards

Mimarinin Parçaları

1) Uygulama Katmanı (OpenAI SDK ile)

A. Doğrudan OpenRouter’a çağrı (Langfuse ile)

# pip install openai langfuse
import os
from langfuse.openai import OpenAI as LFOpenAI  # Langfuse OpenAI wrapper

client = LFOpenAI(
    api_key=os.getenv("OPENROUTER_API_KEY"),
    base_url="https://openrouter.ai/api/v1",   # OpenRouter OpenAI-compatible endpoint
    langfuse_public_key=os.getenv("LANGFUSE_PUBLIC_KEY"),
    langfuse_secret_key=os.getenv("LANGFUSE_SECRET_KEY"),
    langfuse_host=os.getenv("LANGFUSE_HOST"),  # örn: https://cloud.langfuse.com
)

resp = client.chat.completions.create(
    model="openai/gpt-4o-mini",
    messages=[{"role": "user", "content": "Merhaba! Bana bu mimariyi özetler misin?"}],
    # Fallback için alternatifler (OpenRouter destekli):
    extra_body={
        "models": ["anthropic/claude-3-5-sonnet"],
        "provider": {"order": ["openai", "anthropic"], "allow_fallbacks": True}
    },
    # Uygulama atribüsyonu (opsiyonel):
    extra_headers={"HTTP-Referer": "https://yourapp.example", "X-Title": "Your App"},
)

print(resp.choices[0].message["content"])

B. LiteLLM Proxy üzerinden çağrı (App → LiteLLM → OpenRouter/diğerleri)

# pip install openai
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.getenv("LITELLM_API_KEY"),            # Proxy önüne koyduğunuz key
    base_url=os.getenv("LITELLM_BASE_URL"),          # örn: http://localhost:4000
)

resp = client.chat.completions.create(
    model="openai/gpt-4o-mini",  # LiteLLM'de bu isim route'a eşler
    messages=[{"role": "user", "content": "Selam LiteLLM!"}],
    # Proxy tarafında global fallback/bütçe/rate limit zaten yönetilir
)
print(resp.choices[0].message["content"])

Hangisi?

  • Doğrudan OpenRouter: hızlı entegrasyon, çoklu provider, otomatik fallback.
  • LiteLLM ile: kurum-içi governance, bütçe/limit/anahtar politikaları, tek giriş noktası.

2) LiteLLM Proxy (config örneği)

config.yaml (şema sürümlere göre değişebilir; güncel dokümantasyona bakın):

# LiteLLM proxy örnek konfigürasyonu
# Amaç: openai/gpt-4o-mini modeline gelen istekleri OpenRouter üzerinden yönlendirmek,
# bütçe/limit ve Langfuse callback'lerini merkezi yönetmek.

litellm_settings:
  request_timeout: 30
  max_retries: 2
  telemetry: true

model_list:
  - model_name: openai/gpt-4o-mini
    litellm_params:
      model: openai/gpt-4o-mini
      api_base: https://openrouter.ai/api/v1
      api_key: ${OPENROUTER_API_KEY}
      # İsterseniz provider tercihleri:
      # extra_body:
      #   provider: { order: ["openai", "anthropic"], allow_fallbacks: true }

router:
  strategy: simple-shuffle
  allow_fallbacks: true

budgets:
  - tag: prod
    rpm_limit: 1000
    tpm_limit: 60000
    daily_spend_limit: 50   # USD karşılığı mantığında; uygulamaya göre ayarlayın

callbacks:
  - name: langfuse
    type: http
    url: ${LANGFUSE_INGEST_URL}          # Langfuse ingest endpoint
    api_key: ${LANGFUSE_SECRET_KEY}
    # İsteğe bağlı ortak etiketler:
    default_tags:
      - env:prod
      - service:litellm-proxy

Çalıştırma (örnek):

export OPENROUTER_API_KEY=... \
       LANGFUSE_SECRET_KEY=... \
       LANGFUSE_INGEST_URL=https://cloud.langfuse.com/api/public/ingest
litellm --config config.yaml --port 4000

Notlar

  • Virtual keys / per-team limits ile departman/ürün bazlı maliyet kontrolü kurun.
  • Proxy’de rate limit, retry/backoff, caching (varsa) ve timeout politikalarını merkezi yönetin.
  • OpenRouter dışındaki hedeflere (OpenAI native, Bedrock, Groq, Ollama) aynı dosyada route ekleyebilirsiniz.

3) Langfuse ile İzleme, Hata Ayıklama ve Değerlendirme

Python – manuel iz genişletme (opsiyonel):

from langfuse import Langfuse

lf = Langfuse(
    public_key=os.getenv("LANGFUSE_PUBLIC_KEY"),
    secret_key=os.getenv("LANGFUSE_SECRET_KEY"),
    host=os.getenv("LANGFUSE_HOST"),
)

trace = lf.trace(name="chat_flow", user_id="user_123", tags=["prod","turkish"])
span = trace.span(name="rerank_step")
# ... iş mantığınız ...
span.end()
trace.update(observations={"business_unit": "support"})
trace.end()

Güvenlik ve Uyum


Dayanıklılık ve Performans


Maliyet ve Yönetişim


Küçük Bir Uçtan Uca Örnek (RAG-lite)

# 1) Arama → 2) (opsiyonel) rerank → 3) model cevabı
# OpenRouter çağrıları Langfuse ile otomatik izleniyor varsayımıyla.

def answer_question(query, top_k=4):
    docs = retriever.search(query, k=top_k)   # kendi arama/vektör mekanizmanız
    context = "\n\n".join(d.text for d in docs)

    prompt = f"""Aşağıdaki bağlama dayanarak yanıt ver.
    Soru: {query}
    Bağlam:
    {context}
    Cevap:"""

    resp = client.chat.completions.create(
        model="openai/gpt-4o-mini",
        messages=[{"role":"user","content":prompt}],
        extra_body={"models": ["anthropic/claude-3-5-sonnet"]}  # fallback
    )
    return resp.choices[0].message["content"]

“Ne Zaman Hangisi?” Karar Rehberi (kısa)


Dağıtım Notları


Kapanış

Bu mimari, esneklik (çoklu model/sağlayıcı), kontrol (bütçe/limit/policy) ve şeffaflık (observability/eval) dengesini kurar. Küçük başlayıp (OpenRouter + Langfuse) büyüdükçe LiteLLM Proxy’yi araya eklemek genelde en düşük riskli yoldur.