Sertaç Yıldırım saha notları

Ana sayfa → Teknik

Token Panosu: Fatura Değil, Erken Uyarı

3 Nisan Cuma, 10:20. Finanstan mesaj: “Mart faturası 11.400 $. Bütçe 4.000 $ değil miydi?” Öyleydi. Şubat 3.900 $ gelmişti. Artış 9 Mart’ta başlamıştı ve 25 gün boyunca kimse fark etmedi.

Özet
  • Fatura bir alarm değil. Ayda bir gelir, toplam söyler ve sebebi söylemez. Bizim 7.500 $’lık farkı açıklamamız iki gün sürdü.
  • Her isteğe dört etiket. Özellik, segment, prompt sürümü, model. Soru “ne kadar harcadık” değil, “neye harcadık”.
  • Müşteri numarası metrik label’ı olmaz. Dört etiket ~220 seri demek; müşteri numarası 210 bin seri. O bilgi olay kaydında durur.
  • İki alarm yeter. Günlük bütçe gidişatı ve özellik başına saatlik spike. İkisi de gündüz, özelliğin sahibine gider.
  • Input/output oranı erken teşhistir. Normal soru 8:1, sorunlu özellik 60:1 idi. Oran bozulunca prompt’a gereğinden fazla şey dolduruyorsun demektir.
  • En pahalı %1 istek harcamanın %19’u. Ortalama seni rahatlatır; kuyruk seni uyarır.

Sahadan: 11.400 dolarlık Mart

Destek asistanının maliyetini sağlayıcının konsolundan izliyorduk. Konsolda tek bir grafik vardı: gün başına toplam token. Şubat boyunca günde 140 $ civarında düz bir çizgiydi, biz de ayda bir kez bakıyorduk. Mart’ta kimse bakmadı, çünkü bakmayı gerektiren bir şey yoktu — ya da vardı ama bize söyleyen yoktu.

Farkı açıklamak iki gün sürdü. Konsol toplamı biliyordu, sebebi bilmiyordu. İstek log’larını tek tek toplayıp elle ayırdık:

KalemBaşlangıçMart’a etkisi
Yeni “işlem geçmişi” özelliği (90 günlük ham işlem listesini prompt’a koyuyordu)9 Mart+5.100 $
Prompt v4: few-shot örnekler, her çağrıya +1.700 token12 Mart+1.300 $
Zaman aşımında üç kez tekrar deneyen bir entegrasyonMart ortası+700 $
Kullanıcı artışı (gerçek büyüme)+400 $
Toplam fark+7.500 $

Tablodaki dört kalemin hiçbiri hata sayılmazdı. İşlem geçmişi bilerek çıkmış bir özellikti, prompt v4 cevap kalitesini artırmıştı, retry bir sağlamlık kararıydı. Hata benimdi: bu kararların her birinin bir fiyatı olduğunu ve o fiyatı kimsenin görmediğini bilmiyordum. Gerçek büyüme farkın yalnızca 400 $’ıydı.

Fatura bir alarm değildir. Otuz gün gecikmiş bir otopsidir.

Fatura neden geç kalır?

Üç sebep var ve üçü de faturanın doğasında. Zaman: ayda bir gelir; 9 Mart’ta başlayan bir artışı 3 Nisan’da öğrenirsin. Birim: toplam söyler; toplam içinde dört farklı sebep aynı çizgiye karışır. Sahip: fatura finansa gider, harcamayı yapan ekibe değil. Finans rakamın büyük olduğunu bilir, neden büyük olduğunu bilemez.

Token maliyeti, diğer altyapı maliyetlerinden bir noktada ayrılıyor: kod değişikliğiyle anında değişiyor. Sunucu maliyeti bir satın alma kararıyla artar. Token maliyeti ise bir prompt satırıyla, bir tool çıktısıyla ya da bir retry ayarıyla artar. Bu değişiklikler maliyet incelemesinden değil, kod incelemesinden geçer. O yüzden izlemesi de kodun yanında olmalı.

Bunu ilk kez yaşamıyorduk. Prompt cache yazısındaki olayda da tek bir satır maliyeti 2,5 katına çıkarmış, biz dört gün sonra tesadüfen görmüştük. O gün dersi önbellek için almıştım, maliyetin kendisi için değil.

