1 poin oleh GN⁺ 4 jam lalu | 1 komentar | Bagikan ke WhatsApp
  • k10s adalah TUI Kubernetes yang sadar-GPU dan dibuat cepat lewat vibe-coding bersama Claude, tetapi setelah menambahkan fleet view, berbagai state layar mulai rusak
  • model.go membengkak menjadi satu Model tunggal sepanjang 1690 baris dengan Update() sepanjang 500 baris, memikul sekaligus state UI, klien, cache, navigation, dan view
  • AI memang menambahkan fitur dengan cepat, tetapi juga memperbesar god object dan global key handler, sehingga setiap view baru menambah branch ke handler lama
  • Data []string berbasis posisi dan mutasi langsung oleh background tea.Cmd dapat menimbulkan error kolom dan data race yang jelas
  • k10s baru akan ditulis ulang dalam Rust, dan sebelum prompt pertama, interface, message type, ownership rule, serta scope akan dibakukan di CLAUDE.md

Latar belakang menulis ulang k10s

  • k10s dimulai sebagai dashboard Kubernetes yang sadar-GPU, sebuah alat TUI yang dibuat agar operator klaster NVIDIA bisa langsung melihat informasi seperti utilisasi GPU, metrik DCGM, node idle, dan biaya $32/hr
  • Ditulis dengan Go dan Bubble Tea, alat ini dibuat lewat sesi vibe-coding bersama Claude selama sekitar 7 bulan, 234 commit, dan sekitar 30 akhir pekan
  • Pada tahap awal, fitur dasar ala klon k9s seperti pods, nodes, deployments, services, command palette, live updates berbasis watch, dan Vim keybindings sudah berjalan hanya dalam sekitar 3 akhir pekan
  • Fitur inti, yaitu GPU fleet view, adalah layar yang menampilkan alokasi GPU tiap node, utilisasi, metrik berbasis DCGM, suhu, daya, memori, dan status berbasis warna, dan Claude sekaligus menghasilkan struct FleetView, pemfilteran tab GPU/CPU/All, hingga rendering allocation bars
  • Setelah fleet view ditambahkan, saat kembali ke pods view dengan :rs pods, tabel menjadi kosong, live updates berhenti, nodes view menampilkan stale data dari filter fleet view, dan fleet tab count juga menjadi salah
  • Saat menelusuri masalahnya, penulis untuk pertama kalinya membaca seluruh model.go sepanjang 1690 baris yang dibuat Claude, dan menemukan satu struct Model memuat sekaligus widget UI, Kubernetes client, state logs/describe/fleet, navigation history, cache, dan mouse handling
  • Method Update() berukuran 500 baris dan berupa fungsi dispatch msg.(type) dengan 110 branch switch/case
  • AI memang bisa membuat fitur dengan cepat, tetapi jika terus diberi tugas tanpa batasan, arsitektur akan runtuh, dan rasa cepat itu tampak seperti keberhasilan sampai semuanya ambruk bersamaan

