- Son dönemde geliştiriciler, LLM’lerin (büyük dil modelleri) ürettiği kodu düzeltmek ve tamamlamak için daha fazla zaman harcıyor
- Tıpkı mevcut legacy kodda olduğu gibi, kodu güvenle değiştirebilmek için önce ne yapıldığını ve neden öyle uygulandığını anlamak gerekiyor; ancak LLM kodu bu süreci daha da zorlaştırıyor
- Bazı ekipler kodu yeterince gözden geçirip yeniden işledikleri için yavaşlıyor, ancak birçok ekip okunmadan ve yüzeysel test edilerek bırakılmış kodu olduğu gibi depoya yansıtıyor
- Bu durum “anlama borcu (Comprehension Debt)” yaratıyor ve sonunda kodun değiştirilmesi gerektiğinde daha büyük bir zaman maliyeti olarak geri dönüyor
- LLM’ler genel olarak sorun çözmede yaklaşık %70 düzeyinde işe yarayabiliyor, ancak tekrar eden başarısızlıklardan oluşan “Doom Loop”’tan kaçınamıyor; sonuçta insanların kodu bizzat anlayıp düzeltmesi gereken bir durum kaçınılmaz olarak ortaya çıkıyor
LLM’lerin ürettiği kod ve anlama borcu sorunu
- Son dönemde geliştirme dünyasında ChatGPT, Copilot gibi LLM tabanlı otomatik kod üretim araçlarının kullanımı artıyor
- Bu araçlar, geliştiricinin bilgi sahibi olmasına veya doğrudan anlamasına gerek kalmadan karmaşık kodu hızla üretiyor
- Ancak bu süreçte kodun niyeti, kısıtları ve çalışma mantığı net biçimde kavranamadığı için 'anlama borcu' birikiyor
Anlama borcu (Comprehension Debt) nedir
- Anlama borcu, ekip üyelerinin kodun kalitesini, yapısını ve niyetini yeterince anlayamadığı durumu ifade ediyor
- Kısa vadede geliştirme hızını artırabilir, ancak uzun vadede bakım maliyetlerinin artması, bug oluşması ve özellik genişletmenin kısıtlanması gibi çeşitli yan etkilere yol açma riski taşıyor
LLM üretimi kodun ek riskleri
- LLM’lerin ürettiği kod, açık yorumlar veya bağlam sunmadan yalnızca sonucu hızlıca ortaya koyuyor
- Ekip üyeleri arasında bilgi paylaşımının yetersiz kalması ve mevcut sistemlerle uyumluluk eksikliği gibi sorunların ortaya çıkma olasılığı yüksek
- LLM koduna sürekli bağımlı kalınması, tüm projede kod güvenilirliğinin düşmesine yol açabilir
Teknik borçla karşılaştırma
- Geleneksel teknik borç, geliştiricilerin bilinçli tavizler vermesi sonucu ortaya çıkarken, LLM tabanlı anlama borcu fark edilmeden birikebilir ve bu yüzden daha tehlikelidir
- Sorunu fark etmek zordur; nedenini izlemek ve çözmek daha karmaşık hale gelir
- Sorun çözme sırasında “Doom Loop” (LLM’yi tekrar tekrar çalıştırsa da başarısız olunan kısır döngü) deneyimi yaygındır
Sonuç ve çıkarımlar
- Sonuçta kodu doğrudan okuyup düzeltmek yine insanlara kalıyor
- LLM kullanılırken kodun bağlamı ve niyetinin tüm ekip tarafından anlaşılmasını sağlayacak dokümantasyon ve paylaşım çabası önemlidir
- Kod incelemesinin güçlendirilmesi, yorumların ve dokümantasyonun artırılması, bilgi paylaşım oturumları gibi organizasyonel mekanizmalara ihtiyaç var
- Anlama borcu yönetilmeden, otomasyon araçlarının avantajları uzun vadeli bir riske dönüşebilir
- Sektör genelinde herkesin hızla büyüyen bir anlama borcu dağı üzerinde oturduğu bir durum oluşmuş durumda
8 yorum
Ben de yapay zekanın hiçbir zaman tamamen karar veremeyeceğini düşündüğüm için, tüm kodlarda kararı ben veriyor ve işlerin düzgün gidip gitmediğini de bizzat kontrol ediyorum.
Bana göre sadece 10 satırın altında kısa snippet’ler yazdırmak için uygun (ör. JSON parsing, sorting implementasyonu). Sadece bu şekilde kullansam bile zamandan inanılmaz tasarruf sağlıyor gibi geliyor.
AI yardımıyla iskeleti kurmak tamam da, sonuna kadar detayları canlı tutmak gerçekten çok zor gibi.
Ben de kişisel olarak 0'dan 90'a kadar olan kısmı LLM ile yazdığımda ortaya çıkan yan etkileri sık sık hissettiğim için, bu aralar mümkün olduğunca 0'dan 90'a kadar olan kısmı kendim yapıp esas olarak 90'dan 100'e giden süreçte kullanıyorum ve bundan memnunum.
Hacker News görüşü
LLM'lere bağımlılık arttıkça, zaten var olan sorunların daha da kötüleştiğini deneyimledim
Naur'un "teori kurma" kavramını tanıtarak, bir program geliştirme ekibi dağıldığında o programın fiilen ölü hale geldiğine işaret ediyor
Lamport'un 'programlama ≠ kod yazma' argümanına değinerek, programlamanın özünün 'neyi, nasıl' başaracağına dair teori inşası olduğunu vurguluyor
Gerekli model veya teoriyi kurmayan programcıların, LLM'in kendilerine çok hızlı yardım ettiğini hissetme eğiliminin daha güçlü olduğunu düşünüyorum
Gerçekte bilgisayar ve teknolojiden tamamen uzak kaldığım zamanlarda yazılım projelerinde daha büyük değer üretebildiğimi deneyimledim
Tam olarak ne istediğini bildiğinde geliştirme hızı sıçrama yapıyor ve o noktada LLM çok faydalı hale geliyor
Net bir hedef varsa, LLM'in halüsinasyonlarını da anında ayırt edebiliyorsun
Boş bir tuvale bakıp rastgele başlama yaklaşımının etkili olduğunu düşünmüyorum
LLM başlangıca yardımcı olabilir ama yanlış giderse seni tamamen alakasız bir yöne de sürükleyebiliyor
En zor problemleri bazen mutfakta yemek yaparken düşünürken çözdüğüm oldu
AI ile kodlamada iş arkadaşlarıma göre biraz daha başarılı olmamın nedenlerinden biri, LLM gelmeden önce de bir şeyi hızla prototipe dönüştürüp sonra yapıyı tamamen yeniden düzenleme veya çöpe atma döngüsünü tekrar tekrar kullanıyor olmamdı
Bu yaklaşım (hızlı prototipleme, sürekli refactoring vb.) epey biliniyor ama birçok mühendis ya en baştan kusursuz tasarlamaya çalışıyor ya da prototipi iyileştirmeden sürekli yamalamaya devam etme eğiliminde
AI ile birlikte çeşitli paralel implementasyonları ucuza üretmek mümkün olduğu için, farklı versiyonları deneyip karşılaştırarak sonuçta daha güçlü bir program teorisini veya tasarımı daha hızlı ve etkili biçimde oluşturabiliyorsun
AI bu döngüyü kısaltıyor ve yalnızca ortaya çıkan işi incelemeye daha çok odaklanabildiğin için geliştirme süreci çok daha verimli hale geliyor
"Teori kurma" kavramının, LLM kodunun bıraktığı "anlama borcu" ile bağının kurulması etkileyiciydi
Bunun yalnızca programlamayla değil, insan düşüncesi ve anlama süreciyle de derinden ilişkili olduğunu düşünüyorum
LLM'in ürettiği kod, metin veya görseller yalnızca yüzeydeki sonuçlar; bunların arkasındaki teoriyi bizzat kurup deneyimlemezsen, elinde ancak yüzeysel bir kavrayış kalıyor
LLM bir gün teori kurmanın kendisini de yapabilir hale gelse bile, insanın sürece doğrudan dahil olmadığı yapay bir anlayışın anlam bakımından yetersiz kalacağını hissediyorum
Makinenin bizim yerimize düşünmesi ne kadar kolaylaşırsa, insanın <anlama> yeteneğinin de o kadar yavaş yavaş köreleceğinden endişe ediyorum
Lamport'un argümanına katılıyorum ama aynı zamanda AI'ın "teori kurma" sürecinde—yani codebase, algoritmalar ve bütünsel sistem anlayışında—mevcut takıma da, projeyi devralan takıma da belli ölçüde yardımcı olabileceğini düşünüyorum
Tüm bilgiyi tamamen ikame etmesi zor olsa da, AI'ın en azından bazı boşlukları doldurabileceğini umuyorum
Eski geliştiricilerin tamamı ayrıldıktan sonra yeni bir ekibin projeyi devraldığı bir deneyim yaşadım; önceki ekibin tüm bilgisi buharlaşmıştı ve çok zorlandık
Asıl tasarımı anlamaya çalışırken bir sürü bug ürettik ve sonunda kodun büyük kısmını yeniden yazıp genişletmek zorunda kaldık
Ama bütün bu zorlukların içinde, birçok tasarım sorununu doğrudan yeniden yaşayarak öğrenmiş de olduk
LLM'ler sık sık çalışan çözümler üretiyor ama çoğu zaman gerekenin çok ötesinde karmaşık kod çıkarıyor
İlk yazıldığı anda sorunun ne olduğunu en iyi sen bildiğin için bu karmaşıklığı kolayca temizleyebilirsin; ama sonradan o karmaşık kod sanki gerçekten gerekliymiş gibi algılanıyor ve ciddi biçimde sadeleştirmek çok daha zorlaşıyor
Kodun bakımını yapan kişi bağlam veya arka plan bilgisinden yoksun olduğundan, aslında daha basit bir alternatifin mümkün olduğunu çoğu zaman fark etmiyor
İlk olarak, prompt'u net vererek LLM'i gereksiz yere karmaşık çıktı üretmeye yöneltmemek gerekir
İkinci olarak, problemi her zaman mümkün olduğunca basit çözmesini sağlayacak kural, eğitim veya bağlamı vermek gerekir
Son olarak, ortaya çıkan karmaşık çözüm için ek prompt'larla karmaşıklığı azaltmasını isteyebilirsin
LLM'in muazzam miktarda debug etmesi zor kod üretmesi gerçekten var olan bir sorun
"Kaliteyi önemseyen ekipler yeterince review yapmalı ve anlamalı" ilkesi var ama kod üretim hızı o kadar yüksek ki review yetişemiyor, darboğaz oluşuyor ya da süreç biçimsel onaya dönüşüyor
Çevremde insanlar review süreçlerini sürekli artırıyor ama bu yaklaşım ancak junior geliştiricilerde işe yarıyor; AI öğrenmediği için aynı problemler tekrarlanıyor
LLM çok fazla bağlama ihtiyaç duyuyor ama çoğu kişi ona neredeyse hiç bilgi vermeden sadece "şu sorunu çözen bir fonksiyon yaz" diye kullanıyor
Sonuçta herkesin anlamadığı bir kod yığını yani tech debt biriktiriyoruz
Temelde ihtiyaç duyulan şey, LLM'e bunu neden, hangi arka planla, hangi niyetle ve hangi önceki örnekleri yansıtarak üretmesi gerektiğini daha etkili biçimde aktarabilecek bir "primitive"
Kod review darboğaz oluyorsa bile, yine de hem kodlama hem review'un aynı anda darboğaz olmasındansa yalnızca review'un darboğaz olması daha iyi
Bu süreci destekleyecek araçlar (lint, fuzzing, test vb.) zaten mevcut
Tüm projeyi mimari açıdan ele alma ya da kodu hızlı okuyup analiz etme becerisi zayıf olanlar için LLM çağı zor olabilir ama bunlar geliştirilebilir yetenekler ve zamanla herkes uyum sağlayacaktır
Bu alanı sevdiğim için yeni meydan okumalara olumlu bakıyorum
Ajanların uyması gereken kodlama kuralları, kesinlikle kaçınılması gereken tuzaklar ve kodlama standartları belgelerine bağlantılar içeren çeşitli instruction .md dosyaları hazırlayıp güncel tutma deneyimim oldu
Gemini ve Claude gibi modeller bu tür belge tabanlı talimatları belli ölçüde iyi takip ediyor ama bazen tekrarlayan hatalar da yapıyorlar (ör. C++'ta
autokullanma denmesine rağmen yine kullanmaları gibi)Modeller geliştikçe bu geri bildirim işleme tarafının da daha iyi hale geleceğini umuyorum
Sonuç olarak "vibe coding"den çıkıp kod yapısı ve birimler arası etkileşimle insanın ilgilendiği, AI'ın ise sözdizimi ve yazma işine odaklandığı modelin hem verimliliği artıran hem de geliştiricinin genel yönü elinde tuttuğu ideal uzlaşma olduğunu hissettim
Prompt ve bağlam kurma biçimimi değiştirdikten sonra LLM kullanımıyla ilgili sezgilerim belirgin biçimde gelişti
Artık prompt ve bağlam üzerinden çıktının olasılık uzayını daraltma bakış açısıyla yaklaşıyorum
Bu süreç, kodun teorisini yeniden kullanılabilir şekilde enjekte etmek için de çok etkili
Yine de bu bağlam hazırlığı ciddi emek ve düşünce istiyor; hangi noktada doğrudan kendin implement etmenin, hangi noktada LLM'e devretmenin daha iyi olduğunu ayıran çizgiyi bulmak hâlâ kolay değil
"Primitive farklı" tespitine katılıyorum ve gerçekten önemli birimin "test" olduğunu düşünüyorum
Modele kod yazdırırken testleri de birlikte yazdırıyor, testlerin okunmasının kolay olup olmadığını da her zaman kontrol ediyorum
Yalnızca tüm testler geçtiğinde kod merge edilmeli
Test altyapısını sürekli geliştirerek tüm testlerin aşırı yavaşlamasını önlemek gerekir
Eski usul legacy kodun tipik özelliği testsiz olmasıydı; aynı durum LLM çağında da geçerli
"Darboğaz oluyor" eleştirisine karşılık, StackOverflow'dan kod yapıştırırken bile her zaman okuyup inceledikten sonra kullanıyoruz; yani zaten darboğaz insan
Sonuçta bu süreçten geçmeden kodu kullanmak zaten fiilen mümkün değil
Yakın zamanda Dwarkesh Patel podcast'inde konuklardan biri <A Deepness In The Sky> romanını önerdi; okuyunca binlerce yıl sonraki bilgisayar sistemleri ve geçmişten kalan legacy bilginin büyük rol oynaması çok etkileyici geldi
Legacy kodun ve örgütsel bilginin değerini eğlenceli biçimde işleyen çok iyi bir roman, tavsiye ederim
Podcast: https://www.youtube.com/watch?v=3BBNG0TlVwM
Kitap bilgisi: https://amzn.to/42Fki8n
Vernor Vinge'in vefat etmiş olması üzücü; fikirlerinin zaman geçtikçe daha da gerçek ve ilham verici hale geldiğini hissediyorum
Çok uzak bir gelecekte programcı olma sürecini anlatan kısım gerçekten çok ilginçti
Yeni kod yazmaktan çok, aşırı sayıdaki kütüphane ve paket arasından mevcut modülleri bulup birleştirmek asıl beceri haline gelmişti
Mevcut kodun ayrıntılı nüanslarını ve yorumunu kavramak gerçek ustalık olarak tasvir ediliyordu
"A Deepness In The Sky" serinin ikinci kitabı gibi görünüyor; ilk kitabı okumadan önce bunu okumakta sakınca var mı diye merak ediyorum
Doğrudan bununla başlanıp başlanamayacağını soruyor
Çoğu geliştirici assembly ya da makine dili seviyesine kadar anlayış sahibi değil
Yüksek seviyeli diller insanlar arası iletişim ve işbirliğinin temel katmanı haline geldi
LLM'in gelişiyle bu katman doğal dil ve spesifikasyon temelli geliştirmeye doğru itiliyor
Yine de yüksek seviyeli dillerin onlarca yıllık evrimin sonunda program davranışını anlatmak için neredeyse en uygun biçimi sunduğunu düşünüyorum
Doğal dille daha fazla soyutlama denendiğinde bilgi kaybı yaşanıyor; daha düşük seviyeli dillere inildiğinde ise anlatım aşırı uzuyor
Doğal dile sıçrayış sadece soyutlama katmanının değişmesi değil, özünde tamamen yeni bir yöntem
Önceki araçlar (assembler, compiler, framework vb.) sabit mantığa dayalıydı ve matematiksel doğrulama mümkündü; ama LLM sonrası dünya belirsizlik, tahmin ve hatta halüsinasyonların karıştığı bir alana atlamak demek
Birçok JavaScript geliştiricisi yüksek seviyeli kavramları bile (uygun veri yapıları, DOM, Node API vb.) derinlemesine anlamıyor
Soyutlama katmanlarına aşırı bağımlılık gelişiyor ve iç işleyişin nasıl çalıştığına dair zayıf bir anlayış oluşuyor
Dışarıdan bakan biri doğal olarak "Burada gerçekte ne oluyor?" diye soruyor
Bu durum zaten günlük hayatın normal bir parçası haline gelmiş durumda
Sonunda kimsenin kodun içini tam olarak bilmediği bir dünyada, LLM'in kod yazmasının özünde çok da farklı olmadığını mecazi biçimde anlatıyor
Doğal dil spesifikasyonlarının bir rolü olduğu doğru ama mutlaka katı semantiğe sahip bir ara katman teknolojisine ihtiyaç olduğunu düşünüyorum
Örneğin Rust + LLM kombinasyonunda, güçlü tip sistemi geçersiz durumları dışarı itiyor ve derleme uzun sürse bile sonuç çoğu zaman istenene yakın oluyor
Rust topluluğunda "compile ediyorsa büyük ölçüde çalışır" diye bir kültür var; mantıksal bug'lar yine olabilir ama pratikte hata uzayı daralıyor
İdeal olarak, mantıksal anlamı sıkı biçimde tanımlayan katı programlama dilleri ile precondition, postcondition gibi spesifikasyonlar üst üste inşa edilir ve LLM doğal dili formal spesifikasyona çeviren rolü üstlenir
Doğal dil doğası gereği açık seçik değil, belirsizlik içeren bir dil
Programlama dillerinde parsing belirsizliği ciddi bug sayılırken, doğal dilde belirsizlik şiir, nüans ve ima gibi iletişim işlevlerinin parçasıdır
Yüksek seviyeli dillerin deterministik (
import) niteliği tek fark değilProgramlamada determinizm her şey değildir; insan açısından anlamı açık olmayan kod da gayet deterministik olabilir
Yani 'yüksek/düşük seviye soyutlama' ile 'deterministik/olasılıksal' eksenleri tamamen farklı meseleler
Bana ve ekibimize doğru gelen büyük bir iş dalgası gibi görünüyor
Neredeyse 8 yıldır legacy kod kurtararak işi sürdürüyorduk ama son dönemde şirketler kodlama için LLM'lere yaslandığı için talep azaldı
Ancak önümüzdeki yaklaşık 18 ayı atlatabilirsek, kısa sürede birikmiş LLM kaynaklı teknik borcu temizleme taleplerinin sel gibi geleceğini ve bunun devasa bir fırsat yaratacağını öngörüyorum
Claude'un "artık kod production level" diyerek biriktirdiği borcun hasarı yakında görünür hale gelecek
Bir tanıdığımın LLM'in yazdığı bir PR'ı incelerken yaşadığı olayı dinledim
Yüzeyde işlev kusursuz görünüyordu ama içine bakınca backend'i güncellemek yerine sadece cache'i manipüle eden bir numara olduğu ortaya çıktı
Bu kodun merge edilmemesi gerektiğine yöneticiyi ikna etmek için epey uğraşmak zorunda kaldı
Sonuçta dünyada dışarıdan çalışıyor gibi görünen böyle çok sayıda "vibe coded" yazılım olduğundan şüpheleniyorum
Böyle durumlarda bence doğrudan merge edilip sonrasında patlamasını yaşasınlar demek daha iyi olabilir
Yanlış kararların sonuçlarını bizzat yaşamak çoğu zaman asıl farkındalığı sağlar
Geri bildirim olmazsa öğrenme de olmaz; üstelik böyle yöneticiler gerçeklikten kopuk beklenti ve baskıyı artırıp ekipte tükenme ve devir döngüsünü besleyebilir
Teknik olmayan bir engineering manager'ın sektörde bu kadar uzun süre nasıl kalabildiğini merak ediyorum
Son 15 yılda gerçekten teknik olmayan yönetici neredeyse hiç görmedim
Böyle bir yönetici sorun çıkarıyorsa CTO, CEO, sahipler veya yatırımcılara kadar rapor edilmesi gerektiğini düşünüyorum
Sadece LLM kodu değil, başkasının yazdığı her kod belli bir "anlama borcu" yaratır
Google gibi büyük şirketlerde bile yeni mühendislerin algoritmalarda büyük değişiklikleri hızlıca yapabilmesi için aylar süren bir anlama süreci gerekir
Ama insanlar tarafından iyi tasarlanmış kod, LLM çıktısına göre belirgin biçimde daha kolay anlaşılır
Doğrudan o kişiye soru sorabilirsin; LLM de kulağa makul gelen cevaplar verir ama gerçek bağlam farklıdır
Ben de epey "vibe coding" yaptım ama sonuçta kodun zihinsel modeli oluşmadığı için başta zamandan kazandırsa bile debug zamanı geldiğinde daha büyük zaman kaybına yol açıyor
En baştan her şeyi kusursuz biçimde tasarlamak zaten pratikte imkânsız
Ayrıca "onaylanmış satır sayısı"nı üretkenlik veya zaman tasarrufunun kanıtı sayan ölçütlere de güvenmiyorum
LLM'e dayalı kodu dikkatle inceleyip doğru şekle sokarak kullanmak ise gerçekten etkili
Bu süreç aslında daha çok "pair programming"e benziyor
LLM çıktısını hiçbir inceleme olmadan doğrudan kullanma biçiminin ("vibe coding") gerçekten verimli olması mümkün değil
Kernighan Yasası'na atıfla, "debug etmek kod yazmaktan iki kat zordur" deniyor
Bu yüzden kodu LLM yazıyorsa, onu debug etmek için iki kat daha akıllı bir LLM gerekebilir diye düşünüyorum
Benim deneyimim her zaman böyle olmadı; direksiyonda sürekli benim olmam gerekiyor
Ağırlıklı olarak Claude Code kullanıyorum ve hata yaptığında açıkça gösterip düzeltmesini ya da sorunlu bölgeye özellikle bakmasını söylemem gerekiyor
LLM kendi hatasının ne olduğunu bilmediği için, junior bir geliştiriciyle çalışıyor gibi hissediliyor
Yani debug aynı zeka seviyesinde de yapılabilir ama LLM'in sorunu, problemi kendiliğinden fark edememesi
"Debug için iki kat daha akıllı biri gerekir" sözüyle ilgili olarak, bunun LLM'lerin farklı "düşünme derinliği" modlarıyla bağlantılı olabileceğini düşünüyorum
Karmaşık bir fonksiyon söz konusuysa, önce kod yorumları yazarak LLM raporunda niyetini ve yaklaşımını açıkça anlatmasını sağlama yöntemini kullanıyorum
Yorumlarda, başka bir geliştiricinin yazdığını alıp kullanırken de inceleme gerektiği için bunun LLM durumundan farklı olmadığı yönünde bir yazı var; ben öyle düşünmüyorum. İnsan söz konusu olduğunda itibar, ün, ödül, ceza gibi mekanizmalar işler. Muhtemelen bugün LLM’ler gibi çalışsanız anında kovulurdunuz.
Ben her zaman "AI sizin yerinize sorumluluk almaz." diye düşünüyorum.
Kod yazarken AI kullanımının yasaklandığı günün çok da uzak olmadığını düşünüyorum. Kulağa saçma gelebilir ama bunun gerçeğe dönüşeceğine inanıyorum.