İçeriğe geç
Muhammet Şafak
Günlük 8 dk okuma

AI ile self-review — neyi hızlandırıyor, nerede yetmiyor

Üç ay önce kendi diff'imi denetleyecek bir tool yazdım. Bu yazı 'niye' değil 'ne kadar' yazısı: workflow'a hangi katmanlarda giriyor, hangi rakamlarla hızlandırıyor, hangi bug pattern'lerini tekrar tekrar yakalıyor — ve nerede sınırına dayanıyor.


Önceki yazıda CommitBrief’i niye yazdığımı anlatmıştım: kendi diff’ime mesafe alamamak, mevcut AI araçlarının diff seviyesinde düşünmemesi, terminalden çıkmadan ikinci bir göz ihtiyacı. Bu yazı “niye” değil “ne kadar” yazısı. Üç ayın sonunda workflow’a hangi katmanlardan girdiğini, hangi rakamlarla hız kazandırdığını, hangi tip hataları tekrar tekrar yakaladığını ve nerede yetmediğini somutlaştırmak istiyorum.

Önce bir hatırlatma: bu araçların değer ürettiği yer “AI yazsın” değil “AI ikinci bir göz olsun” — daha önce yazdığım gibi üretim ucuzladıkça muhakeme pahalılaşıyor. Bir tool’un değeri o pahalı muhakemeye ne kadar iyi yardım ettiği. Aşağıdakiler benim ölçtüğüm kadarı.

Doğru leverage point: dosya değil, değişiklik

İlk hafta yanlış soyutlamayla başladım: bir dosyayı AI’a verip “bunu review et” demek. Çıktı uzun, jenerik ve büyük ölçüde alakasızdı. Çünkü bir reviewer’ın bakacağı şey dosya değil, o dosyaya gelen değişiklik. CommitBrief’in tasarım birimi diff olunca üç şey aynı anda iyileşti: token bütçesi 10× düştü, severity ataması anlamlı hale geldi (artık “bu fonksiyon iyi yazılmış mı” değil, “bu değişiklik soruna yol açıyor mu” sorusuna cevap aranıyor), false positive bandı küçüldü.

Pratikte bunun anlamı: bir PR’ın “yapay zeka tarafı” dört-beş saniyeye sığabilir. Bu da onu pre-push refleksi haline getirebilecek kadar hızlı yapıyor.

Üç entegrasyon katmanı

CommitBrief’i workflow’a sokmanın üç katmanı var; her birinin farklı bir hız profili.

KatmanKomutHız profiliTipik kullanım
Manuelcommitbrief4-5 sn, $0.02-0.04Push’tan önce kendi gözünün üstüne bir göz
Pre-push hookcommitbrief install-hook --hook=pre-push --fail-on=criticalPush’u kritik bulguda iptal ederSolo geliştirici / küçük takım
CI stepcommitbrief --fail-on=highPR pipeline’ında soft/hard gateTakım PR’larında ortak çıta

Üçü birden değil, birini seç ve aklında tut. Hepsini aynı anda kurmak workflow disiplinini değil, bildirim gürültüsünü artırır. Ben solo akışta manuel komut + pre-push hook kullanıyorum; CI step’i takım projelerinde tutuyorum.

Pre-push hook’un bir inceliği var: önce kurduğum sürüm gerçekte --staged çalıştırıyordu — yani push anında index genelde boş olduğu için sessizce no-op’a düşüyor, push geçiyordu. “CI gate kurduğunu sanıp aslında hiçbir şey kurmamak” — kendi audit’imde bu hatayı yakaladım, v1.0’da pre-push artık git’in stdin protokolünü okuyup commitbrief diff <remote>..<local> çalıştırıyor. Tool’un kendi sınırlarına çarptığı yerlerde dürüst olmak gerekiyor.

Rakamlar — benim akışım

Üç senaryo, üç farklı hız profili.

Senaryo 1 — Pre-push refleksi (solo)

Tipik bir orta boy PR’ım: ~120 satır eklenmiş, 40 silinmiş, dört-beş dosya. Eski akışım:

  • git diff --staged ile gözden geçirme: 4-7 dk
  • İki kez daha okuma (anchor bias’a karşı): +3-4 dk
  • Push, PR aç

Yeni akışım:

  • commitbrief --staged: 4-5 sn → çıktıyı oku: 30-60 sn
  • Critical/High varsa düzelt + tekrar çalıştır (cache hit: 13 µs, $0)
  • Bilinçli derin okuma (artık ne aradığımı biliyorum): 2-3 dk
  • Push, PR aç

Toplam: 9-10 dk → 3-5 dk. %55 civarı bir hız, evet — ama asıl kazanç dakikalarda değil; gerçek hatayı reviewer’a ulaşmadan yakalamak bu işin en pahalı kısmı.

Senaryo 2 — Takım PR round-trip

Bir kritik bulgu reviewer’a ulaşmadan yakalandığında PR round-trip iki günden bir güne iniyor. Bu kasıtlı bir mütevazılık: aslında daha da kısalıyor ama ortalamayı bozan “reviewer’ın yine de fark ettiği başka bir şey” döngüsü her zaman var. AI insan reviewer’ı tamamen bypass etmiyor; reviewer’ın gözünü “kolay bulgular” yerine “hard bulgular”a odaklıyor. Net etki bu.

