Menu

Prompt Code Review: Cara Me-review Kode dengan AI

Prompt code review yang bagus menyebutkan apa yang harus dicari, meminta tingkat keparahan untuk setiap temuan, meminta input konkret yang memicu kegagalan beserta diff-nya, dan menyuruh model melewatkan soal gaya. Lalu kamu mengecek setiap temuan, karena sebagian akan salah.

Setiap prompt di bawah bisa diedit: ubah, lalu buka di ChatGPT, Claude, atau aplikasi AI lain.

Prompt code review harus memberi tahu model apa yang harus dicari, seberapa serius setiap temuan, dan bukti apa yang harus diberikan. "Review kode ini" menghasilkan daftar saran yang ramah, di mana celah keamanan terselip di antara tips docstring dan preferensi penamaan. Prompt review dengan daftar periksa, tingkat keparahan, dan permintaan diff menghasilkan laporan yang bisa langsung kamu tindak lanjuti, satu temuan dalam satu waktu.

Dari "review ini" ke daftar periksa dengan tingkat keparahan

Kode di kedua tab punya dua bug sungguhan. Bandingkan bagaimana masing-masing balasan menyajikannya.

Bisakah kamu me-review kode ini? def get_user(conn, username): cur = conn.cursor() cur.execute(f"SELECT id, email FROM users WHERE name = '{username}'") row = cur.fetchone() return {"id": row[0], "email": row[1]}
Try it
Example replyReplies vary between models and runs.

Secara keseluruhan, fungsinya pendek dan mudah diikuti. Beberapa saran:

  • Tambahkan type hint, misalnya username: str, supaya signature-nya lebih jelas.
  • Tambahkan docstring yang menjelaskan apa yang dikembalikan fungsinya.
  • Pakai parameterized query. Menyusun SQL dengan f-string bisa menyebabkan SQL injection.
  • Tangani pengguna yang tidak ada. fetchone() bisa mengembalikan None.
  • Penamaan: fetch_user mungkin lebih menggambarkan akses ke database.

Balasan pertama menemukan kedua bug itu, dan justru itulah masalahnya kalau menilai review dari apa yang disebutkannya. Injection-nya berada di urutan ketiga dari lima, diperhalus menjadi "bisa menyebabkan", tanpa perbaikan, bersebelahan dengan tips docstring. Pembaca yang membacanya sekilas akan menambahkan type hint lalu lanjut.

Prompt kedua mengubah empat hal:

  • Cakupan. "Hanya bug, keamanan, dan penanganan error. Lewati gaya" menghilangkan gangguannya. Gaya adalah urusan linter dan formatter, yang lebih cepat dan tidak pernah berbeda pendapat dengan dirinya sendiri.
  • Tingkat keparahan. Ini memaksa model membuat peringkat, dan daftar yang berperingkat memberi tahu kamu harus mulai dari mana.
  • Input pemicu. "x' OR '1'='1" mengubah risiko yang samar menjadi demonstrasi yang bisa kamu jalankan. Ini juga penyaring terbaikmu untuk false positive, seperti yang ditunjukkan bagian terakhir.
  • Diff. Diff kecil per temuan bisa diterapkan atau ditolak secara terpisah. Fungsi yang ditulis ulang mencampur setiap perbaikan dengan perubahan yang tidak diminta siapa pun.

"Kalau tidak ada temuan di suatu tingkat keparahan, jangan mengarang" lebih penting daripada kelihatannya. Saat diminta me-review, model cenderung menghasilkan temuan bahkan ketika hanya ada sedikit yang bisa ditemukan, dan temuan-temuan yang paling lemah hanya menggemukkan daftarnya. Izin eksplisit untuk tidak melaporkan apa pun di suatu tingkat memangkas isian itu.

Konteks yang dibutuhkan reviewer

