32  Geçit Katmanı: Yönlendirme, Maliyet ve Yönetişim

Bölüm durumu: çevrildi. Kaynak metin: İngilizce 32. bölüm. Bölümde iki küçük ölçüm var ve ikisi de saniyeler süren birer hesap. Birincisi, tek bir benzerlik eşiğinin bir önbellek isabetini bir hatadan ayırıp ayıramayacağını sormak için nomic-embed-text üzerinden geçirilen on beş etiketli sorgu çifti; ikincisi, ilk ölçümün açığa çıkardığı, o embedding (gömme) modelindeki bir kusuru inceleyen bir ölçüm. Yönlendirme ve güvenilirlik konuları ölçülmedi, kaynaklardan aktarılıyor — bir yeniden deneme fırtınası dizüstü bilgisayarda yeniden üretilemez. Yönlendirme argümanı ise yayımlanmış cascade (kademeli yönlendirme: önce ucuz model cevaplar, gerekirse daha güçlü modele geçilir) sonuçlarına ve bu kitabın Bölüm 12’de zaten yaptığı bir sinyal ölçümüne dayanıyor. Yazılım: ollama 0.24.0, nomic-embed-text servis ediyor; Python 3.14.5, Apple Silicon.

Öğrenme hedefleri. Bu bölümün sonunda:

32.1 Geçit ne işe yarar

Bölüm 31 tek bir modele giden tek bir istekle ilgiliydi. Bu bölümün konusu olan geçit — model geçidi (gateway) — ise bunlardan herhangi biri birden fazla olduğunda ortaya çıkar: kurumdaki her LLM çağrısının içinden geçtiği, tek bir API sunan ve cevabı hangi sağlayıcının verdiğini gizleyen tek bir servis.

Bunu kurmaya ne zaman değdiğini net olarak belirlemek gerekir, çünkü geçit altyapıdır ve altyapının sürekli bir maliyeti vardır. Geçidin ortadan kaldırdığı problemler ilk gün henüz yoktur:

Altı problem ve her birinin geldiği an
problem ne zaman ortaya çıkar
Sağlayıcı anahtarları birkaç servise yapıştırılmıştır ve birini yenilemek (credential rotation: yeni anahtar üretip eskisini iptal etmek) hepsini bulmak demektir ikinci serviste
Kimse hangi takımın ne harcadığını söyleyemez ikinci takımda
Başıboş bir döngü kimse fark etmeden altı saat fatura yazar ilk ajanda
Sağlayıcı değiştirmek her çağıranı düzenlemek demektir ikinci sağlayıcıda
Bir model kullanımdan kaldırılır ve onu kimlerin çağırdığını sayamazsınız ilk kullanımdan kaldırmada
Politika — maskeleme, data residency (verinin tutulduğu ve işlendiği ülke ya da bölge), denetim — üç kez, üç farklı biçimde uygulanır ilk denetimde

Bunların her biri ya bir atıf (harcamayı ya da çağrıyı sahibine bağlama) problemidir ya da bir tek geçiş noktası (choke point: bütün trafiğin içinden geçtiği ve denetimin uygulandığı nokta) problemi; ikisi de trafiğin geçtiği tek bir nokta olmasıyla çözülür. Argümanın tamamı bu. Geçit hiçbir tekil isteği daha iyi yapmaz — istek düzeyindeki performans Bölüm 31’in konusudur — isteklerin popülasyonunu yönetilebilir kılar.

Kaçınılması gereken örüntü (anti-pattern) ise ortada ikinci bir takım yokken geçit kurmaktır. Bu, henüz yaşamadığınız problemler uğruna sisteme bir ağ sıçraması (çağıranla sağlayıcı arasına giren bir sunucu daha), yeni bir arıza kipi ve bir nöbet çizelgesi (gece arıza çıktığında onu düzeltmesi gereken biri) ekler.

32.2 Bütçeler, kotalar ve önceden fiyatlandıramadığınız yarı

Tek geçiş noktasının kazandırdığı ilk şey atıftır ve harcamayı bir sahibine bağlayabildiğiniz an biri sizden onu sınırlamanızı isteyecektir. Mimarinin bedava olmaktan çıktığı yer orası.

Geçitteki alışıldık denetim sanal anahtardır (virtual key): gerçek sağlayıcı anahtarına eşlenen ve kendi sınırlarını taşıyan, takım, servis ya da özellik başına bir kimlik bilgisi. Çağıranlar gerçek anahtarı hiç görmediği için sızan bir sanal anahtar tek başına iptal edilebilir, sağlayıcı anahtarı da tek bir yerde yenilenir. Sık sık birbirine karıştırılan ve sınıra gelindiğinde farklı davranan üç sınır vardır:

Aynı şey olmayan üç sınır
denetim neyi sınırlar sınıra gelindiğinde ne olur
Hız sınırı (rate limit) saniye ya da dakika başına istek ya da token istekler düşürülür ya da kuyruğa alınır; kendiliğinden toparlanır
Kota dönem başına istek ya da token çağıran, dönem devredene kadar engellenir
Bütçe dönem başına para ilginç olanı

Hız sınırları genellikle bir token kovası (token bucket) olarak kurulur — ve buradaki “token” bir LLM token’ı değil, bir geçiş izni demektir. Kova en fazla \(B\) izin tutar ve saniyede sabit \(r\) izinle dolar; her istek bir izin alır (dakika başına token sınırında ise LLM token’ı kadar izin) ve kovayı boş bulan istek reddedilir — tipik olarak HTTP 429 durum koduyla ve ne zaman tekrar gelineceğini söyleyen bir Retry-After başlığıyla. Dolu bir kova \(B\) isteklik bir patlamayı bir anda geçirir; uzun bir süre boyunca ise ortalama \(r\)’yi aşamaz. Örneğin \(B = 10\) ve saniyede \(r = 2\) ise dolu kovayla gelen 10 istek bir anda geçer, sonrakiler saniyede 2 istekle sınırlanır. Sağlayıcılar dakika başına istek ve token cinsinden kendi sınırlarını uygular; geçidin sınırlarını sağlayıcınınkinin altına koyun ki kimin trafiğinin düşürüleceğine sağlayıcı değil geçit karar versin.

Bütçeler ilginç olanıdır, çünkü Bölüm 31’deki iki yarıdan (prefill ve decode) doğrudan çıkan bir asimetri var. Girdi token’larını istek çalışmadan önce, çıktı token’larını yalnızca sonrasında bilirsiniz. Prefill önceden sayılabilir — prompt orada duruyor — ama decode bilinmeyen sayıda token üretir ve çoğu sağlayıcıda token başına pahalı olan yarı çıktıdır.

Dolayısıyla istek öncesi bir bütçe kontrolü zorunlu olarak yaklaşıktır ve bunu ele almanın üç yolu vardır:

Azami tutarı rezerve edin. İsteği max_tokens kadar token üretecekmiş gibi fiyatlandırın ve kalan bütçeyle karşılaştırın. İstek bitince gerçek maliyeti kesinleştirip kullanılmayan rezervi bütçeye geri ekleyin. Güvenlidir ama eksik hizmet verir: tek bir azami isteğe yer olan bir bütçe, on küçük isteği reddeder.

İyimser kabul edip sonra hesabı kapatın. Girdi maliyetini ve çıktı için bir tahmini bütçeden düşerek isteği kabul edin; istek tamamlanınca gerçek tutarla düzeltin. Çoğu geçidin yaptığı bu ve bu, bir bütçenin eşzamanlı çağıran başına kabaca bir isteklik çıktı kadar aşılabileceği anlamına geliyor. Genellikle sorun değil — ama bunu söyleyin ki kimse şaşırmasın.

Çıktıyı tavanlayın. Sanal anahtar başına max_tokens belirleyin. Bu maliyeti bilinir kılmaz — bir istek tavanın altında herhangi bir yerde durabilir — ama sınırlar; ilk seçeneği ucuzlatan da budur: bilinen bir tavana karşı yapılan bir rezervasyon, gerçekten göze alabileceğiniz bir rezervasyondur. Takımların atladığı seçenek bu. İki şey tavanın dışında kalır: her yeniden deneme yeniden faturalanan yeni bir istektir ve çağrı başına araç ücretleri (örneğin barındırılan bir web araması aracı) ayrıca fiyatlanır. Akıl yürütme token’ları çıktı olarak faturalanır; sağlayıcınızın bunları tavanın içinde sayıp saymadığını kontrol edin, çünkü parametrenin adı ve kapsamı API’den API’ye değişir.

Bir gerçekleme ayrıntısı, bunların yük altında ayakta kalıp kalmayacağına karar veriyor. Kontrol ile rezervasyon atomik olmalı — Redis üzerinde bir Lua betiği, bir SELECT … FOR UPDATE, koşullu bir yazma — çünkü eşzamanlı \(c\) çağıran varken önce okuyup sonra yazmak, \(c\) çağıranın hepsinin aynı kalan bütçeyi görmesine ve bütçede yalnızca birine yer olsa bile hepsinin geçmesine yol açar. Aşım o zaman eşzamanlı çağıran sayısıyla — yani trafiğinizle — birlikte ve tam da istemediğiniz anda büyür.

