Sertaç Yıldırımsaha notları

Ana sayfa → Teknik

Vibe Coding Ritüelleri

“Üç saatte bitirdim abi.” İki gün sonra aynı özelliğin hatalarını ayıklıyoruz. Sorun araçta değil — araç gerçekten iyi. Sorun, ritüel olmamasında.

Özet
  • Vibe coding prototipte harika, ürün kodunda tehlikeli. Ayrımı baştan yap.
  • En sık hata “çalışan ama ölçeklenmeyen” kod. On kayıtla mükemmel, on binle felaket.
  • Sık commit, senin geri alma tuşun. Çalışan her adımda kaydet.
  • Bazı yerler elle yazılır: yetkilendirme, para, silme, veri taşıma.

Önce dürüst bir ayrım

“AI kullanma” demiyorum, ben de kullanıyorum ve ekip de kullanıyor. Ama iki farklı iş var ve aynı yaklaşımla yapılamıyor:

Vibe coding uygun
  • Prototip, fikir doğrulama
  • Tek seferlik script, veri dönüştürme
  • Tanımadığın bir kütüphanede ilk adım
  • Test verisi, örnek girdi üretimi
  • Yarın silinecek bir demo
Vibe coding uygun değil
  • Yıllarca yaşayacak ürün kodu
  • Para dokunan her yer
  • Kimlik doğrulama, yetkilendirme
  • Veri silen veya taşıyan işlemler
  • Kişisel veri işleyen akışlar

Aradaki ayrımı yapamayanlar, prototip hızıyla yazdıkları kodu üretime alıyor ve faturayı üç ay sonra ödüyor.

Sahadan üç hata

1. Döngü içinde sorgu

Rapor ekranı üretildi, testte anında açılıyordu. Canlıda 40 saniye sürdü. Kod şuydu:

Çalışıyor ama ölçeklenmiyor
siparisler = SiparisRepo.bul(baslangic, bitis);   // 8.400 kayit

for (s : siparisler) {
    s.musteri = MusteriRepo.bulById(s.musteriId);   // ← 8.400 sorgu
    s.kalemler = KalemRepo.bulBySiparis(s.id);      // ← 8.400 sorgu daha
}

Test verisinde 12 sipariş vardı, yani 25 sorgu — göze çarpmıyor. Canlıda 16.801 sorgu. Bu hata sınıfının adı N+1 ve neredeyse hep aynı şekilde doğuyor: tek kayıt için doğru olan çözüm, listeye uygulanıyor.

Ritüel: üretilen her veri erişim kodunda tek soru — “bu döngü 10 bin kere dönerse ne olur?”

2. Var olmayan kütüphane

Bir yardımcı fonksiyon için önerilen paket, adı gayet makul olan ama gerçekte var olmayan bir paketti. npm install hata verdi, iki dakikada anlaşıldı, zararsız.

Zararsız olmayan versiyonu şu: gerçekten var olan ama terk edilmiş, son güncellemesi dört yıl önce yapılmış bir paketi önerme. Kurulum çalışır, kod çalışır, güvenlik açığı sessizce içeri girer.

Ritüel: yeni bir bağımlılık eklenirken üç şeye bak — son yayın tarihi, haftalık indirme, açık güvenlik uyarısı. Otuz saniye sürüyor.

3. Kodu doğrulamayan test

Bu en sinsisi. Kod yazıldıktan sonra “bunun testlerini de yaz” dendi. Testler yazıldı, hepsi geçti. Sonra biri fark etti: testler, kodun ne yapması gerektiğini değil, ne yaptığını doğruluyordu.

İşe yaramaz test
// Kodda hata var: indirim yuzde yerine tutar olarak uygulanmis
// Test de ayni hatayi "dogru" kabul ediyor:

test("indirim uygulanir", () => {
  expect(indirimUygula(100, 20)).toBe(80);   // dogru gorunuyor
});