Lima prinsip yang muncul dari puing-puingnya

  • Prinsip 1: AI membuat fitur, tetapi tidak membuat arsitektur

    • Claude cukup baik dalam membuat fitur individual seperti fleet view, log streaming, dan mouse support, tetapi tiap fitur diimplementasikan dalam konteks “dibuat agar jalan sekarang” dan tidak mempertimbangkan relasinya dengan fitur lain yang berbagi state yang sama
    • Handler resourcesLoadedMsg memuat kondisi seperti msg.gvr.Resource == k8s.ResourceNodes && m.fleetView != nil, sehingga logika khusus fleet view bercampur ke dalam jalur generic resource loading
    • Setiap view baru yang butuh behavior khusus menambah branch ke handler yang sama, dan berbagai field harus dibersihkan manual agar data dari view sebelumnya tidak bocor ke view baru
    • Di model.go, cleanup manual seperti m.logLines = nil, m.allResources = nil, m.resources = nil tersebar di 9 tempat, dan jika satu saja terlewat, ghost data dari view sebelumnya akan tertinggal
    • Alternatifnya adalah menulis sendiri lebih dulu interface, message type, dan ownership rule yang konkret sebelum menulis kode, lalu memasukkannya ke CLAUDE.md sebagai architecture invariant
    • Contoh aturannya: setiap view mengimplementasikan trait/interface View, sebuah view tidak boleh mengakses state milik view lain, data async hanya masuk lewat variant AppMsg, dan struct App hanya bertanggung jawab atas navigation serta message dispatch
  • Prinsip 2: god object adalah keluaran default AI

    • AI cenderung memilih struktur single struct yang memegang semuanya demi memenuhi prompt langsung dengan ceremony sesedikit mungkin
    • Key handling juga tidak dipisah per view; satu tombol s berfungsi sebagai autoscroll di logs view, shell di pods view, dan container shell di containers view
    • Permintaan seperti “tambahkan shell support ke pods” diimplementasikan dengan menyisipkan branch di sekitar global key handler yang sudah ada
    • Tombol Enter juga bercabang untuk contexts view, namespaces view, logs view, dan generic drill-down logic dalam satu dispatch datar berdasarkan perbandingan string m.currentGVR.Resource
    • Dalam satu file model.go, m.currentGVR.Resource == dipakai lebih dari 20 kali sebagai semacam type discriminator, sehingga setiap penambahan view baru menuntut perubahan di beberapa handler
    • Alternatifnya adalah memasukkan aturan ke CLAUDE.md agar App/Model tidak diberi field state khusus view, setiap view dibuat sebagai struct terpisah, dan key binding ditempatkan pada keymap milik view yang aktif
    • Harus ada guardrail seperti “menambahkan view harus berarti menambahkan file, dan jika perlu memodifikasi view yang ada, berhenti dan tanyakan dulu” agar AI tidak menambah branch lewat jalur terpendek
  • Prinsip 3: ilusi kecepatan memperlebar scope

    • k10s semula adalah alat untuk audiens yang sempit, yaitu operator klaster training GPU, tetapi vibe-coding membuat fitur seperti pods, deployments, services, command palette, mouse support, contexts, dan namespaces terasa seperti “gratis”
    • Akibatnya, arahnya meluas bukan lagi menjadi alat yang fokus pada GPU, melainkan TUI general-purpose untuk semua pengguna Kubernetes, pada dasarnya seperti membuat ulang k9s
    • keyMap yang datar mencampurkan banyak binding khusus view dalam satu struct, seperti Fullscreen, Autoscroll, ToggleTime, WrapText, CopyLogs, ToggleLineNums, Describe, YamlView, Edit, Shell, FilterLogs, FleetTabNext, FleetTabPrev
    • Autoscroll dan Shell sama-sama menggunakan s, dan karena dispatch memeriksa resource saat ini, semuanya memang “berfungsi”, tetapi keybinding menjadi mustahil dipahami secara lokal
    • Kecepatan menulis kode tampak seperti sedang “shipping”, tetapi tiap fitur menambah biaya berupa satu branch lagi di dalam god object
    • Alternatifnya adalah menegaskan scope boundary di CLAUDE.md: k10s adalah alat untuk operator klaster GPU, view yang didukung dibatasi pada fleet, node-detail, gpu-detail, dan workload, dan tidak menambahkan generic resource view atau fitur yang menduplikasi k9s
    • AI bisa memberi budget baris kode yang nyaris tak terbatas, tetapi complexity budget tetap terbatas, jadi scope harus ditolak sejak awal
  • Prinsip 4: data berbasis posisi adalah bom waktu

    • k10s langsung meratakan resource dari Kubernetes API menjadi type OrderedResourceFields []string
    • Fungsi sort di fleet view memperlakukan ra[3] sebagai Alloc, ra[2] sebagai Compute, dan ra[0] sebagai Name, sehingga identitas kolom hanya bergantung pada komentar dan urutan kolom di resource.views.json
    • Jika satu kolom ditambahkan di antara Instance dan Compute dalam resource.views.json, maka sort, conditional render, dan drill target yang merujuk ra[2] dan ra[3] bisa diam-diam menjadi salah
    • Compiler tidak memahami makna []string, dan config JSON juga tidak bisa mengekspresikan sort behavior, conditional rendering, atau custom drill target, sehingga kode Go akhirnya meng-hardcode asumsi posisi
    • AI cenderung memilih []string atau Vec<String> karena mudah langsung dimasukkan ke widget tabel, sedangkan typed struct butuh ceremony awal yang lebih besar sehingga tersisih dari jalur tercepat
    • Alternatifnya adalah mempertahankan data terstruktur sebagai typed struct seperti FleetNode dan PodInfo sampai tepat sebelum render, dan melakukan sort berdasarkan named field, bukan akses posisi seperti row[3]
    • Contoh strukturnya adalah FleetNode { name, instance_type, compute_class, alloc }, sehingga identitas kolom dinyatakan lewat type dan state yang mustahil seperti sort kolom yang salah tidak bisa dibentuk
    • “Making impossible states impossible” adalah ungkapan yang dipakai di komunitas Elm/Rust untuk berarti merancang type agar invalid state tidak bisa dibentuk, alih-alih memeriksanya nanti saat runtime
  • Prinsip 5: AI tidak memiliki state transition

    • Struktur Bubble Tea menempatkan perubahan state hanya di Update() yang digerakkan oleh message, dan ini adalah intinya, tetapi k10s melanggar hal tersebut
    • Handler updateTableMsg mengembalikan closure tea.Cmd, dan di dalam closure itu field Model diubah lewat panggilan seperti m.updateColumns(m.viewWidth), m.updateTableData(), dan m.table.SetCursor(savedCursor)
    • Bubble Tea menjalankan tea.Cmd di goroutine terpisah, sehingga saat closure membaca dan menulis m.resources, m.table, dan m.viewWidth, View() di goroutine utama bisa saja sedang membaca field yang sama
    • Tidak ada lock atau mutex, dan <-m.updateTableChan hanya menunggu sinyal update, bukan mencegah View() membaca state yang baru setengah ditulis
    • Struktur ini adalah data race yang jelas, dan biasanya tampak “berjalan” tetapi sesekali muncul sebagai tampilan yang rusak
    • Alternatifnya adalah worker di background tidak memutasi UI state secara langsung, melainkan mengirim typed message lewat channel, dan main event loop menerima message itu lalu menerapkan mutasi state
    • Aturan concurrency-nya adalah background task tidak boleh langsung mengubah UI state, melainkan mengirim hasil sebagai typed message, dan render()/view() harus berupa pure function tanpa side effect, I/O, atau operasi channel

