Hata

Ajan "hazır" yazdı ama özellik çalışmıyor: yapay zeka ajanının işi nasıl doğrulanır

Güncellendi: · Skillaria.Top

Ajan "hazır" yazar, çünkü işini kendisi değerlendirir ve yalnızca doğruladığını görür: genellikle unit testleri, oysa bunlar modüller arası bağlantıları, migration'ları, yapılandırmayı ve uçtan uca senaryoyu görmez. Çözüm istemde değil yapıdadır: AGENTS.md içinde Definition of Done, zorunlu bir E2E kontrolü, yalnızca passing işaretini koyabilen bir doğrulama betiği ve temiz context'li bağımsız bir değerlendirici.

Neden böyle olur

Yapay zeka ajanıyla çalışan herkesin tanıdığı bir durum: ajan "hazır" yazdı, ama özellik çalışmıyor. Ajan bile bile yalan söylemez. Yalnızca kendi doğruladığını bildirir ve bunun yeterli olduğuna samimiyetle inanır. Beyan ile gerçeklik arasındaki fark, belirli bir modelin kusuru değil, "uygulayıcı kendi işini değerlendirir" düzeninin özelliğidir.

Üç neden vardır. Birincisi: modeller aşırı özgüvenlidir; yanıtlarının kesinliği doğruluğundan fazladır. İkincisi: ajan işini, yaptığı context'in içinde değerlendirir. Çözümün doğru olduğuna zaten kendini ikna etmiştir ve "daha objektif ol" demek context'i değiştirmez. Üçüncüsü ve en pratik olanı: ajanın erişebildiği doğrulama kısmidir. Unit testler hızla yeşile döner, uçtan uca senaryo ise kimse tarafından çalıştırılmamıştır.

Bir yanlış "hazır"ın öyküsü

Ajana şifre sıfırlama görevi verildi. Veritabanı şemasını değiştirdi, bir endpoint ekledi, e-posta şablonunu bağladı, unit testleri çalıştırdı; hepsi yeşil. Sohbette özgüvenle "Hazır" yazıldı.

Gerçekte şunlar oldu:

  • migration ortada çöktü ve şema tutarsız bir durumda kaldı;
  • e-posta şablonu var, ama posta sunucusu (SMTP) ortamda yapılandırılmamış, dolayısıyla mail gitmiyor;
  • "Kullanıcı bağlantıya tıklar → yeni şifreyi girer → giriş yapar" senaryosu hiç çalıştırılmadı.

Bu sorunların hiçbirini unit testler yakalayamazdı: veritabanı mock'lanmıştı, mail gönderimi mock'lanmıştı ve uçtan uca bir çalıştırma hiç yoktu.

Yeşil testler neden özelliğin çalıştığını kanıtlamaz

Bir unit test modülü izole ederek kontrol eder: bağımlılıklar mock'lanır, dış dünya kapatılır. Bu hız ve kesinlik sağlar, ama sistematik bir kör nokta da yaratır. Bu kör nokta testlerin hatası değil, tasarımlarının bir sonucudur. Yeşil unit testler yalnızca her parçanın tek başına çalıştığını kanıtlar, parçaların birlikte çalıştığını değil.

Unit testin hiçbir zaman göremediği dört sınıf hata vardır:

Hata sınıfıÖrnekUnit test neden yakalamaz
Arayüzlerin uyuşmamasıBir bileşen göreli yol verir, diğeri mutlak yol beklerHer biri kendi mock'uyla test edilir ve mock her biçimi kabul eder
Durumun yayılmasıŞema değişti, ama ORM'in önbelleği eskiUnit testte ne gerçek veritabanı var ne önbellek
Kaynakların yaşam döngüsüDosya tanımlayıcıları ve bağlantılar kapanmıyor, büyük dosyalarda bellek sızıyorTest küçük veride çalışır ve kaynaklar tükenmeden biter
Ortam ve yapılandırmaOrtam değişkeni yok, SMTP ayarlı değil, migration uygulanmadıTest uygulamayı gerçek yapılandırmada çalıştırmaz

Kontrol seviyeleri iç içedir: unit testlerin yakaladığı her şeyi integration testleri de yakalar, integration testlerin yakaladığı her şeyi uçtan uca (E2E) çalıştırma da yakalar. Her üst seviye, bir alttakinden kesinlikle daha fazlasını görür. Bu yüzden "hazır" deme yetkisi yalnızca en üst seviyeye ait olmalıdır.

Verification gap nasıl ölçülür

Düzeltmeden önce sayın. Ajanın kapattığı son 10 görevi alın. Her biri için iki soruyu yanıtlayın: ajan "hazır" dedi mi, ve bağımsız bir kontrol bunu doğruladı mı (siz senaryoyu çalıştırdınız, E2E testi yeşil)? Bu ikisi arasındaki uyuşmazlığın oranı verification gap'inizdir.