Bütçeyi zorunlu kılan log (kütük) aynı zamanda maliyet takipçisidir: geçit her çağrının token sayılarını model başına bir fiyat tablosuyla paraya çevirir (önbelleksiz girdi, önbellekli girdi, çıktı — Bölüm 31’deki hesap tablosunun üç fiyatı). O tabloyu sürümlü tutun; fiyatlar değişir ve bayat bir tablo her raporu sessizce yanlış yapar.

Aynı asimetri bir maliyet panosunun ne yapabileceğine de karar veriyor. Girdi maliyeti kabulde bilinebilir ve dolayısıyla zorunlu kılınabilir; çıktı maliyeti yalnızca tamamlanmada gözlemlenebilir ve yalnızca raporlanabilir. Bir şeyi durdurması gereken herhangi bir denetim, girdi tarafında ya da bir tavan üzerinde çalışmak zorunda — max_tokens’ın yalnızca bir kalite denetimi değil, bir bütçe denetimi olmasının nedeni de bu.

Bütçe tavanının sert olup olmadığı bir mühendislik değil, ürün kararıdır. Sert bir tavan harcamayı durdurur ve özelliği de durdurur; bir uyarı özelliği korur ve harcamayı durdurmaz. İşe yarar bir varsayılan, başıboş bir döngünün en olası neden olduğu üretim dışı anahtarlarda sert tavan; en olası nedenin başarı olduğu üretimde ise çok daha yüksek bir tavanla birlikte uyarıdır.

32.3 Devretme ve durumu kötüleştiren yeniden deneme

Çok sağlayıcılı devretme (failover: bir sağlayıcı çöktüğünde trafiği otomatik olarak yedeğe aktarmak), birçok takımın geçit kurmasının nedenidir; aynı zamanda bir geçidin bir olayı düzeltmek yerine en kolay kötüleştirdiği yerdir.

Mekanizma LLM dünyasının dışında, dağıtık sistemler literatüründe iyi belgelenmiş. Bir sağlayıcı bozulduğunda her istemci yavaş ya da başarısız istekler görür ve yeniden dener. Bu yeniden denemeler tam da sağlayıcının en az yedek kapasitesi olduğu anda gelir, böylece daha fazla istek başarısız olur, böylece daha fazla istemci yeniden dener. Google’ın SRE (Site Reliability Engineering, site güvenilirlik mühendisliği) kitabı bunu bir çığ etkisi arızası (cascading failure) olarak ele alıyor ve anlattığı çareler doğrudan bizim duruma da uyuyor (Beyer vd. 2016).

Üç denetim var ve üçünün de doğal yeri geçittir, çünkü isteklerin tamamını gören tek bileşen odur:

  • Jitter’lı üstel backoff. Backoff, her başarısız denemeden sonra bekleme süresini katlayarak uzatmaktır; jitter ise bu beklemeye eklenen rastgeleliktir. Yaygın bir tarif (“full jitter”), \(n\). yeniden denemeden önce 0 ile \(\min(\text{tavan},\ \text{taban} \cdot 2^n)\) arasında rastgele bir süre bekler. Tek başına backoff, birlikte başarısız olan istemcileri birlikte yeniden denemeye devam ettirir; onları dağıtan şey jitter’dır. Tam olarak 1 s, 2 s, 4 s’de yeniden deneyen istemciler her adımda yeniden bir thundering herd (çok sayıda istemcinin aynı anda yeniden istek göndermesi) oluşturur.
  • Devre kesici (circuit breaker). Arızalar bir eşiği aşınca, sağlayıcının hâlâ çalışmadığını yeniden keşfetmek için gecikme harcamayı sürdürmek yerine, bir soğuma dönemi boyunca o sağlayıcıya istek göndermeyi durdurun. Devre kesici normal işleyişte kapalıdır (trafik akar), eşik aşılınca açılır (trafik yedeğe gider ya da hemen hata döner), soğuma döneminden sonra yarı açık olur: birkaç deneme isteği yeniden kapanıp kapanmayacağına karar verir.
  • Yeniden deneme bütçesi. Google iki ayrı sınır uyguluyor (Beyer vd. 2016) ve genellikle atlanan ikincisidir: istek başına üç denemelik bir tavan ve her istemcinin kendi isteklerinin ne kadarının yeniden deneme olduğunu izleyip bu oran %10’u geçtiğinde yeniden denemeyi bıraktığı, istemci başına bir tavan. Tek başına istek başına tavan, neredeyse her şey başarısız olduğunda yükün 3 kata yaklaşmasına yine izin verir — hem de sağlayıcının bunu en az kaldırabileceği anda; oran ise en kötü durumu yaklaşık 1,1 kata indirir.

Üçünün altında iki pratik kural yatar. Yalnızca ikinci denemede başarılı olabilecek olanı yeniden deneyin: 429’lar, 5xx sunucu hataları ve zaman aşımları — varsa Retry-After’a uyarak; bozuk bir istek ya da bağlam penceresinden uzun bir prompt için dönen 400 değil, çünkü o her seferinde aynı biçimde başarısız olur. Ve yalnızca tek bir katmanda yeniden deneyin. Sağlayıcı SDK’ları zaten varsayılan olarak yeniden dener (OpenAI ve Anthropic Python istemcileri iki kez); dolayısıyla her biri üç denemeye izin veren bir SDK, bir geçit ve bir uygulama tek bir isteği \(3^3 = 27\) denemeye çevirebilir — SRE kitabı buna kombinatoryal patlama diyor (Beyer vd. 2016). Zaman aşımları da aynı özeni ister: bir LLM cevabı meşru olarak bir dakika sürebilir; tek ve kısa bir toplam zaman aşımı uzun cevapları keser, cömert bir zaman aşımı ise takılıp kalmış bir sağlayıcıyı gizler. Akış (streaming) varsa biri ilk token’ı bekleme süresine, diğeri token’lar arasındaki boşluğa olmak üzere iki ayrı zaman aşımı koyun. Akışta devretmenin bir sınırı da var: token’lar kullanıcıya akmaya başladıktan sonra sağlayıcı çökerse istek şeffaf biçimde başka modele aktarılamaz, çünkü yarım cevap zaten gitmiştir. İlk token’dan sonra devretme ancak cevabı baştan yeniden üreterek ve bunu istemciye bildirerek yapılabilir.

Bir de LLM geçitlerine özgü bir arıza kipi var ve bu hiç de bir güvenilirlik problemi değil:

Bir devretme modeli değiştirir ve farklı bir model farklı cevaplar verir. Bir sağlayıcının amiral gemisi modelinden bir diğerininkine düşmek, bir veri tabanının kopyaları arasında devretmek gibi değildir. Çıktı biçimi kayar, araç çağırma söz dizimi farklıdır, reddetme davranışı farklıdır ve birine göre ayarlanmış bir yapılandırılmış çıktı ayrıştırıcısı diğerinin çıktısını tümüyle reddedebilir (Bölüm 18).

Bu da devretmeyi bir değerlendirme sorusu yapıyor. Savunulabilir seçenekler, yedek yolu birincil yolla aynı süitte değerlendirmek — bunun yeri Bölüm 35’tir — ya da kimsenin sınamadığı bir modelin çıktısını sessizce servis etmek yerine açık bir hata döndürüp fail closed çalışmak (güvenli karar verilemiyorsa isteği reddetmek). Fail closed sıklıkla doğru seçimdir ve nadiren varsayılandır.

32.4 Maliyete göre yönlendirme ve dayandığı sinyal

Fikir çok cazip: isteklerin çoğu kolay, kolay isteklerin pahalı modele ihtiyacı yok, öyleyse onları ucuz bir modele gönderip gerisini güçlü modele aktaralım (escalation: isteği daha güçlü bir modele ya da bir insana aktarma). İyi yapıldığında bu, geçidin elindeki en büyük maliyet kolu. Kanıt yerine varsayıma dayanarak yapıldığında ise kaliteyi tam da kimsenin örneklemediği isteklerde sessizce düşürüyor.

İki biçim var ve farklı biçimlerde başarısız oluyorlar:

Yönlendirmenin iki yolu ve her birinin maliyeti
nasıl karar verir neye ihtiyaç duyar
Cascade ucuz modeli çalıştır, cevap güvenilmez görünüyorsa güçlü modele aktar ucuz çağrıdan sonra hesaplanan bir sinyal — yani parasını ödersiniz
Yönlendirici (router) önce isteği sınıflandır, tek bir modele gönder herhangi bir çağrıdan önce hesaplanan bir sinyal — daha ucuz ve daha zor