Senaryo 3 — Cache hit ekonomisi

CommitBrief’in cache key’i: SHA256(diff + system_prompt + provider + model + lang + schema_version). Diff değişmediği sürece aynı çağrı 13ms sürüyor ve $0 maliyet üretiyor. Pratikte:

  • Rebase sonrası tekrar review: bedava
  • Push öncesi “son kez bir bakayım”: bedava
  • Sağlayıcı değiştirip karşılaştırma: bedava değil ama yeni cache key’i, paralel ikinci görüş için cazip

Aylık fatura matematiği: Anthropic Sonnet 4.6 ile ortalama $0.03/review × ayda ~50 PR × cache miss oranı %40 ≈ $0.60/ay. Ollama ile sıfır, sadece elektrik. Bir saatlik insan code review zamanının opportunity cost’unun yanında ihmal edilebilir.

Yakaladığım pattern’ler

Üç ayda CommitBrief’in (ve aynı pipeline’ı paylaşan sağlayıcıların) tekrar tekrar yakaladığı beş paterni saydım. Bir kısmı günlük kullanımımdan, bir kısmı CommitBrief’in v1.0 öncesi self-audit’inden — üç farklı sağlayıcıya kendi proje kurallarımla kendi projemi review ettirdim, ortak bulgu setlerini topladım. Her biri “diff okumayla yakalanabilir, gözle yakalanması zor” kategorisinde.

1. Error wrap duplikasyonu. %w format specifier zaten wrapped error’u içerirken prefix’te aynı mesajı tekrarlamak. Log’da "auth failed: auth failed: invalid token" üretir. Statik analiz yakalamıyor çünkü teknik olarak hata değil; semantik bir tekrar. Compiler memnun, log’lar berbat.

2. NOT NULL kolon migration default’suz. Boş tabloda sorunsuz, dolu prod tablosunda fail. CommitBrief’in tipik çıktısı: “Migration fails on any table that already has rows; either backfill in a prior migration or add a DEFAULT before the constraint.” Bu bug staging’de görünmeyip prod’da görünen klasik aileden.

3. i18n catalog’da key var, kullanılmamış. Çoklu dil destekleyen projelerde sık: yeni bir prompt için EN/TR key ekliyorsun ama kodda cat.T(...) yerine hardcoded string bırakıyorsun. EN’de fark edilmez (string aynı), TR’de fonksiyonel kırılma. Benim kendi projemde bu pattern audit’in en tutarlı bulgularından biriydi — guard.prompt ve setup.welcome key’leri YAML’de duruyordu, ama gerçek prompt’lar Go kodunda İngilizce literal’di. Üstüne çok ironik bir vaka: Türkçe [e/H]: (evet/Hayır) prompt’u render ediliyordu ama parser sadece y/yes kabul ediyordu — Türk kullanıcı e yazınca sessizce “no” olarak işleniyordu. “i18n var” sandığım yer aslında “i18n yarım” idi.

4. Config knob accepted-but-ignored. Config schema’da var, config set ile kabul ediyor, dokümante etmişsin — ama kod path’inde okunmuyor. Kullanıcı dokümana inanıp ayarlıyor, etki sıfır. CommitBrief’in kendi cache config’inde bunu yaptım: cache.enabled: false set’lemek hiçbir şey yapmıyordu çünkü pipeline cache’i sadece Dir ve RepoRoot parametresiyle açıyordu. Bu pattern özellikle iki ayrı PR’da bölünür — “config tanımla” PR’ında ve “config kullan” PR’ında. AI ikincisinin eksikliğini fark ediyor; insan reviewer iki PR arasındaki zaman aralığında bağlamı kaybediyor.

5. Boş katmanlar arasında kaybolan ref. Bir kapı kurduğunu sandığın bir mekanizmanın aslında no-op olması. CommitBrief’in pre-push hook’u bunu yapıyordu (yukarıda anlattım). Bu tip bug AI olmadan ya production’da ya da güvenlik incident’inde yakalanır; pattern’i bilen bir reviewer diff’te de görür.

Beşinin ortak özelliği: hiçbiri “kod yanlış derleniyor” tipi değil. Hepsi intent ile gerçeklik arasındaki boşluk. AI’ın gerçekten katma değer ürettiği yer tam burası — sentaks doğrulamak zaten compiler’ın işi.

Proje-spesifik kuralın önemi

CommitBrief’i generic AI review araçlarından ayıran en somut nokta: COMMITBRIEF.md projenin kök dizininde durur ve system prompt olarak LLM’e gider. CommitBrief deposunun kendi COMMITBRIEF.md’sinden üç madde:

  • “Yeni dependency MIT / Apache-2.0 / BSD / ISC / MPL-2.0 / LGPL-3.0+ olmalı; AGPL veya proprietary kabul edilmez.”
  • “Tüm user-facing string’ler cat.T(key, ...) üzerinden gitmeli; hardcoded English / Turkish reddedilir.”
  • “i18n catalog’a yeni key eklendiyse EN/TR parity zorunlu; tek tarafta key olamaz.”