Bu sayı iki nedenle faydalıdır. Sorunun büyüklüğünü "evet, iyi çalışıyor gibi" tartışmasına girmeden gösterir. Ve bir başlangıç ölçüsü verir: her değişiklikten sonra benzer görevler üzerinde yeniden hesaplayıp işe yarayıp yaramadığına bakarsınız.

Gerçekten nasıl doğrulanır: üç katmanlı kontrol

Kullanışlı bir benzetme: bir araba tamir atölyesinin üç istasyonundan geçer ve hiçbirini atlayamaz.

  1. Teşhis (saniyeler): sözdizimi, tipler, linter. Yazım hatalarını ve kaba hataları yakalar.
  2. Test standı (dakikalar): unit ve integration testleri, uygulama açılır. Motor çalışıyor, ama araba hâlâ yerinde duruyor.
  3. Test sürüşü: uçtan uca senaryo, kullanıcının çalıştırdığı şekliyle: API, tarayıcı veya CLI üzerinden, gerçek veritabanı ve yapılandırmayla.

İlerleme kuralı: teşhiste hatalar varken test sürüşüne çıkılmaz ve test sürüşü geçilmeden araba teslim edilmez. Yeşil unit testler ikinci istasyonu geçmek demektir, üçüncüyü değil.

Her şeyi tek bir giriş noktasında toplamak uygundur:

# Makefile
check:
	ruff check .
	mypy app
	pytest tests/unit tests/integration

e2e:
	docker compose up -d db mailhog
	alembic upgrade head
	pytest tests/e2e

verify: check e2e

Burada E2E gerçek bir veritabanı ve test posta sunucusu kaldırır, migration'ları uygular ve senaryoyu baştan sona çalıştırır. Bozuk bir migration veya yapılandırılmamış bir posta hemen görünür, müşteride değil.

AGENTS.md içinde Definition of Done

Ajan "hazır"ın ne anlama geldiğine kendi başına karar vermemelidir. Ölçüt talimat dosyasına yazılır ve doğrulanabilir biçimde ifade edilir:

## Definition of Done
Özellik ancak TÜM maddeler yerine getirildiğinde hazırdır:
1. make check kod 0 ile tamamlandı
2. make e2e kod 0 ile tamamlandı, özelliğin senaryosu tests/e2e içinde
3. Migration'lar temiz bir veritabanında uygulanıyor ve geri alınıyor
4. Yeni ortam değişkenleri .env.example içinde tanımlı
5. PROGRESS.md içinde ne yapıldığı ve nasıl doğrulandığı yazılı

Hazır olduğunun kanıtı SAYILMAZ:
- "Kod yazıldı ve doğru görünüyor"
- "Unit testler geçiyor"
- "Bende yerelde çalışıyor"

Neyin hazır sayılmadığını açıkça listelemek, beklenenden daha iyi çalışır: ajan ilk yeşil çalıştırmada durmayı bırakır.

Passing işaretini kim koyar

Bir sonraki adım, hazır olma işaretini ajanın elinden tamamen almaktır. Özellikler bir listede tutulur (örneğin feature_list.json), alanları şunlardır: "davranış", "doğrulama komutu", "durum". Bir özelliği passing yapabilecek tek şey bir betiktir: genel make check'i çalıştırır, sonra o özelliğin doğrulama komutunu çalıştırır ve başarılıysa durumu commit hash'iyle birlikte kanıt olarak kaydeder. Geçmezse özellik aktif kalır; "neredeyse oldu" diye bir şey yoktur.

{
  "id": "F04",
  "behavior": "Kullanıcı bağlantılı e-postayı alır ve şifresini değiştirir",
  "verification": "pytest tests/e2e/test_password_reset.py",
  "state": "active"
}

Burada bir tuzak var: betik yalnızca verification alanına yazılanı kontrol eder. Bir mimari kontrol Definition of Done'da var ama özelliğin komutunda yoksa, bu açık görünmez kalır. Bu yüzden genel make check, yalnızca testleri değil tüm zorunlu kontrolleri içermelidir.

Bağımsız değerlendirici

Uygulayıcının kendi raporu asla bağımsız bir gerçeklik kaynağı değildir. Çözüm, rolleri ayırmaktır:

  • planlayıcı gereksinimi kabul kriterleri olan özelliklere böler ve kod yazmaz;
  • üretici bir özelliği uygular ve testleri çalıştırır, ama hazır olup olmadığına karar vermez;
  • değerlendirici kontrol listesindeki kriterlere göre hüküm verir.

Değerlendirici, üreticinin gerekçelerini görmemelidir, yoksa onun özgüvenini devralır. Yalnızca gereksinimi, diff'i ve çalıştırma sonuçlarını almalıdır. Claude Code'da bu, kendi temiz context'i olan bir subagent ile kolayca yapılır. Daha da iyisi, değerlendirici başka bir model olsun, çünkü onun kör noktaları farklıdır. "Makul görünüyor" türünden bir değerlendirme yasaktır: her sonuç bir dosyaya, satıra veya loga dayanmalıdır.

Ajanın kendisi düzeltebileceği hata mesajları

