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

Ana sayfa → Teknik

Eval: Demo Değil, Regresyon Testi

System prompt’ta tek kelime değiştirdim: “kısa cevap ver” yerine “öz cevap ver”. Demo’da üç soru sordum, üçü de güzeldi. İki gün sonra destek ekibi yazdı: hacim soruları yanlış çıkıyor. Baktım: 27 sorunun 4’ü artık yanlış tool’a gidiyordu. Değişen tek şey o kelimeydi. Yakalayan kullanıcı oldu; yakalaması gereken bendim.

Özet
  • Demo bir örnektir, eval bir settir. Üç soruyla “iyi görünüyor” demek, üç satır test yazıp “uygulama çalışıyor” demekle aynı.
  • Set uydurulmaz, toplanır. Gerçek sorular, kullanıcının “yanlış” dediği koşular, sınır durumlar, injection metinleri. Bizde 12’den 60’a üç ayda çıktı.
  • Ölçülebileni kesin ölç. Tool seçimi, argümanlar ve sayısal cevap kodla kontrol edilir. Setimizin %80’i böyle; judge yalnızca metin için.
  • LLM-judge’ın üç yanlılığı var: uzunu sever, kendi ailesini sever, sıraya duyarlıdır. Yazılı ölçüt, iki yönlü karşılaştırma ve aylık insan kalibrasyonu şart.
  • Tek kelimelik prompt değişikliği regresyondur. Prompt, model ve tool değişiklikleri aynı kapıdan geçmeli: sürüm ve eval.
  • “Eval yeşil, kullanıcı mutsuz” setin suçudur. Haftada 10 gerçek koşu elle incelenir; kapsanmayan her durum sete eklenir.

Neyi ölçüyoruz?

Agent’ın cevabı tek bir şey değil, bir zincirin sonucu. Zincirin her halkası ayrı ölçülür ve hepsi aynı derecede belirsiz değildir:

HalkaNasıl ölçülürKesin mi?
Doğru tool seçildi mi?Beklenen tool adıyla karşılaştırKesin
Argümanlar doğru mu?Tarih aralığı, kimlik, limit alan alan karşılaştırKesin
Sayı doğru mu?Beklenen değerle karşılaştır (tolerans 0,01)Kesin
Gerekli uyarı var mı?Anahtar kelime / desen kontrolüYarı kesin
Metin anlaşılır mı?Ölçütlü judge ya da insanBelirsiz

Buradan çıkan kural: belirsiz olanı küçült, kesin olanı büyüt. İlk setimizde her madde “cevap iyi mi” diye soruyordu ve hepsi judge’a gidiyordu. Bugün 60 maddenin 48’i kodla kontrol ediliyor; judge yalnızca özet metinleri için kalıyor.

Bir eval maddesi
- id: hacim-01
  soru: "altinda bugunku hacim kac lot?"
  beklenen_tool: hacim
  beklenen_argumanlar:
    enstruman: XAUUSD
    baslangic: BUGUN
    bitis: BUGUN
  beklenen_sayi: 1284.5        # tolerans 0.01
  gerekli_ifade: ["lot"]
  yasak_ifade: ["tahminen", "yaklasik"]   # sayisal cevapta tahmin olmaz

Set nereden gelir?

Uydurulmuş sorular kolay ve işe yaramaz; gerçek sorular zor ve değerli. Dört kaynak kullandık:

  • Gerçek sorular. İlk ayın chat kayıtlarından 27 soru; bunlar setin çekirdeği.
  • Hatalı koşular. Her gerçek hata sete bir satır ekler. Yeniden oynatma burada devreye giriyor: hatalı koşunun kaydı zaten duruyor.
  • Sınır durumlar. Boş sonuç, 92 günlük aralık, iki anlama gelen soru (“dün ne kadar çekildi” — talep mi, onaylanan mı?), hiç olmayan müşteri.
  • Injection metinleri. 12 maddelik set; ölçtüğü şey modelin kanıp kanmadığı değil, kanmanın sonucu olup olmadığı.