Yayımlanan sonuçlar cesaret verici. FrugalGPT bir API kümesi üzerinde cascade kuruyor ve en iyi tekil modelin doğruluğuna, o modelin maliyetinin küçük bir bölümüyle ulaştığını ya da eşit maliyette doğruluğu artırdığını bildiriyor (Chen vd. 2023). RouteLLM tercih verisinden bir yönlendirici öğreniyor ve değerlendirildiği benchmark’larda (kıyaslama) güçlü modelin kalitesinin çoğunu korurken büyük maliyet azalmaları bildiriyor (Ong vd. 2024).

Ama bu sonuçların her biri bir sinyal hakkında bir iddiadır ve yönlendirmenin başarılı ya da başarısız olduğu yer sinyaldir. Mimari işin kolay kısmı; hangi isteklerin zor olduğunu bilmek ise problemin tamamı.

Bu kitap en cazip sinyali zaten ölçtü ve yetersiz buldu. Bölüm 12 bir modelden kendi güvenini kelimelerle belirtmesini istedi ve sonra o güveni kendi hatalarının bir dedektörü olarak sınadı. Ölçüt AUROC’tu: rastgele seçilmiş bir pozitif örneğin rastgele seçilmiş bir negatif örnekten daha yüksek puan alma olasılığı — burada doğru bir cevabın yanlış bir cevaptan daha yüksek güven alması; 0,5 yazı tura, 1,0 kusursuz ayrım demektir. Modelin sözle belirttiği güven AUROC 0,667 aldı; BERTurk sınıflandırıcısının kendi güven skoru (etiket olasılığı) ise 0,843 — kalibre edilmiş bir olasılık değil, bir sınıflandırıcı skoru. Sözel güven hiç yoktan iyi — ortalama güven doğru cevaplarda gerçekten daha yüksek — ama bir yönlendirme politikasının ihtiyaç duyduğu ölçüm aletinden epey uzak.

Bunun üzerine kurulan bir cascade birçok kolay isteği güçlü modele aktarır ve birçok zor isteği kaçırır; iki hata da toplu bir doğruluk sayısında görünmez.

Bu da herhangi bir yönlendirme çerçevesinden daha önemli olan kuralı üretiyor:

Rastgele aktarma baseline’ını (karşılaştırma tabanı) raporlayın. Herhangi bir yönlendirme politikası için, isteklerin aynı oranını rastgele seçip güçlü modele aktarsaydınız ne elde edeceğinizi hesaplayın. Özenle kurduğunuz sinyal o eğriyi yenmiyorsa bir sinyal değildir — doğruluğu yalnızca aktarma oranıyla satın alıyorsunuzdur ve bir yazı tura bunu daha ucuza yapardı.

Bu, Bölüm 14’ün kopyalanmış metin kontrolüyle ve Bölüm 30’un sonuç ile trajectory (ajanın izlediği çağrı, argüman, sonuç ve karar dizisi) ayrımıyla aynı kontrol disiplini: kaybetmesi gereken bir baseline’a karşı sınanmamış bir ölçüm size hiçbir şey söyleyemez.

Hiçbiri makale gerektirmeyen üç pratik not:

Güçlü modele aktarılan bir istek her iki çağrının da parasını — ve süresini — öder. İki çağrı ardışık olduğu için aktarılan isteklerin gecikmesi de ikisinin toplamıdır; aşağıdaki hesap yalnızca paranın tarafı. Küçük model token’ları artı büyük model token’ları kadar tutar; dolayısıyla trafiğin \(e\) kesrini aktaran bir cascade \(C_{\text{küçük}} + e \cdot C_{\text{büyük}}\) tutar; her şeyi büyük modele göndermenin maliyeti ise \(C_{\text{büyük}}\)’tür. \(e = 0{,}5\) ve 10 katlık bir fiyat oranında bu, büyük modelin faturasının \(0{,}1 + 0{,}5 = 0{,}6\)’sı eder — gerçek bir tasarruf, ama yarı yarıya olmaktan çok uzak. Başabaş oranını cascade’i kurmadan önce, benchmark’ınkiyle değil kendi fiyat oranınızla hesaplayın: cascade yalnızca \(e < 1 - C_{\text{küçük}}/C_{\text{büyük}}\) olduğu sürece para kazandırır; bu, 10 katlık oranda \(0{,}9\), 2 katlık oranda \(0{,}5\) demektir.

Yönlendirme modeli değiştirir, dolayısıyla Bölüm 32.3’teki her problemi devralır. Farklı çıktı biçimi, farklı araç çağırma söz dizimi, farklı reddetme davranışı. Yönlendirici, devretmenin kazara yaptığı şeyin kasıtlı ve kalıcı bir sürümüdür.

Yetenek yönlendirmesi kalite yönlendirmesinden kolaydır. “Bu istek görme gerektiriyor”, “bu 200 bin token’lık bir bağlam penceresi gerektiriyor”, “bu AB’de kalmalı” hiçbir şey öngörmeden istekten okuyabileceğiniz özellikler. Üretimde ayakta kalma olasılığı en yüksek yönlendirme kuralları da bunlar, çünkü AUROC’u 0,667 olabilecek bir sinyale bağlı değiller.

32.5 İki tür önbellek ve yalnızca biri güvenli

Geçitte cevap önbelleklemesi, Bölüm 31’in prompt önbelleklemesinden farklı bir mekanizma: o, sunucunun içinde bir ön ekin KV önbelleğini yeniden kullanıyor; bu ise saklanmış bir cevap döndürüyor ve modeli hiç çağırmıyor.

Tam eşleşmeli önbellekleme (model, tam prompt, parametreler) üzerinden anahtarlanır ve bayt bayt aynı olan önceki bir cevabı döndürür. Kalite riski sıfır değil, denetlenebilir — bu farklı bir iddia: aynı prompt için saklanan cevap, ancak cevabın dayandığı ve anahtarın yakalamadığı her şey aynı kaldıkça doğrudur. O liste göründüğünden uzun:

  • Model sürümü, yalnızca takma ad değil; yoksa sessiz bir sağlayıcı yükseltmesinden sonra dünkü modelin cevabını servis edersiniz.
  • Kod çözme (decoding) parametreleri; yoksa bir sıcaklık değişikliğinden sonra bayat çıktı servis edersiniz.
  • Kiracı (tenant: verisi söz konusu olan müşteri kurum) ve çağıranın yetkileri; yoksa bir müşterinin cevabını başkasına servis edersiniz.
  • Araç sonuçları ve belge sürümleri: cevabın üzerine kurulduğu her araç sonucu ya da erişilmiş belge de hesaba katılmalı.
  • Zamanın kendisi: TTL (time to live: bir girdinin süresi dolmadan önce ne kadar süre servis edilebileceği) bunun içindir — iade politikamız nedir sorusunun, başka hiçbir şey değişmese bile bir raf ömrü vardır.

Anahtarı ve TTL’yi doğru kurarsanız risk gerçekten ortadan kalkar; yanlış kurarsanız risk görünmez olur — çünkü bayat bir isabet, doğru bir isabetten ayırt edilemez.

Anlamsal önbellekleme isteği gömer (embedding’ini çıkarır) ve önceki bir istek yeterince benzer olduğunda saklanmış bir cevabı döndürür. İkisine de “önbellekleme” deniyor ama bunlar farklı özellikler; fark da şu: bu önbellek yanlış cevap verebilir.

Anlamsal önbellek yaklaşık bir en yakın komşu aramasıdır ve yanlış pozitifleri, kimsenin sormadığı sorulara verilmiş cevaplardır. Aşağıda, bir önbelleğin ne yapması gerektiğine göre etiketlenmiş, nomic-embed-text ile gömülüp kosinüs benzerliğine göre sıralanmış on beş destek sorgusu çifti var. Sütunlar: sim iki sorgunun kosinüs benzerliği; hit? etiket, yani önbelleğin bu çifti aynı soru sayıp saklanmış cevabı döndürmesinin doğru olup olmayacağı (True evet, False hayır); pair iki sorgunun kendisi.

   sim   hit?   pair
 0.982  False   is the pump covered by the warranty?    | is the pump not covered by the warranty?
 0.957  False   should i upgrade to the pro plan?       | should i avoid upgrading to the pro plan?
 0.957  False   ship 200 units to ankara                | ship 500 units to ankara
 0.954   True   how much does the pro plan cost?        | what is the price of the pro plan?
 0.917  False   what was revenue in q1 2025?            | what was revenue in q1 2026?
 0.913   True   can i get a refund?                     | is a refund possible?
 0.907  False   can i use this outdoors?                | can i not use this outdoors?
 0.898   True   how do i cancel my subscription?        | how can i end my subscription?
 0.891  False   cancel order 4471                       | cancel order 4417
 0.856   True   how do i reset my password?             | i forgot my password, how can i change it?
 0.851  False   what are your business hours on monday? | what are your business hours on sunday?
 0.742  False   what is the price of the pro plan?      | what is the price of the basic plan?
 0.712  False   how do i reset my password?             | how do i reset my api key?
 0.703  False   how do i export my data?                | how do i delete my data?
 0.609   True   what are your business hours?           | when are you open?