Doğrulama, çıktısı düzeltmeye götürdüğünde değerlidir. "Test failed" ya da çıplak bir AssertionError ajana bir şey söylemez. İyi bir mesaj şunları içerir: neyin bozulduğu, kuralın neden var olduğu ve nasıl düzeltileceği:

ERROR arch-check: app/services/refund.py, app/db/session.py dosyasını import ediyor
WHY: servisler veritabanıyla doğrudan konuşmaz, yalnızca repository'ler üzerinden
FIX: app/repositories/refund.py içindeki RefundRepository'yi kullanın

Bu biçim kontrolü bir yasaktan bir öneriye çevirir: ajan ihlali sizin yardımınız olmadan düzeltir.

İnsan kontrolü hâlâ nerede gerekli

Otomasyon insanı ortadan kaldırmaz, yalnızca rolünü daraltır. Kriterin resmileştirilmesinin zor olduğu yerlerde elle kontrol gerekir: arayüzün görünümü, metinler, senaryonun kullanım kolaylığı. Bunu "biraz tıklayıp bakmak" yerine kabul kriterlerinden oluşan bir kontrol listesiyle yapın. Aynı yorumu ajana ikinci kez yazıyorsanız, bunu otomatik bir kontrole dönüştürme işareti budur: bir test, bir linter kuralı veya make check içinde bir grep-guard.

E2E, ajanın davranışını çalıştırmadan önce değiştirir

Uçtan uca testin değeri yalnızca yakalanan hatalarda değildir. Ajan işinin bir E2E senaryosuyla kontrol edileceğini biliyorsa, kodu farklı yazar: yalnızca kendi fonksiyonunu değil komşu bileşenle olan sözleşmeyi düşünür, hata yollarını ele alır ve mimari sınırları çiğnemez, çünkü ihlal çalıştırmada ortaya çıkacaktır. Kontrol girdide bir sınır gibi çalışır, yalnızca çıktıda bir filtre gibi değil.

Bir koşul vardır: E2E ancak sistemin sınırları netse anlamlıdır. Spagetti mimaride uçtan uca bir test yalnızca spagettinin çalıştığını kanıtlar ve tasarımın nerede bozulduğunu göstermez. Bu yüzden önce katmanları ve bağımlılık kurallarını sabitleyin, sonra uçtan uca senaryoları kurun. Ajanlar depodaki mevcut desenleri, iyi olanları da kötüleri de, kolayca kopyalar; sınırları ilk günden koyun.

Sık yapılan hatalar

  • Ajandan "daha dikkatli kontrol et" istemek. Context aynı kalır, değerlendirme yine şişik çıkar.
  • 100% kapsamı garanti sanmak. Unit kapsamı bağlantıları kapsamaz.
  • Özellik onaylanmadan refactoring yapmak. Sıra katıdır: doğruluk → performans → stil.
  • En çok bozulan şeyi E2E'de mock'lamak. Veritabanı, migration'lar ve yapılandırma uçtan uca testte gerçek çalışmalıdır; ücretli dış API'ler test sunucusuyla değiştirilebilir.

Sonuç

Ajan "hazır" yazdığında ve özellik çalışmadığında, sorun neredeyse her zaman modelde değil doğrulama sürecindedir. Verification gap'i sayın, AGENTS.md içinde Definition of Done yazın, E2E'yi zorunlu kılın, hazır işaretini bir betiğe bırakın ve bağımsız bir değerlendirici ekleyin. Bu düzen, gerçek bir proje üzerinde uygulamalı bir kursta ayrıntılı olarak gösterilmektedir.

Sık sorulan sorular

Ajanın E2E testlerini kendisinin çalıştırmasını sağlayabilir miyim?

Evet, komut AGENTS.md içinde Definition of Done'un zorunlu bir parçası olarak yazılmışsa ve ajanın gerekli araçlara erişimi varsa. Ajanın hafızasına bağlı kalmamak için ayrıca bir hook veya CI ile de çalıştırın.

E2E testleri yavaş; her değişiklikte mi çalıştırmalıyım?

Hayır. Lint, tipler ve unit testler her zaman çalışsın. E2E, birden fazla katmanı etkileyen değişikliklerde ve özelliği hazır ilan etmeden önce çalıştırılsın.

Ajanın yaptığı frontend nasıl test edilir?

Tarayıcıda gerçek arayüze tıklayan uçtan uca bir testle (örneğin Playwright), görünüm için ise kontrol listesiyle elle kontrol veya değerlendiricinin inceleyeceği ekran görüntüleriyle.

Değerlendirici yerine kod incelemesi yeterli olmaz mı?

İnsan incelemesi faydalıdır, ama pahalıdır ve saatlerce süren özerk çalışmaya ölçeklenmez. Rubrikli bir değerlendirici bariz sorunları insana ulaşmadan yakalar; tartışmalı konularda karar yine insanındır.

Bu konuyu videoyla öğrenin

Bu konu “Harness Engineering: AI Ajanları İçin Güvenilirlik Mühendisliği” kursunda uygulamalı olarak ayrıntılı işleniyor.

Kursa git