prompt-engineering-production-code.html
< BACK रात में एक मंद प्रकाश वाली डेवलपर की डेस्क जिस पर चमकता मॉनिटर, बिखरे हुए नोट्स, और एक ठंडा कॉफी का मग है, सब कुछ उदास संपादकीय प्रकाश में

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

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

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

मैं नौ साल से वेब पर बिल्डिंग कर रहा हूं। Seahawk Media में हमने 12,000 से अधिक साइट्स शिप की हैं — WordPress, हेडलेस बिल्ड्स, कस्टम React ऐप्स, WooCommerce स्टोर्स जो गंभीर ट्रांजेक्शन वॉल्यूम संभाल रहे हैं। AI कोडिंग असिस्टेंट्स ने सही तरीके से मेरे वर्कफ्लो में प्रवेश किया 2023 की शुरुआत में, और मैं इस बीच झूल गया हूं कि वे चमत्कारी हैं और अपने लैपटॉप को Thames में फेंकना चाहता हूं।Seahawk Media we've shipped well over 12,000 sites — WordPress, headless builds, bespoke React apps, WooCommerce stores handling serious transaction volume. AI coding assistants entered my workflow properly around early 2023, and I've swung between thinking they're miraculous and wanting to throw my laptop into the Thames.

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

---

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

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

सबसे बड़ी गलती जो मैं डेवलपर्स से देखता हूँ — खुद सहित पहले छह महीनों में — LLM को एक सीनियर इंजीनियर की तरह ट्रीट करना है जिसने पहले ही आपका सारा कोड पढ़ लिया हो। आप पूछते हो "user authentication को हैंडल करने के लिए एक function लिखो" और वह कुछ तकनीकी रूप से सही लिखता है, वैक्यूम में। लेकिन आपका प्रोजेक्ट Supabase यूज़ करता है, Firebase नहीं। आपके tokens httpOnly cookies में रहते हैं, localStorage में नहीं। आपका error format { status, message, data } है, जो कुछ भी मॉडल डिफ़ॉल्ट करता है उससे नहीं।{ status, message, data }, not whatever the model defaulted to.

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

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

मैं अब हर 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 }{ success: boolean, error?: string, data?: unknown }
  • स्टाइलिंग कन्वेंशन: utility-first, कोई custom CSS फ़ाइलें नहीं जब तक बिल्कुल ज़रूरी न हो

किसी भी non-trivial request से पहले यह पेस्ट करें। मैं Cursor में यह _context.md फ़ाइल प्रोजेक्ट रूट में रखकर करता हूँ। दो keystrokes से पेस्ट हो जाता है। आउटपुट की क्वालिटी में बड़ा अंतर आता है — कम assumptions, कम चीज़ें जो निकालनी पड़ें।Cursor by keeping a _context.md file in the project root. Two keystrokes to paste. The output quality jumps noticeably — fewer assumptions, fewer things I have to rip out.

---

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 कर सकें।fetchOrdersByUser that accepts a userId: string, queries the orders table in Supabase where user_id matches and status is not cancelled, orders results by created_at descending, and returns Order[] or throws a typed error" will get you something you can actually ship.

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

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

  1. Function name और signature — model को naming conventions invent करने दें ही न — don't let the model invent naming conventions
  2. इनपुट टाइप्स और आउटपुट टाइप्स — TypeScript जेनरिक्स अगर प्रासंगिक हों — TypeScript generics if relevant
  3. डेटा स्रोत — कौन सी टेबल, कौन सा API एंडपॉइंट, कौन सी कैश लेयर — which table, which API endpoint, which cache layer
  4. एज केसेस जो आप पहले से जानते हैं — "उस केस को संभालें जहां array खाली है" — "handle the case where the array is empty"
  5. क्या न करें — "इसके लिए useEffect का उपयोग न करें, server action का उपयोग करें" — "don't use useEffect for this, use a server action"

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

---

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

Seahawk के पास देर 2023 में एक फिनटेक क्लायंट था — मैं नाम नहीं बता सकता — जहां हम एक multi-step KYC फ़्लो बना रहे थे। जटिल सामग्री। डॉक्यूमेंट अपलोड, liveness चेक integration, स्टेटस polling। मैंने शुरुआत में GPT-4 को "पूरा KYC फ़्लो कंपोनेंट बनाओ" कहने की गलती की। इसने 600 लाइनों का नायकत्वपूर्ण कचरा निकाला। उलझा हुआ लॉजिक, मिश्रित चिंताएं, UI स्टेट और बिज़नेस लॉजिक के बीच कोई असली अलगाव नहीं।

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

पहला प्रॉम्प्ट: "एक 4-step KYC फ़्लो के लिए state machine डिज़ाइन करें। स्टेप्स: identity, document upload, liveness, review। मुझे सिर्फ state टाइप और transitions दें, कोई UI नहीं।""Design the state machine for a 4-step KYC flow. Steps: identity, document upload, liveness, review. Give me the state type and transitions only, no UI."

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

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

