< BACK उत्पादन कोड के लिए प्रॉम्प्ट इंजीनियरिंग: कठिन सबक -- लाइन-आर्ट चित्रण

प्रोडक्शन कोड के लिए प्रॉम्प्ट इंजीनियरिंग: कठिन सबक

गुरुवार को 11:43pm था और मैं React कोड की 340 लाइनों को देख रहा था जिसे GPT-4 ने पूरे आत्मविश्वास के साथ जेनरेट किया था। साफ। अच्छी तरह से कमेंटेड। प्रोडक्शन में बिल्कुल टूटा हुआ। कस्टम हुक स्टेट को ऐसे तरीके से मैनेज कर रहा था जो साइलेंट री-रेंडर लूप्स का कारण बनता था, वह तरह जो एरर थ्रो नहीं करते, बस आपके परफॉर्मेंस को चुप चाप मार देते हैं जब तक कि कोई क्लाइंट शुक्रवार की सुबह आपको कॉल न कर दे कि उनका चेकआउट पेज लोड होने में नौ सेकंड क्यों लगते हैं।

उस रात ने मुझे किसी भी YouTube ट्यूटोरियल या Twitter थ्रेड की तुलना में प्रॉम्प्ट इंजीनियरिंग के बारे में ज्यादा सिखाया। और तब से मेरे पास उसके जैसी कई रातें रही हैं।

मैं नौ साल से वेब पर बिल्ड कर रहा हूं। Seahawk Media में हमने 12,000 से ज्यादा साइट्स शिप की हैं, WordPress, हेडलेस बिल्ड्स, कस्टम React ऐप्स, गंभीर ट्रांजेक्शन वॉल्यूम हैंडल करने वाले WooCommerce स्टोर्स। AI कोडिंग असिस्टेंट्स मेरे वर्कफ्लो में सही तरीके से 2023 की शुरुआत के आसपास आए, और मैं यह सोचने के बीच झूलता रहा हूं कि वे चमत्कारी हैं और अपने लैपटॉप को Thames में फेंकना चाहता हूं।

यहां वह है जो मैंने वास्तव में सीखा है। मुश्किल तरीके से।

---

मॉडल आपके कोडबेस को नहीं जानता। आपको उसे बताना होगा।

यह सुनने में आसान लगता है। व्यवहार में ऐसा नहीं है।

डेवलपर्स द्वारा की जाने वाली सबसे बड़ी गलती, पहले छः महीनों तक खुद मेरी सहित, यह है कि LLM को एक सीनियर इंजीनियर की तरह ट्रीट करना जो पहले से ही आपका सारा कोड पढ़ चुका है। आप पूछते हो "यूजर ऑथेंटिकेशन हैंडल करने के लिए एक फंक्शन लिखो" और यह वैक्यूम में तकनीकी रूप से सही कुछ लिखता है। लेकिन आपका प्रोजेक्ट Firebase नहीं, Supabase का इस्तेमाल करता है। आपके टोकन्स httpOnly कुकीज़ में रहते हैं, localStorage में नहीं। आपका एरर फॉर्मेट { status, message, data } है, जो भी मॉडल डिफॉल्ट करता था उसका नहीं।

मॉडल गलत नहीं है। वह सिर्फ आपको नहीं जानता।

इसे हर बार एक प्रोजेक्ट प्रिएंबल दो

मैं अब हर meaningful कोडिंग सेशन को शुरू करता हूँ जिसे मैं "context block" कहता हूँ। लिखने में लगभग 90 सेकंड लगते हैं। कुछ ऐसा दिखता है:

  • Stack: Next.js 14 (App Router), TypeScript, Supabase, Tailwind CSS 3.4
  • State: Zustand, कहीं भी Redux नहीं
  • Auth: Supabase Auth with httpOnly cookies via middleware
  • Error shape: { success: boolean, error?: string, data?: unknown }
  • स्टाइलिंग कन्वेंशन: utility-first, कोई custom CSS फ़ाइलें नहीं जब तक बिल्कुल ज़रूरी न हो

किसी भी गैर-तुच्छ रिक्वेस्ट से पहले यह पेस्ट करो। मैं Cursor में ऐसा करता हूं प्रोजेक्ट रूट में एक _context.md फाइल रखकर। पेस्ट करने के लिए दो कीस्ट्रोक्स। आउटपुट क्वालिटी में ध्यान देने योग्य छलांग आती है, कम अनुमान, कम चीजें जिन्हें मुझे रिप करना पड़ता है।

---

Specificity ही सब कुछ है