Her isteğe dört etiket

İlk iş, her LLM çağrısını bir sahibe bağlamak oldu. “Ne kadar harcadık” sorusu işe yaramıyor. İşe yarayan soru “neye harcadık”. Bunun için dört etiket yetiyor:

  • Özellik. Hangi ekran, hangi akış: genel_soru, islem_gecmisi, emir_durumu… Sabit liste, bizde altı değer.
  • Segment. Bireysel, premium, kurumsal. Maliyeti gelirle yan yana koyabilmek için.
  • Prompt sürümü. v4’ün 1.300 $’ını bu etiket olsaydı ilk gün görürdük.
  • Model. Aynı özellik iki modelde çalışabiliyor; fiyatları dört kat farklı.

Etiketler ilk hafta sürpriz bir şey gösterdi: premium segment isteklerin %12’sini ama maliyetin %31’ini yapıyordu. Premium müşteriler daha uzun, daha çok tur süren sorular soruyordu. Bu bir sorun değildi; ama “premium’a büyük modeli verelim” tartışmasını artık rakamla yapabiliyorduk.

Her çağrı için bir olay kaydı yazılıyor. Token sayısını tahmin etmiyoruz; sağlayıcının cevabındaki usage alanından okuyoruz. Maliyeti de kayıt anında hesaplıyoruz, çünkü fiyat değişince eski kayıtların eski fiyatla kalması gerekiyor:

Istek basina olay kaydi
{
  "ts": "2026-04-14T10:32:07+03:00",
  "istek_id": "req_8f2c41",
  "ozellik": "islem_gecmisi",     # sabit liste, 6 deger
  "segment": "bireysel",          # bireysel | premium | kurumsal
  "prompt_surumu": "v5",
  "model": "buyuk-2026-02",       # takma ad degil, surumlu ad
  "input_token": 4210,            # saglayicinin usage alanindan
  "output_token": 286,            # tahmin degil, olcum
  "maliyet_usd": 0.0161,          # kayit aninda, fiyat tablosu v3 ile
  "deneme_no": 1,                 # retry ise 2, 3 ...
  "musteri_no": "m_104233"        # SADECE bu kayitta. metrikte YOK
}

deneme_no alanı sonradan eklendi. Mart’taki 700 $’lık retry kalemini bulmak için log’larda aynı istek_id’yi aramak zorunda kalmıştık. Retry’ın nasıl sınırlanacağı ayrı bir konu, onu rate limit yazısında anlattım. Burada tek dert var: retry’ın maliyeti görünür olsun.

Cardinality: müşteri numarası label olmaz

Olay kaydından Prometheus’a iki metrik çıkıyor: token sayısı ve maliyet. Label’lar yukarıdaki dört etiket, token için bir de yön (input/output). Hesap basit: 6 özellik × 3 segment × aynı anda en fazla 3 prompt sürümü × 2 model × 2 yön = 216 seri. Prometheus bunu fark etmez bile.

İlk denemede buna müşteri numarasını da ekledim. “Kim pahalı, onu da görelim” dedim. Her farklı label değeri ayrı bir zaman serisi açıyor. Asistanı kullanan aktif müşteri sayısı 38 bin civarındaydı ve iki günde 210 bin seriye çıktık. Prometheus’un belleği yetmedi, pano açılmaz oldu. Diğer servislerin metrikleri de aynı sunucudaydı.

Kural şu: metrik, sayısı az ve sabit olan şeyle bölünür. Müşteri numarası, istek kimliği, konuşma kimliği olay kaydında durur. “Dün en çok harcayan 20 müşteri kim?” sorusu bir panel değil, bir sorgu. Olay kayıtlarını nerede ve ne kadar süre tuttuğumuzu prompt loglama yazısında anlatmıştım; müşteri numarası da oradaki kuralla maskeleniyor.

Metrik label’ı olur
  • Özellik (6 değer)
  • Segment (3 değer)
  • Prompt sürümü (aynı anda 2–3 değer)
  • Model (2 değer)
  • Yön: input / output

