32 Geçit Katmanı: Yönlendirme, Maliyet ve Yönetişim
Öğrenme hedefleri. Bu bölümün sonunda:
- bir model geçidinin ortadan kaldırdığı belirli problemleri adlandırabilir ve bu problemlerin sizde henüz ortaya çıkmadığı durumu tanıyabilirsiniz;
- bir isteğin maliyetinin hangi yarısını önceden fiyatlandırabileceğinizi, hangi yarısını fiyatlandıramayacağınızı bilerek bütçe ve kota uygulayabilirsiniz;
- bir bozulmayı bir kesintiye çeviren yeniden deneme fırtınasını kurmadan sağlayıcılar arası devretme tasarlayabilirsiniz;
- bir maliyet yönlendirme önerisini mimarisine değil, dayandığı sinyale göre değerlendirebilirsiniz;
- tam eşleşmeli ve anlamsal cevap önbelleklemesini farklı riskleri olan farklı özellikler olarak ele alabilirsiniz;
- model sürümlerini sabitleyebilir ve kullanımdan kaldırılan modellerden yenilerine bir değerlendirme kapısı arkasında geçebilirsiniz.
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:
| 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:
| 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:
| 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:
| 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.
| 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.
| 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ı:
| 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
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.
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_tokenskadar çıktının maliyeti. O sayının katlanılabilir olup olmadığına karar verin ve değilse çıktıyı tavanlayın.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.
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.
İ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.
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.
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.
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.
| 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 |
| 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_tokenstavanlamadı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
ollama0.24.0 altındakinomic-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 sonrakiollamasü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.