2022 में, जब मैं अभी AI का ज़्यादा इस्तेमाल नहीं कर रहा था, एक क्लाइंट ने मुझे एक brief दिया जो शब्दशः दो sentences में था: "हमारे लिए एक booking system बनाओ। अच्छा बनाओ।" हम तीन हफ़्ते तक scope को लेकर आगे-पीछे करते रहे। यह अनुभव मेरे साथ रह गया, और यह सीधे तौर पर मेरे prompts लिखने के तरीके को आकार देता है।

Vague prompt → vague code। हर बार।

"एक function लिखो जो orders fetch करे" तो कुछ मिलेगा। "एक TypeScript async function लिखो जिसका नाम fetchOrdersByUser हो, जो एक userId: string स्वीकार करे, Supabase में orders table को query करे जहाँ user_id match करे और status cancelled न हो, results को created_at descending के अनुसार order करे, और Order[] return करे या एक typed error throw करे" तो कुछ ऐसा मिलेगा जो आप वाकई ship कर सकें।

अंतर model की capability में नहीं है। यह prompt की specificity में है।

Code Prompt में क्या शामिल करें

  1. फंक्शन का नाम और सिग्नेचर, मॉडल को नेमिंग कनवेंशन्स इजाद करने न दो।
  2. इनपुट टाइप्स और आउटपुट टाइप्स, TypeScript जेनेरिक्स अगर रेलेवेंट हों।
  3. डेटा सोर्स, कौन सी टेबल, कौन सा API एंडपॉइंट, कौन सी कैश लेयर।
  4. एज केसेस जो आप पहले से जानते हो, "उस केस को हैंडल करो जहां ऐरे खाली है"।
  5. क्या न करें, "इसके लिए useEffect का उपयोग न करें, एक server action का उपयोग करें"

वह आखिरी बिंदु लोगों को एहसास होने से ज़्यादा मायने रखता है। मॉडल को बताना कि क्या करना है से बचना चाहिए, बहुत समय बचाता है। मैंने हर प्रोजेक्ट के लिए एक छोटा "anti-patterns" नोट रखना शुरू किया है, जैसे "कोई client components नहीं जब तक user interaction की ज़रूरत न हो", और मैं उस प्रोजेक्ट के लिए prompts में प्रासंगिक लाइनें शामिल करता हूँ।

---

अपने प्रॉम्प्ट्स को चेन करें। एक बार में सब कुछ न मांगें।

Seahawk के पास late 2023 में एक fintech क्लाइंट था, मैं नाम नहीं कहूंगा, जहाँ हम एक multi-step KYC flow बना रहे थे। जटिल सामान। Document upload, liveness check integration, status polling। मुझ से शुरुआत में GPT-4 से "पूरे KYC flow component को build करो" कहने की गलती हुई। इसने 600 लाइनों का शानदार दिखने वाला garbage produce किया। उलझी हुई logic, मिश्रित concerns, UI state और business logic के बीच असली अलगाव नहीं।

तो मैंने इसे खारिज कर दिया और एक चेन के साथ फिर से शुरू किया।

पहला प्रॉम्प्ट: "एक 4-step KYC फ़्लो के लिए state machine डिज़ाइन करें। स्टेप्स: identity, document upload, liveness, review। मुझे सिर्फ state टाइप और transitions दें, कोई UI नहीं।"

दूसरा प्रॉम्प्ट: "इस state machine को देखते हुए [paste करें], Zustand store लिखें।"

तीसरा प्रॉम्प्ट: "इस store को देखते हुए [paste करें], StepIdentity component लिखें। सिर्फ यह step।"

chained approach का output उपयोग में आने लायक था। perfect नहीं, मैंने फिर भी लगभग 30% फिर से लिखा, लेकिन उपयोग में आने लायक। monolithic approach ने मुझे कुछ नहीं दिया।

Anthropic की अपनी prompting guidance जटिल कार्यों को subtasks में तोड़ने के बारे में बात करती है, और ईमानदारी से कहूँ तो, यह बिल्कुल वही है जो मुझे trial और error से मिला। समस्या को तोड़ो उससे पहले कि अपने codebase को तोड़ दो।

---

इसे अपने आप से बहस कराएं

यह मुझे पूरी तरह से accidentally मिला। मैं एक generated utility function की review कर रहा था और उसे सिर्फ run करने के बजाय, मैंने एक follow-up prompt जोड़ा: "आपके द्वारा अभी लिखे गए कोड में क्या संभावित bugs या edge cases हो सकते हैं?"

मॉडल को तीन समस्याएं मिलीं जिन्हें इसने account में नहीं लिया था। उनमें से एक असली समस्या थी, एक async loop में एक race condition जो production में debug करने में nightmare होता।

