1 puan yazan GN⁺ 2 시간 전 | 1 yorum | WhatsApp'ta paylaş
  • k10s, Claude ile yapılan vibe-coding sayesinde hızla geliştirilen, GPU farkındalığına sahip bir Kubernetes TUI'siydi; ancak fleet view eklendikten sonra birçok ekran durumu bozuldu
  • model.go, 1690 satırlık tek bir Model ve 500 satırlık Update() ile büyüdü; UI, istemci, önbellek, gezinme ve view durumlarının tamamını üstlenir hale geldi
  • Yapay zeka özellikleri hızlıca ekledi ama god object ve global key handler yapısını da büyüttü; her yeni view ile mevcut handler'a yeni branch'ler eklenen bir yapıya dönüştü
  • Konuma dayalı []string verisi ve arka plandaki tea.Cmd içinde doğrudan mutation yapılması, column hataları ve açık veri yarışları üretebiliyordu
  • Yeni k10s, Rust ile baştan yazılırken ilk prompt'tan önce interface, message type, ownership rule ve scope'un CLAUDE.md içinde sabitlenmesine karar verildi

k10s'i yeniden yazma kararı neden alındı

  • k10s, GPU farkındalığına sahip bir Kubernetes panosu olarak başladı; NVIDIA küme operatörlerinin GPU kullanımını, DCGM metriklerini, boşta duran nodeları ve saatlik $32/hr maliyet gibi bilgileri doğrudan görebilmesi için yapılmış bir TUI aracıydı
  • Go ve Bubble Tea ile yazıldı; yaklaşık 7 ay, 234 commit ve yaklaşık 30 hafta sonu boyunca Claude ile yapılan vibe-coding oturumlarında geliştirildi
  • İlk aşamada pods, nodes, deployments, services, command palette, watch tabanlı canlı güncellemeler ve Vim keybindings gibi temel k9s benzeri işlevler yaklaşık 3 hafta sonu içinde çalışır hale geldi
  • Temel özellik olan GPU fleet view, her node'un GPU tahsisini, kullanımını, DCGM tabanlı metriklerini, sıcaklık, güç, bellek ve renge dayalı durum bilgilerini gösteren ekrandı; Claude tek seferde FleetView struct'ını, GPU/CPU/All sekme filtrelerini ve allocation bar render işlemini oluşturdu
  • Ancak fleet view eklendikten sonra :rs pods ile pods view'a dönüldüğünde tablo boşalıyordu, canlı güncellemeler duruyordu, nodes view içinde fleet view filtresinden kalmış eski veri görünüyordu ve fleet sekme sayıları da yanlış çıkıyordu
  • Sorun izlenirken Claude'un oluşturduğu model.go dosyasının tamamı, yani 1690 satır, ilk kez okundu; tek bir Model struct'ı UI widget'larını, Kubernetes client'ını, logs/describe/fleet durumunu, navigation history'yi, cache'i ve mouse handling'i birlikte taşıyordu
  • Update() metodu yaklaşık 500 satırlık bir msg.(type) dispatch fonksiyonuydu ve içinde 110 adet switch/case branch vardı
  • Yapay zeka özellikleri hızlı geliştirebilir ama sınırsız şekilde yön verirseniz mimari dağılır; hız hissi de her şey aynı anda çökene kadar başarı gibi görünür

