- Agen coding LLM masih belum dapat melakukan pemindahan kode seperti copy-paste secara alami
- Saat refaktorisasi kode, sulit menjamin konsistensi karena cara penulisan kode yang bergantung pada ingatan
- Dalam proses pemecahan masalah, hampir tidak pernah mengajukan pertanyaan dan konsisten melakukan percobaan berbasis tebakan
- Developer manusia akan memperjelas masalah lewat pertanyaan saat situasinya ambigu, tetapi LLM terus mengulang percobaan sampai menabrak tembok
- Karena sifat ini, agen LLM dipandang bukan sebagai pengganti developer manusia, melainkan setingkat intern yang hanya terlalu percaya diri
Keterbatasan utama agen coding LLM
Belakangan ini ada banyak upaya memanfaatkan LLM sebagai alat bantu coding, tetapi masih ada hal-hal yang terasa janggal bagi developer manusia. Tulisan ini menjelaskan dengan jelas dua alasan yang terutama menimbulkan ketidaknyamanan pada agen coding LLM
1. Kejanggalan dalam cara memindahkan dan merefaktorisasi kode
- LLM tidak benar-benar melakukan aksi 'copy-paste'
- Misalnya, saat diminta merefaktorisasi file besar menjadi file-file kecil, LLM akan 'mengingat' sebagian blok kode, lalu menggunakan perintah
deletepada file asli sambil menulis kode yang 'diingat' itu ke file baru dengan perintahwrite - Tanpa memanfaatkan alat seperti 'cut' atau 'paste', semua perubahan direkonstruksi dari memori
- Saat memindahkan kode, developer manusia mendapat keyakinan akan kecocokan kode melalui 'copy-paste', tetapi LLM tidak dapat menjaminnya
- Sejauh ini hanya Codex yang kadang memperlihatkan upaya meniru perilaku 'copy-paste' manusia dengan menggunakan perintah
sedatauawk, tetapi itu pun belum sempurna
- Misalnya, saat diminta merefaktorisasi file besar menjadi file-file kecil, LLM akan 'mengingat' sebagian blok kode, lalu menggunakan perintah
2. Pendekatan pemecahan masalah tanpa pertanyaan
- Proses pemecahan masalah LLM juga sangat berbeda dari manusia
- LLM hampir tidak pernah bertanya, dan mencoba menyelesaikan masalah berdasarkan banyak asumsi
- Developer manusia dalam perubahan besar atau situasi yang tidak jelas akan selalu memastikan keadaan lewat pertanyaan, dengan bertindak di bawah prinsip bahwa 'tidak ada pertanyaan yang buruk'
- Sebaliknya, LLM cenderung terus mengulang percobaan, lalu mengulangnya lebih keras ketika muncul masalah
- Prompt memang bisa dirancang secara berlebihan untuk mendorong pertanyaan, tetapi selain beberapa alat seperti Roo, perilaku seperti ini jarang benar-benar muncul
- Pada dasarnya, ini mungkin karena perusahaan pengembang LLM menerapkan RL (reinforcement learning) yang berfokus pada 'menulis kode lebih cepat'
Kesimpulan
- Karena karakteristik ini, LLM masih belum cukup untuk menggantikan developer manusia
- Dalam pekerjaan nyata, kemampuannya lebih mirip 'intern yang terlalu percaya diri'
- Inilah alasan pengalaman kolaborasi dengan LLM belum terasa sepenuhnya alami
1 komentar
Opini Hacker News
Belum lama ini saya mengalami pengalaman yang menarik. Memang bukan soal kode, tetapi ini sangat mungkin terjadi juga pada kode atau ranah terkait (dan memang terjadi juga pada rekan kerja saya). Saat berdiskusi di HN tentang kenapa sebuah regulasi yang lolos 15 tahun lalu tidak digeneralisasi lebih luas, saya menduga bahwa tingkat teknologi saat itu belum cukup untuk menangani kasus umum, jadi regulasinya hanya diterapkan pada bagian yang saat itu memungkinkan (komentar terkait). Beberapa jam kemudian saya mengecek diskusinya lagi, dan beberapa orang mengatakan bahwa bahkan pada masa itu teknologinya sudah cukup murah. Jadi saya meminta LLM mencari dasar untuk topik ini, dan saya mendapat jawaban bahwa penyebabnya adalah keterbatasan teknis. Saya lalu memeriksa materi yang dikutip untuk memverifikasi sumbernya, dan ternyata hanya ada satu sumber yang benar-benar membahas keterbatasan teknis, dan sumber itu adalah komentar saya sendiri di HN. Ketika saya menceritakan hal ini di kantor, seorang rekan mengatakan bahwa ia pernah meninggalkan opini di GitHub tentang "bagaimana X bekerja di Windows", lalu ketika ia mencarinya di Google kemudian, jawaban berbasis LLM justru menggunakan opininya itu sebagai dasar untuk mengklaim hal yang sama. Karena itu saya jadi ingin meminta LLM bukan "bagaimana X bekerja?", melainkan "kalau seseorang bertanya bagaimana X bekerja, tolong tampilkan daftar tautan yang layak dikutip"
Saya rasa cara bertanya seperti ini mirip dengan "sorting prompt". Ini teknik yang saya pelajari dari tulisan Mike Caulfield, dan saya juga memakainya saat menulis kode (misalnya: Claude code slash command). Alih-alih hanya menyuruh LLM menjawab, kalau kita menugaskannya melakukan riset lalu mengelompokkan dan mengevaluasi materi, hasilnya bisa jauh lebih akurat
Kebanyakan orang juga cenderung mempercayai komentar di HN tentang topik tertentu dengan pola pikir seperti, "orang ini kelihatannya paham, jadi anggap saja ini fakta dulu". Karena mendapatkan pengalaman langsung atau pengetahuan yang benar-benar tervalidasi sebenarnya sangat mahal, saya pikir 'pengetahuan murah' seperti ini pada akhirnya tetap punya nilai
Saya pernah mencoba meminta dasar atau bukti dari LLM, tetapi sampai sekarang belum pernah sekali pun LLM benar-benar memberi dasar yang nyata untuk mendukung apa yang ia katakan
LLM kadang bahkan memalsukan tautan. Diperlukan mode riset mendalam agar benar-benar melakukan penelitian yang nyata, dan bahkan begitu pun cara ia menafsirkan informasi di dalam tautan pada akhirnya tetap dipengaruhi oleh pelatihannya
Baru-baru ini saya memasukkan 6~8 sumber tepercaya ke NotebookLM (spesifikasi IETF, OpenID, dan dokumen tambahan), lalu menanyakan pertanyaan yang sangat sederhana: "format credential apa yang diizinkan oleh OID4VP?". Sekitar 90% jawabannya benar, tetapi ia dengan sangat percaya diri menambahkan format acak yang sama sekali tidak punya dasar nyata (seolah-olah dia penulis spesifikasinya). Saya curiga, lalu memeriksa spesifikasinya sendiri, dan langsung tahu itu bohong. Bahkan untuk LLM yang katanya "grounded", kepercayaan saya terhadap fakta kini bisa dibilang runtuh total
Baru-baru ini saya menyuruh Codex CLI me-refactor file HTML, tetapi alih-alih copy-paste kode seperti yang saya harapkan, LLM menggantinya dengan kode baru yang ditulis ulang dari ingatan, dan komentar-komentarnya juga hilang. Ada bagian dengan 40 tautan kompleks berurutan, dan saat pengecekan terakhir sebelum deploy saya klik satu per satu; bagian awal normal, tetapi mulai di tengah ada 31 tautan yang semuanya menghasilkan 404. Domain-nya tidak bermasalah, tetapi jalur URL-nya berubah bentuk. Ketika saya cek URL lama di git commit, ternyata LLM telah "berhalusinasi" dan mengganti URL itu ke path yang sebenarnya tidak ada. Error yang halus dan diam-diam seperti ini benar-benar berbahaya. Harus sangat hati-hati
Saya rasa poin terakhir ini sangat penting. Karena "kesalahan yang sangat halus dan diam-diam masuk", walaupun LLM bisa bekerja sebaik manusia atau bahkan lebih baik, itu tidak berarti hasilnya dapat diperlakukan dengan cara yang sama. Terutama karena code review secara tradisional adalah lapisan penting untuk mencegah masalah, dan bila jenis error yang harus diperiksa berubah, cara code review lama menjadi tidak efisien. Dulu saat ada pemindahan kode dalam jumlah besar, kita bisa berasumsi bloknya dipindahkan apa adanya lalu lebih fokus ke level tinggi, tetapi dalam refactor oleh LLM, kode yang "dipindahkan" itu bisa jadi sebenarnya adalah kode "baru" yang diringkas atau disusun ulang, jadi kita harus membaca setiap karakter. Karena itu saya pikir ada baiknya menambahkan bagian "penggunaan AI" di deskripsi Pull Request agar ada petunjuk tentang di mana dan bagaimana AI digunakan, sehingga reviewer bisa tahu area mana yang perlu dicek lebih ketat
Saya juga cukup sering mengalami hal serupa saat melempar pertanyaan soal kode atau riset. LLM awalnya bekerja baik, tetapi setelah pertanyaan ke-N, ia mulai mengarang sesuka hati. Baru-baru ini sebelum bepergian saya meminta Gemini daftar pabrik bir dengan informasi terbaru, tetapi ia dengan santai memasukkan tempat yang sudah tutup atau hanya sempat beroperasi sementara. Saat saya minta tambahkan tautan jam operasional dan hapus tempat yang sudah tutup, ia hanya menerapkan perubahan di awal daftar, sedangkan bagian belakang malah diubah secara tidak relevan atau sama sekali tidak menghapus tempat yang tutup. Namun setiap kali ia tetap menjawab dengan penuh percaya diri bahwa semuanya sudah diteliti dengan sempurna
Ini memang bukan soal kode, tetapi pernah sekali saya meminta LLM hanya memeriksa ejaan/tata bahasa pada pengumuman acara. LLM mengirimkan versi yang sedikit diperbaiki, tetapi diam-diam menggeser tanggalnya satu hari. Untung saya sadar dan memperbaikinya, tetapi saya jadi belajar bahwa bahkan untuk tugas yang sangat sederhana pun kita tidak boleh percaya buta. Sekalipun prompt-nya hanya satu kalimat yang mudah dan jelas, LLM kadang melakukan hal yang menakjubkan, tetapi terkadang juga salah secara tak terduga bahkan pada hal yang paling sederhana
Lima menit lalu saya juga meminta Claude hanya menambahkan pernyataan debug ke kode, tetapi ia diam-diam mengubah regex. Di diff ini mudah ketahuan, tetapi pada perubahan besar hal seperti ini benar-benar mudah terlewat
Mengecek ulang semua 40 tautan tepat sebelum deploy adalah keputusan yang bijak. Tapi saya agak terkejut kamu langsung mendorongnya ke master setelah Codex selesai tanpa
git diffSaya setuju dengan klaim tulisan itu. Namun menurut saya masalah terbesar adalah agen hanya melihat sebagian sangat kecil dari repositori kode. Ia tidak tahu helper function yang sudah ada dan terus membuat ulang hal yang sama. Dalam pengembangan UI, ia tidak bisa membandingkan struktur UI secara menyeluruh, jadi kode yang tidak konsisten terus berulang. Pada akhirnya manusia harus memberikan konteks yang tepat seperti "lihat helper function di file ini", "lakukan seperti implementasi ini", "pastikan baca dokumen ini". Kalau konteks yang tepat diberikan secara langsung, kegunaan agen bisa meningkat besar. Sebagai catatan, masalah lain adalah ia buruk dalam menelusuri struktur folder di monorepo besar, jadi misalnya menjalankan
npm testdari subdirektori saja sering kali benar-benar gagalIni persis sama dengan masalah yang saya alami. Baru-baru ini saya mereview sekitar 200 baris kode fitur baru yang dibuat dengan Cursor, dan ternyata kode yang benar-benar dibutuhkan hanya sedikit. Mencari fungsi yang sebenarnya sudah ada di utility library benar-benar merepotkan, jadi sering dilewatkan begitu saja. Lima tahun lalu review seperti ini lebih terasa sebagai bagian dari onboarding junior sehingga penting untuk menunjukkan hal-hal itu, tetapi sekarang, dengan Cursor dan sejenisnya, jumlah kode hanya makin banyak, sementara developernya sendiri sebenarnya paham strukturnya namun kadang sengaja membuat seperti itu karena kebijakan perusahaan, sehingga saya merasa produktivitas justru menurun
Menjalankan perintah seperti
npm testdari subfolder memang selalu jadi masalah. Di repo yang terbagi antara frontend Vite/React dan backend .NET, kalau perintah npm gagal, ia panik dan terus mengulang tanpa bisa menyelesaikannya, sehingga hanya mengulang troubleshooting yang tidak perlu. Pernah saya tulis instruksi diCLAUDE.mdagar selalu mengecek direktori saat ini terlebih dahulu, tetapi masalah lupa path secara acak tetap ada. Jadi saya menambahkan alias sepertirun-dev server restart,run-dev client npm installyang bisa dipakai dari direktori mana pun, lalu memasukkan perintah dotnet/npm murni ke daftar terlarang agar AI dipaksa membaca dokumentasi proyek dan memakai alias tersebut. Cara ini lumayan stabil, tetapi untuk sampai ke titik itu dibutuhkan cukup banyak waktu, usaha, dan stresSaya juga berpikir akan bagus jika model konteks besar dimanfaatkan lewat tool call. Gemini chat punya kemampuan meng-ingest seluruh repo GitHub. Bagaimana kalau ada tool 'not-invented-here' yang sebelum menulis fungsi baru akan memeriksa apakah hal yang sama sudah ada di codebase? Tentu saja, pertama-tama saya perlu mencari tahu apakah seseorang sudah membuat tool seperti itu
Itulah alasan dokumen seperti claude.md diperlukan. Kalau kita ingin aturan internal kita diikuti, dokumentasi itu memang wajib
Sebenarnya situasi seperti ini sangat umum dialami engineer senior saat bekerja dengan rekan di dunia nyata
Saya sangat setuju dengan bagian yang dikutip dalam tulisan itu. Saya setuju bahwa LLM belum bisa menggantikan developer tingkat tinggi. Menurut saya, orang waras tidak akan mengatakan hal seperti itu pada titik ini. Tetapi saya pikir developer berkinerja rendah atau menengah sudah mulai tergantikan. Misalnya, di organisasi kami ada tiga orang lulusan bootcamp 6 bulan yang direkrut karena saat itu sangat sulit mencari developer bagus. Namun pada praktiknya, mereka bahkan kesulitan pada misi yang benar-benar sangat mudah, dan setiap kali saya harus merapikan semua kodenya saat review. Setelah itu alat AI meningkat secara eksponensial dan melampaui performa mereka. Akhirnya dua orang di-PHK, dan satu sisanya resign sendiri. Belakangan ini kami juga hampir tidak merekrut developer junior lagi, dan tidak akan pernah merekrut lulusan bootcamp. Lingkungan sekitar juga mirip, dan mungkin karena itu industri bootcamp sendiri sedang menghilang. Apakah AI nantinya bisa menggantikan developer bagus saya tidak tahu, tetapi kalau melihat data saat ini, jelas perkembangannya sangat cepat. Pendapat yang terlalu negatif berarti menolak realitas. Pada masa awal Amerika, 90% penduduk bekerja di pertanian, tetapi sekarang hanya 2%. Namun hasil dan keragaman produksi pangan justru jauh lebih besar. Semua itu adalah hasil kemajuan teknologi. Saya rasa hal serupa bisa terulang di industri pengembangan perangkat lunak dengan sangat cepat
Memang teknologi meningkatkan jumlah produksi makanan, tetapi faktanya nilai gizinya menurun dan toksisitasnya meningkat
Saya penasaran apa menurutmu penyebab lulusan bootcamp itu tidak bisa berkembang
Pelajaran yang lebih penting adalah bahwa tanpa banyak instruksi dan pengawasan, LLM sangat rapuh bahkan untuk tugas yang cukup sederhana. Di proyek kecil saya (2.5K baris), saya memintanya me-refactor parser, dan rencananya tampak masuk akal. Saya menetapkan checkpoint langkah demi langkah dan menyuruhnya maju secara berurutan, tetapi setiap kali saya bertanya, "struktur lama sudah dihapus?", "sudah diganti dengan struktur baru?", jawabannya selalu kembali menjadi, "tidak, masih tetap ada". 80% test gagal, dan bahkan ketika saya menunjukkan arah perbaikan yang spesifik, ia selalu gagal pada masalah yang sama saat diberi tugas abstrak seperti "refactor". Pada akhirnya saya harus menulis instruksi yang sangat detail sampai tingkat "kelas ini ubah seperti ini". Kalau sudah begini, rasanya tidak bisa dibilang independen, dan makna memakai LLM sendiri jadi berkurang
Pengalaman saya agak berbeda. Parser expression tree berbasis typescript (tinqerjs.org) saya selesaikan dalam 2 minggu (paruh waktu) hanya dengan Codex+Claude, tanpa satu baris pun kode ditulis tangan, dan ratusan test (termasuk duplikasi) juga ditambahkan semuanya. Saya juga pernah membuat ORM, dan dengan LLM setidaknya bisa menghemat waktu 4~10 kali lipat. Hampir tidak perlu pengawasan; pada akhirnya tujuan penggunaan dan apakah prosesnya sudah matang yang menentukan hasil. Developer yang terbiasa memanfaatkan LLM juga sedang membangun workflow khas masing-masing, dan kesamaan mereka adalah semuanya fokus pada test, dokumentasi, dan code review
Masalah "kalau instruksi refactor harus terlalu detail, berarti tidak ada gunanya" sepertinya perlu diubah menjadi pendekatan "kalau saya memecahnya menjadi langkah tingkat tinggi yang baik lalu memberi instruksi, hasilnya jauh lebih cepat daripada saya mengerjakannya sendiri"
Ini lagi-lagi terhubung dengan poin tulisan bahwa 'AI tidak melakukan cut-paste, melainkan menghapus lalu membuat ulang'. Dalam praktiknya, drift kode sedikit demi sedikit memang sulit dihindari
Saya penasaran model/tool apa yang dipakai. Saat saya memakai Cursor atau Copilot pun, saya sering mengalami masalah bahwa refactor kecil seperti ini tetap membutuhkan pengawasan terus-menerus
Jelas ada bagian di mana LLM membantu. Misalnya pagi ini saya memperbaiki bug parser metadata PDF dengan bantuan LLM tanpa harus mendalami spesifikasi PDF secara jauh. Tetapi dalam kebanyakan kasus, hasilnya kurang efisien dibanding saya mengerjakannya sendiri. Dulu saya pernah menyuruh Codex Code menulis unit test; saya sudah menyiapkan banyak setup, tetapi karena mocking data merepotkan saya delegasikan. Saya mencoba sampai 8 kali dan tetap harus memperbaikinya secara manual, dan ia juga tidak memahami bahwa entitas tersebut sudah obsolete dan tidak lagi dipakai di layanan. Hasil akhirnya mengecewakan. Memang belum cukup untuk sepenuhnya menggantikan developer, tetapi seperti Stack Overflow di masa lalu, saya merasa ia sangat bagus untuk membuka akses pengetahuan pada topik yang tidak familiar dan mengarahkan ke solusi
Saya tidak menganggap berlebihan kalau prompt direkayasa agar "mendorong pertanyaan menjadi lebih jelas". Justru merancang prompt dengan prinsip 'kalau tidak jelas, tanyakan dulu' sangat efektif. Programmer yang baik bisa memahami apakah spesifikasi sudah disampaikan sepenuhnya atau masih perlu klarifikasi tambahan, lalu mengarahkan AI agar mengajukan pertanyaan lanjutan yang diperlukan sejak awal
Bahkan jumlah pertanyaannya bisa ditentukan langsung. Untuk topik yang kompleks, saya sering lebih dulu meminta 20~30 pertanyaan, dan hasilnya cukup memuaskan. Menyimpan QnA semacam ini dalam file terpisah lalu memakainya lagi di sesi berikutnya atau dengan agen lain juga berguna
Berkat cara seperti ini, saya tidak lagi menulis prompt seperti dulu. Saya hanya melempar ide lalu menambahkan "kalau perlu, tanyakan", dan biasanya ia justru menangkap poin-poin yang tidak saya pikirkan
Setelah membaca pembahasan tentang copy-paste di tulisan utama, saya terinspirasi dan menambahkan tool agent buffer di clippy (utilitas macOS). clippy memiliki server MCP dan berinteraksi dengan clipboard sistem, tetapi kali ini buffer privat terpisah terasa lebih tepat. Fitur yang ditambahkan adalah buffer_copy (menyalin rentang baris tertentu dari file dan menyimpannya ke buffer privat), buffer_paste (menyisipkan/mengganti byte persis dari buffer ke file target), dan buffer_list (melihat isi buffer). Misalnya, jika agen diberi instruksi "salin baris 50~75 dari auth.py", server hanya melakukan file I/O secara langsung, tanpa generasi token atau halusinasi sama sekali. Clipboard sistem juga tidak terpengaruh. Sebelumnya, kode yang dihasilkan AI pun bisa langsung disalin ke clipboard untuk digunakan. Tujuan utama clippy adalah meningkatkan macOS pbcopy—menyalin isi file yang sebenarnya agar dari terminal bisa menempelkan file itu sendiri ke Slack atau email. Bagi pengguna agen kompatibel MCP seperti Claude di macOS, lihat di sini. Bisa dipasang dengan
brew install neilberkman/clippy/clippyBanyak developer juga sebenarnya tidak pandai bertanya. Mereka cenderung menganggap banyak hal sudah jelas lalu menghilangkannya. Dalam 25 tahun pengalaman pengembangan, lebih dari separuh rekan saya punya kelemahan kedua ini. Saya sendiri juga begitu selama setengah perjalanan karier saya, jadi saya sangat relate
Seperti klaim di tulisan utama bahwa "LLM tidak melakukan copy-paste (atau cut-paste)", ia cenderung mengingat kode, menghapusnya, lalu menulis ulang, sehingga terasa seperti setiap kali hanya mengeluarkan write command baru. Dalam refactor sendiri sebenarnya tidak terlalu banyak copy/paste literal; lebih sering ditangani dengan recall berbasis konteks. Dalam pekerjaan nyata, saya juga tidak yakin perintah copy/paste itu sendiri benar-benar berguna (setidaknya dalam pengujian saya tidak memberi perbedaan besar). Sebaliknya, untuk bagian berulang yang memakan banyak konteks, memakai tool seperti fastmod lalu meminta codex atau claude membantu "ubah bagian ini secara massal" justru lebih efektif. Pendekatan pemecahan masalahnya sendiri memang berbeda dari manusia sehingga terasa canggung, tetapi kalau komunikasi dilakukan dengan perencanaan yang baik, pendekatannya bisa sangat berbeda
IDE bisa langsung mengganti nama atau signature fungsi di banyak file, tetapi ketika agen LLM mencobanya, sering kali butuh beberapa menit dan tetap tidak akurat. Saya rasa manfaat dukungan copy/paste yang nyata itu jelas ada
copy/paste sangat membantu mengurangi ledakan konteks. Karena model tidak perlu mengingat isi blok kode, tetapi bisa mengaksesnya kapan saja saat diperlukan