Versi pertama sebuah prompt adalah draf. Draf itu sering memberimu sesuatu yang mendekati keinginanmu, dan jarak antara mendekati dan tepat ditutup dengan iterasi: mengubah prompt dengan sengaja, menjalankannya lagi dengan input yang sama, lalu mengecek apakah perubahannya membantu. Kalau dilakukan asal-asalan, iterasi berubah menjadi mengganti kata-kata secara acak sampai satu output yang kebetulan bagus terlihat beres. Kalau dilakukan sebagai eksperimen kecil, iterasi memberimu prompt yang berhasil untuk seratus input berikutnya, bukan hanya satu input yang kamu uji.
Metodenya punya lima langkah: tentukan seperti apa hasil yang bagus, siapkan input uji yang tetap, ubah satu hal dalam satu waktu, bandingkan output-nya, dan tahu kapan harus berhenti.
Tentukan seperti apa jawaban yang bagus
Sebelum mengedit apa pun, tuliskan apa yang harus dilakukan output-nya, dalam bentuk pengecekan yang bisa dijawab ya atau tidak. "Pesan commit yang bagus" tidak bisa dicek. Yang ini bisa:
- Baris subjeknya kurang dari 50 karakter.
- Pesannya mengikuti format Conventional Commits (
fix:,feat:, dan seterusnya). - Body-nya menyebutkan alasan perubahan itu diperlukan, bukan apa yang sudah ditunjukkan diff-nya.
- Pesannya menyebutkan nomor issue kalau ada.
Kriteria punya dua fungsi. Kriteria memberi tahu apa yang perlu ditambahkan ke prompt, karena masing-masing sering kali adalah instruksi yang belum ada. Kriteria juga mencegahmu menilai output dari seberapa enak kedengarannya, yang merupakan cara termudah untuk menerima jawaban yang meyakinkan tapi salah.
Siapkan sekumpulan kecil input uji
Pilih tiga sampai sepuluh input dan jaga tetap sama selama kamu bekerja. Masukkan kasus-kasus yang umum, beberapa yang aneh (field kosong, input yang sangat panjang, bahasa yang tidak diperkirakan prompt-nya), dan setiap input yang pernah gagal sebelumnya. Prompt yang disetel dengan satu contoh saja cenderung cocok untuk contoh itu dan gagal di contoh berikutnya.
Tulis prompt-nya sebagai template dengan tempat untuk input-nya, supaya setiap versi dijalankan dengan materi yang persis sama.
Ubah satu hal dalam satu waktu
Kalau kamu mengubah peran, format, dan contoh sekaligus lalu output-nya membaik, kamu tidak tahu perubahan mana yang berhasil, dan kamu mungkin menyimpan dua perubahan yang tidak berguna. Ubah satu hal, jalankan, bandingkan. Tab-tab di bawah ini adalah tiga versi dari satu prompt, masing-masing satu perubahan dari versi sebelumnya.
- if len(password) > 8:
+ if len(password) >= 8:
return TruePerbarui validasi panjang password
Commit ini memperbarui logika validasi password dengan mengubah operator perbandingan dari > menjadi >=. Hasilnya, password yang panjangnya tepat 8 karakter sekarang akan dianggap valid. Perubahan ini meningkatkan akurasi validasi dan memberikan pengalaman yang lebih baik bagi pengguna yang membuat akun.
Versi 1 gagal di kriteria 2 dan 3: subjeknya tidak punya awalan tipe, dan body-nya menceritakan ulang diff dengan kata-kata yang lebih banyak. Versi 2 menambahkan persyaratan format dan lolos di kriteria 1 dan 2, tapi body-nya masih menggambarkan diff. Perubahan berikutnya yang terlihat jelas adalah instruksi tambahan ("jelaskan alasannya"), tapi model tidak bisa menjelaskan alasan yang tidak pernah diberikan kepadanya. Versi 3 justru menambahkan konteks yang kurang, dan body serta rujukan issue-nya mengikuti tanpa diminta. Itulah pelajaran paling umum dari iterasi: ketika sebuah instruksi tidak memperbaiki output, prompt-nya biasanya kekurangan informasi, bukan kekurangan penekanan.
Bandingkan output-nya berdampingan
Jalankan setiap versi dengan setiap input uji, dan jalankan masing-masing lebih dari sekali, karena model chat mengambil kata-katanya sebagai sampel dan dua percobaan dari prompt yang sama bisa berbeda. Taruh output-output itu berdampingan dan cek berdasarkan kriteriamu, bukan berdasarkan ingatanmu tentang percobaan terakhir.
Untuk kriteria yang tepat, pemanggilan model kedua bisa melakukan penilaian tahap pertama. Tempel output-output itu ke prompt penilaian dengan kriteria yang dijabarkan:
| Kriteria | Output A | Output B |
|---|---|---|
| 1. Subjek kurang dari 50 karakter | Lolos: subjeknya 44 karakter | Lolos: subjek yang sama, 44 karakter |
| 2. Conventional Commits | Lolos: diawali "fix:" | Lolos: diawali "fix:" |
| 3. Body menjelaskan alasan | Gagal: "Ubah pengecekan panjang dari > menjadi >=" mengulang isi diff | Lolos: "pengguna yang mengikuti instruksinya tidak bisa mendaftar" |
| 4. Menyebutkan issue | Gagal: tidak ada nomor issue | Lolos: "Fixes #412" |
Perlakukan penilai berupa model sebagai asisten, bukan wasit. Zheng dkk. 2023, "Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena", mendokumentasikan bias pada model penilai, termasuk kecenderungan menyukai jawaban yang lebih panjang dan jawaban di posisi tertentu. Buat kriterianya bisa dicek, minta bukti berupa kutipan, tukar urutan A dan B saat membandingkan dua output, dan baca sendiri sebagian output-nya. Pengecekan seperti jumlah karakter lebih bisa diandalkan kalau dilakukan dengan satu baris kode daripada dengan penilaian model.
Perbaiki prompt-nya, bukan percakapannya
Di chat, sangat menggoda untuk mengoreksi jawaban dengan pesan susulan: "lebih pendek", "bukan, sebutkan issue-nya", "pakai format yang satunya". Cara itu memberimu satu output yang bagus dan membiarkan prompt-nya tetap seburuk sebelumnya. Ketika sebuah koreksi berhasil, pindahkan ke dalam prompt lalu jalankan prompt-nya dari awal. Lain kali kamu butuh hasilnya, kamu cukup menempel satu pesan alih-alih mengulang lima pesan.
Simpan versi-versi lama dengan catatan satu baris tentang apa yang diubah dan apa yang diperbaikinya. File teks biasa sudah cukup. Ketika perubahan yang lebih baru membuat hasilnya lebih buruk, kamu bisa kembali ke versi sebelumnya alih-alih mencoba mengingat isi prompt yang dulu.
Menjalankan perbandingan di kode
Begitu sebuah prompt berjalan lewat API, skrip pendek bisa menghasilkan tampilan berdampingan untuk setiap versi dan setiap input uji. Skrip ini memakai SDK Python milik OpenAI dan menulis file markdown yang bisa kamu baca dari atas ke bawah.
from openai import OpenAI
client = OpenAI()
MODEL = "your-model-id" # e.g. from your provider's model list
# each prompt file contains {input} where the test diff goes
PROMPTS = {
"v2": open("prompts/commit_v2.txt").read(),
"v3": open("prompts/commit_v3.txt").read(),
}
TESTS = [open(f"tests/diff_{i}.txt").read() for i in range(1, 6)]
with open("results.md", "w") as out:
for i, test in enumerate(TESTS, 1):
out.write(f"## Test {i}\n\n")
for name, template in PROMPTS.items():
for run in (1, 2):
response = client.chat.completions.create(
model=MODEL,
messages=[{"role": "user", "content": template.replace("{input}", test)}],
)
out.write(f"### {name}, run {run}\n\n{response.choices[0].message.content}\n\n")
Kapan harus berhenti
Berhentilah ketika setiap kriteria lolos di setiap input uji dalam beberapa kali percobaan. Menambahkan lebih banyak setelah itu sebagian besar hanya menambah panjang, dan setiap instruksi tambahan adalah satu hal lagi yang bisa bertentangan dengan instruksi lainnya.
Berhenti juga ketika perubahan-perubahannya mulai saling bertukar kegagalan: satu perubahan memperbaiki tes 2 dan merusak tes 4, perubahan berikutnya membaliknya. Pola itu berarti prompt-nya diminta melakukan sesuatu yang tidak bisa dipastikan oleh satu instruksi. Jalan keluar yang umum adalah menunjukkan formatnya dengan beberapa contoh (few-shot prompting), memecah pekerjaannya menjadi langkah-langkah dengan prompt chaining, atau memindahkan bagian yang deterministik, seperti menghitung karakter atau mengecek format, ke kode yang mengecek output-nya. Kalau kamu kehabisan ide, meta prompting bisa membantu: berikan prompt, input, dan output yang buruk kepada model, lalu tanyakan bagian mana dari prompt itu yang paling mungkin menyebabkannya.
Pertanyaan yang sering diajukan
Bagaimana cara memperbaiki prompt yang memberikan jawaban buruk?
Lihat jawaban yang buruk itu dan sebutkan apa yang salah: formatnya salah, ada fakta yang hilang, pembacanya salah, terlalu panjang. Lalu cari apa yang tidak disebutkan prompt-nya padahal bisa mencegah hal itu, tambahkan satu hal itu, dan jalankan versi barunya dengan input yang sama. Jawaban yang buruk lebih sering berasal dari konteks yang kurang atau instruksi format yang tidak ada daripada dari pilihan kata.
Berapa banyak input uji yang dibutuhkan untuk menguji sebuah prompt?
Untuk prompt yang akan kamu pakai ulang, tiga sampai sepuluh biasanya sudah cukup: beberapa kasus yang umum, satu atau dua kasus tepi (sangat pendek, sangat panjang, tidak biasa), dan satu input yang sebelumnya pernah gagal. Jaga input-input itu tetap sama selama kamu beriterasi, supaya perubahan pada output berasal dari prompt-nya, bukan dari input yang berbeda.
Kenapa aku mendapat jawaban berbeda saat menjalankan prompt yang sama lagi?
Model chat mengambil setiap kata sebagai sampel dari sebuah distribusi peluang, jadi output-nya bervariasi antar percobaan. Saat membandingkan dua versi prompt, jalankan masing-masing lebih dari sekali dengan input yang sama. Perbedaan yang muncul di setiap percobaan mungkin memang nyata; perbedaan yang muncul di satu percobaan saja bisa jadi kebetulan. Lewat API, kamu juga bisa menurunkan temperature untuk mengurangi variasinya.
Bisakah AI dipakai untuk menilai output dari prompt-ku?
Bisa, untuk kriteria yang bisa kamu nyatakan dengan tepat, seperti "body-nya menyebutkan alasan perubahan diperlukan" atau "menyebutkan nomor issue". Berikan kriteriamu yang persis kepada penilainya dan minta lolos atau gagal per kriteria, dengan kutipan sebagai bukti. Penilai berupa model punya bias yang sudah diketahui, termasuk lebih menyukai jawaban yang lebih panjang dan lebih menyukai satu posisi dibanding yang lain, jadi baca sendiri sebagian output-nya dan tukar urutannya saat membandingkan dua output.
Kapan sebaiknya berhenti memperbaiki sebuah prompt?
Berhentilah ketika setiap kriteria lolos di setiap input uji dalam beberapa kali percobaan, atau ketika setiap perubahan baru memperbaiki satu kasus tapi merusak kasus lain. Pada titik itu, masalahnya biasanya bukan di prompt: tugasnya mungkin butuh contoh, perlu dipecah menjadi beberapa langkah, atau butuh pengecekan di kode.