Enkazdan çıkan beş ilke

  • İlke 1: Yapay zeka özellik üretir ama mimari üretmez

    • Claude fleet view, log streaming ve mouse desteği gibi tekil özellikleri iyi oluşturdu; ancak her özellik “şu an çalışsın” bağlamında yazıldığı için aynı durumu paylaşan diğer özelliklerle ilişkisini hesaba katmadı
    • resourcesLoadedMsg handler'ında msg.gvr.Resource == k8s.ResourceNodes && m.fleetView != nil gibi koşullar vardı ve generic resource loading yolunun içine fleet view'a özel mantık karışıyordu
    • Her yeni view özel davranış gerektirdiğinde aynı handler'a bir branch daha ekleniyor, önceki view'ın verisinin yeni view'a sızmaması için çeşitli alanların elde temizlenmesi gerekiyordu
    • model.go içinde m.logLines = nil, m.allResources = nil, m.resources = nil gibi elde yapılan cleanup işlemleri 9 farklı yere dağılmıştı; biri unutulursa önceki view'dan kalan hayalet veri görünüyordu
    • Alternatif, kod yazmadan önce somut interface'leri, message type'ları ve ownership rule'ları bizzat yazıp bunları CLAUDE.md içine mimari invariant olarak koymak
    • Örnek kurallar: her view bir View trait/interface'ini uygulamalı, hiçbir view başka bir view'ın state'ine erişmemeli, async veri yalnızca AppMsg varyantlarıyla gelmeli ve App struct'ı sadece navigation ile message dispatch'ten sorumlu olmalı
  • İlke 2: god object, yapay zekanın varsayılan çıktısıdır

    • Yapay zeka, anlık prompt'u en az ek yapı ile karşılamak için her şeyi taşıyan tek bir struct yapısına yöneldi
    • Key handling de view bazında ayrılmamıştı; s tuşu logs view'da autoscroll, pods view'da shell, containers view'da ise container shell olarak çalışıyordu
    • “pods'a shell support ekle” isteği, mevcut global key handler çevresine yeni bir branch sıkıştırılarak uygulandı
    • Enter tuşu da contexts view, namespaces view, logs view ve generic drill-down mantığını tek bir düz dispatch içinde m.currentGVR.Resource string karşılaştırmalarıyla ayırıyordu
    • model.go içinde m.currentGVR.Resource == ifadesi tür ayırıcı gibi 20'den fazla kez kullanılmıştı ve yeni bir view eklemek için birçok handler'a dokunmak gerekiyordu
    • Alternatif, App/Model içine view'a özgü state alanları eklememek, her view'ı ayrı bir struct yapmak ve key binding'leri aktif view'ın keymap'inde tutma kuralını CLAUDE.md içine koymak
    • “View eklemek dosya eklemek olmalı; mevcut bir view'ı değiştirmek gerekiyorsa dur ve sor” gibi guardrail'ler olmadığında yapay zeka en kısa yol olarak yeni branch eklemeye yöneliyor
  • İlke 3: Hız hissinin yarattığı illüzyon scope'u büyütür

    • k10s başlangıçta GPU training cluster işleten dar bir kitle için tasarlanmıştı; ancak vibe-coding, pods, deployments, services, command palette, mouse support, contexts ve namespaces gibi özelliklerin “bedava” gibi hissedilmesine yol açtı
    • Sonuçta araç, GPU odaklı bir araç olmaktan çıkıp tüm Kubernetes kullanıcılarına hitap eden genel amaçlı bir TUI'ye, yani fiilen k9s'i yeniden yapma yönüne kaydı
    • Düz bir keyMap içinde Fullscreen, Autoscroll, ToggleTime, WrapText, CopyLogs, ToggleLineNums, Describe, YamlView, Edit, Shell, FilterLogs, FleetTabNext, FleetTabPrev gibi farklı view'lara özgü binding'ler tek yapıda karışmış durumdaydı
    • Autoscroll ve Shell ikisi de s tuşuna bağlıydı; dispatch geçerli resource'a bakarak “çalışmasını” sağlıyordu ama keybinding'leri yerel bağlamda anlamayı imkânsız hale getiriyordu
    • Kod yazma hızı “shipping” gibi görünse de her özellik, god object içine bir branch daha ekleme maliyeti yaratıyordu
    • Alternatif, CLAUDE.md içinde scope sınırını açıkça belirtmek: k10s, GPU cluster operatörleri için olmalı; desteklenen view'lar fleet, node-detail, gpu-detail ve workload ile sınırlanmalı; generic resource view'lar veya k9s'in tekrar eden işlevleri eklenmemeli
    • Yapay zeka sınırsız satır bütçesi sağlayabilir ama karmaşıklık bütçesi hâlâ sınırlıdır; bu yüzden scope baştan reddedilmelidir
  • İlke 4: Konuma dayalı veri bir saatli bombadır

    • k10s, Kubernetes API'den aldığı resource'ları doğrudan type OrderedResourceFields []string biçiminde düzleştiriyordu
    • Fleet view'ın sıralama fonksiyonu ra[3] değerini Alloc, ra[2] değerini Compute, ra[0] değerini ise Name olarak ele alıyordu; column kimliği yalnızca yorumlara ve resource.views.json içindeki column sırasına dayanıyordu
    • resource.views.json içinde Instance ile Compute arasına bir column eklendiğinde ra[2], ra[3] kullanan sıralama, koşullu render ve drill target mantığı sessizce bozulabiliyordu
    • Derleyici []string içindeki anlamı bilemez; JSON config de sıralama davranışını, koşullu render'ı ve özel drill target'ları ifade edemediği için Go kodu konuma dayalı varsayımları hardcode ediyordu
    • Yapay zeka, table widget'a doğrudan verilmesi kolay olduğu için []string veya Vec<String> seçmeye yatkındır; typed struct ise başlangıçta daha fazla ek yapı gerektirdiğinden hızlı yolda geri plana itilir
    • Alternatif, yapılandırılmış veriyi render anına kadar FleetNode, PodInfo gibi typed struct olarak korumak ve sıralamayı row[3] gibi konumsal erişim yerine adlandırılmış alanlar üzerinden yapmak
    • Örnek yapı FleetNode { name, instance_type, compute_class, alloc } gibi olabilir; böylece column kimliği tür sistemiyle ifade edilir ve yanlış column'a göre sıralama gibi imkânsız durumlar baştan engellenir
    • “Making impossible states impossible”, Elm/Rust topluluğunda kullanılan ve runtime check yerine geçersiz durumların hiç kurulamamasını sağlayacak şekilde type tasarlamayı anlatan bir ifadedir
  • İlke 5: Yapay zeka state transition'ın sahibi değildir

    • Bubble Tea mimarisinin özü, state değişiminin yalnızca message ile çalışan Update() içinde yapılmasıdır; ancak k10s bunu ihlal etti
    • updateTableMsg handler'ı bir tea.Cmd closure'ı döndürüyordu ve bu closure içinde m.updateColumns(m.viewWidth), m.updateTableData(), m.table.SetCursor(savedCursor) gibi çağrılarla Model alanları değiştiriliyordu
    • Bubble Tea, tea.Cmd işlemlerini ayrı bir goroutine'de çalıştırdığı için closure m.resources, m.table, m.viewWidth alanlarını okuyup yazarken ana goroutine içindeki View() aynı alanları okuyabiliyordu
    • Ortada lock ya da mutex yoktu; <-m.updateTableChan sadece update sinyalini bekliyor, View() fonksiyonunun yarım yazılmış state'i okumasını engellemiyordu
    • Bu yapı açık bir data race idi ve çoğu zaman çalışsa da bazen ekranın bozulması gibi sonuçlar doğuruyordu
    • Alternatif, arka plan worker'larının UI state'ini doğrudan mutate etmemesi, bunun yerine typed message'ları channel üzerinden göndermesi ve ana event loop'un bu message'ları alıp state mutation'ı uygulaması
    • Concurrency kuralı şu olmalı: arka plan görevleri UI state'ini doğrudan değiştirmez, sonuçları typed message olarak gönderir ve render()/view() side effect, I/O ya da channel işlemi içermeyen saf bir fonksiyon olmalıdır