अब मैं यह नियमित रूप से करता हूँ। Code लिखो, फिर इससे कहो कि code की आलोचना करे। फिर इससे कहो कि आलोचना को ठीक करे। अपने काम की समीक्षा करने के लिए मॉडल से पूछना थोड़ा बेतुका लगता है, लेकिन यह लगातार ऐसी चीज़ें सामने लाता है जिन्हें मैं सिर्फ एक painful debugging session के बाद पकड़ता।

आप इसे आगे ले जा सकते हैं। एक working function मिलने के बाद, कोशिश करें: "इसे performance पर फोकस करके फिर से लिखें" या "यह high concurrency के तहत कैसे व्यवहार करेगा?" जवाब हमेशा applicable नहीं होते, लेकिन लगभग 40% समय वे कुछ ऐसा सामने लाते हैं जिस पर कार्य करना लायक है।

---

"भूमिका + बाध्यता" फ्रेम

मैं एक प्रॉम्प्ट पैटर्न का उपयोग लगातार करता हूँ जिसे मैं चाहता हूँ कि पहले साल में ही समझ गया होता। यह इस तरह जाता है: "आप एक [विशिष्ट प्रकार के इंजीनियर] हैं। आपकी बाध्यता है [कठोर नियम]। अब [कार्य]।"

उदाहरण: "आप एक backend engineer हैं जो database query efficiency के बारे में गहराई से परवाह करते हैं। आपकी constraint यह है कि आप इस render के लिए जो चाहिए उससे ज़्यादा fetch नहीं कर सकते, कोई over-fetching नहीं। admin dashboard के लिए एक Supabase query लिखें जो order count, total revenue, और पाँच सबसे recent orders return करे।"

वह framing दो चीज़ें करता है। यह मॉडल के "persona" को उसके साथ align करता है जो मुझे actually चाहिए। और constraint एक guardrail के रूप में काम करता है, कुछ ऐसा जो मॉडल explicitly अपने को check करता है जब यह generate करता है।

OpenAI की प्रॉम्पटिंग सर्वोत्तम प्रथाएँ एक समान विचार का वर्णन करती हैं जो स्पष्ट निर्देशों के साथ मॉडल को एक व्यक्तित्व देने के बारे में है। अगर आपने नहीं पढ़ा है तो पढ़ने योग्य है, हालाँकि मैं कहूँगा कि बाध्यता का टुकड़ा उनके डॉक्स में कम जोर दिया गया है।

उस फ्रेम की गई प्रॉम्प्ट का आउटपुट "एडमिन डैशबोर्ड के लिए एक Supabase क्वेरी लिखें" से तुलना करें। दिन और रात जैसा। सचमुच।

---

कब प्रॉम्पटिंग बंद करें और बस कोड लिखें

यह वह हिस्सा है जिसे कोई जोर से कहना नहीं चाहता।

AI coding tools बिल्कुल शानदार हैं: boilerplate के लिए, CRUD operations के लिए, utility functions के लिए, उस code के लिए tests लिखने में जो आप पहले से लिख चुके हैं, formats के बीच translate करने में (JSON schema को TypeScript type में, SQL को Supabase query में, आदि), और उन चीज़ों के first drafts के लिए जिन्हें आप बाद में भारी संशोधन करेंगे।

ये genuinely कमजोर हैं: आपके app की असली architecture को समझने में, ये जानने में कि आपके specific scale के लिए कौन सा trade-off मायने रखता है, ऐसा कुछ लिखने में जो किसी tricky stateful interaction को छूता है (बिना heavy guidance के), और किसी भी चीज़ में जहाँ spec fundamentally ambiguous हो।

मेरा अब एक personal rule है: अगर मैंने किसी piece of code को सही करने के लिए चार से ज्यादा follow-up prompts भेजे हैं, तो मैं chat बंद कर देता हूँ और खुद लिख देता हूँ। Prompt debugging का time cost सीधे लिखने के time cost से ज्यादा हो सकता है, खासकर किसी भी चीज़ के लिए जो लगभग 50 lines से कम हो।

Stack Overflow Developer Survey 2024 ने पाया कि 76% developers AI tools का उपयोग कर रहे हैं या उपयोग करने की योजना बना रहे हैं, लेकिन उसी data ने accuracy में relatively कम trust दिखाया। usage और trust के बीच यह gap बिल्कुल वह जगह है जहाँ अच्छी prompt engineering रहती है।

---

अपने Prompts को Code की तरह Version करें