Aturan perlindungan yang akan dimasukkan ke CLAUDE.md dan agents.md

  • Invariant arsitektur

    • Setiap view harus mengimplementasikan trait/interface View, dan tidak boleh mengakses state milik view lain
    • Semua data async harus masuk sebagai variant AppMsg, dan background task tidak boleh memutasi field secara langsung
    • Penambahan view baru tidak boleh menuntut modifikasi terhadap view yang sudah ada
    • Struct App harus menjadi thin router yang menangani navigation dan message dispatch
  • Aturan kepemilikan state

    • Jangan menambahkan field state khusus view ke struct App/Model
    • Setiap view harus ada sebagai struct terpisah dan mendeklarasikan key binding-nya sendiri
    • Aplikasi harus mendispatch key ke view yang aktif, dan keybinding baru harus ditambahkan ke keymap view terkait, bukan ke global handler
    • Jika penambahan view menuntut modifikasi view yang sudah ada, berhenti dan minta konfirmasi
  • Scope

    • k10s harus menjadi alat untuk operator klaster GPU, bukan untuk semua pengguna Kubernetes
    • View yang didukung harus dibatasi pada fleet, node-detail, gpu-detail, dan workload
    • Jangan menambahkan generic resource view seperti pods, deployments, atau services
    • Jangan menambahkan fitur yang menyalin fungsi k9s
    • Feature request yang tidak membantu operator job training GPU harus ditolak
  • Representasi data

    • Jangan meratakan data terstruktur menjadi []string, Vec<String>, atau array berbasis posisi
    • Data harus tetap mengalir sebagai typed struct sampai tepat sebelum render call
    • Identitas kolom harus berasal dari nama field struct, bukan index array
    • Fungsi sort harus bekerja pada typed field, bukan akses posisi seperti row[3]
    • Pembuatan string untuk display hanya boleh terjadi di dalam fungsi render()/view()
  • Aturan konkurensi

    • Background task seperti watcher, scraper, atau API call tidak boleh langsung memutasi UI state
    • Background task harus mengirim hasil sebagai typed message ke channel
    • Hanya main event loop yang boleh menerapkan mutasi state dari message yang diterima
    • render()/view() harus berupa pure function tanpa side effect, I/O, atau operasi channel
    • Jika hasil kerja async perlu mengubah state, harus didefinisikan variant AppMsg yang baru

Cara membangun ulang

  • k10s akan ditulis ulang dalam Rust, bukan karena Rust lebih baik, tetapi karena terasa sebagai bahasa yang bisa dikendalikan secara langsung
  • Dalam bahasa yang sudah cukup dikuasai, seseorang bisa merasakan ada yang salah bahkan sebelum dapat menjelaskannya dengan kata-kata, dan kepekaan ini tidak bisa digantikan oleh vibe-coding
  • Saat AI menghasilkan kode yang tampak meyakinkan, diperlukan kemampuan untuk mendeteksi apakah itu sebenarnya sampah
  • Pada versi baru, pekerjaan desain seperti concrete interface, message type, dan ownership rule akan lebih dulu dilakukan manusia secara manual sebelum penulisan kode
  • Keputusan arsitektur yang sebelumnya salah ditentukan AI kini akan didokumentasikan sebelum prompt pertama dikirim
  • Tautan ke TUI dan proyek yang ada: k10s Github dan K10S.DEV

Tambahan

  • Bubble Tea adalah framework Go TUI berbasis The Elm Architecture, dan masalah arsitektur k10s berasal dari implementasi k10s, bukan dari Bubble Tea
  • “Making impossible states impossible” adalah ungkapan di komunitas Elm/Rust yang berarti mencegah invalid state terbentuk lewat desain type, alih-alih memeriksanya saat runtime
  • Seperti “em-dash” dalam tulisan AI, dalam coding AI bau “god-object” bisa tertinggal, dan vibe-coding dapat membuat implementasi terasa murah sehingga berujung pada hilangnya fokus dan bloat