// Ama kod: fiyat - indirim  (yani her zaman tutar dusuyor)
// Beklenen: fiyat * (1 - indirim/100)
// 200 TL'de 20 indirim: kod 180 diyor, dogrusu 160.
// Test 100 TL ile yazildigi icin ikisi de ayni sonucu veriyor.

Ritüel: testi önce yaz, ya da en azından beklenen değerleri koda bakmadan kendin belirle. Koda bakarak yazılan test, kodu değil kendini doğrular.

Yapay zeka yanlış kod yazmıyor; senin sormadığın soruların cevabını bilmiyor. İş, doğru soruları ritüel haline getirmekte.

On ritüel

1. Hedefi önce sabitle

Kod istemeden önce, bitmişliği tarif eden iki üç cümle yaz: girdi ne, çıktı ne, hangi uç durumlar önemli. Bu cümleler hem istemi netleştiriyor hem de sonunda “oldu mu?” sorusunu cevaplanabilir kılıyor. En iyisi bunu test olarak yazmak.

2. Küçük adım kuralı

Tek seferde 400 satır kabul etme. Bir fonksiyon, bir dosya, bir davranış iste. Sebebi kalite değil doğrulanabilirlik: 40 satırı okuyup anlayabilirsin, 400 satırı okumuyorsun — ve okumadığın kod, incelenmemiş koddur.

3. Proje kurallarını yazılı ver

Kod tabanında bir kurallar dosyası tut ve her oturumda bağlam olarak ver: hangi kütüphaneler kullanılıyor, hata nasıl yönetiliyor, log formatı ne, katmanlar nasıl ayrılmış.

Örnek: proje kuralları
# Bu projede
- Tarih islemleri: sadece java.time. Joda YOK.
- Hata: kendi HataKodu enum'umuz, ham exception firlatma.
- Veri erisimi: Repository katmani disinda SQL yazilmaz.
- Log: yapisal log, mesaja string birlestirme yok.
- Test: her servis metodu icin en az bir mutsuz yol testi.

Bunu yazmak yarım saat sürüyor ve tutarlılık kaymasının en büyük panzehiri. Yeni giren bir geliştirici için de faydalı, yani iki kere kâr.

4. “Neden böyle?” sormadan kabul etme

Üretilen koddaki her sıradışı satır için gerekçe iste. Açıklama makul değilse kod da değildir. Bu ritüel iki işe yarıyor: hatayı erken buluyorsun ve öğreniyorsun — ki uzun vadede asıl kazanç bu.

5. Çalışan her adımda commit

Bu, listedeki en pratik madde. AI ile çalışırken kod hızlı değişiyor ve bir noktadan sonra “iki adım önce çalışıyordu” noktasına dönmek imkânsız hale geliyor.

Ritim
küçük adım → testler yeşil → commit
küçük adım → testler yeşil → commit

# Bozulunca:
git diff HEAD~1        # son adimda ne degisti?
git reset --hard HEAD~1  # geri don, tekrar dene

Sonunda git rebase -i ile temizlersin. Ara commit’lerin çirkin olması önemli değil; onlar senin geri alma tuşun.

6. Yeşil bar kuralı

Testler kırmızıyken bir sonraki özelliğe geçme. Kulağa bariz geliyor ama vibe coding’in doğal akışı tam tersini teşvik ediyor: hız hissi devam etsin diye “onu sonra bakarım” deniyor. Üç “sonra” birikince neyin ne zaman bozulduğu kaybediliyor.

7. Tehlikeli bölge listesi

Bazı yerlerde son hali insan yazar. Ekipte listemiz şu:

  • Kimlik doğrulama, yetkilendirme, oturum yönetimi
  • Para hesabı: fiyat, indirim, vergi, iade
  • Veri silen veya taşıyan işlemler (migration dâhil)
  • Kişisel veri işleyen akışlar
  • Dış sistemle mutabakat

