Ölçeklendirme Neden Bu Kadar Zor?
LLM ile prototip yapmak tehlikeli derecede kolay. Birkaç API çağrısı, güzel bir prompt ve öğleden sonra bitmeden çalışan bir demo elinizde. Ama asıl macera, bu demoyu binlerce — hatta milyonlarca — gerçek kullanıcıya sunmanız gerektiğinde başlıyor. Hızlı olmalı, güvenilir olmalı ve sizi iflas ettirmemeli. Klasik web servislerinden farklı olarak LLM uygulamalarında bambaşka sorunlar var: token limitleri, öngörülemeyen yanıt süreleri, model erişilebilirliği ve kullanımla doğru orantılı artan maliyetler.
Daha fazla sunucu ekleyerek bu işi çözemezsiniz. Altı farklı alanda bilinçli bir strateji lazım: token verimliliği, akıllı cache, istek yönetimi, maliyet kontrolü, gecikme azaltma ve gözlemlenebilirlik. Bunlardan birini atladığınızda, umut vadeden demonuz pahalı bir baş ağrısına dönüşür.
Başarılı bir LLM ürünüyle pahalı bir deney arasındaki fark kullandığınız model değil — modelin etrafına kurduğunuz altyapı, optimizasyon ve operasyonel disiplin.
Token Optimizasyonunu Ciddiye Alın
Para nereye gidiyor? Tokenlara. Prompt veya yanıttaki her gereksiz token hem maliyet hem gecikme demek. Token optimizasyonunu "sonra hallederiz" diye erteleyen ekipler gördüm — ay sonu fatura gelince panik oluyorlar. İlk günden birinci öncelik olarak ele alın.
İlk adım: prompt sıkıştırma. Sistem promptları zamanla şişer. Yeni talimatlar eklenir, örnekler birikir, bir bakarsınız her istekle 2.000 token boilerplate gönderiyorsunuz. Düzenli denetim yaparak token sayısını %20-40 azaltabilirsiniz — çıktı kalitesinden ödün vermeden. LLMLingua gibi araçlar düşük bilgi değerli tokenleri otomatik ayıklıyor.
İkinci adım: bağlam yönetimi. Tüm konuşma geçmişini her isteğe tıkmayın. Sliding window kullanarak sadece en güncel ve ilgili mesajları tutun. RAG pipeline'larında alınan chunk sayısını sınırlayın, eski bağlamı özetleyin. Yanıt kalitesini bozmadan ne kadar token kesebildiğinize şaşırırsınız.
- Sistem promptlarını üç ayda bir gözden geçirin — neredeyse her seferinde kırpılacak fazlalık bulursunuz.
- Konuşma geçmişi için sliding window kullanın: son N tur artı bir özet yeterli.
- Belgeleri context window'a eklemeden önce sıkıştırın.
- Her zaman max_tokens limiti koyun — kontrolsüz üretimi önler.
- Yapılandırılmış çıktı formatlarını (JSON mode) deneyin — serbest metin yanıtlardan genelde daha kısa olur.
Semantik Cache: Aynı Yanıt İçin İki Kez Ödeme Yapmayın
Klasik cache, doğal dil sorguları için pek işe yaramaz. İki kullanıcı aynı soruyu tamamen farklı kelimelerle sorar — exact match işe yaramaz. Semantik cache bu sorunu embedding benzerliği ile çözüyor. "Şifremi nasıl sıfırlarım?" ile "Şifremi unuttum, ne yapmalıyım?" aynı soru olarak tanınıyor.
Mantık şöyle: gelen sorguyu embedding vektörüne çeviriyorsunuz, sonra cache'teki vektörlerle cosine similarity karşılaştırması yapıyorsunuz. Eşik değerinin (genelde 0.92-0.97) üzerinde eşleşme varsa, cache'teki yanıtı hemen döndürüyorsunuz — LLM'e hiç gitmeden. Pratikte bu, çoğu üretim iş yükünde gereksiz API çağrılarının %30-60'ını ortadan kaldırıyor. Ciddi tasarruf.
import { cosineSimilarity } from "./math";
import { getEmbedding } from "./embeddings";
interface CacheEntry {
embedding: number[];
response: string;
createdAt: number;
}
const SIMILARITY_THRESHOLD = 0.95;
const TTL_MS = 1000 * 60 * 60; // 1 saat
class SemanticCache {
private entries: CacheEntry[] = [];
async get(query: string): Promise<string | null> {
const queryEmbedding = await getEmbedding(query);
const now = Date.now();
for (const entry of this.entries) {
if (now - entry.createdAt > TTL_MS) continue;
const similarity = cosineSimilarity(queryEmbedding, entry.embedding);
if (similarity >= SIMILARITY_THRESHOLD) {
return entry.response;
}
}
return null;
}
async set(query: string, response: string): Promise<void> {
const embedding = await getEmbedding(query);
this.entries.push({ embedding, response, createdAt: Date.now() });
}
}Embedding benzerliği ve TTL kullanan basit ama etkili bir semantik cache.
Üretimde bu linear scan yerine Pinecone, Qdrant veya pgvector gibi bir vektör veritabanı kullanın — milisaniyenin altında arama yapabilirsiniz. TTL politikası da şart; eski yanıtlar sonsuza kadar kalmasın, özellikle model veya veri kaynakları değiştiğinde.
Rate Limiting ve Yük Dengeleme
Her LLM sağlayıcı katı rate limit uyguluyor — dakika başına istek (RPM), dakika başına token (TPM) veya ikisi birden. Bunları hesaba katmazsanız, trafik artışlarında 429 hataları alırsınız. "Alır mıyım" değil, "ne zaman alırım" meselesi. Ve kullanıcılarınız bunu fark eder.
İşe yarayan yaklaşım katmanlı bir strateji. Uygulama seviyesinde token-bucket veya sliding-window rate limiter ile sağlayıcı kotalarında kalın. Altyapı seviyesinde istekleri birden fazla API key'e dağıtarak toplam kapasiteyi artırın. Yeterli büyüklükteyseniz birden fazla sağlayıcıyla (OpenAI, Anthropic, Google) çalışın. Biri sorun yaşadığında diğerine yönlendirin.
Hataları Zarif Şekilde Yönetmek
Jitter'lı exponential backoff şart. Rate limit hatası aldığınızda, üstel olarak artan bir süre artı rastgele bir gecikme ekleyerek tekrar deneyin. Jitter olmadan tüm client'lar aynı anda tekrar dener ve hemen yeni bir rate limit tetikler — klasik thundering herd sorunu. Tekrar deneme sayısını 3-5 ile sınırlayın; kalıcı hatalarda sonsuz döngüye girmeyin.
Maliyetleri Dizginlemek
Kontrol mekanizması olmazsa LLM maliyetleri çok hızlı tırmanır. Yanlış yapılandırılmış tek bir pipeline veya viral bir özellik, bir gecede on binlerce dolarlık fatura çıkarabilir. Hem akıllı mimari hem de operasyonel güvenlik ağları lazım.
Akıllı Model Yönlendirme
Her istek en güçlü modeli gerektirmez. Model router gelen isteği değerlendirir ve işi yapabilecek en ucuz modele yönlendirir. Basit sınıflandırma, anahtar kelime çıkarma, biçimlendirme gibi işler küçük ve ucuz modellerle — veya kendi sunucunuzda çalışan fine-tune'lanmış açık kaynak modellerle — hallolur. Frontier modelleri gerçekten karmaşık akıl yürütme gerektiren görevlere saklayın.
interface ModelConfig {
name: string;
costPerMillionTokens: number;
maxComplexity: number;
}
const MODELS: ModelConfig[] = [
{ name: "gpt-4o-mini", costPerMillionTokens: 0.15, maxComplexity: 3 },
{ name: "claude-3-haiku", costPerMillionTokens: 0.25, maxComplexity: 5 },
{ name: "claude-sonnet-4", costPerMillionTokens: 3.0, maxComplexity: 8 },
{ name: "claude-opus-4", costPerMillionTokens: 15.0, maxComplexity: 10 },
];
function selectModel(estimatedComplexity: number): ModelConfig {
const suitable = MODELS
.filter((m) => m.maxComplexity >= estimatedComplexity)
.sort((a, b) => a.costPerMillionTokens - b.costPerMillionTokens);
return suitable[0] ?? MODELS[MODELS.length - 1];
}İşi yapabilecek en ucuz modeli seçen basit bir model router.
Bunun yanına kullanıcı ve organizasyon bazlı harcama limitleri, günlük bütçe uyarıları ve harcama eşiğine yaklaşıldığında devreye giren circuit breaker'lar ekleyin. Eşik aşılmaya yakınsa cache'li veya önceden hesaplanmış yanıtlara geçiş yapın.
Hızlı Hissettirmek
Kullanıcılar anında yanıt bekler ama LLM çıkarımı doğası gereği yavaş — tam bir yanıt genelde birkaç saniye sürer. İyi haber şu: toplam üretim süresi aynı kalsa bile uygulamayı çok daha hızlı hissettirebilirsiniz.
Streaming burada en büyük kazanım. Tüm yanıtı beklemek yerine tokenları üretildikçe gönderiyorsunuz. İlk token'a kadar geçen süre (TTFT) saniyelerden birkaç yüz milisaniyeye düşüyor. Kullanıcı hemen okumaya başlıyor. Deneyim "dönen simgeye bakma"dan "yapay zekanın gerçek zamanlı düşünmesini izleme"ye dönüşüyor.
- Streaming'i açın — yapabileceğiniz en etkili gecikme optimizasyonu bu.
- Bağımsız alt görevleri paralel çalıştırın (örneğin başlık ve özeti aynı anda üretin).
- Yoğun olmayan saatlerde sık sorulan sorguların yanıtlarını önceden hesaplayıp cache'leyin.
- Edge deployment ile LLM sağlayıcısına olan ağ gecikmesini en aza indirin.
- Spekülatif yürütme deneyin: hızlı modelle üretmeye başlayın, güçlü modele de yönlendirin, kalite yeterliyse hangisi önce biterse onu kullanın.
RAG gibi çok adımlı pipeline'larda her aşamayı ayrı ayrı profil edin. Darboğaz çoğu zaman beklediğiniz yerde değil. Yavaş bir vektör araması veya optimize edilmemiş bir reranking adımı, LLM çağrısının kendisinden daha fazla gecikmeye neden olabilir.
Göremediğinizi Düzeltemezsiniz
Gözlemlenebilirlik olmadan LLM uygulaması işletmek kör uçuş yapmak gibi. Klasik izleme (uptime, hata oranları, yanıt süreleri) gerekli ama yetmez. Kaliteyi, maliyetleri ve performansı takip etmek için LLM'e özel metrikler şart.
Tip
Her LLM çağrısına structured logging ekleyin: model adı, prompt token sayısı, completion token sayısı, gecikme, tahmini maliyet ve trace ID. Bu veriler debugging ve optimizasyon için altın değerinde. LangSmith, Helicone veya OpenTelemetry tabanlı çözümler bu işi kolaylaştırır.
Takip etmeniz gerekenler: endpoint ve kullanıcı bazlı token kullanımı, cache hit oranı, p50/p95/p99 gecikme, hata türlerine göre oranlar (rate limit, timeout, content filter), otomatik değerlendirme varsa kalite skorları ve model/özellik bazlı günlük maliyet. Bunları gerçek zamanlı dashboard'a koyun — gerilemeleri hızla yakalarsınız.
Gözden kaçırması kolay bir şey var: çıktı kalitesi sessizce bozulabilir. Model daha çok halüsinasyon görmeye, konudan sapmaya veya ince yanlışlar üretmeye başlayabilir — hiçbir klasik hata sinyali tetiklenmez. Üretim çıktılarının bir örneklemini referans yanıtlara göre puanlayan otomatik değerlendirme pipeline'ları kurun. Kalite gerilemeleri için erken uyarı sisteminiz bu olsun.
Sonuç
LLM uygulamalarını prototipten üretime taşımak sadece kapasite artırmak değil. Altyapı, maliyet ve kalite hakkında aynı anda farklı düşünmenizi gerektiren çok boyutlu bir problem.
- Token optimizasyonu her şeyin temeli — kazandığınız her token hem maliyeti hem gecikmeyi düşürür.
- Semantik cache, eşdeğer sorguları tanıyarak gereksiz LLM çağrılarının %30-60'ını ortadan kaldırır.
- Rate limiting ve çoklu sağlayıcı failover, işler ters gittiğinde sizi ayakta tutar.
- Model routing her isteği işi yapabilecek en ucuz modele yönlendirir.
- Streaming ve paralel yürütme, toplam hesaplama süresi aynı kalsa bile uygulamayı hızlı hissettirir.
- Maliyet, gecikme, token kullanımı ve çıktı kalitesini kapsayan kapsamlı gözlemlenebilirlik, üretimde vazgeçilmez.
Bu işte başarılı olan ekipler, altyapı ve optimizasyonu maliyetler patladıktan veya kullanıcılar şikayet etmeye başladıktan sonra eklemiyor. İlk günden birinci öncelik olarak ele alıyorlar. Bu temelleri erken atın — kullanım arttıkça ve yeni modeller çıktıkça sürdürülebilir şekilde büyüyen bir platformunuz olsun.