Listenin üst kısmına bakın. Tüm kümedeki en benzer çift, bir cümle ile onun olumsuz hâlidir — 0,982 — ikinci ve üçüncü sıradakiler de bir olumsuzlama ve değiştirilmiş bir miktar. Öte yandan gerçekten aynı anlamdaki soru — çalışma saatleriniz nedir ile ne zaman açıksınız — 0,609 ile en dipte duruyor.

Buradan çıkan sonuç bir görüş değil, aritmetik. En düşük doğru çift 0,609, en yüksek yanlış çift 0,982; dolayısıyla iki sınıfın aralıkları iç içe geçiyor ve bu kümede hiçbir tek eşik onları ayırmıyor.

İki hata tipi birbirinin yerine geçmez; eşikleri bunu akılda tutarak tarayın. Bir kaçırma bir model çağrısına mal olur ve kullanıcı hiç fark etmez. Bir yanlış isabet ise kendinden emin biçimde servis edilen, hiçbir kayda düşmeyen yanlış bir cevaba mal olur. Bu kümedeki bütün eşik değerleri tarandığında en az toplam hata — beş — hiçbir şeyi önbelleklemeyen dejenere eşiğe ait ve o beşin hepsi kaçırma. Gerçekten bir şey servis eden en iyi eşik 0,982’de ve yalnızca tek bir önbellek isabeti döndürüyor: cümle ve olumsuzu. Bu örneklemde, bir şey servis eden en iyi eşiğin kazandırdığı tek isabet yanlıştı. Aynı soruyu başka sözcüklerle soran gerçek bir çifti yakalayacak kadar gevşek her eşik ise en az üç yanlış cevap da servis etti.

Bir dedektör olarak ele alındığında kosinüs benzerliği burada 0,44 AUROC alıyor — yazı turanın vereceği 0,5’in altında. Beş pozitife karşı on negatiflik bir örneklemde bu sayının güven aralığı çok geniştir; dolayısıyla doğru okuma “benzerlik, aynı soru olmakla ters ilişkili” değil. Doğru okuma şu: on beş çiftle bir eşik bulamazsınız, ama bu çiftler aramanın kolay olmayacağını gösterir.

Bu, Bölüm 3’teki zıt anlamlı sözcük sonucunun cümle düzeyindeki karşılığı: orada increase/decrease 0,881 almıştı — cat/dog’un 0,880’iyle aynı düzeyde. Cümle düzeyinde durum iyileşmiyor, kötüleşiyor ve kapsanıyor ile kapsanmıyor neredeyse üst üste düşüyor. Olası bir sezgi (burada sınanmadı): olumsuzlama birçok token’ın arasına kısa bir token ekliyor ve havuzlama (pooling) — token vektörlerinin ortalamasını alıp tek bir cümle vektörü üretmek — bu küçük farkı ortalamada seyreltiyor. İki cümle ilişkilidir; model zaten bunu yakalamak için eğitildi. Ama aynı zamanda anlamca zıttırlar ve bir önbellek bu farkı göremez.

Ölçüm aletinin bir kusuru vardı; asıl ders onu bulmaktı. Yukarıdaki tablo küçük harfe çevrilmiş durumda ve başlangıçta öyle değildi. Doğal biçimde yazıldığında business hours on Monday ile business hours on Sunday için kosinüs benzerliği 1,0 çıktı — yakın değil, bayt bayt aynı vektörler.

Bunun peşine düşünce önbellekleme hakkında değil, aletin kendisi hakkında yeniden üretilebilir bir bulgu ortaya çıktı. ollama 0.24.0’ın servis ettiği nomic-embed-text ile büyük harfle başlayan herhangi bir kelime tek bir sabit token’a çöküyor:

"Monday" == "Cat" == "Ankara" == "Paris" == "Toyota" == "XYZZY" == "Q"
  -> all byte-identical vectors

"Cat sat on the mat" == "Dog sat on the mat"     identical
"cat sat on the mat" vs "dog sat on the mat"     cos 0.879, different
"Monday" vs "monday"                             cos 0.486

Hafta günü adlarının 21 çiftinin tamamı birbirinin aynısı; January ile February de, Ankara ile Istanbul da öyle. Küçük harfli metin normal davranıyor. Hem /api/embed hem /api/embeddings üzerinde yeniden üretiliyor.

Bunun ne olduğu ve ne olmadığı. Bu, tek bir makinede yeniden üretilebilen bir gözlem; bir hata raporunun gerektirdiği üç şey eksik. Model, digest’iyle (model dosyasının içeriğinden hesaplanan ve değişmeyen özet kimliği) değil, latest gibi kayan bir etiketle çekildi — bu, Bölüm 32.6’nın konusu olan kusurun ta kendisi ve bu bölümün kendi ölçüm aletinde ortaya çıkıyor. Aynı ağırlıklar ikinci bir yığından — özgün checkpoint üzerinde sentence-transformers — geçirilmedi; dolayısıyla kusurun GGUF dönüşümünden mi, tokenizer’dan mı yoksa sunucudan mı kaynaklandığı ayrıştırılmadı. Ve nomic-embed-text bir görev ön eki bekliyor (search_query:, search_document:); ön ek kullanılmadı ve çökmenin ön ekle de sürüp sürmediği sınanmadı — ön ekler küçük harfli olduğu için bu, boş bir soru değil, makul bir etkileşim. Bunu nitelendirilmiş bir kusur değil bir gözlem sayın ve rapor etmeden önce bir digest sabitleyin.

İki şey bunu bir meraktan fazlası yapıyor. Burada sınanmamış olası bir mekanizma: bu model yalnızca küçük harfli (BERT tarzı, “uncased”) bir sözlük kullanıyor; servis yığını küçük harfe çevirme adımını atlarsa büyük harfle başlayan her kelime sözlüğün dışına düşer ve aynı bilinmeyen kelime token’ına ([UNK]) dönüşür. Ayrıca aynı belirti ollama projesinin kendi hata kayıtlarında da ollama issue #13942 olarak (“nomic-embed-text embedding incorrect for uppercase”) raporlanmış: 0.13.1’den itibaren görülen ve 0.30 serisinde düzeltilen bir gerileme; burada kullanılan 0.24.0 bu aralığın içinde. Düzeltme vektörleri de değiştiriyor ve dersin öbür yarısı bu: bir embedding modeli ya da sunucu yükseltmesi, anlamsal bir önbelleğin sakladığı her vektörü sessizce geçersiz kılar.

Bunların hiçbiri bölümün buradan aldığı şeyi değiştirmiyor, çünkü o embedding modeli üzerine kurulmuş bir anlamsal önbellek, pazartesinin cevabını pazarın sorusuna, 1,0 benzerlikte, her seferinde, hiçbir kayda düşmeden servis ederdi.

Bu, Bölüm 14’teki rouge-score tokenizer’ı ve Bölüm 2’deki Türkçe küçük harfe çevirme sorunuyla aynı örüntü: alet çökmedi, makul görünen sayılar döndürdü. Yüzeye çıkmasının tek nedeni, düşük puan alması gereken bir çiftin en yüksek puanı almasıydı.

Öyleyse iki önbelleği farklı çıtaları olan farklı özellikler olarak ele alın:

Adı ortak olan iki önbellek
kalite riski nerede kullanılır
Tam eşleşmeli denetlenebilir — anahtar ve TTL, cevabın dayandığı her şeyi yakaladığında yok tekrarlanan bir cevabın kabul edilebildiği her yerde varsayılan olarak açık (kullanıcının “yeniden üret” diyerek farklı bir cevap beklediği yerlerde değil)
Anlamsal sessizce yanlış bir cevap yalnızca kendi trafiğinizde ölçülmüş bir yanlış pozitif oranıyla; sonucu ağır olan hiçbir işte asla

Anlamsal bir önbelleğin etkilediği tek eksen doğruluk da değil. Önbellek aynı zamanda, her isteğin geçtiği tek bileşenin içinde duran bir prompt ve cevap deposudur; bu da üç şeyi başkasının değil geçidin problemi yapıyor. Üçü de büyük ölçüde tam eşleşmeli önbellek için de geçerli — o da prompt saklar, kiracılar arasındaki sınırı aynı kolaylıkla aşabilir ve onun girdileri de bayatlar; benzerliğe özgü olan yalnızca üçüncü maddenin embedding modeline ilişkin kısmı:

  • Kiracıya göre, veri kişiselse kullanıcıya göre anahtarlayın. Yalnızca embedding’e göre anahtarlanmış bir önbellek, bir müşterinin cevabını başka bir müşterinin sorusuna servis eder. Bu bir kalite kusuru değil, bir veri sızıntısıdır ve elinizdeki her metrikte tıpkı bir önbellek isabeti gibi görünür.
  • Saklama kuralı önbelleğe de uygulanır. Önbellek girdileri prompt’u tutar. “Prompt’ları kaydetmiyoruz” diyen bir politika, anlamsal bir önbellek onları sakladığı anda doğru olmaktan çıkar; dolayısıyla önbelleğe, Bölüm 32.7’nin log’a uyguladığı TTL’yi ve maskelemeyi uygulayın.
  • Bir girdiyi neyin geçersiz kıldığına karar verin. Bir fiyat değişir, bir politika güncellenir, bir belge geri çekilir — ve önbelleklenmiş bir cevap, üzerinde hiçbir sürüm olmadan servis edilmeye devam eder. Bir girdiyi temizleyen olayın adını koyamıyorsanız o girdi kalıcıdır. Embedding modelini ya da onun sunucusunu yükseltmek böyle bir olaydır: eski sürümün sakladığı vektörler yenileriyle artık karşılaştırılamaz.