CLAUDE.md ve agents.md içine konacak koruyucu kurallar

  • Mimari değişmezler

    • Her view bir View trait/interface'ini uygulamalı ve başka view'ların state'ine erişmemeli
    • Tüm async veri AppMsg varyantlarıyla gelmeli; arka plan görevi alanları doğrudan mutate etmemeli
    • Yeni bir view eklemek mevcut view'ların değiştirilmesini gerektirmemeli
    • App struct'ı navigation ve message dispatch yapan ince bir router olmalı
  • State sahipliği kuralları

    • View'a özgü state, App/Model struct'ına alan olarak eklenmemeli
    • Her view ayrı bir struct olarak var olmalı ve kendi key binding'lerini tanımlamalı
    • Uygulama key'leri aktif view'a dispatch etmeli; yeni keybinding global handler'a değil ilgili view'ın keymap'ine eklenmeli
    • Bir view eklemek mevcut view'ların değiştirilmesini gerektiriyorsa durulup onay alınmalı
  • Kapsam

    • k10s tüm Kubernetes kullanıcıları için değil, GPU cluster operatörleri için bir araç olmalı
    • Desteklenen view'lar fleet, node-detail, gpu-detail ve workload ile sınırlı olmalı
    • Pods, deployments, services gibi generic resource view'lar eklenmemeli
    • k9s işlevlerini kopyalayan özellikler eklenmemeli
    • GPU training işleri işleten operatörlere fayda sağlamayan özellik istekleri reddedilmeli
  • Veri temsili

    • Yapılandırılmış veri []string, Vec<String> veya konuma dayalı array'lere düzleştirilmemeli
    • Veri, render çağrısına kadar typed struct olarak akmalı
    • Column kimliği array index'inden değil, struct alan adından gelmeli
    • Sıralama fonksiyonları row[3] gibi konumsal erişim yerine typed field'lar üzerinde çalışmalı
    • Görüntüleme için string üretimi yalnızca render()/view() fonksiyonu içinde yapılmalı
  • Eşzamanlılık kuralları

    • Watcher, scraper, API call gibi arka plan görevleri UI state'ini doğrudan mutate etmemeli
    • Arka plan görevleri sonuçları typed message olarak channel'a göndermeli
    • State mutation'ı yalnızca ana event loop alınan message'lar üzerinden uygulamalı
    • render()/view() side effect, I/O veya channel işlemi içermeyen saf bir fonksiyon olmalı
    • Async iş sonucunda state değişecekse yeni bir AppMsg varyantı tanımlanmalı

Yeniden yapım yaklaşımı

  • k10s bundan sonra Rust ile yeniden yazılacak; bunun nedeni Rust'ın mutlak anlamda daha iyi olması değil, yazarın onu doğrudan yönlendirebildiğini hissetmesi
  • Yeterince iyi bilinen bir dilde, neyin yanlış gittiği bazen daha söze dökülmeden sezilebilir ve vibe-coding bu sezgiyi ikame edemez
  • Yapay zeka ikna edici görünen kod ürettiğinde, onun gerçekten çöp olup olmadığını anlayabilme becerisi gerekir
  • Yeni sürümde kod yazılmadan önce concrete interface'ler, message type'lar ve ownership rule'lar gibi tasarım çalışmaları önce insan tarafından elle yapılacak
  • Önceden yapay zekanın yanlış verdiği architecture decision'lar, artık ilk prompt'tan önce belgede net biçimde tanımlanacak
  • Mevcut TUI ve proje bağlantıları k10s Github ve K10S.DEV adreslerinde bulunuyor

Ek not

  • Bubble Tea, The Elm Architecture tabanlı bir Go TUI framework'üdür; k10s'in mimari sorunları Bubble Tea'den değil, k10s tarafındaki implementasyondan kaynaklanıyordu
  • “Making impossible states impossible”, geçersiz state'leri runtime'da kontrol etmek yerine type tasarımıyla bunların hiç kurulamamasını hedefleyen Elm/Rust topluluğuna ait bir ifadedir
  • Yapay zeka yazımındaki “em-dash” gibi, yapay zeka ile kodlamada da “god-object” bir koku olarak kalabilir; vibe-coding uygulamayı ucuz hissettirdiği için odak kaybı ve şişkinliğe yol açabilir

