Çok modelli erişim için arka uç geliştiriyorsanız, büyük ihtimalle şu çöküşü yaşamışsınızdır: iş kodunun içi if (vendor === 'openai') ... else if (vendor === 'claude') ... ile dolmuş, tek bir akışlı sohbet arayüzü için sekiz yüz satır uyarlama mantığı yazılmış, yeni bir sağlayıcı eklemek için çekirdek zinciri bir kez daha değiştirmeniz gerekiyor. Sorun sizde değil, her büyük model API'sinin protokolünün baştan birleştirilmeyi hiç amaçlamamış olmasında.
Model ağ geçidinin özü, bir protokol çeviri katmanıdır: N sağlayıcının heterojen istek/yanıtlarını 1 dizi iç standart protokole indirger. Bu makale ilke, uygulama ve karşılaştırma olmak üzere üç aşamalı ilerleyerek çeviri katmanının tam olarak nasıl yapılması gerektiğini anlatıyor.
I. Dört tür heterojenlik noktası: Birden fazla sağlayıcıya doğrudan bağlanmak neden kaçınılmaz olarak kontrolden çıkar
Önce gerçek farklara bakalım, her biri rakamlarla birlikte.
Kimlik doğrulama yöntemi: OpenAI Authorization: Bearer sk-xxx kullanır, başlık alanı uzunluğu yaklaşık 51 karakterdir; Claude x-api-key kullanır; Gemini anahtarı URL'deki ?key= sorgu parametresine sıkıştırır; Qwen ve ERNIE Authorization kullanır ancak imza algoritmaları farklıdır, ERNIE'nin access_token geçerlilik süresi varsayılan olarak 30 gündür, süresi dolduğunda 110 hata kodunu döndürür. Dört sağlayıcı, dört farklı yazım.
SSE akışlı parçalama formatı: OpenAI'nin chunk'ı data: {"choices":[{"delta":{"content":"x"}}]} şeklindedir, bitiş işareti data: [DONE]'dır; Claude'un olay türü event: content_block_delta ile data: {"delta":{"text":"x"}} eşleşmesidir, alan adı content'ten text'e dönüşür; Gemini artışı candidates[0].content.parts[0].text içine koyar, iç içe geçme 3 kat derinleşir. İş katmanının aynı cümleyi ayrıştırması için dört ayrı parser yazması gerekir.
Hata kodu sistemi: En can sıkıcı olanı budur. OpenAI HTTP durum kodu + error.type kullanır, hız sınırlaması 429'dur; Claude hız sınırlamasında 429 döndürür ancak body'deki type değeri rate_limit_error'dır; Qwen hız sınırlamasında 200 durum kodu döndürebilir ancak body'de code: "Throttling" taşır; ERNIE kota aşımını error_code: 17 ile ifade eder. Aynı şey, dört farklı ifade.
Token istatistik ölçütü: OpenAI'nin usage.total_tokens = prompt + completion'dır, Çince ve İngilizce BPE'ye göre bölünür; Claude ayrı ayrı input_tokens ve output_tokens döndürür, ayrıca Çince karakter bölme granülerliği daha incedir, aynı 500 karakterlik Çince metin için iki sağlayıcının istatistikleri arasında %20 ila %35 fark olabilir. Kullanım bazlı faturalandırmada bu fark doğrudan fatura hatasına dönüşür.
Dört sağlayıcıya doğrudan bağlanıldığında, iş katmanı kod hacmi tek sağlayıcının 3 ila 4 katına şişer, bakım maliyeti sağlayıcı sayısıyla doğrusal olarak artar.
II. Çeviri katmanı tasarımı: Birleşik format, akış normalleştirmesi, hata kodu eşlemesi, kullanım toplama
Çeviri katmanının dört şey yapması gerekir, hiçbiri eksik olamaz.
Birleşik istek/yanıt formatı: İçeride bir dizi standart Schema tanımlanır, alanlar OpenAI tarzına hizalanır (çünkü ekosistemi en geniştir). Dış istekler önce iç formata dönüştürülür, ardından adaptör tarafından her sağlayıcının formatına dönüştürülür. Adaptör deseni, her sağlayıcı için bir sınıf, buildRequest() ve parseResponse() olmak üzere iki metodu uygular.
Akışlı parçalama normalleştirmesi: Temel nokta, her sağlayıcının SSE chunk'ını birleşik {delta: string, finish_reason: string|null} yapısına dönüştürmektir. Yöntem bir durum makinesi yazmak, sağlayıcı türüne göre farklı parser'lara dağıtmak ve birleşik yapı çıktısı vermektir. Kilit nokta sınır işlemedir: SSE'nin \n\n ayırıcısı, data: öneki, çok satırlı data birleştirmesi, bunların hepsi parser içinde yutulmalıdır. Benim takıldığım tuzak Claude'un ping olayı ve message_stop olayıydı, açıkça yok sayılmazsa boş delta ön uca itilir ve UI titremesine yol açar.
Hata kodu eşleme tablosu: Bir vendorCode -> unifiedCode eşlemesi tutulur, 6 kategoriye birleştirilir: AUTH_FAILED, RATE_LIMITED, QUOTA_EXCEEDED, INVALID_REQUEST, UPSTREAM_ERROR, TIMEOUT. Üst akış ne döndürürse döndürsün, çeviri katmanı tabloya bakıp birleşik koda dönüştürür, iş katmanı yalnızca bu 6'yı tanır.
Kullanım toplama: Her çağrıdan sonra her sağlayıcının token ölçütü birleşik olarak iç standart token'a dönüştürülür, veritabanına yazarken vendor, model, request_id eklenir, sonraki mutabakat ve maliyet analizi için kullanılır. Burada ölçüt farkına dikkat edilmelidir, Claude'un output_tokens'ı ile OpenAI'nin completion_tokens'ı doğrudan toplanamaz, dönüşüm katsayısıyla aynı tabana normalize edilmelidir.
Katmanlı mimaride genellikle dört katmana ayırırım: erişim katmanı (kimlik doğrulama + hız sınırlama), yönlendirme katmanı (model seçimi), çeviri katmanı (protokol dönüşümü), adaptör katmanı (sağlayıcı SDK çağrısı). Çeviri katmanı saf fonksiyondur, IO'ya dokunmaz, birim testi kolaydır.
III. Uygulama kodu: Tek satır base_url değiştirerek toplama ağ geçidine bağlanma
Çeviri katmanını sıfırdan yazmak istemiyorsanız, hazır bir AI API toplama platformu kullanmak daha pragmatik bir seçimdir. Projemizde token8341 kullandık, OpenAI SDK ile uyumludur, tek satır base_url değiştirerek geçiş yapılır, çeviri katmanı işini sizin yerinize o yapar.
from openai import OpenAI
client = OpenAI(
api_key="your-key",
base_url="https://api.token8341.com/v1" # sadece bu satırı değiştir
)
resp = client.chat.completions.create(
model="deepseek-v3", # gpt-4o / qwen-max / claude-4-sonnet ile de değiştirilebilir
messages=[{"role": "user", "content": "SSE'yi açıkla"}],
stream=True
)
for chunk in resp:
delta = chunk.choices[0].delta.content
if delta:
print(delta, end="")Bu kodda SSE parçalama normalleştirmesi, hata kodu eşlemesi, kullanım toplama hepsi ağ geçidi tarafında tamamlanmıştır, iş katmanının aldığı standart OpenAI formatıdır. Çok modelli yönlendirme de tasarruf edilir, ağ geçidi göreve göre otomatik olarak en uygun modeli seçebilir, örneğin uzun Çince metinler Qwen'e, çıkarım görevleri DeepSeek'e, maliyet hassas senaryolar Doubao'ya yönlendirilir.
Tuzak uyarısı: base_url değiştirildikten sonra, sağlayıcıya özgü parametreleri doğrudan geçirmeyin. Örneğin OpenAI'nin logit_bias'ı, Claude'un top_k'sı, ağ geçidi hepsini desteklemeyebilir, geçirildiğinde sessizce yok sayılabilir, etkin olduğunu sanırsınız ama aslında olmamıştır. Yayına almadan önce yük testi betiğiyle parametre uyumluluğunu bir kez çalıştırın.
IV. Karşılaştırma: Çok modelli yönlendirme vs tek model bağlama
Gerçek ölçüm rakamlarımızdan bir grup verelim. Tek model bağlama (OpenAI'ye doğrudan bağlantı): entegrasyon süresi yaklaşık 2 kişi-gün, arıza geçişi için kodu değiştirip yeniden yayınlamak gerekir, ortalama kurtarma süresi 15 dakika, maliyet optimizasyon alanı yok. Çok modelli yönlendirme (ağ geçidi üzerinden): entegrasyon süresi yaklaşık 0,5 kişi-gün, arıza geçişi otomatik tamamlanır, kurtarma süresi 3 saniyeden az, maliyet göreve göre yönlendirme ile yaklaşık %30 ila %40 azaltılabilir.
Bakım karmaşıklığı açısından, 4 sağlayıcıya doğrudan bağlantının uyarlama kodu yaklaşık 2000 satırdır, ağ geçidi üzerinden sonra iş katmanı uyarlama kodu 200 satırın altına düşer, %90 azalma. Gecikme açısından, ağ geçidi bir sıçrama daha ekler, P99 yaklaşık 20 ila 40ms artar, tasarruf ettiği bakım maliyeti ve geçiş esnekliğiyle karşılaştırıldığında bu ek yük kabul edilebilir.
Elbette ağ geçidi her derde deva değildir. İşiniz yalnızca bir model kullanıyorsa ve asla değiştirmeyecekseniz, doğrudan bağlantı daha basittir. Ancak çok model, çok sağlayıcı, maliyet optimizasyonu söz konusuysa, çeviri katmanı zorunlu altyapıdır. Model ağ geçidi, büyük model API'si, AI API toplama bu üç şey, özünde aynı katman sorununun üç farklı ifadesidir.
Son bir uyarı: çeviri katmanının birim test kapsama oranı tam olmalıdır, özellikle akışlı parçalamanın sınır durumları, burası çevrimiçi olayların sık görüldüğü bölgedir.
Yazar: Liu Zhiyuan
Yayın tarihi: 28 Ekim 2026