Yine de bir tane kuracaksanız, onu savunulabilir kılan ölçüm, kimsenin yapmadığı ölçümdür: önbellek isabetlerinden örnek alın, kaçının gerçekten aynı soru olduğunu elle kontrol edin ve o oranı bir aralıkla raporlayın (Bölüm 5). Doğruluk oranı olmayan bir isabet oranı, yalnızca kanıta benzeyen bir sayıdır. Yanlış isabetleri azaltmanın yolları da var: yukarıdaki tablodaki bütün yanlış isabetler bir sayı, tarih, olumsuzlama ya da varlık farkı içeriyor. İsabeti döndürmeden önce iki sorgudaki sayıların ve adların eşleştiğini denetleyen basit bir kontrol ya da adayı bir çapraz kodlayıcıyla (cross-encoder) yeniden puanlamak (Bölüm 19.5) bunların bir kısmını yakalayabilir; ama bu bölümde sınanmadı ve yerini ölçüme bırakmaz. Ve bunların hepsinden önce, farklı olmak zorunda olan iki girdiyi gömüp embedding modelinin onları ayırt edebildiğini doğrulayın.

32.6 Sürümleri sabitlemek ve bir kullanımdan kaldırmadan sağ çıkmak

Kararlı bir adın arkasındaki bir LLM kararlı bir bağımlılık değildir. Sağlayıcılar sürümsüz bir takma adın (alias) işaret ettiği modeli günceller ve ardından gelen arızanın ayırt edici bir biçimi vardır: hiçbir şey hata vermez, hiçbir şey kaydedilmez ve çıktılarınız değişir.

Sessiz bir model yükseltmesi, sahip olduğunuz her kapıyı atlayan bir bağımlılık değişikliğidir. Hiçbir kod değişikliğinde (diff) görünmez, hiçbir testi tetiklemez ve sizin değil sağlayıcının takvimine göre gelir.

Çözümün yeri geçittir ve çözüm üç parçadan oluşur:

Çağıranlar bir takma ad ister; geçit onu sabitlenmiş bir sürüme çözer. Uygulama kodu summarizer der, geçit bunu tarihli bir model tanımlayıcısına eşler. Tek bir değişiklik her çağıranın aldığı modeli değiştirir ve — daha da yararlısı — tek bir sorgu “kimler hâlâ eski modelde?” sorusunu cevaplar.

Geçiş bir değerlendirme kapısı arkasında yapılır. Değerlendirme kapısı (eval gate), yeni sürümün ancak değerlendirmeyi geçerse devreye alınması demektir. Takma adı trafiğin küçük bir payı için yeni sürüme çevirin, ikisini de Bölüm 35’in süitinde puanlayın ve yeni sürümü yalnızca puanlar korunursa tüm trafiğe açın. Bu sıradan bir bağımlılık yükseltme disiplini; fark, geçit olmadan trafiği bölecek bir yerin olmaması.

Kullanımdan kaldırma, harekete geçebileceğiniz bir geri sayımla gelir. Sağlayıcılar modelleri önceden haber vererek emekliye ayırıyor; ama çağıranları sayamıyorsanız o haberin bir yararı yok. Geçidin istek log’u o sayımı verir.

Bilerek hiç model değiştirmeye niyetiniz olmasa da sabitlemeye değer: sessizce kayan bir takma ad, geçmişteki her değerlendirmeyi yeniden üretilemez kılar. Üç ay önceki bir puan, artık adını koyamayacağınız bir modelin puanıdır ve bu da ondan çıkarılan her gerileme (regression) karşılaştırmasını sessizce çürütür.

32.7 Politika için tek geçiş noktası

Bir geçit için son argüman en çok mühendisliğin dışındaki herkesi ilgilendiriyor ve teknik olmaktan çok yapısal.

Maskeleme, denetim log’u, data residency ve saklama süresi kesişen (cross-cutting) konulardır: her çağrı için geçerli olmaları gerekir ve beş servisin dördü için geçerli olan bir politika geçerli değildir. Bunları servis başına uygulamak kaymayı garantiler, çünkü beş takım biraz farklı beş karar verir ve bunların yalnızca biri kimsenin fark edeceği bir biçimde yanlış olur.

Dört politika ve tek bir yerin beş ayrı uygulamadan neden iyi olduğu
politika neye ihtiyaç duyar neden geçide ait
Maskeleme kişisel veriyi dışarı çıkmadan önce silmek ya da yer tutucu token’larla değiştirmek her yerde aynı biçimde uygulanan tek bir gerçekleme — mekaniği Bölüm 37’de
Denetim kimin, ne zaman, hangi modeli, neyle çağırdığı her çağrıyı gören tek bileşen geçit
Data residency AB verisini AB uç noktalarına yönlendirmek işin yönlendirme yarısı bir yönlendirme kararıdır ve yönlendirme zaten geçitte yapılır. Ama bu yalnızca yarısı: sağlayıcıyla yapılan sözleşme, alt işleyicilerin nerede olduğu ve log’larla önbelleklerin nerede tutulduğu da uyumlu olmalı; tek başına bir AB uç noktası bunların hiçbirini çözmez
Saklama kişisel veri içeren prompt’ları kaydetmemek ya da kısa süre kaydetmek beş yerine tek bir saklama kuralı

Yükümlülüklerin kendisi — hukuki dayanak, DPIA, AB Yapay Zekâ Yasası’nın katmanları, KVKK’nın gereksinimleri — Bölüm 38’in konusu. Buraya ait olan, dayandıkları mimari iddia: tek bir yerde zorunlu kılamadığınız bir politika, yalnızca uyulmasını umduğunuz bir politikadır.

Bir maliyeti var ve açıkça söylenmeli. Geçit, kurumdaki her LLM çağrısının kritik yolunda oturur; dolayısıyla erişilebilirliği herkesin erişilebilirliğine bir tavan, gecikmesi herkesin gecikmesine bir ektir. Bu gerçek bir ödünleşim (trade-off) ve “bir tane kurmalı mıyız?” sorusunun cevabının, Bölüm 32.1’deki problemler gerçekten var olana kadar “henüz değil” olmasının nedeni de bu.

32.8 Sezgi kontrolleri

Her birini açmadan önce cevaplayın. İlk ikisi bu katmanı hiç kurup kurmayacağınızı ve kurduktan sonra gerçekçi olarak ne vaat edebileceğini soruyor; ortadaki ikisi bir geçidin işleri en kolay kötüleştirdiği yerler — bir kesintiyi büyüterek ya da bir yazı turayı yönlendirici kılığına sokarak; son ikisi ise sessiz arızalar: kimsenin sormadığı bir sorudan servis edilen bir cevap ve bir dağıtım olmadan değişen bir model.

Hayır; şimdi bir tane kurmak net bir kayıptır.

Bir geçidin çözdüğü her problem bir çokluk problemidir: atfedilecek birkaç çağıran, soyutlanacak birkaç sağlayıcı, aynı tutulacak birkaç politika. Her birinden bir tane varken bunların hiçbiri yok ve katmanı ekleyerek kazandığınız şey bir ağ sıçraması, bir dağıtım ve erişilebilirliği artık kendinizinkine tavan olan bir bileşen.

Gerçek tetikleyici herhangi bir şeyin ikincisidir — ikinci takım, ikinci sağlayıcı ya da döngüye girebilen ilk ajan. O zamana kadar bir istemci kütüphanesi ve bir harcama uyarısı yeter.

Çıktı uzunluğunu tavanlamadıkça hayır.

Girdi token’ları çağrıdan önce sayılabilir; çıktı token’ları yalnızca çağrı bittiğinde bilinir ve pahalı yarı genellikle çıktıdır. Dolayısıyla kabul denetimi ya kötümserdir — max_tokens kadar bütçe rezerve edip kullanılmayanı sonra iade etmek, ki karşılayabileceğiniz istekleri reddeder — ya da iyimserdir, ki eşzamanlı çağıran başına kabaca bir isteklik çıktı kadar aşabilir.

