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

Ana sayfa → Teknik

Agent’ın İzi: Log Değil, Karar Zinciri

Mesaj kısaydı: “Agent dün geceki rakamı yanlış söyledi.” Log’u açtım: 400 satır JSON, hepsi zaman sıralı, hepsi doğru. Yanlışın hangi adımda doğduğunu bulmam 40 dakika sürdü. Sebep bir tool argümanındaki tarih aralığıydı ve satır 217’de duruyordu. Bugün aynı soruyu 12 saniyede cevaplıyorum; log’u değil, koşunun ağacını açıyorum.

Özet
  • Log zaman sıralıdır, koşu ise ağaçtır. “Hangi adım bu kararı doğurdu” sorusunu düz satırlar cevaplamaz.
  • Koşu = trace, adım = span, tool çağrısı = alt span. Mikroservislerdeki yapının aynısı; üzerine agent alanları eklenir: model, prompt sürümü, token, tool argüman özeti, fren.
  • En değerli alan argüman özeti. Hatalarımızın çoğu modelin “yanlış düşünmesi” değil, tool’a yanlış argüman vermesiydi: 30 günün 3’ü.
  • Müşteri verisi maskelenir. Ham cevap değil, ilk 500 karakter + hash. Hash iki koşunun aynı veriyi görüp görmediğini söyler.
  • Yeniden oynatma, hatayı ikiye ayırır: model mi yanlış karar verdi, tool mu yanlış veri döndürdü? Bizde hatalı koşuların üçte ikisi ikinci gruptaydı.
  • Kullanıcı geri bildirimi ize bağlanmalı. “Bu cevap yanlış” düğmesi trace kimliğini taşımıyorsa, geri bildirim bir duygudur; taşıyorsa bir hata kaydı.

Neden düz log yetmiyor?

Bir agent koşusunda aynı anda üç şey akıyor: modelin turları, tool çağrıları ve orchestrator’ın adımları. Düz log bunları tek bir şeride diziyor. Sorun, sorularımızın şerit değil ağaç sorusu olması:

  • “Bu cevap hangi veriye dayanıyordu?” → cevabı üreten span’in çocuklarına bak.
  • “Bu tool neden çağrıldı?” → span’in ebeveynine bak.
  • “Süre nereye gitti?” → kardeş span’lerin sürelerini karşılaştır.
  • “Dün ile bugün arasında ne değişti?” → iki ağacı yan yana koy.

Bunların hiçbiri “satır 217”yi okuyarak cevaplanmıyor. Altı log dosyası değil, tek ekran yazısındaki dert burada aynısıyla geçerli; tek fark, servis sınırlarının yerini adım sınırlarının alması.

Log “ne oldu”yu söyler, iz “neden oldu”yu. Agent’ta ikinci soru birinciden pahalıdır.

Ne kaydediyoruz?

Bir kosunun agaci
trace: rec-2026-09-21-01        (gece mutabakati, 38 sn)
├─ span: adim-1 veri_cek         6,1 sn
│   ├─ tool: banka_dosyasi_oku   2,2 sn   arg#a91f  cevap 480 B
│   └─ tool: islem_listesi       3,8 sn   arg#7c02  cevap 512 B  kayit=2300
├─ span: adim-2 eslestir         0,4 sn   (kod, model yok)
├─ span: adim-3 siniflandir     21,3 sn
│   └─ model: qwen3:4b  giris 4.812 tok  cikis 233 tok  tur 1
└─ span: adim-4 ozet_yaz        10,6 sn
    └─ model: qwen3:4b  giris 1.340 tok  cikis 412 tok  tur 1

Her span’de tutulan alanlar, işe yarar bulduğumuz sırayla:

AlanNeden
Tool argüman özetiHataların çoğu burada. Tarih aralığı, müşteri no, limit. Tam argüman değil, maskelenmiş özeti + hash
Model ve sürümüSürüm değişince eski koşularla karşılaştırma
Prompt sürümü“Dün iyiydi bugün kötü”nün ilk şüphelisi
Giren / çıkan tokenMaliyetin ve pencere doluluğunun girdisi
Cevap boyutu ve hashİki koşu aynı veriyi mi gördü?
Fren bilgisiTur sınırı mı, bütçe mi, zaman aşımı mı devreye girdi?
Kullanıcı / koşu kimliğiGeri bildirimi ve denetimi bağlamak için

