Debugging dengan AI paling berhasil ketika kamu memberi model apa yang akan kamu berikan kepada rekan kerja di sebelah mejamu: error lengkapnya, kode yang memunculkannya, apa yang kamu harapkan, apa yang terjadi, dan apa yang sudah kamu coret dari daftar kemungkinan. Model tidak bisa menjalankan programmu atau melihat datamu, jadi semua yang diketahuinya tentang bug itu berasal dari apa yang kamu tempel. Satu kebiasaan yang paling berguna adalah meminta penyebabnya sebelum perbaikannya.
Tempel semuanya, bukan hanya error-nya
Dua tab di bawah ini menggambarkan bug yang sama. Sebuah skrip membaca file CSV yang diekspor dari Excel dan crash dengan KeyError: 'email', padahal file itu jelas punya kolom email.
KeyError berarti dictionary-nya tidak punya key bernama 'email'. Kamu bisa menghindari error itu dengan memakai .get(), yang mengembalikan None alih-alih memunculkan error:
email = row.get("email")
Atau cek dulu:
if "email" in row:
email = row["email"]
Balasan pertama benar tentang apa itu KeyError, tapi sarannya justru merugikan di sini. Dengan row.get("email"), crash-nya hilang, dan setiap email menjadi None. Model menjawab versi error yang paling umum karena hanya itu yang digambarkan prompt-nya.
Laporan lengkap berhasil karena dua baris. "Hanya kolom pertama yang gagal" dan "disimpan dari Excel sebagai CSV UTF-8" adalah petunjuk yang mengarah ke byte order mark, dan tidak satu pun ada di pesan error-nya. Kamu jarang tahu detail mana yang menjadi petunjuk, dan itulah kenapa kamu menempel semuanya.
Lima hal yang perlu disertakan
- Error lengkapnya. Seluruh traceback atau output console, bukan parafrasenya. Nomor baris dan rantai pemanggilannya menunjukkan di mana kegagalan dimulai, yang sering kali beberapa frame jauhnya dari tempat error itu muncul.
- Kode yang memunculkannya. Fungsi yang gagal dan kode yang memanggilnya. Kalau error-nya menyebut sebuah baris, pastikan baris itu ada di bagian yang kamu tempel.
- Yang diharapkan dan yang terjadi. Masing-masing satu kalimat. Untuk bug tanpa error sama sekali (output salah, halaman kosong, query yang lambat), inilah seluruh laporan bug-nya.
- Environment-mu. Versi bahasa, sistem operasi, versi framework dan library kalau itu bisa berpengaruh. Bug encoding, path, dan tanggal sering bergantung pada platform.
- Apa yang sudah kamu coba. Ini mencegah model menyarankannya lagi, dan hasil setiap percobaan adalah bukti. "Menghapus bagian email membuatnya berjalan" mempersempit bug CSV tadi menjadi satu kolom.
Minta penyebabnya sebelum perbaikannya
Permintaan perbaikan mengundang model untuk mengubah kode sampai error-nya hilang. Permintaan penyebab meminta model bernalar tentang kenapa error itu terjadi, dan perbaikannya mengikuti dari situ. Minta daftar pendek penyebab yang diurutkan, dengan cara mengecek masing-masing, lalu jalankan pengecekannya sendiri. Template ini melakukan hal itu:
TypeError: Cannot read properties of undefined (reading 'map')function UserList() {
const [users, setUsers] = useState();
useEffect(() => {
fetch("/api/users")
.then((res) => res.json())
.then((data) => setUsers(data));
}, []);
return (
<ul>
{users.map((u) => (
<li key={u.id}>{u.name}</li>
))}
</ul>
);
}- Komponennya di-render sebelum datanya ada.
useState()dimulai sebagaiundefined, dan React me-render komponennya sekali sebelum effect-nya berjalan, jadiusers.mapdipanggil padaundefined. Itu saja sudah menghasilkan error yang persis sama denganmu, di setiap pemuatan. Cek: tambahkanconsole.log(users)tepat sebelumreturn. Kalau yang tercatatundefineddan error-nya langsung menyusul, inilah penyebabnya. - API-nya mengembalikan sesuatu selain array. Kalau API mengembalikan objek seperti
{ users: [...] }, error-nya akan berbeda (users.map is not a function), jadi ini bukan error yang kamu tempel. Tapi ini masih bisa menjadi masalah berikutnya setelah penyebab 1 diperbaiki. Cek:console.log(data)di dalam.thenyang kedua. - Request-nya gagal. Belum terlibat: karena render pertama sudah melempar error, React tidak pernah menjalankan effect-nya, jadi request-nya bahkan tidak terkirim. Cek: tab Network tidak menunjukkan request
/api/users, yang sekaligus memastikan penyebab 1.
Balasan itu melakukan sesuatu yang dilewatkan jawaban yang langsung memberi perbaikan: balasan itu mencoret penyebab-penyebab karena error yang akan dihasilkannya berbeda dari yang kamu tempel, atau karena kodenya tidak pernah berjalan cukup jauh sampai penyebab itu terjadi. Itu juga alasan kenapa teks error yang persis itu penting. Meminta model menyebutkan penyebab-penyebabnya sebelum menjawab adalah bentuk ringan dari chain-of-thought prompting: penalarannya datang lebih dulu dan kesimpulannya bertumpu di sana.
Buat reproduksi minimal
Reproduksi minimal adalah program terkecil yang masih menunjukkan bug-nya: data yang ditulis langsung alih-alih pemanggilan database, satu fungsi alih-alih seluruh modul. Membuatnya sering kali sudah menemukan bug-nya sebelum kamu bertanya kepada siapa pun, karena setiap bagian yang kamu hapus akan tetap menyisakan bug-nya (berarti bagian itu tidak terlibat) atau membuatnya hilang (berarti bagian itu terlibat). Kalau tidak menemukannya, reproduksi itu menjadi prompt yang ideal: cukup pendek untuk dibaca model baris demi baris, dan bebas dari kode tidak berkaitan yang bisa membuatnya mengejar masalah yang salah.
Kalau bug-nya bergantung pada data, sertakan beberapa baris yang memicunya. Model bisa bernalar tentang [{"id": 1, "name": null}]; model tidak bisa bernalar tentang "beberapa baris di production".
Ketika perbaikannya tidak lagi berhasil
Kalau perbaikan ketiga dari model gagal dengan cara yang sama, permintaan perbaikan keempat kecil kemungkinannya lebih baik. Ada dua hal yang lebih membantu:
- Berikan bukti baru. Tambahkan baris print atau log yang menunjukkan nilai sebenarnya di titik kegagalan, jalankan, lalu tempel output-nya. Bukti yang bertentangan dengan teori model adalah jalan tercepat menuju teori yang lebih baik.
- Mulai percakapan baru. Thread debugging yang panjang dipenuhi teori-teori yang sudah ditinggalkan dan versi-versi lama kodenya, dan model bisa terus membangun di atasnya. Chat baru dengan kode terbaru, error-nya, buktinya, dan satu baris yang berbunyi "sudah dicoret: X dan Y" sering kali lebih jauh hasilnya dalam satu balasan.
Hati-hati dengan jawaban yang yakin tentang perilaku sebuah library. Model bisa menggambarkan opsi atau fungsi yang tidak ada; lihat halusinasi AI untuk cara mengeceknya. Ketika kodenya tidak rusak tapi kamu tidak mengerti kenapa kode itu berperilaku seperti itu, prompt untuk menjelaskan kode adalah alat yang lebih tepat.
Pertanyaan yang sering diajukan
Bagaimana cara meminta ChatGPT atau Claude memperbaiki kodeku?
Tempel pesan error lengkapnya dan kode yang memunculkannya, lalu tambahkan tiga baris pendek: apa yang kamu harapkan, apa yang terjadi, dan apa yang sudah kamu coba. Minta penyebab yang paling mungkin dan cara memastikannya sebelum meminta perbaikan. "Perbaiki ini" saja menghasilkan perbaikan untuk versi error yang paling umum, yang belum tentu error milikmu.
Apakah aku sebaiknya menempel seluruh proyekku ke AI?
Tidak. Tempel fungsi tempat error terjadi, kode yang memanggilnya, dan contoh data yang diterimanya. Lebih baik lagi, potong masalahnya sampai menjadi program terkecil yang masih menunjukkan bug itu. File-file yang tidak berkaitan membuat jawabannya lebih lambat dan memberi model lebih banyak tempat untuk mencari masalah yang sebenarnya tidak ada.
Kenapa perbaikan dari AI menghilangkan error-nya tapi programnya tetap tidak berjalan?
Perbaikan itu hanya mengobati gejalanya. Misalnya, mengganti row["email"] dengan row.get("email") menghentikan KeyError, tapi kalau key-nya hilang karena bug di bagian sebelumnya, sekarang setiap email diam-diam menjadi None. Meminta penyebabnya dulu, dan cara memastikannya, mencegah perbaikan yang hanya menyembunyikan masalah.
Bagaimana kalau AI terus menyarankan perbaikan yang tidak berhasil?
Berhentilah meminta perbaikan dan berikan bukti. Laporkan apa yang diubah setiap percobaan, tambahkan baris print atau log yang menunjukkan nilai sebenarnya, lalu tempel output-nya. Kalau percakapannya sudah panjang, mulai percakapan baru dengan ringkasan yang bersih: kodenya, error-nya, buktinya, dan perbaikan yang sudah dicoret.