Sanal anahtar başına max_tokens belirlemek, bilinmeyen bir nihai maliyeti rezerve edilebilir bir üst sınıra çeviren şeydir — sınırladığı çıktı için. Yeniden denemeler ve çağrı başına araç ücretleri onun dışında kalır ve onlar da rezerve edilmeli; akıl yürütme token’ları ise ancak sağlayıcınız onları tavana dâhil ediyorsa sayılır. Bu, bölümdeki en ucuz denetimdir ve en sık boş bırakılanıdır.

Kısmi bir bozulmayı tam bir kesintiye çevirebilirsiniz.

Yeniden denemeler tam da sağlayıcının en az yedek kapasitesi olduğu anda gelir, böylece daha fazla istek başarısız olur, böylece daha fazla istemci yeniden dener. Denetimler şunlar: jitter’lı backoff, çünkü düz backoff istemci filosunu yeniden eşzamanlayıp aynı anda yüklenen bir kalabalığa çevirir; bir devre kesici, ki bir kesintiyi yeniden keşfetmek için gecikme harcamayı bırakasınız; ve trafiğin bir kesri olarak bir yeniden deneme bütçesi — Google’ın istemcileri, istek başına üç denemelik tavana ek olarak, yeniden denemeler isteklerinin %10’unu geçtiğinde yeniden denemeyi bırakıyor.

Herkesin uyguladığı, istek başına tavandır ve bu tavan tek başına en kötü durumda yükün 3 kata yaklaşmasına yine izin verir — birkaç katman ayrı ayrı yeniden deniyorsa daha fazlasına. Oran bunu yaklaşık 1,1 kata indirir.

Rastgele aktarma baseline’ını görmeden cevaplanamaz.

%40’lık maliyet düşüşü %40’lık bir aktarma oranı demek değildir: 10 katlık bir fiyat oranında cascade maliyeti \(0{,}1 + e\) olduğundan %40 tasarruf, isteklerin yaklaşık yarısının (\(e \approx 0{,}5\)) güçlü modele aktarıldığı anlamına gelir. İsteklerin herhangi bir kısmını — politikanızın gerçekte aktardığı oran kadarını — rastgele seçip güçlü modele aktarmak da, sinyal olsun olmasın, biraz doğruluğu geri kazandırır. Soru, politikanızın aynı aktarma oranında bir yazı turayı yenip yenmediği — ve yenmiyorsa bir yönlendirici değil, pahalı bir rastgele sayı üreteci kurmuşsunuz demektir.

Önce o baseline’ı çalıştırın. Hiçbir maliyeti yok, çünkü değerlendirme kümesinde iki modelin de cevapları zaten elinizde ve bir sinyali bir orandan ayıran tek şey o.

Yalnızca o sayıyla hayır, çünkü o sayı önemli olan şeyi içermiyor.

İsabet oranı önbelleğin ne sıklıkla cevapladığını söyler. Ne sıklıkla doğru cevapladığı hakkında hiçbir şey söylemez ve anlamsal bir önbelleğin arıza kipi, kullanıcının sormadığı bir soruya akıcı bir cevap döndürmektir. Hiçbir şey hata vermez ve hiçbir şey kaydedilmez.

İsabetlerden örnek alıp hangi kesrinin gerçekten aynı soru olduğunu elle kontrol edin ve bunu bir aralıkla raporlayın. Ayrıca embedding benzerliğinin en önemli olduğu yerde anlamı izlemediğini not edin: Bölüm 3 zıt anlamlıların ilişkili sözcükler kadar yüksek puan aldığını gösterdi; bunun cümle düzeyindeki hâli de yukarıda ölçüldü — listenin tepesinde, 0,982’de bir cümle ve onun olumsuzu. Bir önbelleğin birbirine karıştırmaması gereken çift tam da budur.

Model tanımlayıcısına ve sabitlenmiş olup olmadığına.

Sürümsüz bir takma ad, sağlayıcının o an servis ettiği her neyse ona işaret eder; dolayısıyla bir model yükseltmesi üretime bir dağıtım, bir fark ya da bir test olmadan ulaşır. Sahip olduğunuz her kapıyı atlayan bir bağımlılık değişikliğidir ve onların takvimine göre gelir.

Çözüm yapısaldır: çağıranlar bir takma ad ister, geçit onu tarihli bir sürüme çözer ve geçişler bir trafik diliminde değerlendirme kapısı arkasında yapılır. Yan faydası yeniden üretilebilirlik — kayan bir takma ada karşı alınan bir puan, artık adını koyamayacağınız bir modelin puanıdır.

32.9 Mülakat soruları

Kaynak konusunda — Bölüm 2’deki çekincenin aynısı. Aşağıdaki sorular, bu kitabın baştan sona kullandığı iki güvenilir açık kaynakta — Chip Huyen’in Introduction to Machine Learning Interviews kitabı (Huyen 2021) ve Machine Learning Interviews deposu — tekrar tekrar geçen sorulardır; bunlara bu bölümün kendi ölçümlerinin cevaplanabilir kıldığı sorular eklendi.

32.9.1 Katmanı anlayıp anlamadığınızı sınayanlar

S: Bir model geçidi gerçekte size ne veriyor?

Atıf ve tek geçiş noktası; başka bir şey değil. Bir isteği hızlandırmaz — o Bölüm 31’in konusudur — ve bir ağ sıçraması ekler. Kazandırdığı şey şu: harcama takım başına atfedilebilir, anahtarlar tek yerden yenilenebilir, sağlayıcılar çağıranları düzenlemeden değiştirilebilir, politika bir kez zorunlu kılınabilir ve bir kullanımdan kaldırma bildirimi bir çağıran listesine dönüştürülebilir. Sonra ne zaman kurulmayacağını söyleyin: ikinci takım ve ikinci sağlayıcıdan önce o problemler yoktur ve geçit saf maliyettir.

S: Bir geçit bir harcama sınırını kesin olarak zorunlu kılabilir mi?

Çıktıyı tavanlamadan hayır. Girdi token’ları istek çalışmadan önce sayılabilir, çıktı token’ları yalnızca sonrasında ve pahalı yarı genellikle çıktıdır. Dolayısıyla zorunlu kılma ya kötümserdir — max_tokens kadarını rezerve edip kullanılmayanı sonra iade etmek, ki eksik hizmet verir — ya da iyimserdir, ki eşzamanlı çağıran başına yaklaşık bir isteklik çıktı kadar aşabilir. Sanal anahtar başına max_tokens belirlemek bilinmeyen bir nihai maliyeti rezerve edilebilir bir üst sınıra çevirir ve takımların atladığı adım budur.

S: Sağlayıcınız bozuluyor ve geçidiniz yeniden denemeye başlıyor. Ne olur?

Muhtemelen kendi yol açtığınız bir kesinti. Yeniden denemeler tam da sağlayıcının en az kapasitesi olduğu anda gelir, böylece arızalar artar ve yeniden denemeler onlarla birlikte artar. Üç denetimi adlandırın: jitter’lı üstel backoff, çünkü tek başına backoff istemci filosunu yeniden eşzamanlar; bir devre kesici, ki bir kesintiyi yeniden keşfetmek için gecikme ödemeyi bırakasınız; ve trafiğin bir kesri olarak bir yeniden deneme bütçesi — Google’ın istemcileri, istek başına üç denemelik tavana ek olarak, yeniden denemeler isteklerinin %10’unu geçtiğinde yeniden denemeyi bırakıyor. Ardından yalnızca tek bir katmanın yeniden denemesi gerektiğini ve bir 400’ün hiç yeniden denenmeye değmediğini ekleyin.

32.9.2 Bir tane yayına alıp almadığınızı sınayanlar

S: Yedek sağlayıcınız gece devreye girdi ve kimse fark etmedi. İyi mi kötü mü?

Kötü; güvenilirlik boyutu işin en küçük kısmı. Yedek farklı bir modeldir: çıktı biçimi, araç çağırma söz dizimi ve reddetme davranışı farklıdır; dolayısıyla birincil üzerinde ayarlanmış bir ayrıştırıcı yedeğin çıktısını reddedebilir ve kalite bir değerlendirme olmadan değişmiştir. Ya yedek yol birincille aynı değerlendirme süitindedir ya da geçit açık bir hata döndürüp fail closed çalışır. Sınanmamış bir modeli sessizce servis etmek, kimsenin bilerek seçmediği ama birçok ekibin yayına aldığı seçenektir.

S: Kalite gerilemesi olmadan LLM harcamasını %30 nasıl kesersiniz?

