Saya menemukan sesuatu yang memalukan minggu lalu.
Pipeline podcast AI saya memiliki system prompt yang rumit — sebuah "dialogue guide" — yang saya habiskan berhari-hari untuk menulisnya. Prompt itu memberi tahu para host (dua komentator sepak bola yang dibuat oleh AI) cara berbicara satu sama lain. Jangan ulangi pembukaan yang sama. Variasikan struktur antar segmen. Gunakan catchphrase secara hemat. Jangan pernah mengarang statistik.
LLM membaca setiap kata. Lalu mengabaikan hampir semuanya.
Host Vietnam mengatakan "Trời ơi" (Ya Tuhan) 13 kali dalam satu episode. Host Jepang membuka setiap segmen dengan "いやー、健一さん!" (Nah, Kenichi-san!). Host Inggris dengan percaya diri mengutip xG 0,35 dan penguasaan bola 65% — angka yang tidak ada di database saya.
Prompt itu diakui dengan sopan. Lalu diabaikan.
Ini adalah hal paling berguna yang saya pelajari tentang prompt engineering: LLM memiliki dua mode membaca, dan mereka memperlakukannya dengan cara yang sangat berbeda.
Masalah Dua Mode Membaca
Beginilah tampilan dialogue guide asli saya. Saya menerjemahkan versi Vietnam ke bahasa Inggris karena strukturnya sama:
STYLE GUIDELINES:
HOST INTERACTION PATTERN: Emotional Host + Analytical Host.
STRICT RULES FOR EVERY SEGMENT:
0. NEVER REPEAT THE SAME OPENING. Vary which host initiates,
which match moment they react to first.
1. EMOTIONAL START (mandatory): Every segment begins with
the emotional host's pure reaction.
2. DATA-GROUNDING RULE (mandatory): Every claim must cite
specific numbers. Not "they dominated" but "61% possession,
3.17 xG to 0.65."
3. CATCHPHRASES:
Emotional host: "You see that?!" "Wait wait wait..."
Analytical host: "There's a deeper reason..." "Let me tell you."
Terlihat teliti, bukan? Saya benar-benar mengira saya sudah melakukan pekerjaan dengan baik.
Tapi ketika saya membaca skrip yang benar-benar dihasilkan, inilah yang terjadi:
| Aturan | Yang dikatakan guide | Yang dilakukan LLM |
|---|---|---|
| Aturan 0 (jangan ulangi) | Variasikan pembukaan | Setiap segmen dibuka dengan catchphrase emotional host |
| Aturan 2 (data) | Kutip angka spesifik | Mengutip angka karangan dengan otoritas penuh |
| Aturan 3 (catchphrase) | Daftar frasa khas | Menggunakan setiap frasa 5–13 kali per episode |
Aturannya ada di sana. LLM membacanya. Tapi aturan itu memiliki kekuatan seperti saran, bukan persyaratan.
Saat itulah saya menyadari: LLM memproses aturan saya sebagai "konteks gaya" — bukan sebagai "batasan yang dapat ditegakkan."
Polanya: Context vs. Command
Pikirkan bagaimana Anda membaca berbagai jenis teks. Jika saya memberi Anda menu restoran, Anda membacanya sebagai informasi untuk ditindaklanjuti. Jika saya memberi Anda artikel Wikipedia tentang sejarah pasta, Anda membacanya sebagai pengetahuan latar.
LLM melakukan hal serupa dengan prompt. Ketika aturan muncul di bagian berlabel "STYLE GUIDELINES" atau "HOST INTERACTION PATTERN" atau "RULES FOR SEGMENTS," model memperlakukannya sebagai informasi ambien — konteks yang mewarnai respons tetapi tidak membatasinya.
Ketika aturan muncul di bagian berlabel "CRITICAL IMPROVEMENTS REQUIRED" atau "SPECIFIC PHRASE LIMITS," model memperlakukannya sebagai perintah yang dapat ditegakkan — hal-hal yang harus diverifikasi dan dikoreksi.
Wawasannya bukan tentang kata "critical" atau "required." Ini tentang di mana dalam pipeline aturan itu berada.
Solusinya: Biarkan Langkah Review Menegakkan Apa yang Diabaikan Langkah Generation
Pipeline saya memiliki dua panggilan LLM:
- Langkah generation — menulis skrip segmen demi segmen, menggunakan dialogue guide sebagai konteks
- Langkah review — membaca seluruh skrip yang telah disusun dan memperbaikinya
Semua aturan saya berada di langkah generation. Langkah review memiliki aturan anti-pengulangan generik ("jangan katakan 'That's fascinating' dua kali") yang sepenuhnya berpusat pada bahasa Inggris dan tidak tahu apa-apa tentang catchphrase host atau persyaratan struktural.
Solusinya bersifat struktural, bukan leksikal. Saya memindahkan penegakan ke langkah review, di mana seluruh skrip terlihat sekaligus.
Inilah yang berubah:
Sebelum: Aturan di prompt generation (diabaikan)
STYLE GUIDELINES:
0. NEVER REPEAT THE SAME OPENING...
1. EMOTIONAL START...
2. DATA-GROUNDING...
3. CATCHPHRASES: "You see that?!" ...
Sesudah: Aturan diekstraksi dan disuntikkan ke prompt review (ditegakkan)
CRITICAL IMPROVEMENTS REQUIRED ACROSS THE ENTIRE SCRIPT:
2a. ENFORCE STYLE GUIDELINES' STRUCTURAL RULES:
The STYLE GUIDELINES above contain specific requirements
about segment structure. These are REQUIREMENTS, not suggestions.
- If the guidelines say "X of Y segments must vary," CHANGE
segments that violate this.
- Check how EACH segment opens. If 4+ out of 5 open identically,
VARY at least 2.
3b. LOCALE-SPECIFIC PHRASE LIMITS (extracted from host profiles —
MAXIMUM 2 TIMES each across entire script):
- "Trời ơi" / "Trời má" — max 4x combined
- "Có một lý do sâu hơn" — max 2x
- "Mày thấy chưa?!" — max 2x
...
Dua hal terjadi di sini:
-
Aturan struktural dinaikkan dari konteks menjadi perintah — difrasekan ulang sebagai "ENFORCE this" dan "CHANGE segments that violate this" alih-alih "inilah pola yang disukai"
-
Catchphrase diekstraksi dari profil host dan ditampilkan sebagai batasan eksplisit, bukan sebagai daftar saran. "Catchphrases: ini beberapa contoh" menjadi "Frasa ini: MAKSIMUM 2 KALI masing-masing."
Kedua perubahan berada di prompt review, bukan prompt generation. Itulah keputusan arsitektur kuncinya. Langkah generation mendapat style guide sebagai konteks — ia membutuhkan cita rasa kepribadian. Langkah review mendapat aturan sebagai penegakan — ia membutuhkan mandat kepatuhan.
Detail Ekstraksi (Mengapa Ini Bekerja di 7 Bahasa)
Saya tidak ingin memelihara daftar frasa per bahasa secara manual. Setiap kali saya mengubah profil host, saya harus memperbarui prompt review juga. Itu jenis penyimpangan yang membunuh produk developer solo.
Sebagai gantinya, saya menulis fungsi ekstraksi kecil yang mem-parsing profil host pada waktu review. Profil setiap locale memiliki bagian catchphrase dengan label standar:
- Vietnam:
Câu cửa miệng: - Jepang:
口癖: - Spanyol:
Latiguillos: - Prancis:
Phrases fétiches: - Korea:
입버릇: - Mandarin:
口头禅:
Fungsi ini menemukan label tersebut, mengekstrak string yang diapit tanda kutip setelahnya, dan memformatnya sebagai batasan yang dapat ditegakkan:
@staticmethod
def _extract_catchphrase_limits(host_profiles: str) -> str:
patterns = [
(r'Câu cửa miệng:?', r'"([^"]+)"'), # Vietnamese
(r'口癖:?', r'「([^」]+)」'), # Japanese
(r'Latiguillos:?', r'"([^"]+)"'), # Spanish
# ... etc for all 7 languages
]
limits = []
for marker_pattern, quote_pattern in patterns:
match = re.search(marker_pattern, host_profiles)
if match:
phrases = re.findall(quote_pattern, host_profiles[match.end():])
for phrase in phrases:
limits.append(f' - "{phrase}" — max 2x')
return "\n".join(limits)
Sekarang ketika saya mengedit profil host dan mengubah catchphrase mereka, prompt review otomatis diperbarui. Tidak ada penyimpangan. Tidak ada bahasa yang terlupakan.
Apa yang Benar-Benar Diperbaiki (Dengan Angka)
Inilah yang berubah antara episode yang dihasilkan sebelum perbaikan ini dan yang dihasilkan setelahnya:
| Metrik | Sebelum | Sesudah |
|---|---|---|
| Jumlah "Trời ơi" (kuota: maks 4) | 13 | Belum diuji dalam vi, tapi dalam ja: semua 4 catchphrase dalam kuota |
| "Có một lý do sâu hơn" (kuota: maks 2) | 5 | Dalam kuota di uji ja yang setara |
| Statistik karangan (xG, penguasaan bola %, lebar formasi) | 4 angka karangan | Nol angka karangan |
| Pembukaan segmen dengan pola identik | 6/6 identik | Masih 5/5 dalam ja — lihat di bawah |
| Koneksi Vietnam/Jepang dipertahankan | 1/4 bertahan (review menghapus 3) | 11/11 bertahan |
| Kontaminasi silang suara host | Keduanya menggunakan frasa satu sama lain | Pemisahan yang jelas |
Kuota catchphrase, aturan anti-karangan, dan pelestarian lokalisasi semuanya berfungsi. Profil host sekarang mendikte kepribadian host dengan cukup jelas sehingga LLM tidak lagi bingung siapa yang mengatakan apa.
Apa yang Masih Rusak
Satu aturan masih gagal: variasi struktural. Dialogue guide mengatakan "setidaknya 2 dari 5 segmen harus menggunakan pembukaan struktural yang berbeda." Setelah perbaikan, episode Jepang masih membuka setiap segmen secara identik: "いやー、健一さん!" — lima kali dalam satu episode.
Ini bukan masalah penegakan prompt. Ini adalah masalah arsitektur.
Langkah generation menghasilkan setiap segmen secara independen. Segmen 3 tidak sadar bahwa segmen 1 dan 2 dibuka dengan catchphrase emotional host. Setiap segmen dihasilkan secara terisolasi dengan dialogue guide yang sama, sehingga masing-masing sampai pada keputusan yang sama "mari buka dengan emotional host."
Langkah review seharusnya menangkap ini — ia melihat seluruh skrip sekaligus. Dan saya telah menambahkan bahasa penegakan eksplisit yang menyuruhnya memvariasikan pembukaan. Tapi Gemini 3.5 Flash, model yang menjalankan review, tampaknya merasa lebih sulit untuk merestruktur pembukaan segmen daripada memangkas catchphrase atau melunakkan klaim karangan. Variasi pembukaan memerlukan regenerasi sebagian konten, bukan hanya memperketat atau menghapus. Itu pekerjaan yang lebih berat untuk model.
Saya masih mengerjakan ini — mungkin model review yang lebih mampu atau restruktur pipeline di mana segmen berbagi status pembukaan. Poin yang lebih luas: penegakan prompt tidak bisa memperbaiki masalah arsitektur. Jika struktur pipeline Anda membuat aturan tidak mungkin diikuti, sebanyak apa pun "CRITICAL" atau "MANDATORY" di prompt Anda tidak akan menyelamatkan Anda.
Kerangka Kerja: Tiga Pertanyaan untuk Setiap Aturan
Setelah pengalaman ini, saya sekarang mengaudit setiap system prompt yang saya tulis dengan tiga pertanyaan:
1. Di mana aturan ini berada — generation atau review? Aturan tentang kepribadian dan nada berada di generation. Aturan tentang kepatuhan, konsistensi, dan struktur berada di review. Jika sebuah aturan melintasi keduanya (seperti catchphrase — mereka adalah kepribadian tetapi butuh batasan), letakkan di keduanya.
2. Apakah aturan ini difrasekan sebagai konteks atau perintah? "Inilah catchphrase-nya" adalah konteks. "Maksimum 2 kali masing-masing" adalah perintah. Keduanya diperlukan untuk aturan yang sama — langkah generation perlu tahu APA catchphrase-nya, dan langkah review perlu menegakkan SEBERAPA SERING mereka muncul.
3. Bisakah pipeline benar-benar mengikuti aturan ini? Generation per segmen tidak bisa menegakkan variasi lintas segmen. Tidak ada prompt yang akan memperbaiki ini. Anda perlu memindahkan aturan ke langkah review (yang melihat seluruh skrip) atau merestruktur pipeline sehingga segmen berbagi status.
Kerangka kerja ini tidak spesifik untuk pembuatan podcast. Ini berlaku untuk pipeline LLM multi-langkah apa pun — pembuatan konten, review kode, peringkasan dokumen, apa pun yang memiliki langkah generation dan quality-control terpisah.
Saya masih terus mengiterasi ini, tapi jika Anda sedang membangun pipeline LLM multi-langkah pertama Anda: pisahkan menjadi setidaknya dua langkah. Langkah pertama menghasilkan dengan kepribadian dan kebebasan — beri konteks, contoh, panduan nada. Langkah kedua me-review dengan presisi dan penegakan — beri batasan eksplisit, pemeriksaan kepatuhan, dan wewenang untuk mengubah hal-hal.
Langkah generation seharusnya terasa seperti memberi briefing kepada kolaborator kreatif. Langkah review seharusnya terasa seperti memberikan checklist kepada editor.
Dan ketika aturan Anda masih diabaikan setelah Anda melakukan keduanya, tanyakan pertanyaan arsitektur dulu. Apakah ini prompt-nya, atau pipeline-nya?
Pertanyaan yang Sering Diajukan
Apakah ini berlaku untuk setup single-prompt (tanpa pipeline)?
Ya, tapi secara terbatas. Dalam satu prompt, Anda meminta model yang sama untuk menjadi kreatif dan patuh secara bersamaan — ia akan selalu mengutamakan kreativitas daripada kepatuhan ketika keduanya bertentangan. Bahkan dalam satu prompt, memisahkan instruksi Anda menjadi bagian "konteks" dan bagian "batasan" eksplisit membantu. Tapi Anda akan mencapai batas. Dua panggilan terpisah dengan instruksi berbeda hampir selalu mengungguli satu panggilan.
Kenapa tidak membuat aturan di prompt generation lebih tegas saja?
Saya sudah mencoba. Saya menambahkan "MANDATORY," "CRITICAL," "NEVER," dan kapital semua. Langkah generation memiliki terlalu banyak tuntutan yang bersaing — ia mencoba menjadi menarik, terdengar alami, bervariasi, otentik secara lokal, dan patuh sekaligus. Ketika model harus memilih antara "terdengar seperti penggemar sepak bola Vietnam yang bersemangat" dan "hanya katakan 'Trời ơi' dua kali," kepribadian selalu menang. Langkah review tidak memiliki konflik seperti itu — satu-satunya tugasnya adalah menegakkan.
Model apa yang Anda gunakan untuk langkah review?
Gemini 3.5 Flash (untuk biaya — review berjalan di setiap episode di 7 bahasa). Model ini menangani penegakan sederhana (memangkas catchphrase, melunakkan statistik karangan) dengan baik. Model ini kesulitan dengan tugas yang memerlukan regenerasi konten, seperti merestruktur pembukaan segmen. Model yang lebih kuat akan membantu di sana, tapi saya belum bisa membenarkan biayanya.
Saya membangun DIALOGUE, sebuah platform podcast AI, sendiri di malam hari dan akhir pekan. Kode untuk ekstraksi catchphrase dan perubahan prompt review bersifat terbuka — Anda bisa membaca system prompt lengkap dan logika penegakan di podcast-engine repository saya. Saya menulis tentang apa yang saya pelajari sepanjang perjalanan.
Jika Anda pernah mengalami masalah serupa — aturan yang dibaca tapi tidak ditegakkan — saya penasaran: apa aturannya, dan di mana letaknya dalam pipeline Anda?
Sekian dari saya.
Salam hangat, Chandler