1 yorum

 
GN⁺ 2 시간 전
Hacker News yorumları
  • Üretilen kodun iyi olduğunu söyleyenler genelde o kodu okumayan kişilerdi
    Yazıda önerilen hafifletme yöntemleri de uzun süre dayanmaz. Sistem ya da bileşen tasarlarken “bir view başka bir view’un durumuna erişmez” gibi değişmezler ortaya çıkar; ama er ya da geç bu koşullarla çakışan bir özellik eklemek gerekir
    O noktada genelde ya özellikten vazgeçilir, ya değişmezin üstüne garip ve verimsiz bir şey eklenir, ya da değişmezin kendisi değiştirilir. Bu seçim basit bir bağlam meselesi değil, bir muhakeme meselesidir ve mevcut modeller bu muhakemede çok sık hata yapıyor
    Mimari kısıtları açıkça yazsanız bile ajan, o kısıtların değişmesi gereken yerde bile onlara zorla uyan karmaşık ve bakımı imkânsız kod üretir. İnsan yazımı koda kıyasla daha da dikkatli okumazsanız, sonunda “kendi kendini yiyen kod” ortaya çıkar ve bunu ancak çok geç fark edersiniz

    • İyi kod yazmayı biliyorsanız, çeşitli tekniklerle AI’ın iyi kod yazmasını sağlayabilirsiniz; bu gayet mümkün
      Önemli olan, AI’ın zorlandığı noktaları tespit edip işi onun için kolaylaştırmak. Örneğin aşırı küçük bağlam, net sınırları olan modüler yapı, girdi/çıktıdan ayrılmış saf modüller, arayüzlerin arkasına gizleme, 1 saniyenin altında çalışan 100 test, benchmark’lar gibi şeyler gerekir
      AI sınırlar ve küçük bağlam olduğunda iyi çalışır. Bunları vermezseniz performansı düşer ve bunun sorumluluğu aracı kullanan kişidedir
    • “Er ya da geç değişmezlerle çakışan bir özellik eklenir” noktası, bence spesifikasyon güdümlü geliştirmenin büyük sorunu
      Hiçbir spesifikasyon gerçek dünyaya uzun süre dayanmaz; yeterince araştırma ve tasarım yapılsa bile, içindeki bazı değişmezlerin sonunda yanlış olduğu ortaya çıkar
      Bir insan geliştirme sırasında bu durumla karşılaşınca geri çekilip değişmezin yanlış olup olmadığını, değişirse etkisinin ne olacağını yeniden düşünebilir. Buna karşılık AI, yanlış varsayım ya da tasarım altında bir şekilde hack’lenmiş çözüm üretmeye daha yatkın ve bütünü yeniden değerlendirecek içgörüden yoksun
      Daha iyi iş akışları ve doğrulamayla bu durum iyileşebilir, ama Claude Code gibi araçların varsayılan olarak iyi yönettiği bir alan değil; sınırları var
    • Şirkette yeni bir iç framework yaparken ve mevcut framework kullanım noktalarını taşırken benzer bir şey yaşadım
      Başta güçlü ilkeler koyduk ve birkaç kullanım noktasını elde taşıyarak güven kazandık. Tüm geçiş neredeyse 10 yıl ertelenecek kadar büyük ve pahalıydı; bu yüzden maliyeti düşürmek için AI ile hızlandırmak istedik
      AI mekanik ve basit olan %80’lik kısımda fena değildi. Kalan %20 framework değişikliği gerektiriyordu; çoğu API alanı ekleme gibi küçük değişikliklerdi ama bir iki tanesi kavramsal yeniden tasarım istiyordu
      Bir sistemin backend’i vakaların %99’unda belli veriyi üretebiliyordu ama bazı önemli durumlarda bunu mantıksal olarak üretemediği için dışarıdan bildirilmesi gerekiyordu. Oysa önemli bir optimizasyon “bu imkânsızdır” varsayımı üstüne kurulmuştu
      AI aracı bunu fark etmedi ve sanki düzgün çalışacakmış gibi eski mantığı ekledi. Dağıtım biçimimiz sayesinde bu henüz bir production bug’ı olmadı ama partner ekibe doğru soruları sorarken aynı ihtiyacın başka yerlerde de olduğunu keşfettik
      Sonuçta bir insan derine inmiş olduğu için büyük bir soruna dönüşmedi. Doğrulama araçları ve daha akıllı modeller gelecekte bu tür geçişleri kolaylaştırabilir, ama bugün üretilen kod bazen güzel görünse de kırılgan; bu yüzden yakından izlemek gerekiyor
    • Sadece kod çıktısını okumak yetmiyor; en azından benim deneyimimde kodu bizzat yazmak da gerekiyor
      Yaklaşık iki aydır kullandığım tuhaf bir mimari desen vardı; her kullandığımda hafif bir rahatsızlık hissediyordum ama ancak dün gece bunun iyi bir soyutlama olmadığını ve daha iyi bölünebileceğini fark ettim
      Kodu LLM’e ürettirdiğimde bu rahatsızlığı çok daha az keskin hissediyorum; bu da sorunu fark etmeyi ve çözüm bulmayı geciktiriyor. Çevresel kısımlar üretilebilir ama çekirdek işlevlerin büyük kısmını hâlâ kendiniz yazmanız gerekiyor
    • Gayriresmî biçimde yazılmış değişmezler, arada insan reviewer olsa bile bozulup bozulmadığını kanıtlamayı zorlaştırır; doğal dil de bunun için yeterince hassas değildir
      Bunları hassas bir biçimsel dille ifade etseniz bile, ajanların altındaki LLM bu değişmezlerin neden gerekli olduğunu ve neden önemli olduğunu anlayacak kapasiteden yoksun. Token’larla biçimsel spesifikasyonları ilişkilendirip ispat bile yazan bir LLM çıkabilir, ama prompt’un gayriresmî kısımlarından üretilen tuhaf kodlar yine de gelmeye devam eder
      Kısıtları ve prompt’ları bir teknik gereklilik listesine ya da spesifikasyona eklemek tek başına bunu engelleyemez. Daha iyi tuzak kursanız da canlı kaçıp gider
      Sorun, prompt’u ya da görevi yerine getirmek için koda ekleme yapıldıkça oluşan kod şişmesi. Çoğu zaman daha az kod daha iyidir ve başkalarının ne isteyeceğini, ne bekleyeceğini öngörebilen birine ihtiyaç vardır. Üreticiler iyi ama yangın hortumu gibi; biraz daha kontrollü kullanılmaları gerekiyor
  • Copilot bir satırı otomatik tamamlarken “yine de tüm fonksiyonu sen yazmalısın” deniyordu; fonksiyon tamamlanınca “fonksiyonun etrafındaki mantığı sen yazmalısın” dendi; o mantık da tamamlanınca “özelliği sen yazmalısın” dendi
    Şimdi özellik de tamamlanınca “yine de mimariyi sen yazmalısın” deniyor. Bu modeller mimariyi çözebilir mi bilmiyorum ama beklenti çizgisinin sürekli kayması ilginç

    • O hayalî “insanlar” en baştan beri yanılıyordu
      AI bir satırı da tamamlasa, tüm fonksiyonu da, özelliği ve ticket’ı da tamamlasa, yine de kodu okuyup anlamanız gerekir
    • Modeller mimari de yapabilir ama şu an için genelde çok güçlü yönlendirme olmadıkça bunu çok kötü yapıyorlar
      AI’ı sürekli kullanıyorum ve giderek iyileşiyor ama hâlâ her satırı gözden geçiriyorum. Tek tek satır düzeyinde bile bugün, geçen yılın tab autocomplete’inden belirgin biçimde daha iyi olduğunu söylemek zor; bazen çok iyi, bazen gerçekten kötü
    • Çözümün yazının satır aralarında olduğunu düşünüyorum
      LLM’ler yazılım geliştirmede harika, ama mimariyi onların yazmasına izin vermediğinizde. Modülleri, struct’ları, enum’ları kendiniz oluşturun; mümkünse alanları ve varyantları da siz ekleyin
      Her struct, enum, alan ve modüle doc comment yazın; sonra LLM’e bu modülleri ve veri yapılarını gösterip gerekli fonksiyon gövdelerini doldurtun
    • Mevcut dillerde codebase küresel olarak karmaşık ve istenen değişmezleri görünür kılmıyor; bu yüzden ölçeklenebilirlik zayıf
      “Kritik yolda asla blocking yapma” diye kaç kere söyleseniz de LLM kritik yola blocking koyuyor; “X yapılırsa Y türü test gerekir” deseniz X’i yapıp testi atlıyor
      İnsanlar da talimatlara %100 uymaz ama LLM daha rastlantısal davranıyor. İnsan hataları, istenenin tam tersini bu kadar isabetli biçimde yapma eğiliminde değil
      LLM kod içindeki önemli değişmezleri görüp bunların etrafından dolanabilir, başarısızlığı başarı gibi gösteren testler yazabilir ve sonra da istendiği gibi yaptığını söyleyip bunu 5 bin satırlık commit’in içine gömebilir
      LLM’lerin harika olduğuna ve geleceği temsil ettiğine eminim; bu yüzden onlar için https://GitHub.com/Cuzzo/clear adlı bir dil geliştiriyorum. Amaç, küresel bağlam gerekmemesi gereken yerde küresel bağlam isteyen dillerin sorununu aşmak; böylece birlikte çalışmak kolaylaşır
      Başarılar da oldu ama bazen o kadar sinir bozucu oluyor ki, akıl sağlığımı buna harcamaya değdi mi diye düşündüğüm oluyor
    • Ben buna tek kullanımlık mimari diyorum
      Bu, mimarinin önemsiz olduğu anlamına gelmiyor; sadece dün iyi uyan mimarinin bugün de mutlaka iyi uyacağı anlamına gelmiyor
  • Kodlama ajanları kullanırken kendime birkaç kural koydum
    Birincisi, ajanla kod üreteceksem, yeterli zaman verilse bunu kendim de doğru biçimde yazabileceğimden mutlak olarak emin olmalıyım
    İkincisi, öyle değilse, üretilen şeyi tamamen anlayıp kendim yeniden üretebilecek duruma gelmeden ilerlemem
    Üçüncüsü, ikinci kuralı bozarsam bilişsel borç oluşturabilirim ama projeyi tamamlandı ilan etmeden önce bunu tamamen kapatmam gerekir
    Borç biriktikçe, sonraki üretilen kodun kalitesinin düşme ihtimali artıyor ve bu da bileşik faiz gibi büyüyor. Kişisel projelerde bu yöntem keyifli; çok şey öğreniyorum ve sonunda rahatça anlayabildiğim bir codebase kalıyor

    • Kod sağlığı ve codebase büyümesi hakkında sağlam bir zihinsel model korumak için makul kurallar ama AI sonrası teslim hızı beklentilerinin ciddi biçimde değiştiği iş ortamında bunlara uymak zor
      Codebase’le bağlantıyı korurken ekibin darboğazı da olmamak arasında bir denge noktası gerekiyor
    • Benzer kuralları izlemeye çalışırken zor bir matematik problemiyle karşılaştım
      Claude doktora seviyesinde bir matematikçi, ben değilim; ama istediğim çözümün özelliklerini ve doğruluğunu nasıl test edeceğimi tam olarak biliyordum. Bu yüzden kendi basit ve naif çözümüm yerine Claude’un çözümünü bıraktım, pull request’te de bunu belirttim ve herkes bunun doğru karar olduğunu düşündü
      Böyle durumlar için istisna tanımak gerekir mi merak ediyorum. AI yalnızca ileri matematikte değil, kodlamada da benden çok daha iyi hale gelirse, kodu doğrudan değerlendirme yeteneğimi kaybetsem bile testleri değerlendirebildiğim sürece tamamen elle kod yazmayı bırakır mıyım sorusu daha ilginç geliyor
    • “Bilişsel borç” yerine anlama borcu ifadesini daha çok seviyorum
      Çünkü biriken borç tam olarak koda dair anlayış eksikliği; bu yüzden daha isabetli
    • Kişisel projelerde daha keyifli yöntem önemli olduğu için sorun değil ama işte; bağımlılıkları, ekip arkadaşlarının işini, dış servisleri, hatta silikona kadar inen tüm katmanları o şekilde tam anlayarak çalışmıyoruz
      AI’a neden birdenbire farklı muamele yapılması gerektiğini bilmiyorum
      Sonunda karar risk ve ödüle göre verilmeli. Yanlış olduğunda zarar ne olur, bunun testte ve review’de yakalanma olasılığı nedir, doğru giderse getirisi ne olur; bunlara bakmak gerekir. Kütüphaneler ve dış servisler için de aynı şey geçerli
      Testsiz ve güncellenemeyen bir kripto sözleşmesindeki karmaşık finans kurallarıyla, iç log verilerini görselleştiren bir viewer aynı risk düzeyi değildir
    • Benzer bir yaklaşım denedim ama sonuçta ikinci kurala yeterince sadık kalmanın pratikte zor olduğunu düşünüyorum
      Teoride kulağa hoş geliyor ama gerçekte insan farkına varmadan hep zihinsel kestirmelere kaçıyor
      Yabancı bir codebase’te bir problemi düzeltirken bunu kendim yaptığım durumla, ajanın yaptığını “tamamen anladım” dediğim durumu kıyaslayınca, bir hafta sonra aklımda kalan miktar farklı oluyor. Kendim yaptığımda genel bilgi olarak birikiyor ve önemli kısımlar çoğunlukla kalıyor; ama ajanın yaptığını kendi işimmiş gibi sahiplenmeye çalıştığımda, o anda anlamış gibi hissetsem bile çok hızlı unutuyorum
      Bu yüzden böyle durumlarda LLM yardımının çoğunlukla hedeflerime zarar verdiği sonucuna vardım; zaman ve iş baskısı gibi başka kaygıları hesaba katmasam bile
  • Ben de aynı şeyi yaşadım
    Tuzak şöyle işliyor: iyi bir codebase’te AI çok sayıda özellik üretebiliyor ve daha hızlı, daha güvenli, daha doğru görünmeye başlıyor. Özellikle de çok iyi bilmediğiniz alanlarda bu his daha güçlü oluyor
    Zaman geçtikçe codebase büyüyor, gezinme süresi uzuyor, hata oranı artıyor. Bunu kabul etmek istemediğiniz için daha da zorluyorsunuz; değişiklik yapmak fiilen imkânsız hale geldikten sonra ancak duruyorsunuz
    Koda yeniden bakınca, “spagetti” demek bile yetmiyor; durum adeta Çin Seddi gibi
    Sonunda 140 bin satırın 75 binini sildim ve ajanlarla kodlamaya aşırı daldığım 3 ayın boşa gittiğini hissediyorum. İşe yaramaz özellikler yaptım, bug sayısını artırdım, kodun zihinsel modelini kaybettim, ancak kodun içinde görünür olan zor kararları kaçırdım ve kullanıcıları da hayal kırıklığına uğrattım

    • Bu sonucun şaşırtıcı bulunması ilginç
      Alay etmek için söylemiyorum; gerçekten ilk beklentinin ne olduğunu ve nereden geldiğini merak ediyorum
      Görünüşe göre LLM’ler için beklenti farklı. İnternette tanıdığınız rastgele bir “geliştirici”ye özet bir özellik açıklaması verip ondan yarı bozuk bir uygulama yığını alsanız kimse şaşırmazdı
      Ama insanlar bazen, uzun uzun halüsinasyon gören bir makineden, bir insandan bile beklemeyecekleri mucizeleri bekliyor. O güvenin nereden geldiğini merak ediyorum
    • Büyük bir codebase, küçük codebase’lerin toplamı olmalı diye düşünüyorum
      Büyük bir şehrin küçük şehirlerin toplamı gibi olması gibi; bir harita vardır, yerel bölgelere zoom yaparsınız ve o sınır içinde çalışırsınız. Bir kahve içmek için New York’un tüm ayrıntılarını bilmeniz gerekmez
      Bakımı yapılabilir sağlam bir mimari kurmak, aracı kullanan kişinin sorumluluğudur. AI bunu engellemez; aracı doğru tutarsanız hatta yardımcı olabilir
    • AI’ı tamamen bırakmak dışında da iş akışı çözümleri olabilir gibi geliyor
      Örneğin AI tarafından üretilen kodu anında legacy code gibi ele almak; güçlü kapsülleme sınırları ve iyi tanımlı arayüzler koyup sonra daha manuel bir akışla entegre etmek
      Tek seferlik prompt’tan inline kod üretimine kadar bir yelpaze var ve hangi yaklaşımın uygun olduğu probleme ve codebase içindeki yerine göre değişir
      Tek seferlik üretim, spesifikasyonun çok tekrarlandığı prototip aşamasına daha uygun; prototip oturunca modül/dosya düzeyinde üretime inilip daha sistematik ilerlenebilir ve bu katmanda da iyi bir zihinsel model korunmalı
    • Üretilen kodu hiç okumadan her şeyi otomatik commit mi ettin diye merak ediyorum
      Okudun ama anlamadıysan, her çıktı için ayrıntılı yorum eklemesini isteyebilirdin; modelin codebase büyüdükçe zorlandığını biliyorsan, karmaşıklık arttıkça çıktıyı daha da sıkı incelemek gerekir
    • Büyük codebase’lerle çok çalışmadım ama acaba Working Effectively with Legacy Code tarzı bir iş akışı uygulanamaz mı diye düşünüyorum
      Daha yüksek kaliteli kod adaları oluşturmak, AI’ı geliştiricinin niyetini ve iş kurallarını yeniden kurmaya yardımcı olmak için kullanmak ve hedef modülde seam ile unit test’ler oluşturmak gibi
      AI mutlaka throughput artırmak için kullanılmak zorunda değil; daha sonraki elle kodlama ya da ajan uygulamalarını destekleyen esnek bir keşif ve refactoring aracı da olabilir
  • Bu tür yazıları her gördüğümde, insanların AI ile elde ettiğini söylediği hızla benim doğrudan elle kodlayarak elde ettiğim hızı kıyaslıyorum
    Tesadüfen 7 aydır bir 3D MMO projesi üzerinde çalışıyorum; şu anda oynanabilir durumda, insanlar eğleniyor, grafikler fena değil ve sunucuda yüzlerce kişiyi rahatça barındırabiliyor. Mimari de oldukça iyi; özellik eklemek kolay ve yaklaşık 1 yıllık geliştirme sonunda yayımlanabilir gibi görünüyor
    Ama asıl yazıdaki kişi 7 ay boyunca vibe coding yapıp temel bir TUI bile çıkaramamış. Özellik geliştirme hızı yüksekmiş gibi hissedilebilir ama böyle temel bir UI’ı yapmak için inanılmaz yavaş. İyi TUI kütüphaneleri bolca var ve gereken verilerle tablo doldurmak türünden bir şey; bunu elde birkaç haftada yapmak mümkün
    AI kullanınca hızlıca çok ilerliyormuşsunuz gibi güçlü bir his oluşuyor ama gerçekte çoğu zaman manuel kodlamadan çok daha yavaş gibi görünüyor. Verimlilik verileri de AI kullananların kendilerini daha hızlı hissettiğini ama gerçek çıktıların daha düşük olduğunu destekliyor gibi

    • Bu metrik büyük ölçüde kimin AI’ı ne için kullandığına bağlı
      Yazılım geliştirme işlerinde en büyük zaman kaybı, paydaş beklentilerini ve çözümü hizalamaya çalışan toplantılardır. Bu açıdan bakınca AI neredeyse hiç yardımcı olmaz; bu yüzden fikir aşamasından test döngüsüne girişe kadar harcanan insan saatini karşılaştırırsanız hayal kırıklığı yaratan sonuçlar çıkması normal
      Ama problem çözme, bug düzeltme ve onaylanmış çözümü uygulama tarafında eskisine göre en az 10 kat daha iyi olduğumu hissediyorum. Sadece saf zaman değil; gözlenen davranışı yorumlama ve problemi araştırma becerim de iyileşti
      Yine de AI ile değerli ve doğru sonuç üretemeyen insanlar var. Ne istediğinizi ve onu nasıl istediğinizi tam biliyorsanız AI çok yardımcı oluyor. Benim zaten yapacağım şeyi ona yaptırırsam daha hızlı yapıyor. Ama ne istediğinizi tam bilmiyorsanız AI ilerlemeye zarar veriyor
    • Ben de yakın zamanda aynı sonuca vardım
      İnsanların LLM ile yaptıklarını gösterdiğinde çok etkileyici gelmemesinin sebebi, çoğunun elde de çok kısa sürede yapılabilecek şeyler olması
      Ayrıca etkileyici yazılımların sayısında bir artış da gözlemlemiyorum; bu da LLM’lerin şu anda önemli problemlerden çok basit problemleri çözmekte kullanıldığı gerçeğiyle uyumlu görünüyor
    • LLM’lerden en büyük faydayı hisseden kişiler, muhtemelen zaten iyi yazılım yapmayı pek bilmeyen ya da bunu yapacak yetkinliği olmayanlardır
    • Bana da 7 ay kısmı tuhaf geldi. Yeni bir dilde yazılsa bile bu kadar sürmemeli gibi
      Ayrıca çok az konuşulan şeylerden biri de kod kalitesi
      Vibe coding ile oluşmuş bir codebase, LLM’lerin kod yazmada o kadar da iyi olmadığının harika bir örneği. Kendi hatalarını düzeltirken hemen yeniden üretiyorlar ve desen kullanımı da tutarlı değil
      Son zamanlarda Claude, mevcut codebase stiline hiç uymayan “ilginç” kod stili seçimleri de yapabiliyor
    • GPT ailesi, metin yani dil ve kod üretmek için tasarlanmış ve bunun üzerine yaşayan bir yapı olduğu için, sistem içinde doğal olarak her şeyi doğrudan üretme yönüne kaymış gibi görünüyor
      “Kıdemli geliştirici” tarzı bir dille bu tekrarları engellemek gerekiyor
  • “Kod yazmadan önce somut arayüzleri, mesaj tiplerini, sahiplik kurallarını kendim tasarlıyorum” kısmı zaten kodlamanın zor tarafı
    Mimari varsa kod yazmak çok kolaydır. Kodu kendiniz yazmıyorsanız, null kabul eden bir API tasarladığınızı ama veritabanının bunu kabul etmediğini ya da kabul etse bile başka küçük sorunları kaçırdığınızı fark etmeniz zorlaşır
    Bu yazıyı yazıp da sorunun AI olduğunu fark etmemiş olmasını anlamıyorum. Sadece mimariyi AI’a bırakmış olması değil; AI’ın yaptığı her şeyi dikkatle izlememiş olması da sorun
    AI süslenmiş bir kod üretecidir ve yaptığı her şeyi kontrol etmek gerekir. Yazılım mühendisliğinin zor kısmı kod yazmak değil, onun dışındaki her şeydi

    • Bence iki tür geliştirici var: kodun zor taraf olduğunu düşünenler ve düşünmeyenler
      Kodlamanın zor olduğunu düşünen geliştiriciler AI ile kodlamayı gerçekten seviyor; çünkü önceden zor olan bir şey kolaylaştı
      Buna karşılık kodlamanın kolay olduğunu düşünenler için mesele soyutlama, bakım yapılabilirlik ve ölçeklenebilirliktir. Yazılımın büyümesine izin verecek makul bir temel kurmak zordur; doğru soyutlamayı bulduğunuzda geri kalanı nispeten kolaylaşır
      Bu insanlar için AI ile kodlama faydalı bir araçtır ama sihirli bir araç değildir. Asıl yazıyı yazan kişi AI’ın sınırlarını fark ettiğine göre ikinci grupta ve AI’ın yapamadığı zor kısmı görmüş durumda
    • Şu anda tanımların karıştığı bir sorun var
      Bir tarafta güçlü tab autocomplete ya da yandaki pencere chatbot’unu kullanıp yine de her şeyi açıkça review eden insanlar var; diğer tarafta ise Steve Yegge gibi, kodun çoğunu okumayacakmışsınız gibi onlarca ajanı koordine eden yeni editörleri tanıtan kişiler var: https://steve-yegge.medium.com/welcome-to-gas-town-4f25ee16d...
      İlk grup hâlâ tasarım, arayüzler ve veri yapıları üzerine derin düşünüp güçlü review yapıyor. İkinci grup bunu yapmadığı için daha kaygı verici
    • Ajanlar neredeyse her zaman planlama ile uygulama arasında başarısız oluyor
      plan → red/green/refactor yaklaşımını izliyorum; planın kendisi tüm dokümanları ve forum tartışmalarını içine çektiği için oldukça makul ve dayanaklı görünüyor
      Sorun şu ki işe başlayınca mutlaka dokümantasyonla implementasyonun gerçekte farklılaştığı yerler çıkıyor. Araç kombinasyonu o şekilde hiç kullanılmamış olabilir, doküman eski olabilir ya da sadece bug vardır
      Yine de proje ya da özellik hedefi yeterince netse ve yerelde çalıştırıp test edilebiliyorsa, ajan mimari çıkmazlarda döne döne bir çıkış bulabiliyor. Hatta dependency’leri ve kütüphane kodunu inceleyip upstream düzeltme bile öneriyor; bu da derin bir debugging oturumunda benim yapacağıma benziyor
      Bu yüzden sıkıcı işleri bizzat yapmak yerine yönlendirme ve gözetim rolünde olmaktan oldukça memnunum. Ama ekip arkadaşlarımın önemli bir kısmı mimari sorunları bu kadar derin kazmıyor ve varsayılan olarak “mimara eskale etme” yoluna gidiyor; bu da uzun vadede iyi görünmüyor
      Her şeyi çalıştırıp anlayabildiğimiz pencere hızla kapanıyor gibi. Ama derleyicinin makine koduna çevirme sürecini ya da modern CPU’ların branch prediction ve caching davranışını tamamen anlamadan da onları kullandığımız gibi, belki yeni araçlar ve framework’ler geliştirerek buna uyum sağlarız
    • AI’ın yaptığı her şeyi kontrol etmek gerektiğini pek çok kişi kaçırıyor gibi görünüyor
      Kod deneyimi çok fazla olmayan biri olarak, sonucu kontrol edip neyin doğru neyin yanlış olduğunu görerek hayatımda hiç olmadığı kadar çok şey öğreniyorum
      Bu yüzden yakın zamanda büyük bir değişim olacağını da sanmıyorum. İnsanlar “Claude çıktısını nasıl bu kadar iyi hale getiriyorsun?” diye sorduğunda cevabım hep aynı: “Dikkatlice baktım, sorunları buldum ve Claude’a düzeltmesini söyledim.” Gerçekten hepsi bu; ama bunu duyunca insanların bakışları bile hemen sönüyor
      Tıpkı Google’ın bilgi bulmayı kolaylaştırması ama iyi bilgiyle kötü bilgiyi ayırt eden insan unsurunu ortadan kaldırmaması gibi
    • Ajan kullanırken tamamen nefret etmemek ya da başarısız olmamak için benim için işe yarayan tek yol buydu
      Önce problemi düşünmek, yapıyı ve API’leri tasarlamak, ancak ondan sonra implementasyonu AI’a bırakmak
  • Başlık “elle kod yazmaya geri döndüm” diyor ama gerçekte yapılan şey, kod yazılmadan önce tasarım işini elle yapmak gibi görünüyor
    Sonrasında kodu hâlâ Claude üretiyor gibi
    Daha da önemlisi, 7 ay boyunca üretilen kaynak koduna bakmadan vibe coding projesinin iyi çalıştığını düşünüp bir de alan adı satın almış olmasını anlamak zor

    • Kısacası clickbait bir başlık ve yazının amacı kendi projesine ilgi çekmek gibi duruyor
    • Aklıma bir fikir geldikten birkaç dakika sonra proje alan adını satın aldığım da oldu
      Bu bir yan proje ise ve diff’leri takip ederek kademeli doğrulama yapıyorsanız, koda çok derin bakmamak o kadar da tuhaf sayılmaz. Kesinlikle farklı bir çalışma biçimi ama delilik seviyesinde değil
  • Geliştiricilerin proje yönetimi ve ürün yönetimi derslerini speedrun şeklinde yaşadığını görmek gibi geliyor
    Artık spesifikasyonların faydalı olduğunu ve çok sayıda yanlış kod yazdırmanın projeyi hızlandırmadığını görüyorlar. Geliştiriciler toplantılara ve tartışmalara kod yazmayı engelliyor diye kızıyor ama bu süreçler çoğu zaman herkesin daha fazla yanlış şey yazmasını önlemek için var
    İş takibinin yararlı olduğu da anlaşıldı; şimdi de tasarımın tamamen önden yapılması gerektiği söylemi arttıkça iş şelale modeline doğru kayıyor
    Sonra buna prototipleme diye bir ad verilecek, eski gereksinimlerle yeni gereksinimleri birlikte yöneten artımlı özellik geliştirmeden söz edilecek ve sonunda müşterinin daha fazla dahil olması gerektiği söylenecek
    Proje yöneticileriyle ürün yöneticilerinin aslında ne yaptığını görmek gerekiyor. Onlar kod adlı ürünü yönlendiriyor ama kod okumaları beklenmiyor; bunu yalnızca doğal dille başarmaları gerekiyor

    • Doğru. Bu insanlar sanki hiç yönetici olmamış gibi
      İnsanların da kırık şeyler yazdığını sanmıyorlar mı? Ekiplerin yanlış yola girip bir haftayı, hatta ayları yaktığı olmuyor mu sanıyorlar? Artık vibe coding ile bunların hepsini 30 dakikada yaşayabiliyorsunuz. Eski bir teknik ürün yöneticisi olarak his tam anlamıyla aynı
  • Aslında elde kod yazmak gibi görünmüyor; bu yüzden başlıkla sonuç arasındaki fark kafa karıştırıcı

    • Bence kasten kışkırtıcı bir başlık atıp HN’in bunu kapmasını ve ana sayfaya taşımasını istemiş
    • Yazının kendisi de sanki elde yazılmamış. HN’de yukarı çıkan şey yazı değil, başlık olmuş gibi görünüyor