Ortak özellikleri: liste kısa ve sen belirliyorsun.

Metrik label’ı olmaz
  • Müşteri numarası
  • İstek ya da konuşma kimliği
  • Soru metni, soru özeti
  • Hata mesajının tamamı
  • Tarih, saat, token sayısı

Bunlar olay kaydına yazılır, sorguyla okunur.

İki alarm

Pano tek başına yetmiyor. Mart’ta da bir panomuz vardı, bakan yoktu. Panoya bakmayı hatırlamak yerine, panonun bizi çağırmasını istedik. İki alarm kurduk:

Alarm kurallari
# aylik butce 8.100 $ -> gunluk butce 270 $

# 1) GUNLUK BUTCE: gunun gidisati
tahmin = bugun_harcanan + kalan_saat * son_3_saatin_saatlik_ortalamasi
EGER tahmin > 270 * 1.2
    -> ekip kanalina mesaj (gunduz, sayfalama yok)

# 2) SPIKE: ozellik basina, saatlik
son_saat  = token(ozellik, son 1 saat)
referans  = token(ozellik, son 7 gunun AYNI saati, ortalama)
EGER son_saat > referans * 3  VE  son_saat > 200000
    -> ozelligin sahibine mesaj
# ikinci kosul gece dusuk trafikte gurultuyu kesiyor:
# 3 istek yerine 9 istek gelmesi alarm degil

İki ayrıntı önemli. Birincisi, referans aynı saat. Pazartesi 10:00 ile Pazar 03:00’ı karşılaştırırsan her sabah alarm çalar. İkincisi, alarm özelliğin sahibine gidiyor, nöbetçiye değil. Token artışı bir kesinti değil. Kimseyi gece uyandırmaya değmez, ama ertesi ayı beklemeye de değmez. Aynı gün, gündüz, işin sahibine.

Nisan’dan bu yana spike alarmı iki kez çaldı. Birincisi gerçekti: bir sürümde few-shot bloğu iki kez eklenmişti. Deploy’dan üç saat sonra yakaladık, maliyeti 8 $ oldu. Aynı hata Mart’ta olsaydı ay sonuna kadar gidecekti. İkincisi bir kampanya günüydü: trafik gerçekten üç katına çıkmıştı. O alarmı yanlış saymıyoruz; kampanya takvimini alarmın bilmesi gerekiyordu ve artık biliyor.

Etiketi olmayan token’ın sahibi de yoktur. Sahibi olmayan harcamayı kimse düşürmez.

Input/output oranı: erken teşhis

Maliyetin kendisi ne kadar harcadığını söylüyor. Input ile output token’ın oranı ise nasıl harcadığını söylüyor. Mart verisinden özellik başına bakınca tablo şuydu:

ÖzellikInput / istekOutput / istekOranİstek başı
Genel soru2.4003008:10,011 $
Emir durumu3.10022014:10,012 $
İşlem geçmişi (Mart)18.00030060:10,058 $
İşlem geçmişi (düzeltme sonrası)4.20029014:10,016 $

60:1 şunu söylüyor: modele çok şey okutuyorsun ama ondan az şey istiyorsun. İşlem geçmişi 90 günlük ham işlem listesini prompt’a koyuyordu. Oysa müşterinin sorusu çoğunlukla “bu ay ne kadar komisyon ödedim?” gibi tek satırlık bir şeydi. Listeyi 30 günlük özete çevirdik, özeti de modelden değil veritabanından aldık. İstek başı maliyet yaklaşık dörtte birine indi, cevaplar değişmedi.

Oranın ters yönde bozulması da bir sinyal. Output birden uzuyorsa model ya kendini tekrar ediyor ya da bir talimat onu gereksiz ayrıntıya itiyor. Bizim fiyatlarımızda output token input’tan dört kat pahalı, yani bu tarafta küçük bir kayma da hızlı büyüyor. Sabit önekin önbellekte tutulması ise oranı değiştirmeden input maliyetini düşürüyor; onu prompt cache yazısında ayrıca anlattım.

En pahalı %1