Buralarda öneri almak serbest; kopyalayıp geçmek yasak. Ölçüt basit: yanlış olursa geri dönüşü var mı?

8. Üç deneme kuralı

Aynı hatayı üçüncü kez düzeltmeye çalışıyorsan dur. Döngüye girmişsindir ve her denemede kod biraz daha karışıyordur. Yapılacak şey: son çalışan commit’e dön, hatayı kendin oku, problemi tarif et, sonra yeniden başla.

Bu kural bende en çok zaman kazandıran madde oldu. Döngüde geçen 40 dakika, elle bakılan 10 dakikadan pahalı.

9. Ne yapıştırdığına dikkat

Hata ayıklarken log yapıştırmak çok doğal — ve loglarda müşteri e-postası, token, bağlantı dizesi olabiliyor. Ekip kuralı yazılı olsun; olmayınca herkes iyi niyetle kendi kuralını uyduruyor.

10. Bir kere de kendin yaz

Yeni bir konu öğreniyorsan, üretilen kodu okuyup kapat ve aynı şeyi kendin yaz. Yarım saat kaybediyorsun ama o konu artık senin oluyor. Bunu yapmayan insanlarda gördüğüm şey şu: bir yıl sonra çok iş çıkarmış ama derinleşmemiş oluyorlar ve ilk gerçek krizde tıkanıyorlar.

Kod incelemesinde neye bakılır?

Üretilen kodun kendine has bir kokusu var. İncelemede özellikle şunlara bakıyorum:

İşaretNe anlama gelir
Döngü içinde sorgu / HTTP çağrısıTest verisiyle çalışan, canlıda ölen kod
Her şeyi yakalayan geniş try/catchHatalar sessizce yutuluyor
Aynı işi yapan ikinci bir yardımcı sınıfMevcut kod tabanına bakılmamış
Kodun anlattığını tekrar eden yorumlarGenelde zararsız, ama gözden geçirilmediğinin işareti
Projede kullanılmayan bir desen/kütüphaneTutarlılık kayması başlıyor
Sadece mutlu yolu test eden testlerAsıl riskli yollar test edilmemiş

Peki gerçekten hızlandırıyor mu?

Evet, ama ölçtüğün yere bağlı. Bizde şu tabloya benzer bir şey çıktı:

  • İlk çalışan sürüme kadar: belirgin şekilde hızlı. Burada tartışma yok.
  • İncelemeden geçmiş sürüme kadar: kazanç azalıyor, çünkü inceleme yükü artıyor.
  • Canlıda sorunsuz çalışan sürüme kadar: ritüel yoksa kazanç eksiye düşebiliyor.

Yani hız gerçek; ama ölçmen gereken şey “ne kadar hızlı yazdım” değil “ne kadar sürede güvenle canlıya çıktı”.

Kontrol listesi

PR açmadan önce
  • Bu koddaki her satırı açıklayabiliyor muyum?
  • Döngü içinde sorgu veya dış çağrı var mı?
  • Testler beklenen davranışı mı doğruluyor, mevcut kodu mu?
  • Yeni bir bağımlılık eklendiyse bakımı sürüyor mu?
  • Projedeki mevcut desenlere uyuyor mu, yeni bir yol mu açtı?
  • Tehlikeli bölgelerden birine dokundum mu? Dokunduysam elle mi yazdım?
  • Ara commit’ler var mı? (Tek dev commit ise geri dönüş zor.)
  • Yapıştırdığım şeylerde gizli veri var mıydı?

Sonuç

Vibe coding bir yetenek değil bir mod. Doğru anda açıp yanlış anda kapatmayı bilmek gerekiyor. Prototipte aç, ödeme akışında kapat.

Ve baştaki “üç saatte bitirdim” cümlesine dönelim: o cümle yanlış değildi. Eksik olan kısım şuydu — üç saatte yazıldı, ama hiç kimse okumadı. Ritüellerin tamamı aslında tek bir şeyi geri getirmeye çalışıyor: okumayı.