Ekibe yeni katılan bir arkadaşımıza geçen ay ilk görevini verdiğimde, iki saat sonra yanıma geldi: "bitti, PR'ı açtım, testler yeşil." Kodun kendisi gerçekten temizdi, isimlendirmeler doğruydu, fonksiyon kısaydı. Ama sordum: "bu endpoint'e aynı anda iki istek gelirse ne olur?" Sessizlik. "Peki üçüncü parti servis zaman aşımına uğrarsa?" Yine sessizlik. Kod çalışıyordu, doğruydu bile — ama yazan kişi kodun ne zaman yanlış davranacağını hiç düşünmemişti. O gün fark ettim ki biz ekipte insanlara aslında kod yazmayı öğretmiyoruz; kod yazmayı zaten çoğu genç arkadaş biliyor, üniversitede ya da kendi projelerinde öğrenmiş oluyorlar. Bizim asıl öğrettiğimiz şey, yazdıkları koddan — ve daha da önemlisi başkasının, hatta kendi geçmiş halinin yazdığı koddan — şüphelenmeyi bilmek.
Çalışıyor olması, doğru olduğu anlamına gelmez
Bu ayrımı genellikle ilk hafta içinde bir örnekle anlatıyoruz. Basit bir indirim hesaplama fonksiyonu veriyoruz, mutlu yol senaryosunda kusursuz çalışıyor: yüzde 20 indirim, 100 liralık üründe 80 lira çıkıyor. Sonra soruyoruz: fiyat 0 ise ne olur? İndirim yüzde 100'den büyükse? Negatif fiyat gelirse (evet, bir entegrasyon hatasıyla gerçekten geldi bir keresinde)? Kur farkından dolayı virgülden sonra 14 hane gelen bir sayı işlenirse? Genelde üç dört soru sonra arkadaşın yüzündeki ifade değişiyor; "çalışıyor" ile "doğru" kelimelerinin aslında aynı şey olmadığını o an içselleştiriyor. Testler yeşil yanıyor diye kod güvenilir değildir — testler, sizin düşünmeye tenezzül ettiğiniz senaryoları doğrular, düşünmediğiniz senaryolar hakkında hiçbir şey söylemez.
Şüphenin üç katmanı
Zamanla bu öğretim şeklini üç katmana ayırdığımızı fark ettim. Birinci katman kendi kodundan şüphelenmek: "bu satırı yazarken hangi varsayımı yaptım, o varsayım her zaman doğru mu?" İkinci katman başkasının kodundan şüphelenmek — kod incelemesinde "bu güzel görünüyor" demek yerine "bu hangi durumda patlar?" sorusunu sormak. Üçüncü katman, son bir yıldır giderek daha kritik hale gelen katman: yapay zekânın ürettiği koddan şüphelenmek. Şu an ekipte kod önerilerinin önemli bir kısmı bir dil modelinden geliyor ve modelin ürettiği kod neredeyse her zaman derli toplu, okunaklı, kendinden emin görünüyor — tıpkı stajını yeni bitirmiş, çok zeki ama hiç prod ortamında yanmamış bir mühendis gibi. Kendinden emin görünmek ile güvenilir olmak aynı şey değil; model, var olmayan bir kütüphane fonksiyonunu da aynı kendinden emin tonla önerir, gerçekten var olan bir fonksiyonu da. Ekipte artık bir kural var: yapay zekânın ürettiği hiçbir kod, onu isteyen kişi mantığını tam olarak açıklayamadan merge edilmez. "Model böyle yazdı" bir gerekçe değil, itiraftır.
Şüpheyi öğretmenin somut yöntemleri
Soyut bir "şüpheci ol" tavsiyesi kimseyi değiştirmez; bizim işe yarayan birkaç somut alışkanlığımız var. Birincisi, her PR açıklamasına "bu değişiklik hangi durumda yanlış davranır?" sorusunun cevabını zorunlu tutuyoruz — boş bırakılamayan bir alan. İkincisi, kod incelemesinde onaylayan kişinin en az bir "kenar durumu" (edge case) sorusu sorması gerekiyor; sorusu olmayan bir inceleme, incelenmemiş demektir bizim için. Üçüncüsü, "hayali arıza günü" dediğimiz bir alıştırma: yeni katılan arkadaşa çalışan bir servis veriyoruz ve "bu servisi bugün nasıl çökertirsin?" diye soruyoruz. Cevap üretmek, kod yazmaktan çok daha zor bir egzersiz; çünkü kırmak, yapmaktan farklı bir zihniyet gerektiriyor. Dördüncüsü, ki en çok sevdiğim: gerçek bir prod olayının (post-mortem'in) kesinleşmiş, isimsizleştirilmiş halini yeni katılanlarla birlikte satır satır okuyoruz. "Bu hatayı önleyecek testi kim yazardı, neden yazmadı?" sorusunun cevabı genelde "kimse böyle bir şeyin olabileceğini düşünmedi" oluyor — ve tam da bu yüzden bu alıştırmayı yapıyoruz.
Bir vakayı hatırlatayım
Geçen yıl bir gece, bir dil modelinin önerdiği kod, bir ödeme yeniden deneme (retry) mantığını "iyileştiriyordu": başarısız bir işlemi otomatik olarak üç kez tekrar deniyordu. Kod tertemizdi, açıklaması makul görünüyordu, testler geçiyordu — çünkü test senaryosu her denemede aynı sahte yanıtı döndüren bir mock kullanıyordu. Gerçek dünyada olan şuydu: ilk deneme aslında sunucuya ulaşmıştı ve para çekmişti, ama yanıt ağ gecikmesi yüzünden zamanında dönmemişti; sistem "başarısız" sanıp ikinci, üçüncü denemeyi tetikledi. Bir kullanıcının kartından aynı sipariş için üç kez para çekildi. Modelin suçu değildi bu — model, kendisine verilen "başarısız işlemi tekrar dene" talimatını harfiyen yerine getirmişti. Suç, o talimatı sorgulamadan onaylayan bizdeydi: "başarısız" ile "yanıtı gelmedi" arasındaki farkı, idempotency anahtarı olmadan asla güvenle ayıramayacağımızı unutmuştuk. O olaydan sonra ekipte yeni bir refleks yerleşti: bir model "bunu otomatikleştirdim, tekrar dene" dediğinde, ilk soru artık "tekrar denemek ne zaman güvenli değildir?" oluyor.
Şüphenin sınırı: paralize eden değil, üreten şüphe
Burada bir tuzak var, onu da görmezden gelmiyoruz: her şeyden şüphelenen bir mühendis hiçbir şey teslim edemez. Amacımız paranoyak bir ekip kurmak değil; "yeterince şüphelenip sonra karar veren" bir ekip kurmak. Bunun için bir kalibrasyon aracımız var: her değişikliği, geri alınabilirliğine göre değerlendiriyoruz. Geri alınması kolay, etkisi sınırlı bir değişiklikte (bir buton rengi, bir log mesajı) uzun şüphe seansına gerek yok, hızlıca deneyip görün. Geri alınması zor, etkisi geniş bir değişiklikte (bir ödeme akışı, bir veri şeması) şüphe bütçesi tam açılır. Yeni katılan arkadaşlara ilk öğrettiğimiz refleks aslında bu ayrımı yapabilmek: her satır koda aynı yoğunlukta şüpheyle yaklaşmak, hem zaman kaybettirir hem de asıl kritik yerde dikkati köreltir. İyi mühendis, şüphesini nereye harcayacağını bilen mühendistir.
Geçenlerde o ilk PR'ı açan arkadaş, başka bir arkadaşının kodunu incelerken durup sordu: "bu fonksiyon aynı anda iki kez tetiklenirse iki kez para mı çekiyor?" Sorunun kendisi, aylar önce kendisine sorduğum sorunun neredeyse birebir aynısıydı. O an anladım ki öğretmeye çalıştığımız şey gerçekten yerine oturmuş — kod yazmayı zaten biliyordu, şimdi koddan şüphelenmeyi de öğrenmişti. Ekip kültürü konusunda konuşmayı her zaman severim, iletişim sayfam açık.