Bunlar generic “iyi kod” tavsiyeleri değil; bu projenin kendi politikası. Generic bir AI asistanı “bu dependency MIT mi GPL mi” sormaz; benim kuralıma göre review eden bir AI sorar. Bu fark, review’un kullanışlılığını sentaks-seviyesinden mimari-niyet-seviyesine taşıyor — ve aynı tek dosyayı paylaşan bir takımda “hangi standartlar geçerli” tartışmasını koddan önce gerçekleştirmiş oluyor.

Sağlayıcı kararı + maliyet

Dört sağlayıcının (Anthropic, OpenAI, Gemini, Ollama) artı iki CLI-tabanlı sağlayıcının (claude-cli, gemini-cli) tek bir abstraction üstünde yaşaması iki şeyi mümkün kılıyor: karşılaştırma ucuz, lock-in yok.

SağlayıcıTipik reviewGüçlü yanZayıf yan
Anthropic Sonnet 4.6$0.03En tutarlı muhakeme, ephemeral prompt cache (5dk)En pahalı orta seviye
Gemini 2.5 Pro$0.012M context, cömert ücretsiz tierZaman zaman overly verbose
OpenAI GPT-4o$0.02Hızlı; ≥1024 token prefix’lerde otomatik cacheSonnet’ten kısa açıklamalar
Ollama (yerel)$0Zero exfiltration, kendi donanımınDonanım gerekli, modele bağlı kalite
claude-cli$0*Mevcut Claude Code subscriptionPlain text — structured findings yok
gemini-cli$0*Mevcut Gemini CLI authAynı

* Mevcut abonelik var sayılırsa marjinal $0.

Pratikte: günlük akışta Anthropic Sonnet kullanıyorum (tutarlılık önemli). Yüksek hassasiyet gereken PR’larda aynı diff’i Gemini Pro’ya da gönderip iki bulgu setini karşılaştırıyorum — cache mantığı sağlayıcı per-key olduğu için ikisi ayrı entry, ama maliyet hâlâ yuvarlanmış birkaç kuruş. Yerelde kalması gereken kod için Ollama. CLI sağlayıcılarını henüz günlük akışta kullanmıyorum çünkü plain text çıktı --fail-on severity gate’ini bypass ediyor; aboneliğin zaten ödeniyorsa hızlı bir “ikinci bakış” için faydalı, CI integration’ı için değil.

Nerede yetmiyor

Üç ay sonra hâlâ tool’un sınırlarına çarpıyorum. Dürüst liste:

  • Mimari sorgulama yok. “Bu özelliği yapmalı mıyım”, “bu abstraction doğru mu” sorularına cevabı yok. Tek bir diff’in sistemin bütünüyle nasıl oturduğunu görmüyor.
  • Intent doğrulama yok. “Doğru özelliği mi yapıyorsun” diyemiyor. Yanlış spec’in mükemmel implementasyonu yeşil çıkar.
  • Cross-file consistency sınırlı. Tek bir PR’daki dosyalar arası tutarlılık tamam, ama PR dışındaki kod tabanıyla kontrast kuramıyor (“bu pattern projenin başka yerinde X şeklinde yapılıyor, burada Y kullanmışsın” gibi). Repo geneli vektörleme yapmıyor; PRD’de bilinçli scope kararı.
  • False positive bandı var. Genelde info seviyesinde ve görmezden gelmek kolay, ama yine de var. OUTPUT.md template’iyle info bulgularını filtrelemek mümkün.
  • Prompt injection riski. Diff’in içindeki saldırgan içerik LLM’i yanıltabilir. CommitBrief’in mitigation’ı: <project_rules>...</project_rules> XML wrapper + immutability guard + her review öncesi secret scan. Yine de sıfır risk değil; security-sensitive diff’lere --no-cache + dikkatli okuma tavsiye ederim.

Bu sınırların hiçbiri “araç işe yaramıyor” sonucuna götürmüyor — sadece yerini doğru koymak lazım. CommitBrief lint’in yerine değil, lint + test’in üstüne, insan review’un altına bir katman.

Kapanış

İlk yazıda söylediğim cümleyi tekrar etmek istiyorum: üretim ucuzladıysa, üretileni denetlemek pahalı kalmamalı. Üç ayın somut çıkarımı şu: AI’ın değer ürettiği nokta yargıyı kalibre etmek; yargıyı yerine koymak değil. Bir tool’un doğru tasarımı bu farkı reddetmek değil; kabul edip iki tarafı birbirine bağlamak.

CommitBrief benim için bu bağlantıyı kuran şey oldu. Sizin için işe yararsa, COMMITBRIEF.md’inizi paylaşmanızı isterim — başka projelerin “iyi kod” u nasıl tanımladığını görmek, bu işin en öğretici tarafı.

Etiketler: #araclar#Git#Go
Paylaş:

İlgili Yazılar

Sitede Ara

Yazı, proje ve sayfalarda arama yapmak için yazmaya başlayın.

Esc ile kapat Pagefind ile güçlendirildi