1 komentar

 
GN⁺ 4 jam lalu
Komentar Hacker News
  • Orang-orang yang bilang kode hasil generasi itu bagus pada dasarnya hanya orang-orang yang tidak membaca kode tersebut
    Solusi mitigasi yang disarankan di tulisan itu juga sulit bertahan lama. Saat merancang sistem atau komponen, akan muncul invarian seperti “view tidak mengakses state milik view lain”, dan pada akhirnya pasti ada fitur yang harus ditambahkan yang berbenturan dengan kondisi itu
    Pada titik itu biasanya pilihannya adalah membuang fiturnya, menumpuknya di atas invarian secara canggung dan tidak efisien, atau mengubah invarian itu sendiri. Pilihan ini bukan sekadar masalah konteks, melainkan masalah penilaian, dan model saat ini terlalu sering salah dalam penilaian ini
    Jika batasan arsitektur dinyatakan secara eksplisit, agen justru membuat kode yang rumit dan mustahil dirawat dengan memaksa diri menyesuaikan ke batasan itu bahkan ketika seharusnya diubah. Kalau tidak dibaca lebih teliti daripada kode buatan manusia, pada akhirnya akan muncul “kode yang memakan dirinya sendiri” dan kita baru sadar saat semuanya sudah terlambat

    • Kalau Anda tahu cara menulis kode yang baik, ada banyak teknik untuk membuat AI menulis kode yang baik, dan itu cukup memungkinkan
      Kuncinya adalah mengidentifikasi titik yang sulit bagi AI lalu membuatnya jadi mudah. Misalnya diperlukan konteks yang amat kecil, modularisasi dengan batas yang jelas, modul murni yang terpisah dari input/output, penyembunyian di balik interface, 100 tes yang selesai di bawah 1 detik, benchmark, dan sebagainya
      AI bekerja baik ketika ada batasan dan konteks kecil. Jika itu tidak diberikan, performanya turun, dan tanggung jawabnya ada pada orang yang memakai alat tersebut
    • Menurut saya, poin “suatu saat kita akan menambahkan fitur yang berbenturan dengan invarian” adalah masalah besar dalam pengembangan berbasis spesifikasi
      Tidak ada spesifikasi yang mampu bertahan terhadap kenyataan, dan sehebat apa pun investigasi serta desain awalnya, pada akhirnya ada invarian dalam spesifikasi yang akan terbukti salah
      Ketika manusia menemui situasi ini saat pengembangan, ia bisa mundur selangkah dan memikirkan lagi apakah invarian itu salah serta apa dampaknya jika diubah. Sebaliknya, AI sering kali memaksakan solusi tambal sulam di bawah asumsi atau desain yang keliru, dan kurang punya wawasan untuk mengevaluasi ulang keseluruhan
      Ini bisa membaik dengan alur kerja dan verifikasi yang baik, tetapi bukan area yang secara default ditangani dengan baik oleh alat seperti Claude Code, dan memang ada batasnya
    • Saya mengalami hal serupa saat di kantor membuat framework internal baru dan memigrasikan penggunaan framework lama ke sana
      Awalnya kami menetapkan prinsip yang kuat dan memindahkan beberapa penggunaan secara manual untuk membangun keyakinan. Migrasi totalnya sangat besar dan mahal sampai-sampai tertunda hampir 10 tahun, jadi kami ingin mempercepat dengan AI untuk menurunkan biaya
      AI lumayan untuk 80% kasus yang mekanis dan sederhana. Sisa 20% memerlukan perubahan pada framework, dan kebanyakannya perubahan kecil seperti menambah field API, tetapi satu dua kasus memerlukan desain ulang konseptual
      Backend pada suatu sistem bisa menghasilkan data tertentu dalam 99% kasus, tetapi ada beberapa kasus penting di mana secara logis data itu tidak bisa dibuat sehingga harus dilaporkan dari luar. Namun optimasi penting dibangun di atas asumsi bahwa “itu mustahil”
      Alat AI tidak mendeteksi situasi ini dan menambahkan logika migrasi seolah semuanya akan bekerja benar. Berkat cara deploy kami, ini belum menjadi bug produksi, tetapi saat mengajukan pertanyaan yang benar ke tim partner kami menemukan kebutuhan serupa ada di tempat lain juga
      Pada akhirnya masalah besar tidak terjadi karena ada satu orang yang benar-benar mendalami hal itu. Mungkin alat verifikasi dan model yang lebih pintar akan membuat migrasi seperti ini lebih mudah di masa depan, tetapi untuk saat ini kode generatif terlihat indah sekaligus rapuh sehingga harus terus diawasi dari dekat
    • Bukan cuma membaca output kode, setidaknya dalam pengalaman saya, kita juga harus menulis kodenya sendiri
      Saya punya pola arsitektur yang agak aneh dan sudah dipakai sekitar dua bulan; setiap kali memakainya terasa sedikit tidak nyaman, dan baru tadi malam saya sadar bahwa itu bukan abstraksi yang bagus serta ada cara membaginya dengan lebih baik
      Ketika saya membiarkan LLM menghasilkan kode, rasa tidak nyaman itu terasa jauh kurang jelas sehingga saya butuh lebih lama untuk menyadari masalah dan menemukan solusinya. Bagian pinggiran boleh saja digenerasi, tetapi untuk fitur inti saya masih harus menulis sebagian besar sendiri
    • Invarian yang ditulis secara informal sulit dibuktikan rusak atau tidak bahkan jika ada reviewer manusia, dan bahasa alami tidak cukup presisi untuk pekerjaan itu
      Bahkan jika diekspresikan dalam bahasa formal yang presisi, LLM di bawah agen masih kurang mampu memahami mengapa invarian itu diperlukan dan mengapa itu penting. Mungkin nanti akan ada LLM yang bisa menghubungkan token dengan spesifikasi formal lalu menulis pembuktiannya, tetapi kode aneh yang lahir dari bagian prompt yang informal akan tetap muncul
      Ini tidak bisa dicegah hanya dengan menambahkan batasan dan prompt ke daftar teknis atau spesifikasi. Anda bisa membuat jebakan yang lebih baik, tetapi makhluknya tetap lolos
      Masalahnya adalah pembengkakan kode: menambah kode demi memuaskan prompt atau tugas. Sering kali kode yang lebih sedikit justru lebih baik, dan dibutuhkan orang yang bisa memprediksi apa yang diinginkan dan diharapkan orang lain. Generator itu bagus, tetapi harus dipakai dengan lebih terkendali, bukan seperti selang pemadam
  • Dulu saat Copilot mengisi otomatis satu baris, orang berkata “tetap saja kamu yang harus menulis seluruh fungsi”, lalu saat fungsi lengkap mereka berkata “logika di sekitar fungsi itu tetap harus kamu tulis”, lalu setelah logika itu selesai mereka berkata “fiturnya tetap harus kamu tulis”
    Sekarang setelah fitur pun bisa selesai, mereka berkata “tetap saja arsitekturnya harus kamu yang tulis”. Saya tidak tahu apakah model ini bisa menyelesaikan arsitektur, tetapi menarik melihat ekspektasinya terus bergeser

    • “Orang-orang” hipotetis itu memang salah sejak awal
      Baik AI menyelesaikan satu baris, satu fungsi, satu fitur, atau satu tiket, kita tetap harus membaca dan memahami kodenya
    • Model juga bisa mengerjakan arsitektur, tetapi saat ini biasanya sangat buruk kecuali diarahkan sangat kuat
      Saya memakai AI terus-menerus dan memang makin membaik, tetapi saya tetap mereview setiap baris. Bahkan di level baris pun, sulit dibilang lebih baik daripada tab autocomplete tahun lalu; kadang sangat bagus, kadang sangat buruk
    • Menurut saya solusinya ada di baris-baris tak tertulis dari artikel itu
      LLM sangat bagus untuk pengembangan perangkat lunak, tetapi hanya jika tidak dibiarkan menulis arsitektur. Modul, struct, enum dibuat sendiri, dan sebisa mungkin field serta variannya juga ditambahkan sendiri
      Beri komentar dokumentasi pada setiap struct, enum, field, dan modul, lalu arahkan LLM ke modul dan struktur data itu agar ia mengisi isi fungsi yang dibutuhkan dan semacamnya
    • Saya rasa bahasa saat ini kurang skalabel karena codebase-nya rumit secara global dan invarian yang diinginkan tidak terlihat jelas
      Walau sudah berkali-kali bilang “jangan pernah blocking di jalur kritis”, LLM tetap memasukkan blocking ke jalur kritis; walau dibilang “kalau melakukan X maka perlu tes tipe Y”, ia melakukan X tetapi lupa tesnya
      Manusia juga tidak selalu mengikuti instruksi 100%, tetapi LLM lebih acak. Kesalahan manusia relatif lebih jarang berupa melakukan kebalikan persis dari yang diinginkan
      LLM bisa melihat invarian penting dalam kode lalu membuat jalan memutar, menulis tes yang membuat kegagalan tampak seperti keberhasilan, mengatakan sudah melakukan sesuai permintaan, lalu menguburnya di dalam commit 5 ribu baris
      Saya yakin LLM hebat dan merupakan masa depan, dan karena itu saya membuat bahasa https://GitHub.com/Cuzzo/clear untuk mereka. Kita harus melampaui masalah bahasa yang menuntut konteks global di tempat-tempat yang seharusnya tidak membutuhkannya agar lebih mudah bekerja bersama mereka
      Ada keberhasilan juga, tetapi kadang begitu membuat frustrasi sampai saya bertanya-tanya apakah waras saya layak dikorbankan untuk ini
    • Saya menyebut ini arsitektur sekali pakai
      Bukan berarti arsitektur tidak penting, tetapi arsitektur yang cocok kemarin belum tentu masih cocok hari ini
  • Saat memakai agen coding, saya menetapkan beberapa aturan
    Pertama, jika saya membiarkan agen menghasilkan kode, itu haruslah sesuatu yang saya benar-benar yakin bisa saya tulis sendiri dengan benar jika diberi waktu
    Kedua, kalau tidak, saya tidak lanjut sampai saya memahami sepenuhnya hasil generasinya dan bisa mereproduksinya sendiri
    Ketiga, jika saya melanggar aturan kedua, saya mungkin menciptakan utang kognitif, tetapi saya harus melunasinya penuh sebelum menyatakan proyek selesai
    Makin besar utangnya, makin besar kemungkinan kualitas kode generasi berikutnya turun, dan rasanya seperti berbunga majemuk. Untuk proyek pribadi, cara ini menyenangkan, banyak mengajarkan saya, dan menyisakan codebase yang bisa saya pahami dengan nyaman

    • Ini aturan yang masuk akal untuk menjaga model mental yang kokoh soal kewarasan kode dan pertumbuhan codebase, tetapi sulit dipatuhi di tempat kerja yang setelah AI ekspektasi kecepatan deadline-nya berubah besar
      Harus ada titik keseimbangan agar tetap terhubung dengan keadaan codebase tanpa menjadi bottleneck tim
    • Saya pernah mencoba mengikuti aturan serupa lalu menghadapi soal matematika yang sulit
      Claude adalah matematikawan tingkat doktor dan saya bukan, tetapi saya tahu persis sifat solusi yang saya inginkan serta cara menguji kebenarannya. Jadi saya mempertahankan solusi Claude alih-alih solusi saya yang sederhana dan naif, menuliskan fakta itu di pull request, dan semua orang menilai itu keputusan yang benar
      Saya penasaran apakah kasus seperti ini layak jadi pengecualian. Jika AI nantinya jauh lebih baik daripada saya bukan hanya dalam matematika tingkat tinggi tetapi juga coding, pertanyaan yang lebih menarik adalah apakah saya akan berhenti total menulis kode sendiri, dengan asumsi saya tetap bisa menilai tesnya walaupun kemampuan menilai kode langsung memudar
    • Saya lebih suka istilah utang pemahaman daripada “utang kognitif”
      Karena utang yang menumpuk itu tepatnya adalah kurangnya pemahaman terhadap kode, jadi istilah itu lebih presisi
    • Untuk proyek pribadi, yang penting adalah cara yang lebih menyenangkan, jadi tidak masalah, tetapi dalam pekerjaan kita juga tidak memahami secara mendalam setiap lapisan mulai dari dependensi, pekerjaan rekan, layanan eksternal, sampai silikon
      Saya tidak tahu kenapa AI tiba-tiba harus diperlakukan berbeda
      Pada akhirnya semuanya harus dinilai lewat risiko dan imbalan. Harus dipertimbangkan kerugiannya kalau salah, seberapa mungkin terdeteksi lewat tes dan review, serta apa keuntungannya jika berhasil. Hal yang sama berlaku untuk library dan layanan eksternal
      Aturan finansial rumit dalam kontrak kripto yang tidak bisa diperbarui dan tanpa tes jelas tidak punya risiko yang sama dengan viewer untuk memvisualisasikan data log internal
    • Saya mengambil pendekatan serupa, tetapi pada akhirnya menurut saya realistisnya sangat sulit mematuhi aturan kedua dengan cukup baik
      Secara teori terdengar bagus, tetapi dalam praktik kita akan selalu mengambil jalan pintas mental tanpa sadar
      Saat memperbaiki masalah di codebase yang asing, jika dibandingkan antara ketika saya melakukannya sendiri dan ketika saya merasa telah “sepenuhnya memahami” apa yang dilakukan agen, jumlah yang tersisa di kepala seminggu kemudian berbeda. Kalau dikerjakan sendiri, itu menjadi pengetahuan umum dan bagian pentingnya biasanya tertinggal; tetapi kalau saya mencoba menganggap hasil kerja agen itu sebagai milik saya, saat itu terasa seperti paham namun sangat cepat terlupakan
      Karena itu saya menyimpulkan bahwa bantuan LLM dalam kasus seperti ini kebanyakan justru merugikan tujuan saya, bahkan tanpa mempertimbangkan kekhawatiran lain seperti waktu dan tekanan bisnis
  • Saya juga mengalami hal yang sama
    Penipuannya berjalan seperti ini. Pada codebase yang bagus, AI bisa membuat banyak fitur, dan tampak lebih cepat, lebih aman, bahkan lebih akurat. Terutama di area yang kurang kita pahami, kesannya makin begitu
    Seiring waktu codebase membesar, waktu untuk menelusuri makin panjang, dan tingkat kegagalan naik. Karena enggan mengakuinya, kita malah memaksa lebih keras, lalu baru berhenti ketika perubahan praktis sudah mustahil
    Saat melihat lagi kodenya, kata spaghetti saja tidak cukup; kondisinya seperti Tembok Besar China
    Pada akhirnya saya menghapus 75 ribu dari 140 ribu baris, dan merasa 3 bulan tenggelam dalam agentic coding itu terbuang sia-sia. Saya membuat fitur yang tak berguna, menambah bug, kehilangan model mental atas kode, melewatkan keputusan sulit yang hanya terlihat saat benar-benar berada di dalam kode, dan pada akhirnya juga gagal untuk pengguna

    • Menarik bahwa hasil seperti ini dianggap mengejutkan
      Bukan ingin menyindir, saya sungguh penasaran apa ekspektasi awalnya dan dari mana asalnya
      LLM tampaknya diberi ekspektasi berbeda. Kalau Anda menyerahkan deskripsi fitur ringkas kepada “developer” acak yang hanya pernah ditemui online lalu menerima tumpukan implementasi setengah rusak, tidak ada yang akan kaget
      Namun kadang orang berharap mukjizat dari mesin yang juga suka berhalusinasi panjang lebar, sesuatu yang bahkan tidak mereka harapkan dari manusia. Saya penasaran dari mana datangnya kepercayaan itu
    • Menurut saya codebase besar seharusnya adalah kumpulan codebase kecil
      Seperti kota besar yang merupakan kumpulan kota-kota kecil, ada peta, dan kita bisa memperbesar ke area lokal lalu bekerja dalam cakupan itu. Anda tidak perlu tahu semua detail New York hanya untuk minum secangkir kopi
      Membangun arsitektur yang sehat dan mudah dirawat adalah tanggung jawab orang yang memakai alat. AI tidak menghalangi itu, dan kalau dipakai dengan benar justru bisa membantu
    • Sepertinya ada solusi alur kerja selain membuang AI
      Misalnya dengan langsung memperlakukan kode hasil AI sebagai legacy code, memberi batas enkapsulasi yang kuat dan interface yang didefinisikan dengan baik, lalu mengintegrasikannya dalam alur kerja yang lebih manual
      Ada spektrum mulai dari prompt sekali jalan sampai generasi kode inline, dan cara yang tepat berbeda tergantung masalah serta posisi di codebase
      Generasi sekali jalan lebih cocok di tahap prototipe saat spesifikasi masih sering diulang, lalu setelah prototipe mantap turun ke generasi tingkat modul atau file agar lebih sistematis, sambil terus menjaga model mental yang layak di level itu
    • Saya penasaran apakah kode generatif itu benar-benar tidak dibaca dan semuanya di-auto-commit
      Kalau dibaca tetapi tidak dipahami, mestinya bisa meminta komentar terperinci pada tiap output; dan kalau tahu model makin kesulitan saat codebase membesar, maka makin tinggi kompleksitasnya justru output harus ditinjau lebih ketat
    • Saya belum pernah menangani codebase besar, tetapi mungkin alur kerja ala Working Effectively with Legacy Code bisa diterapkan
      Caranya dengan membuat pulau-pulau kode berkualitas lebih tinggi, memakai AI untuk membantu merekonstruksi maksud developer dan aturan bisnis, lalu membuat seam dan unit test pada modul target
      AI tidak harus selalu dipakai untuk menaikkan throughput; ia juga bisa menjadi alat eksplorasi dan refactoring yang fleksibel untuk membantu hand-coding atau implementasi agen di tahap berikutnya
  • Setiap kali melihat tulisan seperti ini saya jadi membandingkan kecepatan yang katanya didapat orang dari AI dengan kecepatan yang saya dapat hanya dengan coding manual
    Kebetulan saya sudah 7 bulan mengerjakan proyek 3D MMO, dan saat ini sudah bisa dimainkan, orang-orang juga merasa seru, grafiknya lumayan, dan ratusan orang bisa masuk ke server dengan mudah. Arsitekturnya juga cukup bagus sehingga fitur mudah diperluas, dan saya rasa setelah sekitar 1 tahun pengembangan proyeknya bisa dirilis
    Sementara penulis asli selama 7 bulan vibe coding bahkan belum bisa membuat TUI dasar. Kecepatan fitur mungkin terasa tinggi, tetapi untuk membuat UI dasar seperti itu kecepatannya sulit dipercaya lambatnya. Ada banyak library TUI yang bagus, dan ini jenis hal yang cukup dibuat manual dalam beberapa minggu dengan mengisi tabel dari data yang diperlukan
    Saat memakai AI memang kuat sekali rasanya seperti maju cepat dalam jumlah besar, tetapi kenyataannya tampaknya sering jauh lebih lambat daripada coding manual. Data produktivitas juga sepertinya mendukung bahwa pengguna AI merasa lebih cepat tetapi output nyata mereka lebih sedikit

    • Metrik ini sangat bergantung pada siapa yang memakai AI dan untuk apa
      Penyedot waktu terbesar dalam kerja pengembangan perangkat lunak adalah rapat untuk menyelaraskan ekspektasi stakeholder dan solusi. Dari sudut pandang itu AI hampir tidak membantu, jadi kalau Anda membandingkan jam kerja dari usulan sampai masuk loop tes, hasilnya memang akan mengecewakan
      Tetapi untuk pemecahan masalah, perbaikan bug, dan implementasi solusi yang sudah disetujui, rasanya sekarang setidaknya 10 kali lebih baik daripada dulu. Bukan hanya dari sisi waktu mentah, tetapi juga dalam kemampuan menafsirkan perilaku yang diamati dan menyelidiki masalah
      Namun memang ada orang yang tidak bisa menghasilkan output AI yang akurat dan bernilai. Kalau Anda tahu persis apa yang diinginkan dan bagaimana menginginkannya, AI sangat membantu. Kalau saya menyuruhnya melakukan hal yang memang sudah akan saya lakukan, ia mengerjakannya lebih cepat. Tetapi kalau saya sendiri tidak tahu persis apa yang saya mau, AI justru merusak progres
    • Saya juga baru sampai pada kesimpulan yang sama
      Alasan karya buatan LLM yang ditunjukkan orang-orang tidak terlalu mengesankan adalah karena kebanyakan adalah hal-hal yang sebenarnya juga bisa dibuat manual dalam waktu sangat singkat
      Saya juga tidak melihat ledakan perangkat lunak yang benar-benar mengesankan, dan itu tampaknya selaras dengan fakta bahwa LLM saat ini dipakai untuk menyelesaikan masalah yang sederhana, bukan yang penting
    • Kemungkinan orang yang merasa mendapat manfaat terbesar dari LLM adalah mereka yang sejak awal tidak tahu cara membuat perangkat lunak yang baik, atau tidak cukup mampu melakukannya
    • Saya juga merasa aneh dengan angka 7 bulan itu. Bahkan kalau ditulis dalam bahasa baru pun rasanya tidak akan selama itu
      Hal lain yang kurang dibahas adalah kualitas kode
      Codebase hasil vibe coding adalah contoh bagus bahwa LLM tidak terlalu unggul dalam menulis kode. Ia memperbaiki kesalahannya sendiri lalu langsung membuatnya lagi, dan pemakaian polanya juga tidak konsisten
      Belakangan Claude juga kadang memilih gaya kode yang “menarik” tetapi tidak cocok dengan gaya codebase saat ini
    • Keluarga GPT dibangun untuk menghasilkan teks, yakni bahasa dan kode; itulah tujuan dan nyawanya, jadi secara internal tampaknya condong ke arah membuat semuanya sendiri secara langsung
      Pengulangan seperti itu harus dicegah dengan bahasa ala “senior developer”
  • Bagian “sebelum menulis kode saya merancang sendiri interface konkret, jenis pesan, dan aturan ownership” itulah justru bagian sulit dari coding
    Kalau arsitekturnya sudah ada, menulis kode jadi sangat mudah. Kalau Anda tidak menulis kodenya sendiri, akan lebih sulit menyadari bahwa Anda telah merancang API yang mengizinkan null padahal database tidak mengizinkannya, atau kalaupun mengizinkannya, Anda melewatkan masalah kecil lain
    Saya tidak paham bagaimana setelah menulis artikel itu ia masih belum sadar bahwa masalahnya adalah AI. Bukan hanya karena ia menyerahkan arsitektur ke AI, tetapi juga karena ia tidak mengawasi dengan cermat semua hal yang dilakukan AI
    AI adalah generator kode yang dipoles, dan semua yang dikerjakannya harus diperiksa. Bagian sulit dari rekayasa perangkat lunak bukanlah menulis kode, melainkan semua hal lain di sekitarnya

    • Menurut saya ada dua jenis developer: yang menganggap kode adalah bagian sulit, dan yang tidak
      Developer yang menganggap coding itu sulit benar-benar menyukai AI coding, karena hal yang tadinya sulit kini menjadi mudah
      Sebaliknya, bagi orang yang menganggap coding itu mudah, coding adalah masalah abstraksi, maintainability, dan skalabilitas. Yang sulit adalah meletakkan fondasi yang masuk akal agar perangkat lunak bisa tumbuh, dan begitu abstraksi yang tepat ditemukan, sisanya relatif mudah
      Bagi orang seperti ini AI coding adalah alat yang berguna, tetapi bukan alat ajaib. Penulis asli menyadari keterbatasan AI, jadi ia termasuk kelompok kedua dan telah melihat bagian sulit yang tidak bisa dilakukan AI
    • Saat ini ada masalah definisi yang membingungkan
      Di satu sisi ada orang yang memakai tab autocomplete yang kuat atau chatbot di jendela samping sambil tetap mereview semuanya dengan jelas, dan di sisi lain ada editor baru yang dipromosikan Steve Yegge dengan koordinasi puluhan agen seolah sebagian besar kodenya tidak akan dibaca: https://steve-yegge.medium.com/welcome-to-gas-town-4f25ee16d...
      Kelompok pertama masih memikirkan desain, interface, dan struktur data secara mendalam serta melakukan review ketat. Kelompok kedua lebih mengkhawatirkan karena tidak begitu
    • Menurut saya agen hampir selalu gagal di antara perencanaan dan eksekusi
      Mereka mengikuti pendekatan plan → red/green/refactor, dan rencananya sendiri tampak cukup meyakinkan serta berlandaskan karena menyerap habis dokumentasi dan diskusi forum
      Masalahnya adalah begitu mulai bekerja, pasti muncul titik-titik di mana dokumentasi dan implementasi ternyata berbeda. Mungkin kombinasi alat itu belum pernah dipakai dengan cara tersebut, mungkin dokumentasinya usang, atau mungkin memang bug
      Meski begitu, kalau tujuan proyek atau fiturnya cukup jelas dan bisa dijalankan serta dites secara lokal, agen bisa berputar-putar di jalan buntu arsitektur lalu akhirnya keluar. Mereka bahkan melihat dependensi dan kode library serta mengusulkan perbaikan upstream, mirip dengan yang saya lakukan dalam sesi debugging mendalam
      Karena itu saya cukup puas dengan cara kerja memerintah dan mengawasi daripada mengerjakan tugas membosankan sendiri. Hanya saja banyak rekan tim saya secara default tidak menggali masalah arsitektur sedalam ini dan lebih memilih “eskalasi ke arsitek”, yang menurut saya dalam jangka panjang tidak baik
      Jendela di mana seseorang masih bisa menjalankan dan memahami semuanya tampaknya menutup dengan cepat. Namun mungkin kita akan beradaptasi dengan membuat alat dan framework baru, seperti halnya kita tetap memakai compiler tanpa sepenuhnya memahami bagaimana ia mengubah kode menjadi machine code, atau tanpa sepenuhnya memahami branch prediction dan caching pada CPU modern
    • Banyak orang tampaknya melewatkan fakta bahwa semua yang dilakukan AI harus diperiksa
      Dari sudut pandang orang yang belum terlalu berpengalaman dengan kode, saya justru belajar lebih banyak daripada sebelumnya dengan memeriksa hasilnya dan melihat mana yang benar dan salah
      Karena itu saya juga tidak merasa ini akan segera membaik drastis. Saat orang bertanya “bagaimana output Claude bisa sebagus itu”, jawaban saya selalu “saya mengawasinya dengan cermat, menemukan masalah, lalu menyuruh Claude memperbaikinya”. Itu benar-benar semuanya, tetapi begitu mendengar itu pandangan mata mereka sudah mulai kosong
      Ini seperti Google yang memudahkan pencarian informasi, tetapi tidak menghapus peran manusia dalam membedakan informasi yang baik dan buruk
    • Satu-satunya cara agar saya tidak benar-benar membenci atau gagal total saat memakai agen adalah metode ini
      Pikirkan dulu masalahnya, rancang struktur dan API-nya, baru setelah itu serahkan implementasinya ke AI
  • Judulnya memang “kembali menulis kode dengan tangan”, tetapi yang sebenarnya dilakukan adalah mengerjakan desain dengan tangan sebelum kodenya ditulis
    Setelah itu kodenya tampaknya tetap dihasilkan oleh Claude
    Yang lebih serius lagi, sulit dipahami bahwa selama 7 bulan ia mengira proyek vibe coding itu berjalan baik tanpa melihat source code yang dihasilkan, dan bahkan sudah membeli domain untuknya

    • Singkatnya, ini judul clickbait, dan tujuan artikelnya tampaknya untuk menarik perhatian ke proyeknya sendiri
    • Saya juga pernah membeli domain proyek hanya beberapa menit setelah dapat ide
      Kalau ini side project dan Anda memeriksa perubahan secara bertahap dengan mengikuti diff, tidak mendalami kodenya juga tidak terlalu aneh. Memang gaya kerja yang berbeda, tetapi belum sampai tingkat gila
  • Rasanya seperti melihat para developer melakukan speedrun terhadap pelajaran manajemen proyek dan manajemen produk
    Sekarang mereka mulai melihat bahwa spesifikasi itu berguna, dan membuat banyak kode yang salah tidak otomatis mempercepat proyek. Developer sering kesal karena rapat dan diskusi dianggap mengganggu waktu menulis kode, padahal proses itu sering ada justru untuk mencegah semua orang menulis lebih banyak hal yang salah
    Mereka juga mulai sadar bahwa manajemen pekerjaan itu berguna, dan sekarang dengan makin seringnya pembicaraan bahwa semua desain harus dilakukan di awal, arahnya malah menuju waterfall
    Berikutnya orang akan memberi nama pada prototyping, lalu muncul pembicaraan tentang fitur inkremental yang mengelola requirement lama dan baru sekaligus, dan akhirnya akan ada yang bilang pelanggan harus lebih terlibat
    Perlu dilihat apa sebenarnya yang dilakukan project manager dan product manager. Mereka memimpin produk berupa kode, tetapi tidak diharapkan membaca kodenya, dan harus mencapai itu hanya lewat bahasa alami

    • Benar sekali. Orang-orang ini tampaknya belum pernah jadi manajer
      Memangnya mereka pikir manusia tidak menulis hal yang rusak? Tidak pernah ada tim yang salah arah lalu membakar seminggu atau bahkan berbulan-bulan kerja? Sekarang dengan vibe coding Anda bisa mengalami semuanya dalam 30 menit. Sebagai mantan technical product manager, rasanya persis sama
  • Sebenarnya sepertinya bukan kembali menulis kode dengan tangan, jadi jarak antara judul dan kesimpulannya membingungkan

    • Menurut saya tujuannya memang memasang judul sensasional agar HN terpancing dan naik ke halaman depan
    • Tulisannya sendiri juga tampaknya tidak ditulis dengan tangan. Yang naik ke puncak HN itu bukan tulisannya, melainkan judulnya