SiCore TokenWorks
LLM APIAPI Gateway

LLM Sağlayıcıları Arasında Kodunuzu Değiştirmeden Nasıl Geçiş Yaparsınız

SiCore TokenWorks Team·2026-09-03

Çoğu insan bir projeye başlarken sağlayıcı taşınabilirliğini düşünmez. Kayıt olması en kolay olan satıcıdan bir anahtar alır, entegrasyonu yazar ve yayına alır. Birkaç ay sonra bir kıyaslama okur, ya da bir fatura görür, ya da bir hız sınırına çarpar ve başka bir şey denemek ister. İşte o zaman acı ortaya çıkar, çünkü ilk sağlayıcı hakkındaki varsayımları HTTP katmanına gömmüşlerdir.

Çözüm bir soyutlama kütüphanesi değil. Bir tel formatıdır. OpenAI sohbet tamamlama API'si sessizce LLM'lerle konuşmak için varsayılan protokol haline geldi ve bir kez buna göre yazdığınızda, sağlayıcı değiştirmek çoğunlukla iki dizeyi değiştirmek meselesidir.

Herkesin kopyaladığı API

OpenAI basit bir sözleşme tanımladı: /v1/chat/completions adresine JSON POST edersiniz, geri choices[0].message.content dizesi alırsınız. İstek şöyle görünür:

curl https://api.openai.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -d '{
    "model": "gpt-4o",
    "messages": [{"role": "user", "content": "Explain DNS in one paragraph"}]
  }'

Neredeyse her büyük model artık bu lehçeyi konuşuyor. DeepSeek, Qwen, ERNIE, Doubao ve diğerleri aynı gövdeyi kabul eden ve aynı şekli döndüren bir uç nokta sunuyor. Bu, istemci kodunuzun diğer uçta kimin olduğunu umursamadığı anlamına gelir. model dizesini ve uç noktayı değiştirebilirsiniz ve başka hiçbir şey değişmez.

İşte bu modellerden birkaçını tek bir temel URL altında barındıran bir toplayıcıya yönlendirilmiş aynı çağrı:

curl https://api.token8341.com/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKENWORKS_API_KEY" \
  -d '{
    "model": "deepseek-chat",
    "messages": [{"role": "user", "content": "Explain DNS in one paragraph"}]
  }'

Tek istemci, birçok model

Python'da normalde OpenAI SDK'sını bir kez örnekleyip her istek için bir model adı geçirirsiniz. Sağlayıcınız uyumlu API'yi destekliyorsa, base_url'i bir kez ayarlarsınız ve diğer her şeyi aynı tutarsınız:

from openai import OpenAI

client = OpenAI(
    base_url="https://api.token8341.com/v1",
    api_key="sk-your-tokenworks-key",
)

def ask(model: str, prompt: str) -> str:
    resp = client.chat.completions.create(
        model=model,
        messages=[{"role": "user", "content": prompt}],
    )
    return resp.choices[0].message.content

# Same function, three different model families.
print(ask("gpt-4o", "Summarize this log for me."))
print(ask("deepseek-chat", "Summarize this log for me."))
print(ask("qwen-max", "Summarize this log for me."))

Fonksiyon değişmez. Model dizesi değişir. Bütün numara bu. Akış aynı şekilde çalışır:

stream = client.chat.completions.create(
    model="deepseek-chat",
    messages=[{"role": "user", "content": "Write a haiku about databases"}],
    stream=True,
)
for chunk in stream:
    delta = chunk.choices[0].delta.content or ""
    print(delta, end="")

Fonksiyon çağırma, JSON modu ve gömmeler de aynı uyumlu yüzeyi kullanır, yani geçiş yaptığınızda düz sohbetle sınırlı kalmazsınız.

Geçişin size kazandırmadıkları

Bedava değişmeyen kısım konusunda net olmak istiyorum. Taşıma katmanı taşınabilir; modeller değil.

Farklı modeller istemlere farklı tepki verir. GPT-4o için ayarlanmış bir sistem istemi, farklı bir yapı isteyen bir akıl yürütme modelinde düşük performans gösterebilir. Bağlam pencereleri farklıdır, bazen çok fazla: bir model 128k token alabilirken diğeri 32k alabilir. Tokenleştiriciler de farklıdır, yani aynı belge her modelde farklı sayıda token maliyetine sahiptir. Maksimum çıktı uzunluğu da protokol başına değil, model başına olan başka bir düğmedir.

Yani "kod değiştirmeden geçiş" aslında "HTTP istemcinizi yeniden yazmadan geçiş" demektir. Üretim trafiğini yeni bir modele yönlendirmeden önce kendinize bir değerlendirme çalışması borçlusunuz. İyi haber şu ki uyumlu API bu değerlendirmeyi çalıştırmayı ucuz hale getirir, çünkü test düzeneği sadece model adları üzerinde döngüdür.

Pratik bir kalıp

Yan projelerde gerçekte yaptığım şey küçük bir yapılandırma tablosu tutmak, kod değişikliği değil:

MODELS = {
    "fast": "deepseek-chat",
    "smart": "qwen-max",
    "frontier": "gpt-4o",
}

def run(task, prompt):
    return ask(MODELS[task], prompt)

fast şeridi için daha ucuz bir model denemek ister misiniz? Bir satırı değiştirin. İlk sağlayıcı hız sınırına takıldığında ikinci bir sağlayıcıya geri dönmek ister misiniz? İstisnayı yakalayın ve bir sonraki model dizesiyle yeniden deneyin. Bunların hiçbiri istek oluşturmayı etkilemez.

Bu geri dönüş kalıbı, çok modelli bir uç noktanın değerini kanıtladığı yerdir. Tek bir temel URL ve tek bir anahtarla, ilk gün yazdığınız aynı iki satır istemci kurulumu üzerinden sağlayıcılar arasında yönlendirme, yeniden deneme ve A/B testi yapabilirsiniz.

Dikkat edilecek yanıt tuhaflıkları

Taşıma katmanı uyumludur, ancak birkaç yanıt düzeyi farkı hâlâ sızar. Akıl yürütme modelleri bazen normal mesajın yanında reasoning_content gibi ekstra bir alan döndürür. choices[0].message.content okuyan kod her durumda çalışmaya devam eder, ancak bu akıl yürütme metnini bir hata ayıklama görünümünde göstermek isteyebilirsiniz. Hata mesajları da farklıdır: bir sağlayıcı yardımcı bir insufficient_quota dizesi döndürürken, bir diğeri gövdesiz çıplak bir 429 döndürür. Yeniden denemeler oluşturuyorsanız, satıcıya özgü metni ayrıştırmak yerine herhangi bir 429 veya 5xx'i "geri çekil ve tekrar dene" olarak değerlendirin.

Bunların hiçbiri tek bir sağlayıcıya kilitli kalmanız için bir neden değil. Hata işlemenizi genel ve model seçiminizi bir değişken olarak tutmanız için bir nedendir.

Bu, SiCore TokenWorks'un benimsediği konumdur: https://api.token8341.com/v1 adresinde OpenAI uyumlu bir uç nokta; burada GPT-4o, Claude, Gemini, DeepSeek, Qwen, ERNIE, Doubao, Spark ve Pangu arasında geçiş yaptığınızda değişen tek şey model dizesidir.