Bir Pazartesi sabahı beş kritik hata raporuyla uyanıyorsunuz. İnceleme izleme aracınız görevini yapmış. Her çökme raporunu, her öfkeli bir yıldızlı yorumu, her "kaydet düğmesine bastığımda uygulama donuyor" bildirimini yakalamış. Nelerin bozuk olduğunu tam olarak biliyorsunuz. Bilmediğiniz şey ise nereye bakacağınız.
İlk pipeline'ımı kurduktan sonra çarptığım duvar buydu. Uygulama incelemelerini ve gelen çökme günlüklerini sorunsuzca izliyor, her bir geri bildirimi düzenli kategorilere ayırıyordu: hatalar, çökmeler veya özellik talepleri. Panel sağlıklı görünüyordu. Asıl hata ayıklama (debugging) süreci ise öyle değildi.
Bir hatanın var olduğunu bilmek, bir mil boyundaki yolun sadece ilk birkaç santimetresidir. Hâlâ IDE'yi açmam, modüller arasında grep yapmam, yığın izlerini (stack traces) mevcut kod tabanıyla karşılaştırmam ve hata yolunu zihnimde yeniden kurgulamam gerekiyordu. Biletler (tickets) birikmeye başladığında ve kahveniz hâlâ sıcakken, bu manuel arkeoloji sahip olmadığınız bir zamanı tüketir. Pipeline'ın sadece sorunları işaret etmesini değil, onları araştırmasını istiyordum.
Bu yüzden sistemi tek bir hedef etrafında yeniden inşa ettim: ham bir hata raporunu alıp doğrulanmış bir teşhis döndürmek. Bir LLM musallatlığı içeren paragraf değil. Dosyayı isimlendiren, satırı gösteren, riski tahmin eden ve bir çözüm öneren yapılandırılmış bir bulgu. İşte süreç şöyle şekillendi.
Neden Yapılandırılmış Veri, Bir Sohbet Kaydından Daha İyidir
Araştırma ajanını PydanticAI ile inşa ettim. Sebebi basitti. Bir dil modelinden kod hakkında mantık yürütmesini istediğinizde, varsayılan çıktısı dostane bir metin akışıdır. Bu bir insan okuyucuya yardımcı olabilir ancak sonraki aşamadaki bir betik (script) için işe yaramaz. Makine tarafından okunabilir bir sözleşmeye ihtiyacım vardı.
Ajan; kök neden, etkilenen dosyalar, önerilen değişiklikler ve karmaşıklık ile risk değerlendirmesi olmak üzere dört spesifik alan içeren doğrulanmış bir veri modeli döndürür. Eğer model bir alanı eksik bırakırsa veya bir dosya yolunu uydurursa (hallucinate), doğrulama başarısız olur ve bunu anında yakalarım. Bu titizlik, pipeline'ın dürüst kalmasını sağlar.
Gerçek dedektiflik işini yapmak için ajan, dört adet salt okunur (read-only) araç alır ve başka hiçbir şey almaz. grep aracılığıyla kod arayabilir, bir dosyadaki belirli satır aralıklarını okuyabilir, dizin içeriğini listeleyebilir ve sınıflar veya fonksiyonlar gibi sembollerin yerini tespit edebilir. Önemli olan kısmın "salt okunur" olmasıdır. Yazma erişimi olan bir ajanın gece saat 2'de depo (repository) içinde dolaşmasını istemedim. Önce anla, sonra düzenle.
Repo Haritası: Araçlardan Önce Bağlam
Ajanın ilk versiyonu doğru sonuçlar veriyordu ancak aşırı maliyetliydi. Daireler çizen bir turist gibi tokenları hızla tüketiyordu. Model önce list-dir çağırıyor, sonra grep yapıyor, sonra bir dosya okuyor, sonra tekrar list-dir yapıyor; proje yapısının zihinsel modelini her seferinde pahalı bir token harcayarak yavaş yavaş oluşturuyordu.
Çözüm, ajan daha işe başlamadan önce kompakt bir repo haritası oluşturmaktı. Bu harita, deponun damıtılmış bir özetidir: anahtar dosyalar, bunların temel işlevleri veya sınıfları ve ana modüllerin birbirine nasıl bağlandığı. Bunu ajana deneme yanılma yoluyla yolları keşfetmesini söylemek yerine bir GPS vermek gibi düşünebilirsiniz.
Bu harita bağlam penceresinde (context window) olduğunda, ajan src/utils/parser.ts dosyasının var olup olmadığını anlamak için gereksiz çağrılar yapmaz. Araziyi zaten biliyordur. Doğrudan dumanların yükseldiği tepeye yönelir. Bu tek değişiklik, "gezinme" aşamasını tamamen ortadan kaldırdı.
Araç Hunisi: Bir Sonuca Zorlamak
Bir harita olsa bile ajan kararsız kalabiliyordu. Şüpheli bir dosya buluyor, sonra kendi kararından şüphe ediyor, sonra tekrar arıyor, sonra başka bir dosya okuyor; sadece "bir kontrol daha" döngüsüne girip kalıyordu. Bir ivme kazandırmak için bir yönteme ihtiyacım vardı.
Ajanın ilerledikçe neler yapabileceğini kısıtlayan üç aşamalı bir araç hunisi uyguladım.
Birinci aşama keşiftir. Ajan, dört aracın tamamına tam erişime sahiptir. Mantık yürütme sürecinde hatayı yeniden oluşturmak için gereken her şeyi arayabilir, göz atabilir ve okuyabilir.
İkinci aşama derinlemesine incelemedir. Ajan muhtemel hata noktalarını belirledikten sonra keşif araçlarını kaybeder. Sadece dosyaları okuyabilir. Artık grep yapmak veya dizin listelemek yok. Bu aşamada, halihazırda bulduğu kodu incelemeli ve kanıt zincirini oluşturmalıdır.
Üçüncü aşama çıktıdır. Tüm araçlar kilitlenir. Ajan artık kod tabanına sorgu gönderemez. Oturup raporu yazması gerekir. Bu, bitmek bilmeyen "şuna da bir bakayım" sarmalını engeller.
Bu huni, analiz başına düşen ortalama araç çağrısı sayısını kırktan yaklaşık on çağrıya düşürdü. Ajan daha hızlı, daha ucuz ve paradoksal olarak daha özgüvenli hale geldi; çünkü bir sonuca varmak zorundaydı.
Backend'i Değiştirilebilir Tutmak
Sistemi tek bir model sağlayıcısına sabitlemek istemedim. Göreve bağlı olarak farklı motorlar kullanıyorum. Bazen Claude Code, bazen Grok Build, bazen de o an en ucuz olan neyse onu kullanıyorum. Temel mantığı sağlayıcıdan bağımsız tutmak için işi iki aşamaya böldüm.
Birinci aşama keşiftir. Herhangi bir yetenekli model olabilen kodlama ajanı, repo haritasını okur, araçları kullanır ve ham bir markdown raporu üretir. Bu, maliyetli olan düşünme kısmıdır.
İkinci aşama yapılandırmadır. Ucuz ve hızlı bir LLM, bu markdown'ı alır ve katı bir Pydantic modeline yeniden biçimlendirir. Bu aşama neredeyse hiç muhakeme gerektirmez. Sadece veri çıkarma ve biçimlendirmeden ibarettir, bu nedenle hafif donanımlarda çalışabilir.
Sınır net olduğu için doğrulama mantığına dokunmadan arka ucu değiştirebilirim. Markdown raporu, keşif yapan beyin ile fiilen kullandığım yapılandırılmış çıktı arasında evrensel bir adaptör görevi görür.
Gerçekten İşe Yarayan Ne Oldu
Bu kurulum, gelen sorunları ele alma biçimimi değiştirdi. Sınıflandırma katmanı hala hataları özellik taleplerinden ayırıyor, ancak artık analiz katmanı hemen ardından devreye giriyor. Editörümü açana kadar beni bekleyen bir dosya yolu, bir satır aralığı ve önerilen bir değişiklik hazır oluyor. Her şeyi hala manuel olarak inceliyorum. Bu bir asistandır, otopilot değil. Ancak eskiden [olan] bağlam toplama...