chained approach का output usable था। Perfect नहीं था — मुझे अभी भी लगभग 30% को फिर से लिखना पड़ा — लेकिन usable था। monolithic approach ने मुझे कुछ नहीं दिया।

Anthropic की अपनी prompting guidance जटिल कार्यों को subtasks में तोड़ने के बारे में बात करती है, और ईमानदारी से कहूँ तो, यह बिल्कुल वही है जो मुझे trial और error से मिला। समस्या को तोड़ो उससे पहले कि अपने codebase को तोड़ दो। talks about breaking complex tasks into subtasks, and honestly, this aligns exactly with what I found through trial and error. Break the problem down before you break your codebase.

---

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

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

मॉडल को तीन issues मिले जिन्हें उसने ध्यान में नहीं रखा था। उनमें से एक genuine problem था — एक async loop में race condition जो production में debug करने के लिए एक nightmare होता।

अब मैं यह नियमित रूप से करता हूँ। कोड लिखो, फिर उससे कोड की आलोचना करने के लिए कहो। फिर आलोचना को ठीक करने के लिए कहो। यह थोड़ा absurd लगता है — मॉडल से अपने काम की review करने के लिए कहना — लेकिन यह लगातार ऐसी चीजें सामने लाता है जो मैंने केवल एक painful debugging session के बाद ही पकड़ता।

आप इसे आगे ले जा सकते हैं। एक working function मिलने के बाद, कोशिश करें: "इसे performance पर फोकस करके फिर से लिखें" या "यह high concurrency के तहत कैसे व्यवहार करेगा?" जवाब हमेशा applicable नहीं होते, लेकिन लगभग 40% समय वे कुछ ऐसा सामने लाते हैं जिस पर कार्य करना लायक है।"Rewrite this with a focus on performance" or "How would this behave under high concurrency?" The answers aren't always applicable, but about 40% of the time they surface something worth acting on.

---

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

मैं एक प्रॉम्प्ट पैटर्न का उपयोग लगातार करता हूँ जिसे मैं चाहता हूँ कि पहले साल में ही समझ गया होता। यह इस तरह जाता है: "आप एक [विशिष्ट प्रकार के इंजीनियर] हैं। आपकी बाध्यता है [कठोर नियम]। अब [कार्य]।""You are a [specific type of engineer]. Your constraint is [hard rule]. Now [task]."

उदाहरण: "आप एक बैकएंड इंजीनियर हैं जो डेटाबेस क्वेरी दक्षता के लिए गहराई से परवाह करते हैं। आपकी बाध्यता यह है कि आप इस रेंडर के लिए आवश्यक से अधिक नहीं ला सकते — कोई ओवर-फेचिंग नहीं। एडमिन डैशबोर्ड के लिए एक Supabase क्वेरी लिखें जो ऑर्डर काउंट, कुल राजस्व, और पाँच सबसे हाल के ऑर्डर्स को रिटर्न करे।""You are a backend engineer who cares deeply about database query efficiency. Your constraint is that you cannot fetch more than what's needed for this render — no over-fetching. Write a Supabase query for the admin dashboard that returns order count, total revenue, and the five most recent orders."

वह फ्रेमिंग दो चीजें करता है। यह मॉडल के "व्यक्तित्व" को उससे जोड़ता है जो मुझे वास्तव में चाहिए। और बाध्यता एक गार्ड-रेल के रूप में कार्य करती है — कुछ जो मॉडल स्पष्ट रूप से अपने आप को जाँचता है जैसे-जैसे वह जेनरेट करता है।

OpenAI की प्रॉम्पटिंग सर्वोत्तम प्रथाएँ एक समान विचार का वर्णन करती हैं जो स्पष्ट निर्देशों के साथ मॉडल को एक व्यक्तित्व देने के बारे में है। अगर आपने नहीं पढ़ा है तो पढ़ने योग्य है, हालाँकि मैं कहूँगा कि बाध्यता का टुकड़ा उनके डॉक्स में कम जोर दिया गया है। describe a similar idea around giving the model a persona with explicit instructions. Worth reading if you haven't, though I'd say the constraint piece is underemphasised in their docs.

उस फ्रेम की गई प्रॉम्प्ट का आउटपुट "एडमिन डैशबोर्ड के लिए एक 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 use कर रहे हैं या use करने की योजना बना रहे हैं — लेकिन उसी data ने accuracy में relatively कम trust दिखाई। Usage और trust के बीच यह gap बिल्कुल वह जगह है जहाँ अच्छी prompt engineering रहती है।Stack Overflow Developer Survey 2024 found that 76% of developers are using or planning to use AI tools — but the same data showed relatively low trust in accuracy. That gap between usage and trust is exactly where good prompt engineering lives.

---

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

पिछले साल मैंने projects में एक prompts/ folder रखना शुरू किया जहाँ AI assistance significant है। Markdown files। Major feature area के लिए एक। जब कोई prompt particularly अच्छा output देता है, तो मैं उसे save कर लेता हूँ। जब मुझे कोई बेहतर version मिलता है, तो मैं file को update कर देता हूँ।prompts/ folder in projects where AI assistance is significant. Markdown files. One per major feature area. When a prompt produces particularly good output, I save it. When I find a better version, I update the file.