AyMaddeEklenme sebebi
1. ay12İlk gerçek sorular
2. ay31+7 hata, +8 sınır durum, +4 injection
3. ay60+12 kullanıcı geri bildirimi, +9 yeni tool, +8 injection
Eval seti yazılmaz, birikir. Her gerçek hata bir satırdır; sete eklenmeyen hata ikinci kez gelir.

Sahadan: tek kelime, dört hata

Girişteki olay setimiz kurulduktan sonra bir daha yaşandı — ama bu kez sonuç farklıydı. Aynı türde bir prompt düzenlemesi yaptım ve commit öncesi seti koşturdum:

Eval ciktisi
$ agent eval --prompt v9 --model qwen3:4b
  60 madde, 2 dk 41 sn

  tool secimi     : 58/60   (onceki surum: 60/60)   -2  ✗
  arguman         : 59/60   (onceki surum: 60/60)   -1  ✗
  sayisal cevap   : 22/22
  injection       : 12/12
  metin (judge)   : 11/12   (onceki surum: 10/12)   +1

  BOZULAN:
    hacim-01  beklenen=hacim      gelen=islem      (arg: enstruman eksik)
    hacim-04  beklenen=hacim      gelen=islem
    kyc-03    arguman: baslangic  beklenen=AY_BASI gelen=BUGUN

Üç dakikada gördüm: metin kalitesi bir puan arttı, tool seçimi iki puan düştü. Prompt’taki yeni kelime, modelin “işlem” kavramını öne çıkarmış ve hacim sorularını oraya çekmişti. Değişikliği geri aldım, kelimeyi başka bir yere taşıdım, tekrar koştum: 60/60.

Buradaki kazanç “model iyi” ya da “prompt kötü” değil. Değişikliğin bedelini görmek. Metin bir puan iyileşiyor, tool seçimi iki puan kötüleşiyorsa bu bir takas; takası bilerek yapmak ile farkında olmadan yapmak arasındaki fark, bu yazının tamamı.

LLM-judge: ne zaman, nasıl?

Metin kalitesini kodla ölçemiyorsun. İki seçenek var: insan (pahalı, yavaş) ya da judge (ucuz, yanlı). Biz ikisini karıştırdık, ama önce judge’ın nesini ölçtüğümüzü anlamamız gerekti.

Judge’ın yanlılıkları
  • Uzunu sever. Aynı bilgiyi veren iki cevaptan uzun olanı seçiyor.
  • Kendini sever. Kendi ailesinden bir modelin ürettiği metni daha çok beğeniyor.
  • Sıraya duyarlı. “A mı B mi” ile “B mi A mı” farklı cevaplar verebiliyor.
  • Emin olmayı sever: “bilmiyorum” diyen doğru cevabı, emin ve yanlış cevaba göre daha düşük puanlıyor.
Sağlamlaştırma
  • Yazılı ölçüt: 4 madde, her biri 0/1. “Genel izlenim” yok.
  • Karşılaştırmayı iki yönde de yap, tutarsızsa insana gönder.
  • Ayda bir 20 örnekte insan puanıyla karşılaştır; ayrışma %15’i geçerse ölçütü düzelt.
  • Judge’ı sadece metin için kullan; sayıyı asla ona sordurma.

Judge’ın ürettiği puan bizde bir kapı değil, bir uyarı: düşerse commit engellenmez, ama PR’da görünür. Kapı olan şeyler kesin ölçülenler: tool seçimi, argüman, sayı, injection.

Ne zaman koşar?

DeğişiklikKoşan setSüre
Prompt düzenlemesiTam set (60)~3 dk
Yeni ya da değişen toolTam set + o tool’un maddeleri iki kez~4 dk
Model sürümüTam set + judge + 20 örnek insan kontrolüYarım gün
Akış (orchestrator) değişikliğiTam set + uçtan uca 5 koşu~10 dk
GeceTam set + üretimden 10 örnekOtomatik

Üç dakikalık bir sürecin kapı olması, disiplini kendiliğinden kuruyor: kimse “bir kelime değiştirdim, koşmaya değmez” demiyor, çünkü bu yazının giriş paragrafı ekipte anlatılan bir hikâye.