Ortalama istek maliyeti 0,013 $. Bu rakam hiçbir şey söylemiyor. İstekleri maliyete göre sıraladığımızda en pahalı %1’in harcamanın %19’unu yaptığını gördük. O %1’e tek tek baktık. Üç tip çıktı:

  • Uzayan konuşmalar. 40 tura çıkan bir konuşmada her tur, bütün geçmişi yeniden gönderiyor. 40. turun maliyeti 1. turun 30 katıydı. Geçmişi son 10 tur ve bir özetle sınırladık.
  • Yapıştırılan belgeler. Müşteri hesap ekstresinin tamamını sohbete yapıştırıyor. Girdiye üst sınır koyduk; sınırı aşınca asistan “hangi satırı soruyorsun?” diye soruyor.
  • İç kullanıcılar. Destek ekibinden biri asistanı test için bir betikle 600 kez çağırmıştı. Kötü niyet yok, ama betiğin segmenti yoktu. Artık iç kullanım ayrı segment.

Panoda artık ortalama yok. Onun yerine istek başı maliyetin p50, p95 ve p99 değeri var. Latency’de nasıl ortalamaya bakmıyorsak (gecikme yazısında anlattığım gibi), maliyette de bakmıyoruz.

Ortalama maliyet seni rahatlatır. En pahalı %1 seni uyarır.

Ne izlemeli?

NeNasılNeden
Günlük harcama / bütçeGün içi gidişat tahminiAy sonunu beklememek için
Özellik başına saatlik tokenSon 7 günün aynı saatiyleSpike’ı sahibine bağlamak için
Prompt sürümü başına istek maliyetiYeni sürüm çıkınca yan yanaHer prompt değişikliğinin bir fiyatı var
Input/output oranıÖzellik başınaPrompt’u gereksiz doldurmayı erken görmek için
İstek başı maliyet p95 / p99GünlükKuyruk, ortalamanın sakladığı yer
Retry token payıdeneme_no > 1 olanlarSağlamlık kararının görünmeyen faturası

Bende işe yaramayanlar

  • Sağlayıcı konsolunda bütçe uyarısı. Hesap bazında çalışıyordu, yani yine toplam söylüyordu. Ayın 20’sinde “bütçenin %80’i doldu” demek, sebebi söylemeden telaş üretmek.
  • Haftalık maliyet raporu e-postası. İlk iki hafta açıldı, sonra filtreye takıldı. Rapor kimseyi aramıyor; alarm arıyor.
  • Token sayısını istemci tarafında tahmin etmek. Kendi tokenizer tahminimiz Türkçe metinlerde %15–20 eksik sayıyordu. Sağlayıcının cevabındaki sayıyı kullanmaya başlayınca pano ile fatura ilk kez tuttu.

Kontrol listesi

Token harcaman görünür mü?
  • Harcamanın kaçta kaçını bir özelliğe bağlayabiliyorum?
  • Yeni prompt sürümünün istek başı maliyetini ilk gün görebiliyor muyum?
  • Token sayısı sağlayıcıdan mı geliyor, benim tahminimden mi?
  • Metrik label’larından hangisinin değer sayısı sınırsız?
  • Günlük bütçe alarmı var mı, yoksa ayın sonunu mu bekliyorum?
  • Spike alarmı kime gidiyor: nöbetçiye mi, özelliğin sahibine mi?
  • Retry’ların token payını biliyor muyum?
  • En pahalı %1 isteğe son ne zaman tek tek baktım?

Sonuç

Mart’ın 7.500 $’lık farkı tek bir büyük hatadan gelmedi. Dört makul karardan geldi ve dördünün de fiyatı görünmüyordu. Nisan faturası 7.700 $ geldi. Bütçeyi 8.100 $’a çektik, çünkü işlem geçmişi ve v4 gerçekten işe yarayan değişiklikler; bir fiyatları olması normal. Normal olmayan, o fiyatı faturadan öğrenmekti.

Asıl değişen rakam değil, öğrenme süresi. Mart’ta bir artışı 25 günde öğrendik. Nisan’da aynı tipte bir hatayı üç saatte öğrendik.

Test şu: yarın bir prompt satırı maliyeti ikiye katlasa, bunu kimden ve ne zaman duyarsın? Cevap “finanstan, ay sonunda” ise panon yok, faturan var.