Neyi kaydetmiyoruz

  • Ham müşteri verisi. İsim, IBAN, kimlik numarası maskelenir. Kayıt numaraları açık kalır; onlarsız hata ayıklanmıyor.
  • Tool cevabının tamamı. İlk 500 karakter + hash. Tamamı gerekirse veri zaten kaynağında duruyor.
  • Modelin bütün ara metni. Karar ve gerekçenin ilk cümlesi yeter; gerisi 14 günde bir sorunu çözmüyor, sadece disk yiyor.

Saklama: ayrıntılı iz 14 gün, özet metrikler 13 ay. Denetim log’u ayrı ve daha uzun: yan etkili her çağrı tam argümanlarıyla, ayrı bir yerde, ayrı yetkiyle.

Sahadan: 40 dakika, sonra 12 saniye

İlk olayda şu sırayla ilerlemiştim: log’u indir, zaman damgasını bul, tool çağrılarını gözle ayıkla, argümanları elle karşılaştır, tarih aralığının bir gün kaydığını gör. 40 dakika.

İz kurulduktan sonra aynı şikâyet geldiğinde:

  1. Kullanıcının “yanlış” düğmesi trace kimliğini taşıyor; bağlantıyı açtım.
  2. Ağaçta adim-1’in altındaki islem_listesi span’ine baktım: argüman özeti baslangic=2026-09-19, olması gereken 2026-09-20.
  3. Ebeveyn span’de tarih aralığını üreten kodun sürümü yazıyordu; o gün bir düzeltme çıkmıştı.

12 saniye. Asıl kazanç, hatanın modelde olmadığını saniyeler içinde görebilmekti. İz olmadan geçen 40 dakikanın yarısını modelin cevabını okuyup “acaba anlamadı mı” diye düşünerek harcamıştım.

Agent hatalarının çoğu modelin yanlış düşünmesi değil, tool’a yanlış argüman gitmesidir. Argümanı kaydetmiyorsan bunu göremezsin.

Yeniden oynatma

İzde tool cevaplarının hash’i ve ilk 500 karakteri var; ayrıca hatalı koşularda cevabın tamamını 48 saat saklıyoruz. Bu, koşuyu yeniden oynatmayı mümkün kılıyor: aynı girdi, kayıtlı tool cevapları, gerçek tool çağrısı yok.

Yeniden oynatma
$ agent replay rec-2026-09-21-01 --model qwen3:4b
  adim-3 siniflandir: 13 kayit -> 11 dogru (onceki kosu: 11)
  sonuc: ayni

$ agent replay rec-2026-09-21-01 --model qwen3:8b --prompt v7
  adim-3 siniflandir: 13 kayit -> 13 dogru
  sonuc: farkli (2 kayit duzeldi)

Faydaları:

  • Hatayı ikiye ayırır. Kayıtlı cevaplarla aynı hata çıkıyorsa suç modelde; çıkmıyorsa tool ya da veri değişmiş.
  • Sürüm karşılaştırmasının en ucuz yolu. Gerçek sistemleri hiç çağırmadan, gerçek bir koşu üzerinde.
  • Yan etki yok. Replay modunda yazma tool’ları kapalı; para hareketi olan bir adımı kazara tekrar çalıştırmazsın.
  • Eval setinin kaynağı. Gerçek hatalı koşular, en değerli test verisidir.

Geri bildirimi ize bağlamak

Chat ekranındaki “bu cevap yanlış” düğmesi ilk hâlinde sadece bir sayaç artırıyordu. Ayda 20–30 tıklama geliyordu ve hiçbirini inceleyemiyorduk, çünkü hangi koşu olduğunu bilmiyorduk. Düğmeye trace kimliğini ekledikten sonra:

ÖnceSonra
Geri bildirimSayaç: “bu ay 24 olumsuz”24 koşu, tıklanabilir
İncelenen024’ün 24’ü (ortalama 3 dk)
Kök sebepBilinmiyor9 tool argümanı, 6 eksik veri, 5 model, 4 kullanıcı beklentisi
Aksiyon“Model kötü”2 tool düzeltmesi, 1 prompt, 1 eval maddesi

Son satır önemli: geri bildirimlerin yarısından fazlası modelle ilgili değildi. “Model kötü” cümlesi, iz olmayan ekiplerin varsayılan teşhisi.

Yapılacaklar
  • Koşuya kimlik ver, kullanıcıya kadar taşı.
  • Tool argümanlarını maskeleyip kaydet.
  • Model, prompt ve tool sürümlerini span’e yaz.
  • Hatalı koşuların %100’ünü, başarılıların örneklemini sakla.
  • Replay’i günlük iş akışının parçası yap.
  • Denetim log’unu izden ayrı tut.
Yapılmayacaklar
  • Ham müşteri verisini ize yazmak.
  • Her koşuyu tam ayrıntıyla sonsuza kadar saklamak.
  • Geri bildirimi koşudan kopuk bir sayaç olarak tutmak.
  • Modelin bütün ara metnini kaydedip “sonra bakarız” demek.
  • Replay’i yazma tool’ları açıkken çalıştırmak.

Ne izlemeli?

  • Koşu başına adım ve tur sayısı. Akışın yazılı olup olmadığını söyler.
  • Adım bazında süre p50/p95. Yavaşlığın hangi adımda olduğunu gösterir; model her zaman suçlu değil.
  • Tool argüman hatası oranı. Bizim en büyük kalemimiz; ayrı bir grafik hak ediyor.
  • Fren tetiklenmeleri, türe göre. Hangi fren kaç kez?
  • Geri bildirim → kök sebep dağılımı. Aylık; aksiyonun nereye gideceğini bu söyler.
  • Örnekleme oranı ve saklama boyutu. İzleme maliyeti de bir maliyettir; bizde koşu başına ~11 KB.

Kontrol listesi

İzi kurarken
  • Her koşunun bir kimliği var mı? Kullanıcı arayüzüne kadar gidiyor mu?
  • Adımlar ve tool çağrıları ağaç olarak mı duruyor, satır olarak mı?
  • Tool argümanları kaydediliyor mu? Maskeleme kuralı ne?
  • Model, prompt ve tool sürümleri her span’de var mı?
  • Hangi frenin tetiklendiği yazılıyor mu?
  • Hatalı koşular tam, başarılılar örneklem olarak mı saklanıyor?
  • Saklama süresi ne? Ayrıntı ve özet için ayrı mı?
  • Yeniden oynatma var mı? Replay’de yazma tool’ları kapalı mı?
  • Kullanıcı geri bildirimi koşuya bağlı mı?
  • Denetim log’u ayrı mı, kimler erişiyor?
  • Bir şikâyet geldiğinde kök sebebe kaç dakikada iniyorsun? Ölçtün mü?

Sonuç

O gün 400 satır log’un içinde 40 dakika geçirdim ve sonunda bulduğum şey bir tarih aralığıydı. Modelin bununla ilgisi yoktu; ben onun ilgisi olup olmadığını bilmediğim için yarım saatimi ona harcadım. Gözlemlenebilirliğin değeri tam olarak burada: suçlunun kim olmadığını hızlıca söylemek.

Kurduğumuz şey yeni bir teknoloji değil; mikroservislerde yıllardır kullandığımız trace–span yapısının agent’a uyarlanmışı. Eklediğimiz tek şey, agent’a özgü alanlar: argüman özeti, token, prompt sürümü, fren. Bir de replay, ki en çok onu kullanıyoruz.

Akılda kalacak cümle: agent’ın izi, kararlarının zinciridir. Zinciri kaydetmiyorsan elinde yalnızca sonuç kalır; sonuca bakarak neyi düzelteceğini bilemezsin.