मैंने पिछले हफ़्ते कुछ शर्मनाक खोजा।
मेरे AI podcast pipeline में एक विस्तृत system prompt है — एक "dialogue guide" — जिसे लिखने में मैंने कई दिन लगाए। यह hosts (दो AI-generated फ़ुटबॉल कमेंटेटर) को बताता है कि एक-दूसरे से कैसे बात करनी है। एक जैसी opening न दोहराएँ। segments के बीच structure बदलें। catchphrases का इस्तेमाल संयम से करें। कभी भी statistics न गढ़ें।
LLM ने हर शब्द पढ़ा। फिर लगभग सब कुछ अनदेखा कर दिया।
Vietnamese host ने एक episode में "Trời ơi" (हे भगवान) 13 बार कहा। Japanese host ने हर segment की शुरुआत "いやー、健一さん!" (अच्छा, Kenichi-san!) से की। English host ने पूरे confidence के साथ xG 0.35 और 65% ball possession के आँकड़े पेश किए — ऐसे numbers जो मेरे database में कहीं मौजूद नहीं हैं।
Prompt को विनम्रता से स्वीकार किया गया। और फिर अनदेखा कर दिया गया।
यह prompt engineering के बारे में सबसे उपयोगी चीज़ है जो मैंने सीखी: LLMs के पास दो reading modes हैं, और वे इन्हें पूरी तरह अलग तरीके से treat करते हैं।
दो Reading Modes की समस्या
यहाँ मेरा original dialogue guide है। मैंने Vietnamese version का English में अनुवाद किया है क्योंकि structure एक जैसा है:
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."
अच्छी तरह से लिखा गया लगता है, है ना? मुझे सच में लगा कि मैंने पूरी मेहनत की है।
लेकिन जब मैंने actual generated scripts पढ़ीं, तो यह हुआ:
| नियम | Guide ने क्या कहा | LLM ने क्या किया |
|---|---|---|
| नियम 0 (कभी न दोहराएँ) | opening बदलें | हर segment emotional host के catchphrase से खुला |
| नियम 2 (data) | specific numbers cite करें | पूरे authority के साथ मनगढ़ंत numbers cite किए |
| नियम 3 (catchphrases) | signature phrases की सूची | हर phrase को 5–13 बार प्रति episode इस्तेमाल किया |
नियम वहाँ थे। LLM ने उन्हें पढ़ा। लेकिन उनमें एक सुझाव जैसी ताकत थी, किसी ज़रूरत जैसी नहीं।
तभी मुझे एहसास हुआ: LLM मेरे नियमों को "style context" की तरह process कर रहा था — न कि "enforceable constraints" की तरह।
पैटर्न: Context बनाम Command
सोचिए कि आप अलग-अलग तरह के text कैसे पढ़ते हैं। अगर मैं आपको restaurant menu दूँ, तो आप उसे action करने की जानकारी की तरह पढ़ते हैं। अगर मैं आपको pasta के इतिहास पर Wikipedia article दूँ, तो आप उसे background knowledge की तरह पढ़ते हैं।
LLMs, prompts के साथ कुछ ऐसा ही करते हैं। जब नियम "STYLE GUIDELINES" या "HOST INTERACTION PATTERN" या "RULES FOR SEGMENTS" जैसे लेबल वाले section में आते हैं, तो model उन्हें ambient information की तरह treat करता है — ऐसा context जो response को रंग देता है लेकिन उसे रोकता नहीं।
जब नियम "CRITICAL IMPROVEMENTS REQUIRED" या "SPECIFIC PHRASE LIMITS" जैसे लेबल वाले section में आते हैं, तो model उन्हें enforceable commands की तरह treat करता है — ऐसी चीज़ें जिन्हें verify और correct करना ज़रूरी है।
यह insight "critical" या "required" शब्दों के बारे में नहीं है। यह इस बारे में है कि नियम pipeline में कहाँ रहता है।
समाधान: Review Step को वह लागू करने दें जो Generation Step अनदेखा करता है
मेरे pipeline में दो LLM calls हैं:
- Generation step — script को segment दर segment लिखता है, dialogue guide को context की तरह इस्तेमाल करते हुए
- Review step — पूरी assembled script पढ़ता है और उसे बेहतर बनाता है
Generation step वह जगह थी जहाँ मेरे सारे नियम रहते थे। Review step में generic anti-repetition rules थे ("दो बार 'That's fascinating' मत कहो") जो पूरी तरह English-centric थे और मेरे host catchphrases या structural requirements के बारे में कुछ नहीं जानते थे।
समाधान structural था, lexical नहीं। मैंने enforcement को review step में move किया, जहाँ पूरी script एक साथ दिखाई देती है।
यहाँ क्या बदला:
पहले: नियम generation prompt में (अनदेखा)
STYLE GUIDELINES:
0. NEVER REPEAT THE SAME OPENING...
1. EMOTIONAL START...
2. DATA-GROUNDING...
3. CATCHPHRASES: "You see that?!" ...
बाद में: नियम निकालकर review prompt में डाले गए (लागू)
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
...
यहाँ दो चीज़ें हुईं:
-
Structural rules को context से promote करके command बनाया गया — "यह preferred pattern है" के बजाय "ENFORCE this" और "CHANGE segments that violate this" के रूप में rephrase किया गया
-
Catchphrases को host profiles से extract करके explicit limits के रूप में दिखाया गया, suggestions की list के रूप में नहीं। "Catchphrases: ये कुछ हैं" बन गया "ये phrases: हर एक MAXIMUM 2 TIMES।"
दोनों बदलाव review prompt में रहते हैं, generation prompt में नहीं। यही key architectural decision है। Generation step को style guide context की तरह मिलता है — उसे personality flavor चाहिए। Review step को rules enforcement की तरह मिलते हैं — उसे compliance mandate चाहिए।
Extraction की Detail (यह 7 भाषाओं में क्यों काम करता है)
मैं हर भाषा की phrase lists manually maintain नहीं करना चाहता था। जब भी मैं host profile में बदलाव करता, मुझे review prompt भी update करना पड़ता। यह वह drift है जो एक solo developer के product को खत्म कर देती है।
इसके बजाय, मैंने एक छोटा extraction function लिखा जो review time पर host profiles को parse करता है। हर locale के profile में एक catchphrase section है जिसका standard label है:
- Vietnamese:
Câu cửa miệng: - Japanese:
口癖: - Spanish:
Latiguillos: - French:
Phrases fétiches: - Korean:
입버릇: - Chinese:
口头禅:
Function उस label को ढूँढता है, उसके बाद आने वाली किसी भी quoted string को extract करता है, और उन्हें enforceable limits के रूप में format करता है:
@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)
अब जब मैं host profile edit करता हूँ और उनके catchphrases बदलता हूँ, review prompt automatically update हो जाता है। कोई drift नहीं। कोई भूली हुई भाषा नहीं।
इसने असल में क्या ठीक किया (आँकड़ों के साथ)
इन बदलावों से पहले generate हुए episode और बाद में generate हुए episode के बीच यह बदला:
| मीट्रिक | पहले | बाद में |
|---|---|---|
| "Trời ơi" count (कोटा: max 4) | 13 | अभी vi में test नहीं हुआ, लेकिन ja में: सभी 4 catchphrases कोटे के अंदर |
| "Có một lý do sâu hơn" (कोटा: max 2) | 5 | equivalent ja test में कोटे के अंदर |
| मनगढ़ंत statistics (xG, possession %, formation width) | 4 गढ़े हुए numbers | शून्य गढ़े हुए numbers |
| एक जैसे pattern वाली segment openings | 6/6 एक जैसी | ja में अभी भी 5/5 — नीचे देखें |
| Vietnam/Japan connections बची रहीं | 1/4 बचीं (review ने 3 हटा दीं) | 11/11 बचीं |
| Host voice cross-contamination | दोनों ने एक-दूसरे के phrases इस्तेमाल किए | स्पष्ट separation |
Catchphrase quotas, anti-fabrication rules, और localization preservation — सभी ने काम किया। Host profiles अब hosts की personalities को इतनी साफ़ तरह से dictate करते हैं कि LLM अब confuse नहीं होता कि कौन क्या कह रहा है।
क्या अभी भी टूटा हुआ है
एक नियम अभी भी fail होता है: structural variety. Dialogue guide कहता है "कम से कम 5 में से 2 segments में अलग structural entries होनी चाहिए।" बदलावों के बाद, Japanese episode ने फिर भी हर segment एक जैसा खोला: "いやー、健一さん!" — एक ही episode में पाँच बार।
यह prompt enforcement problem नहीं है। यह architecture problem है।
Generation step हर segment को independently produce करता है। Segment 3 को बिल्कुल पता नहीं होता कि segment 1 और 2 emotional host के catchphrase से खुले। हर segment isolation में उसी dialogue guide के साथ generate होता है, इसलिए हर एक उसी "emotional host से खोलते हैं" के फ़ैसले पर पहुँचता है।
Review step को यह पकड़ना चाहिए — वह पूरी script एक साथ देखता है। और मैंने explicit enforcement language जोड़ा है जो उसे openings vary करने को कहता है। लेकिन Gemini 3.5 Flash, जो model review चला रहा है, को लगता है कि segment openings को restructure करना, catchphrases trim करने या fabricated claims को soften करने से ज़्यादा मुश्किल है। Opening variety के लिए content के parts को regenerate करना पड़ता है, सिर्फ़ tighten या remove नहीं। यह model के लिए ज़्यादा भारी काम है।
मैं अभी भी इस पर काम कर रहा हूँ — शायद एक ज़्यादा capable review model या pipeline restructure जहाँ segments opening state share करें। व्यापक बात: prompt enforcement, architecture problems को ठीक नहीं कर सकता। अगर आपके pipeline का structure किसी नियम का पालन करना असंभव बना देता है, तो आपके prompts में कितने भी "CRITICAL" या "MANDATORY" आपको नहीं बचा पाएँगे।
Framework: हर नियम के लिए तीन सवाल
इस अनुभव के बाद, अब मैं हर system prompt को तीन सवालों के आधार पर audit करता हूँ जो मैं लिखता हूँ:
1. यह नियम कहाँ रहता है — generation में या review में? Personality और tone के नियम generation में रहते हैं। Compliance, consistency, और structure के नियम review में रहते हैं। अगर कोई नियम दोनों को छूता है (जैसे catchphrases — ये personality हैं लेकिन limits चाहिए), तो दोनों में डालें।
2. क्या यह नियम context की तरह phrase किया गया है या command की तरह? "ये catchphrases हैं" context है। "हर एक maximum 2 बार" command है। एक ही नियम के लिए दोनों ज़रूरी हैं — generation step को जानना चाहिए कि catchphrases क्या हैं, और review step को enforce करना चाहिए कि वे कितनी बार आते हैं।
3. क्या pipeline सच में इस नियम का पालन कर सकता है? Per-segment generation, cross-segment variety enforce नहीं कर सकता। कोई prompt इसे ठीक नहीं करेगा। आपको या तो नियम को review step में ले जाना होगा (जो पूरी script देखता है) या pipeline को restructure करना होगा ताकि segments state share करें।
यह framework सिर्फ़ podcast generation के लिए नहीं है। यह किसी भी multi-step LLM pipeline पर लागू होता है — content generation, code review, document summarization, कुछ भी जहाँ अलग generation और quality-control passes हों।
मैं अभी भी इस पर iterate कर रहा हूँ, लेकिन अगर आप अपना पहला multi-step LLM pipeline बना रहे हैं: इसे कम से कम दो steps में बाँटें। पहला step personality और freedom के साथ generate करता है — इसे context, examples, tone guidance दें। दूसरा step precision और enforcement के साथ review करता है — इसे explicit limits, compliance checks, और चीज़ें बदलने का authority दें।
Generation step ऐसा feel होना चाहिए जैसे आप किसी creative collaborator को brief कर रहे हैं। Review step ऐसा feel होना चाहिए जैसे आप किसी editor को checklist थमा रहे हैं।
और जब आपके नियम दोनों करने के बाद भी अनदेखे जा रहे हों, तो पहले architecture question पूछें। क्या यह prompt है, या pipeline?
अक्सर पूछे जाने वाले सवाल
क्या यह single-prompt setup (बिना pipeline के) पर लागू होता है?
हाँ, लेकिन सीमित तरीके से। एक ही prompt में, आप उसी model से एक साथ creative और compliant होने को कह रहे हैं — जब दोनों में conflict होगा, तो वह हमेशा creativity को compliance पर तरजीह देगा। एक ही prompt में भी, अपने instructions को "context" section और explicit "constraints" section में अलग करने से मदद मिलती है। लेकिन आप एक ceiling तक पहुँच जाएँगे। अलग-अलग instructions वाली दो separate calls लगभग हमेशा एक से बेहतर perform करती हैं।
आपने generation prompt में ही नियमों को ज़्यादा ज़ोरदार तरीके से क्यों नहीं डाला?
मैंने try किया। मैंने "MANDATORY," "CRITICAL," "NEVER," और सब all-caps जोड़ा। Generation step की बहुत सारी competing demands हैं — वह एक साथ engaging, natural-sounding, varied, locally authentic, और compliant होने की कोशिश कर रहा है। जब model को "excited Vietnamese football fan जैसा sound करो" और "सिर्फ़ दो बार 'Trời ơi' कहो" में से चुनना होता है, personality हमेशा जीतती है। Review step में ऐसा कोई conflict नहीं है — उसका एकमात्र काम enforce करना है।
आप review step के लिए कौन सा model use कर रहे हैं?
Gemini 3.5 Flash (cost के लिए — review 7 भाषाओं में हर episode पर चलता है)। यह simple enforcement (catchphrases trim करना, fabricated stats को soften करना) अच्छी तरह handle करता है। यह उन tasks से struggle करता है जिनमें content regeneration चाहिए, जैसे segment openings को restructure करना। एक stronger model वहाँ मदद करेगा, लेकिन मैंने अभी तक cost justify नहीं की है।
मैं DIALOGUE, एक AI podcast platform, अकेला अपनी शामों और weekends में बना रहा हूँ। Catchphrase extraction और review prompt changes का code open है — आप मेरे podcast-engine repository में पूरा system prompt और enforcement logic पढ़ सकते हैं। मैं रास्ते में जो सीखता हूँ, उसके बारे में लिखता हूँ।
अगर आपको भी ऐसी ही समस्या का सामना करना पड़ा है — नियम जो पढ़े तो जाते हैं लेकिन लागू नहीं होते — मुझे जानने की उत्सुकता है: वह नियम क्या था, और वह आपके pipeline में कहाँ रहता था?
बस, मेरी तरफ से इतना।
शुभकामनाओं सहित, Chandler