Ayda 4.000 dolardan 40 dolara: agent guardrail'lerinin gerçek maliyet eğrisi
Kanı durduran şey daha küçük bir model değildi — planlayıcının fazladan adım iştahını kesmekti.
Mart 2025'te bir Salı sabahı, 09:14. İkinci kahvemdeydim. Stripe'tan mail geldi: "OpenAI kullanımınız eşiğe yaklaşıyor." Fatura döngüsünün dördüncü gününde 1.247 dolar yazıyordu.
Migros fişinin arkasında hesapladım. 1.247 ÷ 4 × 30 = 9.350 dolar. Sonra Pazartesi'den beri trafiğin tırmandığını hatırladım, gerçekçi rakam ayda 4.000 dolar civarıydı. Yine de. Bir marketplace arama çubuğunda tool seçimi yapması beklenen bir yardımcı için ayda dört bin dolar. Üç gün. Agent prodda üç gündür ayaktaydı.
Laptopu kapattım, kahveyi içtim, laptopu açtım. Logları okumaya başladım.
Marketplace'in CFO'su benim adımı bilmez. Sadece faturadaki satırı bilir. İlişkimiz bundan ibaret. Satır garipleşince finansçısı kibar bir mail atar, her hafta o kibarlık biraz daha azalır. Cuma geldiğimde kibarlık dördüncü günündeydi.
Aslında ne çalışıyordu
Nova'nın tool-seçim agent'ı 7 milyon ürünlük kataloğun önünde duruyor. Biri "kahve makinesi 2.000 TL altı, espresso da yapsın" diye arattığında, agent hangi retrieval tool'larının hangi sırayla çağrılacağına karar veriyor. Beş tool vardı: BM25 search, vector search, image-match ("buna benzeyen" sorguları için), brand-affinity skoru ve stok kontrolü.
İlk versiyonu, itiraf edeyim, pek kurcalamadığım bir kurulumdu. Planlayıcı GPT-4o. Tool sonuçlarını yorumlayan da GPT-4o. Derinlik limiti yok. Bütçe limiti yok. Reasoner ne kadar tool zinciri uygun gördüyse o kadarını yapıyordu.
"Uygun gördüğü" şu çıktı: sorgu başına ortalama 8 LLM çağrısı. 32K input token. 4K output token. Günde 12K sorguyla çarpınca yaklaşık 95K çağrı, 3.5M input token, 480K output token. Her gün.
Planlayıcı uzun planlama adımlarına bayılıyordu. BM25 çağırıyor, sonuçları okuyor, "belirsiz" diyip vector search planlıyor, onu okuyor, "bütünlük için" image-match çağırıyor, başka bir adım daha ekliyor, sonra özetliyordu. Her adım yeni bir tam-context çağrısıydı. Modelin benim Stripe limitimden haberi yoktu. Sadece titiz davranıyordu.
Sorun şu: ben titizliğe hiçbir fırsat maliyeti yüklememiştim. Planlayıcı promptunda "sonuç eksikse ek tool çağırabilirsin" yazıyordu. Eksik ama yeterli'nin durabileceği bir nokta olduğunu söyleyen hiçbir şey yoktu. Bu yüzden hiç durmadı.
Bir sorgunun ne kadar uzayabileceğine dair üst sınır yoktu. Logic gate yoktu. "Şu kadar tool çağırdıysan dur" yoktu. Planlayıcının zincir oluşturma iştahı sonsuzdu, ben de ona sınırsız mutfak vermiştim.
Guard 1 — bütçe zarfı
Bütçe zarfını Salı öğleden sonra deploy ettim. Bu, kimseye gösteremeyeceğim versiyon:
// İlk deneme — Salı 14:30, panik modu
class BudgetEnvelope {
private spent = 0;
charge(input: number, output: number) {
this.spent += input + output;
// bunu bir hafta önce eklesem $800 kurtarmıştım
if (this.spent > 50_000) {
console.warn("Bütçe yüksek"); // <- bu bir guardrail değil
}
}
}O console.warn, uykusuz 14:30'da yazılan kod tipidir. Log atar. Hiçbir şey yapmaz. Agent harcamaya devam eder.
Çarşamba sabahı asıl versiyon hazırdı:
class BudgetEnvelope {
private spent = 0;
constructor(private readonly capPerQuery = 50_000) {}
charge(input: number, output: number) {
this.spent += input + output;
if (this.spent > this.capPerQuery) {
// uyarı değil — fırlat. planlayıcı yakalar ve eldeki
// tool sonuçlarıyla en iyi cevabı verir.
throw new BudgetExceeded(this.spent, this.capPerQuery);
}
}
}Sorgu başına 50K token, sert tavan. Planlayıcı exception'ı yakalıyor, o ana kadar çalışan tool'larla "elimden gelenin en iyisi" cevabı dönüyordu. Bazı cevaplar kötüleşti. Çoğu aynı kaldı. Çünkü fazladan adımların çoğu sinyal değil, planlayıcının lüksüydü.
Bu tek değişiklik günlük projeksiyonu 4 binden 1.400 dolara indirdi. Tek sınıfla yüzde 66 düşüş. Planlayıcı bütçesinin çoğunu sekizinci tool çağrısına harcıyordu, orada marjinal bilgi neredeyse sıfırdı.
Şunun altını çizmek istiyorum, çünkü her seferinde unutup yeniden öğrendiğim kısım bu. Bütçe zarfı bir maliyet kontrolü değil. Planlama şekli kontrolü. Planlayıcı sabit bir bütçesi olduğunu öğrendiği an, yüksek değerli tool çağrılarını öne almaya başladı, çünkü promptta "token bütçen var" yazıyordu. İlk çağrıdaki davranış değişikliği, son çağrıdaki kesimden daha büyüktü.
Guard 2 — model katmanlama
Sonraki bariz adım. Planlayıcı için gerçekten GPT-4o gerekli mi? Planlama yapılandırılmış bir iş. Planlayıcı bir JSON object çıktısı veriyor, "sıradaki tool şu" diye. Düzyazı yazmıyor. Kuantum mekaniği üzerinde akıl yürütmüyor.
Planlayıcıyı Claude Haiku 4.5'e çevirdim. Sonuç yorumlama adımını da küçük modele ve sıkı bir structured-output şemasına bağladım. Reasoner kalite model sadece tek yerde kaldı: final cevabın doğal dilde kompoze edildiği aşama.
Production'da katmanlama şöyle göründü:
| Adım | Önce | Sonra |
|---|---|---|
| Planlayıcı | GPT-4o | Haiku 4.5 |
| Tool sonuç parse | GPT-4o | Haiku 4.5 + schema |
| Final kompozisyon | GPT-4o | GPT-4o |
Aylık projeksiyon 1.400 dolardan 380 dolara indi. Planlama kalitesi eval setimde belki yüzde 2 düştü, zaten "iyi plan" diye skorlama gürültü tabanım içindeydi.
Eval set hakkında bir parantez. "Eval set" dediğim şey 230 elle etiketlenmiş sorguydu, üç gün öğleden sonraları kafemde otururken hazırladım. Üzerinde gözünü kapatıp koşabileceğin gold standard değil, ama "yeni planlayıcı geçen haftaki gibi mi davranıyor?" sorusunu cevaplayacak kadar yeterli. Mükemmellik aramak yerine "rejimin değişmediğini" doğrulamak yeterliydi.
Bu, çoğu insanın ilk yapacağı adım. Ben bilerek ikinci yaptım. Model değiştirmek kolay çözüm, alkış toplar. Adım kesmek sıkıcı çözüm, faturayı asıl indiren bu.
Guard 3 — gerçekten para kazandıran caching
Denediğim ilk cache, ham sorgu stringi üzerinde basit bir LRU'ydu. Trafiğin yüzde 4'üne hit attı. İnsanlar birebir aynı stringi aratmıyor.
İkinci cache cümle embedding'leri kullandı. Embedding'i kaba bir bucket'a hash'liyorsun, benzer geçmiş sorgulara bakıyorsun, cosine similarity 0.92'nin üstündeyse tool seçim planını yeniden kullanıyorsun. Deploydan sonraki ilk Salı sabahı yoğun saatte yüzde 38 hit gördüm. İnsanlar aynı şeyleri biraz farklı kelimelerle arıyordu. Haftalık ortalama yüzde 22'de oturdu.
async function planWithCache(query: string) {
const emb = await embed(query);
const hit = await cache.findSimilar(emb, 0.92);
if (hit) {
// planı tekrar kullan, cevabı değil.
// cevap bayatlayabilir; tool seçimi nadiren bayatlar.
return runPlan(hit.plan, query);
}
const plan = await planner(query);
await cache.put(emb, plan, ttl="6h");
return runPlan(plan, query);
}Önemli detay: cevabı değil, planı cache'ledim. Stok ve fiyat değişir. "3 bin altı kablosuz kulaklık" için hangi retrieval tool'larının ateşleneceği değişmez. Tool sonuç cache'i sadece deterministik sorgulara uygulandı, aynı SKU lookup'ı, aynı brand affinity skoru, 15 dakikalık TTL ile, çünkü warehouse verisi o kadar süre tutarlı kalıyor.
380 dolar, 120 dolara indi. Caching üçte iki daha kesti.
Cache invalidation klasik en zor problem olarak anılır ya, bu sefer öyle değildi. Plan cache'inin TTL'i kısaydı, altı saat. Plan kategori bazında tutuluyordu, kullanıcı bazında değil. Aynı "kahve makinesi" intent'iyle gelen iki farklı kullanıcı aynı planı paylaşıyordu ama farklı çalıştırma sonuçları alıyordu. Bu detayı atlamak, kullanıcı A'nın cevabının kullanıcı B'ye gitmesi demek olurdu. Ondan sonra geri çıkamadığın bir hata gelirdi.
Guard 4 — adaptif derinlik
Maliyet artık katlanılabilirdi ama bir şey daha vardı. Loglara bakınca planlayıcının kendinden bile sakladığı bir şeyi fark ettim: sorguların çoğu beş tool'a ihtiyaç duymuyor. İki yetiyor.
Takımdaki bir junior tool sonuçları için confidence scorer yazmıştı. Özünde "cevap verecek kadar temiz sonuç aldık mı?" sorusunu çözüyordu. Başka bir serviste kullanılmadan duruyordu. Onu bağladım.
async function adaptivePlan(query: string, plan: Tool[]) {
const results = [];
for (const tool of plan) {
const r = await run(tool, query);
results.push(r);
const confidence = scoreResults(results, query);
// zaten emin isek dur. planlayıcı devam etmek istiyor.
// planlayıcı yanılıyor.
if (confidence > 0.85 && results.length >= 2) break;
}
return results;
}Sonraki haftanın loglarından sayılar: sorguların yüzde 18'i ikiden fazla tool çağrısına ihtiyaç duydu. Geri kalan yüzde 82, beşinci adımda alacakları aynı cevapla erken duruyordu. Planlayıcı beş adımlı planlar yapıyordu çünkü prompt örnekleri öyle gösteriyordu. Gerçek dünya o kadarına ihtiyaç duymuyordu.
120 dolar, 40 dolara indi.
Bu adımı yapmak öncekilerden daha uzun sürdü. "Confidence 0.85" sayısını calibrate etmek için iki gün boyunca logları tekrar tekrar süzdüm. 0.75'te durdurursam ne oluyor? Cevap kalitesi düşüyor mu? 0.90'da? Yüzde 18 yerine yüzde 12'yi kesiyor. Bu tür eşik ayarları, hipotezini test edeceğin gerçek üretim trafiği olmadan teoride yapılamaz. Bir hafta bekledim, loglardan bakıp ince ayar çektim.
Mart 2025'teki kendime ne söylerdim
En büyük tek düşüş daha ucuz modelden gelmedi. Guard 1 ile Guard 4 — bütçe zarfı ve işin bitince dur — ikilisinden geldi. Birlikte tasarrufun yüzde 80'ini yaptılar. Model değişimi yüzde 20.
Sezgiye ters kısım şu: ucuz modeller tembel cevap. İnternet bayılıyor çünkü tek satırlık PR. "Haiku'ya geçtim, yüzde 80 tasarruf ettim" güzel bir tweet olur. Asıl mühendislik işi, hangi adımların hiç çalışmaması gerektiğini bulmak. Ve bunun için loglarınla birkaç akşam oturman gerek.
Bu yazıyı okurken belki "ben Haiku'ya geçerek başlardım" diyenler vardır. Mantıklı bir refleks, ama yanıltıcı. Çünkü Haiku ile dahi planlayıcı, bütçesiz bırakılırsa, 8 yerine 14 tool çağıracaktı. Testte gördüm. Birim maliyet düşük olunca planlayıcının iştahı serbest kalıyor. Önce şekli bağlamadan modeli ucuzlatmak, çukurun tabanını yumuşak bir yatakla dolduruyor. Düşmeye devam ediyorsun, sadece daha yavaş.
Vardığım yerin matematiği: ayda 40 dolar, 360K sorgu (12K günlük × 30). Sorgu başına 0.0003 dolar. Marketplace CFO'sunun yeni rakamları görünce tepkisi tek bir başparmak emojisiydi. O adamdan geçit töreni sayılır.
En zor kısım agent'ı yazmak değil. Çalışmaması gereken parçaları yazmak.
Geriye dönüp bakınca, dört guardrail'ın hepsi aslında aynı şeyi farklı katmanlarda söylüyor. Modele güvenme, ona sınır koy. Bütçe zarfı tokenda sınır koyuyor. Model katmanlama, kararın hangi maliyet sınıfında alındığına sınır koyuyor. Cache, aynı kararın iki kez verilmesine sınır koyuyor. Adaptif derinlik, planın kendi hayalindeki uzunluğuna sınır koyuyor. Dördü de farklı yerlerde aynı cümleyi söylüyor: tamamlamak senin işin, sonsuza kadar düşünmek değil.
İkinci en pahalı ayım, LLM'i kendisini özetlemesi için çağıran bir debug log statement'ını silmeyi unuttuğum aydı. Altıncı gün fark ettim. Faturaya bakarken kahve fincanım soğumuştu, ben de masada öylece on dakika oturdum.
// madem buradasın
- 7 dk okuma
Agentic AI guardrail'leri: while(true) döngüsünü token bütçeni yakmasından durdurmak
Vibes-döngüsünü production'da gerçekten çalıştırabileceğin bir şeye çeviren dört guardrail: bütçe zarfı, retry eğrileri, break koşulları ve gerçek bir fallback zinciri.
agentic-aiproductionengineering-lessons - 9 dk okuma
Agentic AI çoğunlukla vibe'larla yazılmış bir while(true)
Uzun süreli agent döngülerini production'da çalıştırmaktan çıkan dersler, gerçekten işe yarayan fallback pattern'leri ve agent'ın aynı tool'u 47 kere denediği gün.
agentic-aiproductionengineering-lessons