Seçmeden önce ölçün. Önce tam eşleşmeli cevap önbelleklemesi — anahtar ilgili durumu (kiracı, yetkiler, veri sürümü) kapsıyorsa ve tekrarlanan cevaplar kabul edilebilirse; isabet oranı trafiğinizin bir öğleden sonrada ölçebileceğiniz bir özelliği. Sonra Bölüm 31’deki prompt tarafı kolları, çünkü prompt ağırlıklı iş yüklerinde — bir sistem prompt’u artı erişilmiş bağlam — çıktı token başına daha pahalı olsa bile faturaya girdi hâkimdir. Ancak ondan sonra yönlendirme — ve yönlendirmenin kanıt gerektiren bir iddia olduğunu söyleyin: ucuz modelin doğruluğuna, pahalınınkine ve hangi isteğin hangisine ihtiyaç duyduğunu önceden söyleyen bir sinyale ihtiyacınız var. Sinyal aynı orandaki rastgele aktarmayı yenmiyorsa yönlendirme hiçbir şey kazandırmıyordur.

S: 60 gün içinde emekliye ayrılacak bir modelden geçişi tasarlayın.

Çağıranları geçidin istek log’undan sayın — geçit olmadan imkânsız olan adım. Takma adı küçük bir trafik payı için yeni sürüme çevirin, ikisini de üretim değerlendirme süitinde (Bölüm 35) puanlayın ve kanıta göre yeni sürümü tüm trafiğe açın. Eski sürümü son tarihe kadar sabitlenmiş ve karşılaştırma için erişilebilir tutun. Sürümsüz bir takma adın geçmişteki her puanı yeniden üretilemez kıldığını da açıkça söyleyin — sabitlemenin önce gelmesinin nedeni bu.

32.10 2026 alet çantası

Birinci tablonun tek satırı var, çünkü burada ölçülen tek şey bir embedding modeliydi. Bölümün asıl konusu ikinci tabloda; onu bir liste olarak değil, bir “kendin kur ya da hazır al” menüsü olarak okumaya değer: barındırılan hizmetler aksi hâlde işleteceğiniz bir bileşeni ortadan kaldırıyor ve o bileşen her çağrının kritik yolunda oturuyor.

Bu sayıların geldiği yığın. Python 3.14.5, Apple Silicon
kütüphane kullanılan sürüm burada ne işe yarıyor
ollama 0.24.0 önbellek eşiği ölçümü ve onun ardından gelen embedding modeli kusuru için nomic-embed-text servis ediyor

Bilmeye değer, yukarıda kullanılmadı:

Daha geniş ekosistem, yazım anındaki sürümler
proje sürüm ne zaman başvurursunuz
litellm 1.98.0 yaygın açık kaynak cevabı: birçok sağlayıcı üzerinde OpenAI biçimli tek bir API; proxy’de sanal anahtarlar, bütçeler ve yedekler
portkey-ai 2.3.4 yönlendirme, yeniden deneme ve önbellekleme sunan bir geçit; barındırılan hizmet olarak ya da kendi sunucunuzda
aisuite 0.1.14 bir proxy işletmeden soyutlamayı istediğinizde sağlayıcılar arası ince ve tek tip bir istemci
helicone 1.0.14 sağlayıcı API’lerinin önünde loglama ve maliyet atfı; Bölüm 34 ile örtüşür
Cloudflare AI Gateway hizmet uçta önbellekleme, hız sınırlama ve analitik; işletilecek bir bileşen olmadan
Kong AI Gateway hizmet / eklenti bir platform takımının zaten işletiyor olabileceği bir API geçidi üzerinde yapay zekâ yönlendirmesi ve politikası
OpenRouter hizmet tek bir anahtarın arkasından birçok barındırılan model arasında yönlendirme; sözleşmesiz yetenek yönlendirmesi için yararlı

32.11 Lab: başıboş bir döngüyü durduran bir geçit

Bu labın amacı bir denetimin gerçekten devreye girdiğini görmek. Kimsenin tetiklendiğini görmediği bir bütçe bir denetim değil, bir yapılandırmadır.

32.11.1 Adım 1 — bir sağlayıcının önüne bir proxy koyun

Herhangi bir geçit iş görür, kendi yazdığınız kırk satır dâhil. Üç şeye ihtiyacı var: istekleri iletmesi, çağrı başına (sanal anahtar, model, girdi token'ı, çıktı token'ı) kaydetmesi ve reddedebilmesi.

32.11.2 Adım 2 — iki çağırana ayrı sanal anahtarlar verin

İki anahtar, iki farazi takım, arkalarında tek bir gerçek sağlayıcı anahtarı. İkisinden de trafik gönderin ve anahtar başına bir harcama tablosu üretin. O tabloyu üretemiyorsanız labın geri kalanındaki hiçbir sınır zorunlu kılınamaz.

32.11.3 Adım 3 — gerçekten ulaşacağınız bir bütçe belirleyin

Sıradan trafikle birkaç dakika içinde tetiklenecek kadar küçük. Sonra anahtarlardan birine karşı adım tavanı olmayan bir ajan döngüsü çalıştırın — Bölüm 23’ün arıza kipi — ve bütçenin onu durdurmasını izleyin. Sınırı geçtikten sonra ne kadar harcadığını kaydedin, çünkü o aşım Bölüm 32.2’deki asimetrinin size maliyetidir.

32.11.4 Adım 4 — bir anahtarda çıktıyı tavanlayın, diğerinde tavanlamayın

Bir sanal anahtarda max_tokens belirleyin ve adım 3’ü tekrarlayın. Aşım öngörülebilir bir şeye küçülmeli. İki sayıyı da raporlayın; aradaki fark çıktıyı tavanlamanın argümanıdır.

32.11.5 Adım 5 — tam eşleşmeli önbellekleme ekleyip isabet oranını ölçün

(model sürümü, prompt, parametreler) üzerinden anahtarlayın; anahtara kiracıyı, çağıranın yetkilerini ve cevabın dayandığı verinin sürümünü de ekleyin. Yalnızca prompt yetmez; tam liste Bölüm 32.5’te. Bir saatlik gerçekçi trafiği tekrar oynatın — varsa gerçek, yoksa tekrarlanan sorularla sentetik — ve isabet oranıyla tasarrufu raporlayın. Aynı prompt’u iki sanal anahtardan da gönderin ve ortak bir girdi paylaşmadıklarını doğrulayın. Önbelleklenmiş bir cevabın dayandığı bir belgeyi güncelleyin ve o girdinin artık servis edilmediğini doğrulayın. Sonra açıkça söyleyin: gerçek trafiğinizin ne kadarının birebir tekrarlanmasını bekliyorsunuz?

32.11.6 Adım 6 — anlamsal bir önbelleğe güvenmeden önce embedding modelini kontrol edin

Herhangi bir benzerlik eşiğini ölçmeden önce, farklı olmak zorunda olan iki girdiyi gömün ve modelin onları ayırt edebildiğini doğrulayın. Bu bölümün embedding modeli edemiyordu: büyük harfle başlayan her kelime tek bir vektöre çöküyordu. Beş dakikalık bir iş; ama bir önbellek ile rastgele cevap üreteci arasındaki farkı belirler.

32.11.7 Adım 7 — devretmeyi bilerek bozun

Bir yedeği farklı bir modele yöneltin. Çıktısını ayrıştırdığınız yirmi istek gönderin — Bölüm 18’deki yapılandırılmış çıktı ideal — sonra birincili arızalanmaya zorlayıp aynı yirmisini gönderin. Ayrıştırıcının kaçını reddettiğini sayın.

32.11.8 Teslim edilecekler

Anahtar başına harcama tablosu; çıktı tavanıyla ve tavansız aşım; yalıtım ve geçersiz kılma kontrolleriyle birlikte önbellek isabet oranı; embedding modeli sağlamlık kontrolünüz; yedek yolda ayrıştırıcı arıza sayısı; ve yedeğinizin fail open mı (yedeğin cevabını yine de servis etmek) yoksa fail closed mı (hata döndürmek) çalışması gerektiğine dair, bu kararı haklı çıkaran sayıyla birlikte bir paragraf.