“Eval yeşil ama kullanıcı mutsuz”

Bu cümleyi iki kez duyduk ve ikisinde de haklıydılar. Sebep her seferinde aynıydı: set gerçeği temsil etmiyordu.

  • Birinci sefer: setteki soruların hepsi tek cümlelikti. Kullanıcılar ise “dün ne kadar çekim onaylandı, kaçı hâlâ bekliyor, bekleyenlerin toplamı ne?” gibi üç soruyu bir arada soruyordu. Sete 9 çok parçalı soru ekledik; 4’ü ilk koşuda kırmızıydı.
  • İkinci sefer: set hep dolu veriyle çalışıyordu. Kullanıcı hafta sonu sordu, veri boştu ve agent “0 lot” yerine anlaşılmaz bir cevap verdi. Sete 6 boş sonuç maddesi girdi.

Kalıcı çözüm örnekleme oldu: her hafta üretimden rastgele 10 koşu elle inceleniyor (izden tek tıkla açılıyor). Setin kapsamadığı ne varsa aynı gün sete giriyor. Bu 20 dakikalık iş, setin gerçekle bağını koruyan tek şey.

Eval setinin işi modeli aklamak değil, sistemi ölçmektir. Yeşil bir set, yanlış soruları sorduğunun kanıtı olabilir.

Ne izlemeli?

  • Set büyüklüğü ve kapsama. Kaç madde, hangi tool’ları kapsıyor? Hiç maddesi olmayan tool var mı?
  • Sürüm başına skor. Tool seçimi / argüman / sayı / injection ayrı ayrı; tek bir “başarı yüzdesi” hiçbir şey anlatmaz.
  • Judge – insan ayrışması. Aylık 20 örnek; %15 üstü ölçütü düzeltmeyi gerektirir.
  • Setin yaşı. Son 30 günde kaç madde eklendi? Sıfırsa set ölüyordur.
  • Üretim şikâyeti / eval kaçırma oranı. Şikâyetlerin kaçı sette zaten vardı? Yüksekse eşikler yanlış, düşükse set dar.
  • Eval süresi ve maliyeti. 3 dakikayı aşarsa kimse koşmaz; koşulmayan test yoktur.

Kontrol listesi

Prompt’u değiştirmeden önce
  • Bir eval setim var mı? Kaç madde?
  • Maddeler nereden geldi: uydurma mı, gerçek koşu mu?
  • Kaç madde kodla kesin kontrol ediliyor, kaçı judge’a gidiyor?
  • Her maddede beklenen tool ve argümanlar yazılı mı?
  • Sınır durumlar var mı: boş sonuç, çok büyük aralık, iki anlamlı soru?
  • Injection maddeleri sette mi?
  • Judge’ın ölçütü yazılı mı? İki yönlü karşılaştırma yapılıyor mu?
  • İnsan kalibrasyonu ne sıklıkta? Son ayrışma kaç?
  • Set hangi değişikliklerde koşuyor? Kapı mı, uyarı mı?
  • Üretimden örnekleme var mı? Haftada kaç koşu inceleniyor?
  • Son 30 günde sete kaç madde eklendi?

Sonuç

Bir kelime değiştirdim ve dört soruyu bozdum. Demo’da görünmedi, çünkü demo üç soruydu ve üçü de o dört sorunun içinde değildi. Hatayı kullanıcı buldu; arada iki gün ve bilmediğim sayıda yanlış rapor vardı.

Bugün aynı değişiklik üç dakikada ölçülüyor ve sonucu bir takas olarak görüyorum: metin bir puan iyi, tool seçimi iki puan kötü. Kararı ben veriyorum. Eval’in yaptığı tek şey bu — kararı görünür kılmak. Modeli iyileştirmiyor, prompt yazmıyor, sadece değişikliğin bedelini söylüyor.

Akılda kalacak cümle: prompt kodsa, eval testtir. Testi olmayan kodu canlıya çıkarmıyorsan, eval’i olmayan prompt’u da çıkarma.