Reviewer manusia tahu untuk apa kodenya dan dari mana input-nya berasal. Model hanya tahu apa yang kamu tempel. "username datang langsung dari formulir login" adalah kalimat yang membuat SQL injection menjadi temuan dengan tingkat keparahan tinggi, bukan sekadar teori. Konteks yang berguna untuk sebuah review:

  • Dari mana input-nya berasal: pengguna, layanan internal lain, file konfigurasi yang kamu kendalikan.
  • Apa yang memanggil kode itu dan apa yang diharapkannya kembali.
  • Runtime-nya: versi bahasa, framework, driver database. Perbaikan untuk injection di atas memakai ? karena sqlite3 memakai placeholder itu; beberapa driver lain memakai %s.
  • Apa yang paling penting bagimu untuk perubahan ini: kebenaran, keamanan, performa, atau ketiganya.

Prompt review yang bisa dipakai ulang

Blok ini mengubah daftar periksa tadi menjadi template. Ganti bahasanya, fokusnya, dan kodenya, tapi pertahankan aturannya. Mematikan bagian batasan adalah cara cepat untuk melihat seberapa banyak gangguan yang kembali tanpa bagian itu.

Template code review
Fill in
Parts
Kamu adalah reviewer JavaScript senior. Kamu hanya melaporkan masalah sungguhan dan tidak ada yang lain.
Review kode di bawah ini, dengan fokus pada bug dan penanganan error.
Kode ini berjalan di browser. `ids` adalah array berisi id numerik dari API kami sendiri.
async function loadAll(ids) { const results = []; ids.forEach(async (id) => { const res = await fetch(`/api/items/${id}`); results.push(await res.json()); }); return results; }
Untuk setiap temuan: tingkat keparahan (tinggi, sedang, atau rendah), barisnya, input atau situasi yang memicunya, dan diff yang minimal. Yang paling parah lebih dulu.
Tidak ada komentar tentang gaya, penamaan, atau format. Kalau kamu tidak yakin sebuah temuan itu nyata, katakan begitu dan sebutkan apa yang bisa memastikannya. Kalau kamu tidak menemukan apa pun, katakan "Tidak ada temuan".
Try it
Example replyReplies vary between models and runs.

1. Tinggi: fungsinya selesai sebelum request mana pun selesai (baris 3) forEach tidak menunggu callback async. loadAll langsung mengembalikan array results yang kosong, dan push-nya terjadi belakangan. Pemanggil mana pun mendapat [].

2. Sedang: request yang gagal diperlakukan sebagai data (baris 5) Respons 404 atau 500 bukan exception di fetch. Body error berformat JSON di-parse dan di-push seolah-olah itu sebuah item, dan body yang bukan JSON membuat res.json() melempar error di dalam callback yang tidak di-await siapa pun.

Perbaikan untuk keduanya, yang sekaligus menjaga urutan hasilnya tetap sama dengan ids:

 async function loadAll(ids) {
-  const results = [];
-  ids.forEach(async (id) => {
-    const res = await fetch(`/api/items/${id}`);
-    results.push(await res.json());
-  });
-  return results;
+  return Promise.all(
+    ids.map(async (id) => {
+      const res = await fetch(`/api/items/${id}`);
+      if (!res.ok) throw new Error(`Item ${id}: HTTP ${res.status}`);
+      return res.json();
+    })
+  );
 }

Baris peran menetapkan standar ("hanya masalah sungguhan dan tidak ada yang lain"), dan di situlah role prompting paling membantu. Kalau review-nya dibaca oleh program, misalnya skrip yang memposting temuan sebagai komentar di pull request, minta JSON dengan field yang tetap alih-alih prosa; output terstruktur menunjukkan caranya.

Menangani false positive

Sebagian temuan akan salah. Model tidak bisa melihat pemanggil yang memvalidasi input-nya, constraint database yang membuat sebuah kasus mustahil terjadi, atau alasan sebuah baris yang terlihat aneh memang disengaja. Model juga bisa salah tentang perilaku sebuah library; halusinasi AI menjelaskan kenapa klaim yang meyakinkan bukanlah klaim yang sudah dicek.