32.12 Alıştırmalar

  1. Atıf sorusu. Üzerinde çalıştığınız bir sistem için tahmin etmeden cevaplayın: geçen ay LLM çağrılarına en çok hangi takım harcadı? Öğrenmenin ne kadar sürdüğünü ve bunun bir dakika sürmesi için neye ihtiyacınız olduğunu yazın.

  2. Bütçe aşımı. Bildiğiniz bir iş yükü için, iyimser kabul altında bir bütçenin ne kadar aşılabileceğini hesaplayın: eşzamanlı çağıran sayısı çarpı max_tokens kadar çıktının maliyeti. O sayının katlanılabilir olup olmadığına karar verin ve değilse çıktıyı tavanlayın.

  3. Yeniden deneme fırtınası, kâğıt üstünde. Bilinen bir istek hızı ve istek başına en fazla üç deneme politikası olan bir servis alın. Tüm denemelerin yarısı arızalanmaya başladığında (her denemenin bağımsız olarak arızalandığını varsayın), sonra hepsi arızalandığında sağlayıcının gördüğü yükü hesaplayın. %10’luk bir yeniden deneme bütçesiyle yeniden hesaplayıp karşılaştırın. Sonra o da üç kez yeniden deneyen ikinci bir katman ekleyin.

  4. Yedek eşdeğerliği. Dayandığınız bir prompt’u birincil ve yedek modelinizde çalıştırın. Çıktıları karşılaştırın — biçim, uzunluk, reddetmeler, araç çağırma söz dizimi — ve ayrıştırıcınızın sağ çıkıp çıkmadığına karar verin. Cevabı gece üçte ihtiyacınız olmadan önce yazın.

  5. İsabet oranı, ölçülmüş. Bir gün boyunca gerçek trafikte tam eşleşmeli önbelleklemeyi ölçün. İsabet oranını, tasarrufu ve kaçırmaların kıl payı olan kesrini raporlayın. Sizi anlamsal bir önbellek kurmaya özendirecek olan o son sayıdır.

  6. Embedding modelinizi denetleyin. Erişim ya da önbellekleme için kullanacağınız embedding modelini alın ve farklı olmak zorunda olan çiftlerde sınayın: bir cümle ve olumsuzu, iki tarih, iki sipariş numarası, iki özel isim. Benzerlikleri raporlayın. Herhangi bir çiftin benzerliği 1,0 çıkıyorsa durun ve nedenini bulun.

  7. Yönlendirme, bir denetimle. Kendi göreviniz üzerinde bir cascade kurun: küçük bir model, büyük bir model ve bir aktarma sinyali. Birkaç aktarma oranında doğruluk ve maliyeti raporlayın ve her zaman yanında rastgele aktarma baseline’ını da raporlayın. Sinyaliniz rastgeleyi yenmiyorsa bunu söyleyin.

  8. Sabitleme denetimi. Kodunuzun gönderdiği her model tanımlayıcısını listeleyin. Hangilerinin tarihli sabitleme, hangilerinin kayan takma ad olduğunu işaretleyin. Her kayan olan için, sağlayıcı bu gece onu kaydırsa ne olacağını — ve bunu nasıl öğreneceğinizi — söyleyin.

32.13 Daha derine

Okumadan önce: kodunuzun gönderdiği her model tanımlayıcısını listeleyin ve hangilerinin tarihli sabitleme, hangilerinin kayan takma ad olduğunu işaretleyin. On dakika sürüyor ve geri kalanın ne kadar acil olduğuna o karar veriyor.

Makalelerin ötesi
kaynak ne olduğu
Addressing Cascading Failures bu bölümün kaynak gösterdiği kitaptan, yeniden deneme fırtınası mekanizmasının tamamı (Beyer vd. 2016)
Handling Overload eşlik eden bölüm: yük düşürme, kısma ve istemci tarafı yeniden deneme bütçesi
Exponential backoff and jitter önemli olan kısmın neden jitter olduğu, bunu gösteren benzetimle birlikte
litellm referans açık kaynak geçit; sanal anahtarları, bütçeleri ve yedekleri somut nesneler olarak görmek için proxy yapılandırmasını okuyun
portkey-ai/gateway yönlendirme ve yeniden denemeler konusunda farklı görüşleri olan ikinci bir uygulama — karşıtlık olarak yararlı
helicone tek probleminiz buysa, işin yalnızca atıf ve loglama yarısı
Cloudflare AI Gateway hiçbirini siz işletmediğinizde katmanın nasıl göründüğü
GPTCache çalışan bir sistem olarak anlamsal önbellekleme; bu bölümün eşik tablosunun yerine değil, yanında okuyun
RouteLLM RouteLLM makalesindeki (Ong vd. 2024) yönlendirici, değerlendirme düzeneğiyle — kopyalanmaya değen kısım o
Birincil kaynaklar
konu kaynak
çığ etkisi arızası, yeniden deneme bütçeleri, devre kesiciler Beyer vd. (2016)
bir model API kümesi üzerinde maliyet cascade’leri Chen vd. (2023)
tercih verisinden öğrenilmiş bir yönlendirici Ong vd. (2024)

32.14 Akılda kalması gerekenler

  • Geçit atıf ve tek geçiş noktası kazandırır, başka bir şey değil. Bir isteği hızlandırmaz — o Bölüm 31’in konusudur — ve erişilebilirliği herkesinkine tavan olan bir ağ sıçraması ekler. İkinci takım, ikinci sağlayıcı ya da döngüye girebilen ilk ajan geldiğinde kurun, öncesinde değil.

  • Bir isteği çalıştırmadan önce fiyatlandıramazsınız. Girdi token’ları kabulde sayılabilir, çıktı token’ları yalnızca tamamlanmada ve pahalı olan genellikle çıktıdır. Dolayısıyla bir bütçe ya kötümser biçimde zorunlu kılınır ya da eşzamanlı çağıran başına yaklaşık bir isteklik çıktı kadar aşar — anahtar başına max_tokens tavanlamadıysanız, ki bu en sık boş bırakılan denetimdir.

  • Yeniden denemeler bir bozulmayı bir kesintiye çevirir. Jitter’lı backoff, çünkü düz backoff istemci filosunu yeniden eşzamanlar; bir devre kesici; ve trafiğin bir kesri olarak bir yeniden deneme bütçesi. Google istek başına üç denemelik bir tavan ve yeniden denemeler o istemcinin isteklerinin %10’unu geçtiğinde yeniden denemeyi durduran istemci başına bir kural işletiyor — birincisi en kötü durumda yine de yaklaşık 3 kat yüke izin verir, ikincisi bunu yaklaşık 1,1 kata indirir. Yalnızca yeniden denenebilir hataları ve yalnızca tek bir katmanda yeniden deneyin.

  • Devretme bir model değişimidir, dolayısıyla bir değerlendirme problemidir. Farklı biçim, farklı araç çağırma söz dizimi, farklı reddetmeler; birincil üzerinde ayarlanmış bir ayrıştırıcı yedeği reddedebilir. Ya yedek yolu aynı süitte değerlendirin ya da açık bir hata döndürüp fail closed çalışın. Sınanmamış bir modeli sessizce servis etmek, kimsenin bilerek seçmediği ama birçok ekibin yayına aldığı seçenektir.

  • Yönlendirme bir mimari hakkında değil, bir sinyal hakkında bir iddiadır. Yayımlanmış cascade’ler ve öğrenilmiş yönlendiriciler gerçek tasarruflar bildiriyor (Chen vd. 2023; Ong vd. 2024), ama o sonuçların her biri hangi isteklerin zor olduğunu bilmeye bağlı. En cazip sinyal — modele ne kadar emin olduğunu sormak — Bölüm 12’de sınıflandırıcı skorunun 0,843’üne karşı AUROC 0,667 ölçüldü. Her zaman rastgele aktarma baseline’ını raporlayın; politika onu yenmiyorsa işi yapan şey aktarma oranıdır.

  • Tam eşleşmeli önbellekleme, anahtar doğru kurulduğunda neredeyse bedava tasarruf; anlamsal önbellekleme ise bir doğruluk kararı. On beş etiketli çift üzerinde ölçüldüğünde kümedeki en benzer çift bir cümle ve onun olumsuzu, 0,982’de çıktı; gerçekten aynı anlamdaki bir soru çifti ise 0,609 aldı. Sınıflar o kadar örtüşüyor ki hiçbir tek eşik onları ayırmıyor: en az hatalı seçenek hiçbir şeyi önbelleklememek ve bu, gerçekten aynı anlamı taşıyan beş çiftin beşini de kaçırıyor.

  • Önbelleğe güvenmeden önce embedding modelini kontrol edin. Bu bölümün düzeneğinde ollama 0.24.0 altındaki nomic-embed-text, büyük harfle başlayan her kelimeyi tek bir sabit token’a eşledi: Monday, Cat, Ankara ve XYZZY bayt bayt aynı vektörleri üretti ve Cat sat on the mat, Dog sat on the mat’e eşit çıktı. Küçük harfli metin sorunsuzdu. Aynı belirti ollama projesine de raporlanmış ve sonraki ollama sürümlerinde düzeltilmiş — o düzeltme de vektörleri değiştiriyor. Onun üzerine kurulmuş bir önbellek, pazarın sorusuna pazartesinin cevabını 1,0 benzerlikte verirdi ve hiçbir kayıt bırakmazdı. Yüzeye çıkmasının tek nedeni düşük puan alması gereken bir çiftin en yüksek puanı almasıydı.

  • Sürümü sabitleyin; takma ad, dağıtım olmadan değişen bir bağımlılıktır. Sessiz bir sağlayıcı yükseltmesi sahip olduğunuz her kapıyı atlar ve ayrıca geçmişteki her değerlendirmeyi yeniden üretilemez kılar, çünkü puan artık adını koyamayacağınız bir modele aittir.

  • Politika tek geçiş noktasına aittir. Maskeleme, denetim, data residency ve saklama her çağrı için geçerli olmalı; beş ayrı uygulama kaymayı garantiler. Tek bir yerde zorunlu kılamadığınız bir politika, yalnızca uyulmasını umduğunuz bir politikadır.