Menjalankan Prompt yang Sama Lima Kali Menghasilkan Lima Salinan dari Kesalahan yang Sama
N-version programming berasumsi bahwa keragaman berasal dari penulis yang berbeda. Dengan LLM, itu berarti model yang berbeda, provider yang berbeda, mungkin training run yang berbeda. Tapi asumsi itu salah. Anda bisa mendapatkan keragaman yang bermakna dari model yang persis sama dengan mengubah cara Anda bertanya, bukan apa yang Anda tanyakan.
Masalahnya: memutar temperature sampai 1.0 dan menjalankan prompt Anda lima kali bukanlah strategi. Anda akan mendapatkan variasi di permukaan. Nama variabel berubah. Komentar bertukar tempat. Strukturnya tetap identik, dan bug-nya juga tetap identik.
Jika Anda ingin implementasi yang gagal secara independen, Anda perlu meminta untuk pola pikir yang berbeda, bukan output yang berbeda.
Apa yang Sebenarnya Dibutuhkan N-Version Programming dari LLM
N-version programming adalah teknik fault tolerance di mana beberapa implementasi independen dari spesifikasi yang sama dieksekusi secara paralel. Output-nya dibandingkan, dan majority vote menentukan hasil yang benar. Idinya adalah developer yang berbeda, yang bekerja secara independen, akan memperkenalkan bug yang berbeda. Bug-nya tidak akan berkorelasi, jadi majority vote menekannya.
Ini adalah ide lama. Ini juga mahal. Anda membayar N tim untuk membangun hal yang sama.
LLM membuatnya cukup murah untuk dicoba. Alih-alih N tim, Anda punya N API call. Masalahnya adalah N API call ke model yang sama dengan prompt yang sama menghasilkan N implementasi yang hampir identik. Bug-nya berkorelasi sempurna. Majority vote Anda tidak berguna.
Solusinya adalah memperlakukan prompt sebagai developer, bukan model. Prompt yang berbeda menghasilkan developer yang berbeda.
Mengapa Temperature Saja Hanya Menghasilkan Keragaman Kosmetik
Temperature mengontrol distribusi probabilitas atas token. Pada temperature tinggi, model memilih token berikutnya yang kurang mungkin. Ini menciptakan variasi dalam frasa, penamaan variabel, dan struktur superfisial.
Ini tidak menciptakan variasi dalam pendekatan algoritmik. Jika Anda meminta fungsi untuk menemukan longest palindromic substring, temperature mengubah apakah Anda menggunakan left dan right atau l dan r. Ini tidak mengubah apakah Anda meraih expand-around-center atau dynamic programming.
Untuk N-version programming, itu tidak berguna. Anda membutuhkan implementasi yang menyelesaikan masalah secara berbeda, bukan implementasi yang terlihat berbeda sambil menyelesaikannya dengan cara yang sama.
Empat Strategi Prompting yang Memaksa Keragaman Algoritmik
Berikut adalah empat pendekatan yang mengubah cara model berpikir tentang masalah.
Variasikan Framing Masalah
Tugas yang sama yang diframing sebagai “tulis parser” versus “tulis state machine yang mengenali grammar ini” akan menghasilkan kode yang berbeda. Satu mungkin menggunakan recursive descent. Yang lain mungkin menggunakan pendekatan table-driven.
Anda bisa mengotomatisasi ini dengan meminta model untuk mengadopsi framing tertentu sebelum menyelesaikan:
import os
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
def generate_with_framing(task: str, framing: str) -> str:
prompt = f"""{framing}
Task: {task}
Write a complete, correct implementation. Do not explain your approach."""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": prompt}],
temperature=0.7,
)
return response.choices[0].message.content
task = "Parse a CSV string into a list of dictionaries, handling quoted fields and newlines within quotes."
framings = [
"Approach this as a finite state machine with explicit state transitions.",
"Approach this using recursive descent parsing with a lexer and parser.",
"Approach this by splitting on delimiters and post-processing edge cases.",
]
for framing in framings:
print(f"=== {framing} ===")
print(generate_with_framing(task, framing))
Menjalankan ini terhadap GPT-4o, framing state machine secara konsisten menghasilkan parser character-by-character dengan state enum yang eksplisit. Framing recursive descent menghasilkan lexer dan fungsi parser terpisah. Framing split-and-fix menghasilkan solusi yang lebih ringkas tapi rapuh.
Ganti Persona
Persona yang berbeda memicu pengetahuan yang berbeda. Seorang systems programmer menulis kode yang berbeda dari seorang data scientist atau competitive programmer.
personas = [
"You are a systems programmer who prioritizes memory efficiency and avoids unnecessary allocations.",
"You are a Pythonic developer who prefers concise, idiomatic code using standard library features.",
"You are an algorithms researcher who reaches for theoretically optimal solutions even if the code is longer.",
]
Persona prompting secara mengejutkan efektif untuk keragaman struktural. Systems programmer meraih arrays dan indices. Pythonic developer meraih itertools dan comprehensions. Algorithms researcher mungkin mengambil library atau menulis solusi yang lebih formal.
Batasi Toolkit yang Tersedia
Membatasi atau memperluas toolkit yang tersedia memaksa pendekatan yang berbeda.
constraints = [
"You may only use the Python standard library. No external dependencies.",
"You may use numpy and pandas. Optimize for vectorized operations.",
"You must implement this without using regular expressions.",
]
Ini sangat berguna ketika Anda tahu satu pendekatan memiliki blind spot. Jika parser berbasis regex Anda terus salah menangani nested quotes, paksa versi yang tidak menggunakan regex.
Chain-of-Thought dengan Divergent Reasoning
Alih-alih meminta kode secara langsung, minta model untuk menghasilkan beberapa strategi solusi dan pilih yang paling tidak jelas.
cot_prompt = f"""Task: {task}
First, list three different algorithms or approaches to solve this problem.
Then, pick the one that is most different from the others and implement it.
Do not pick the most obvious approach."""
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": cot_prompt}],
temperature=0.7,
)
Chain-of-thought memaksa model untuk memunculkan reasoning-nya. Constraint “most different” mendorongnya menjauh dari solusi default. Dalam praktiknya, ini menghasilkan keragaman struktural tertinggi dari teknik tunggal mana pun.
Di Mana Ini Gagal: Batas Keragaman
Keragaman same-model memiliki batas, dan Anda akan menemukannya.
Kesenjangan pengetahuan fundamental dibagi bersama. Jika training data mengandung kesalahpahaman sistematis tentang floating-point comparison, setiap framing dan setiap persona akan mereproduksi kesalahpahaman itu. Model memiliki satu set weights. Anda tidak bisa mengatasinya dengan prompt.
Ada juga diminishing returns. Tiga framing pertama mungkin memberi Anda state machine, recursive parser, dan pendekatan split-based. Framing keempat mungkin memberi Anda state machine dengan nama variabel yang berbeda. Setelah tiga hingga lima pendekatan yang benar-benar berbeda, Anda mengikis dasar barel.
Beberapa teknik menurunkan kualitas. Constraint “most different” kadang-kadang menghasilkan solusi yang berbeda karena salah. Divergence demi kepentingannya sendiri tidak berguna. Anda membutuhkan mekanisme voting atau testing untuk menyaring ide yang buruk.
Setup Praktis yang Bisa Anda Deploy Hari Ini
Jika Anda membangun ini ke dalam sistem, jangan randomize. Rancang keragaman Anda.
Pilih tiga hingga lima teknik dari daftar di atas. Hasilkan satu implementasi per teknik. Jalankan test suite atau property-based tests terhadap semuanya. Pertahankan yang lolos. Gunakan simple majority vote untuk output akhir.
from collections import Counter
def majority_vote(outputs: list[str], test_fn) -> str:
passing = [o for o in outputs if test_fn(o)]
if not passing:
raise RuntimeError("No implementation passed tests")
# Exact match voting; swap for AST comparison if needed
return Counter(passing).most_common(1)[0][0]
Langkah test filtering tidak bisa dinegosiasikan. Keragaman tanpa correctness hanyalah noise.
FAQ
Apakah ini berfungsi dengan model yang lebih kecil?
Ya, tapi diversity ceiling-nya lebih rendah. Model yang lebih kecil memiliki lebih sedikit strategi solusi yang berbeda dalam training data-nya. Anda mungkin mendapatkan dua pendekatan yang benar-benar berbeda alih-alih empat. Teknik-tekniknya masih berfungsi; mereka hanya menghasilkan variasi yang lebih sedikit.
Berapa banyak implementasi yang sebenarnya saya butuhkan?
Tiga adalah minimum praktis untuk majority voting. Lima memberi Anda coverage yang lebih baik tapi dengan biaya yang meningkat secara linear. Setelah lima, same-model diversity merosot menjadi variasi kosmetik. Jika Anda membutuhkan lebih dari lima, beralihlah ke cross-model diversity.
Apakah same-model diversity sebaik cross-model diversity?
Tidak. Model yang berbeda memiliki training data, arsitektur, dan fine-tuning yang berbeda. Mereka gagal dengan cara yang benar-benar berbeda. Same-model diversity adalah trade-off cost dan operational convenience. Gunakan ketika Anda membutuhkan fault tolerance yang baik dengan cepat, bukan ketika Anda membutuhkan fault tolerance yang sempurna.
Bisakah saya menggabungkan teknik-teknik ini?
Tentu saja. Prompt persona yang digabungkan dengan tool constraint dan langkah chain-of-thought akan menghasilkan lebih banyak keragaman daripada teknik tunggal mana pun. Biayanya adalah prompt yang lebih panjang dan lebih banyak token per generation. Untuk critical code paths, token ekstra itu sepadan.
Apa yang Harus Dicoba Pertama
Mulailah dengan framing variation. Ini adalah yang paling mudah diimplementasikan dan menghasilkan keragaman struktural yang paling konsisten. Tambahkan persona switching jika Anda membutuhkan lebih banyak. Simpan cross-model diversity untuk kasus di mana same-model diversity mencapai batasnya.
Jalankan implementasi Anda melalui test suite yang sama sebelum Anda membiarkannya vote. Implementasi yang beragam tapi tidak diuji hanyalah implementasi yang buggy yang belum Anda temui.