ये obsessive लगता है। इसने मेरे आखिरी बड़े project पर अकेले शायद छह घंटे बचाए हैं — एक Shopify से migrate कर रहे retailer के लिए headless WooCommerce build। मैंने एक product query prompt (minor edits के साथ) को चार अलग-अलग components में reuse किया बजाय context को हर बार scratch से re-engineer करने के।

Git-track करो। Seriously। Prompt quality reproducible है अगर आप prompts को throwaway inputs की जगह artifacts की तरह treat करो। LangChain के prompt templates इस idea को एक framework context में formalize करते हैं, लेकिन तुम्हें कोई framework की ज़रूरत नहीं — Markdown files का एक folder ज्यादातर agency workflows के लिए काफी है।LangChain's prompt templates formalise this idea in a framework context, but you don't need any framework — a folder of Markdown files is enough for most agency workflows.

---

FAQ

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

ज्यादातर हस्तांतरणीय है। मूल सिद्धांत — विशिष्टता, संदर्भ-निर्धारण, चेनिंग, आलोचना लूप — GPT-4, Claude 3.5 Sonnet, Gemini, जो भी आगे आए, सभी में लागू होते हैं। सिंटैक्स थोड़ा-बहुत अलग होता है और कुछ मॉडल कुछ फ्रेमिंग के प्रति बेहतर प्रतिक्रिया देते हैं, लेकिन अंतर्निहित तर्क कायम रहता है। मुझे लगा है कि Claude स्पष्ट बाधाओं के प्रति अच्छी प्रतिक्रिया देता है; GPT-4 उदाहरणों के प्रति अच्छी प्रतिक्रिया देता है। छोटे अंतर, एक ही बुनियादी सिद्धांत।syntax varies a bit and some models respond better to certain framing, but the underlying logic holds. I've found Claude tends to respond well to explicit constraints; GPT-4 responds well to examples. Minor differences, same fundamentals.

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

किसी अन्य कोड के जैसे ही। अगर वह प्रोडक्शन में जा रहा है, तो उसकी समीक्षा होती है। बस इतना। मैंने Seahawk में PRs में "यह AI-जेनरेट किया गया था" फ़्लैग करना बंद कर दिया है क्योंकि यह एक लाल झंडा बन गया था — रिव्यूअर्स इसकी अलग तरीके से जांच करते थे, कभी-कभी अनुचित तरीके से, कभी-कभी पर्याप्त नहीं। कोड अपने गुणों पर खरा उतरता है या नहीं। जो मैं फ़्लैग करता हूं: कोई भी भाग जहां तर्क स्पष्ट नहीं है और मैंने तर्क की व्याख्या करने वाली इनलाइन टिप्पणियां नहीं जोड़ी हैं।

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

दोनों। Cursor में मैं .cursorrules फ़ाइल पर निर्भर करता हूं स्थायी प्रोजेक्ट-स्तरीय निर्देशों के लिए — ऐसी चीजें जो मैं अन्यथा हर बार पेस्ट करूंगा। ChatGPT या Claude वेब UI में एकबारा कार्यों के लिए, यह सब चैट में है। .cursorrules दृष्टिकोण ने दोहराव को कमजोर किया है और लंबे सत्र में मॉडल अधिक सुसंगत रहता है।.cursorrules file for persistent project-level instructions — things I'd otherwise paste every time. For one-off tasks in the ChatGPT or Claude web UI, it's all in the chat. The .cursorrules approach has meaningfully reduced repetition and the model stays more consistent across a long session.

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

यह निश्चित कार्यों को बदल रहा है, डेवलपर्स को नहीं। निर्णय कॉल — क्या बनाना है, इसे कैसे आर्किटेक्ट करना है, कौन सा ट्रेड-ऑफ इस क्लाइंट की वास्तविक स्थिति के अनुकूल है — ये कहीं भी स्वचालित नहीं हैं। अगर कुछ है, तो जो डेवलपर्स दबाव में हैं वे वे हैं जो विशुद्ध रूप से निष्पादन-उन्मुख थे, डिजाइन या आर्किटेक्चर-उन्मुख नहीं। निर्णय परत को तीव्र करें। यह रक्षणीय हिस्सा है।tasks, not developers. The judgment calls — what to build, how to architect it, which trade-off fits this client's actual situation — those are nowhere near automated. If anything, the developers getting squeezed are the ones who were purely execution-oriented, not design or architecture-oriented. Sharpen the judgment layer. That's the defensible bit.

---

वेब पर नौ साल तक चीजें बनाते हुए, एक बुनियादी सबक बार-बार दोहराता रहता है: आपके आउटपुट की गुणवत्ता आपके इनपुट की गुणवत्ता से तय होती है। जब क्लाइंट ब्रीफ होते थे तो यह सच था। अब प्रॉम्प्ट्स के साथ भी सच है।the quality of your output is determined by the quality of your inputs. That was true when it was client briefs. It's true now with prompts.

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

< BACK