Uji setiap temuan dengan input pemicunya. Kalau kamu tidak bisa membuat input yang mencapai masalah itu di sistemmu, bantah dengan konteks yang kurang alih-alih menerima perbaikannya:

Bantah sebuah temuan
Kamu menandai fungsi ini karena `cents` mungkin undefined atau berupa string: function formatPrice(cents) { return `$${(cents / 100).toFixed(2)}`; } Fungsi ini hanya dipanggil dari `renderCart`, yang langsung return kecuali `Number.isInteger(cents)` bernilai true. Apakah ini masih masalah? Kalau tidak, tarik temuannya.
Try it
Example replyReplies vary between models and runs.

Dengan pengecekan itu, tidak: formatPrice hanya pernah menerima integer, jadi temuan itu tidak berlaku dan aku menariknya.

Satu hal yang tidak dicakup pengecekan itu: integer negatif lolos Number.isInteger, dan formatPrice(-500) mengembalikan "$-5.00". Kalau refund atau diskon bisa sampai ke fungsi ini, kamu mungkin ingin "-$5.00". Kalau tidak bisa, tidak ada yang perlu diubah.

Model yang diberi bukti baru seharusnya menarik temuannya atau menjelaskan kenapa temuan itu tetap berlaku dengan bukti itu di depannya. Keduanya berguna. Model yang selalu setuju dengan setiap bantahan tidak sedang me-review, jadi nilai balasannya dari alasannya, bukan dari apakah model itu setuju. Untuk kode yang ditulis model itu sendiri, jalankan review-nya di percakapan baru, supaya review-nya tidak dibaca lewat penalaran yang sama yang menghasilkan kodenya. Kebiasaan yang sama soal cakupan, konteks, dan tes membuat kodenya lebih baik sejak awal; lihat prompt untuk menulis kode.

Pertanyaan yang sering diajukan

Apa prompt yang bagus untuk code review?

Sebutkan apa yang harus di-review (bug, keamanan, penanganan error), minta tingkat keparahan untuk setiap temuan, dan wajibkan input konkret yang memicu masalahnya beserta diff yang memperbaikinya. Minta model melewatkan format dan penamaan kecuali diminta. Berikan konteks yang akan dimiliki reviewer manusia: untuk apa kodenya dan apa yang memanggilnya.

Bisakah AI menggantikan code review oleh manusia?

Tidak, tapi AI berguna sebagai putaran pertama. AI cepat, dan pandai menemukan pola bug yang umum seperti None yang tidak ditangani, await yang terlewat, dan SQL yang disusun dari string. AI tidak tahu aturan produkmu, bagian lain dari codebase-mu, atau alasan sebuah keputusan diambil, dan sebagian temuannya akan salah. Pakai sebelum review oleh manusia, bukan sebagai penggantinya.

Kenapa code review oleh AI melaporkan masalah yang sebenarnya tidak ada?

Model hanya melihat kode yang kamu tempel. Kalau sebuah nilai sudah divalidasi oleh pemanggilnya, atau sebuah kasus tidak mungkin terjadi di sistemmu, model tidak bisa mengetahuinya, jadi model tetap menandai risikonya. Meminta input konkret yang memicu kegagalan menyaring banyak temuan seperti ini: temuan tanpa input realistis yang memicunya biasanya adalah false positive.

Apakah aku sebaiknya meminta AI menulis ulang kodeku saat review?

Minta diff yang kecil, satu per temuan, alih-alih file yang ditulis ulang. Penulisan ulang total mencampur perbaikan dengan perubahan yang tidak diminta siapa pun, dan kamu harus me-review hasil tulisan ulang itu juga. Diff memungkinkan kamu menerima atau menolak setiap temuan secara terpisah.

Ilustrasi bahasa pemrograman di Coddy

Belajar coding dengan Coddy

Mulai