पिछले साल मैंने projects में एक prompts/ folder रखना शुरू किया जहाँ AI assistance significant है। Markdown files। Major feature area के लिए एक। जब कोई prompt particularly अच्छा output देता है, तो मैं उसे save कर लेता हूँ। जब मुझे कोई बेहतर version मिलता है, तो मैं file को update कर देता हूँ।

Obsessive लगता है। इसने मुझे शायद last big project पर अकेले छह घंटे save किए हैं, एक headless WooCommerce build एक retailer के लिए जो Shopify से move कर रहा है। मैंने एक product query prompt (minor edits के साथ) को चार अलग components में reuse किया बजाय context को scratch से re-engineer करने के।

Git-track करो। सीरीयसली। Prompt की क्वालिटी रिप्रोड्यूसिबल होती है जब तुम prompts को throwaway inputs की जगह artifacts मानो। LangChain के prompt templates ने इस आइडिया को framework context में फॉर्मलाइज़ किया है, लेकिन तुम्हें कोई framework की ज़रूरत नहीं, ज़्यादातर agency workflows के लिए Markdown files का एक फ़ोल्डर काफ़ी है।

---

FAQ

क्या प्रॉम्प्ट इंजीनियरिंग वास्तव में एक हस्तांतरणीय कौशल है या सिर्फ मॉडल-विशिष्ट है?

ज़्यादातर transferable है। Core principles — specificity, context-setting, chaining, critique loops — ये सब GPT-4, Claude 3.5 Sonnet, Gemini, जो भी अगला आए, सब में लागू होते हैं। Syntax थोड़ा अलग होता है और कुछ मॉडेल्स कुछ framing के लिए बेहतर respond करते हैं, लेकिन underlying logic बना रहता है। मुझे लगा है कि Claude explicit constraints के लिए अच्छा respond करता है; GPT-4 examples के लिए। छोटे अंतर, एक ही फंडामेंटल्स।

आप कोड रिव्यू में AI-जेनरेट किए गए कोड को कैसे संभालते हैं?

किसी और कोड जैसे ही है। अगर ये production में जा रहा है, तो review होता है। Full stop। मैंने Seahawk में PRs में "यह AI-generated था" फ़्लैग करना बंद कर दिया क्योंकि ये red herring बन गया, reviewers इसे अलग तरीके से scrutinise करते थे, कभी unfairly, कभी काफ़ी न होने के बराबर। Code अपनी merits पर खड़ा होता है या गिरता है। जो मैं फ़्लैग करता हूँ: कोई भी section जहाँ logic non-obvious है और मैंने inline comments नहीं लगाए हों जो reasoning explain करें।

क्या आप सिस्टम प्रॉम्प्ट का उपयोग करते हैं या सिर्फ चैट प्रॉम्प्ट का?

दोनों। Cursor में मैं .cursorrules file पर lean करता हूँ persistent project-level instructions के लिए, चीज़ें जो मैं वरना हर बार paste करूँ। ChatGPT या Claude web UI में one-off tasks के लिए, सब कुछ chat में होता है। .cursorrules अप्रोच ने repetition को meaningfully कम किया है और मॉडेल एक long session के दौरान ज़्यादा consistent रहता है।

AI द्वारा डेवलपर्स को बदलने के बारे में आपका ईमानदार विचार क्या है?

ये developers की जगह नहीं ले रहा, कुछ tasks ले रहा है। Judgment calls, क्या build करना है, architecture कैसे करना है, कौन सा trade-off इस client की actual situation के लिए fit है, ये सब automated होने के करीब भी नहीं हैं। अगर कुछ है तो developers जो squeezed हो रहे हैं वो हैं जो purely execution-oriented थे, design या architecture-oriented नहीं। Judgment layer को sharpen करो। वही defensible part है।

---

वेब पर नौ साल तक चीजें बनाते हुए, एक बुनियादी सबक बार-बार दोहराता रहता है: आपके आउटपुट की गुणवत्ता आपके इनपुट की गुणवत्ता से तय होती है। जब क्लाइंट ब्रीफ होते थे तो यह सच था। अब प्रॉम्प्ट्स के साथ भी सच है।

मॉडल एक तेज़, कभी-कभी शानदार, अक्सर अत्यधिक आत्मविश्वासी जूनियर डेवलपर है। इसके अनुसार उसे संभालें।

संबंधित पढ़ें: Next.js और Supabase के साथ Real-Time Auction Site बनाना, 2026 में कस्टम सॉफ़्टवेयर की कीमत कैसे निकालें: एक व्यावहारिक अनुमानक, और custom web development।

< BACK