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

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

गुरुवार को रात 11:43 बजे थे और मैं React के 340 लाइन्स के कोड को घूर रहा था जो GPT-4 ने पूरे आत्मविश्वास के साथ जेनरेट किया था। साफ-सुथरा। अच्छी तरह से कमेंटेड। प्रोडक्शन में पूरी तरह टूटा हुआ। कस्टम हुक state को इस तरह manage कर रहा था जिससे silent re-render loops हो रहे थे, जो errors throw नहीं करते -- वे बस चुपचाप आपके performance को मार देते हैं जब तक कोई क्लायंट शुक्रवार की सुबह आपको कॉल न करे यह पूछने के लिए कि उनका checkout page नौ सेकंड में लोड होने में क्यों समय लगता है।

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

मैं नौ साल से वेब पर बिल्डिंग कर रहा हूं। Seahawk Media पर हमने 12,000 से अधिक साइट्स शिप की हैं -- WordPress, headless builds, custom React apps, WooCommerce स्टोर्स जो गंभीर transaction volume handle करते हैं। AI coding assistants मेरे वर्कफ़्लो में सही तरीके से 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 को एक senior engineer की तरह treat करना जो पहले से ही आपके सभी कोड को पढ़ चुका है। आप पूछते हैं "user authentication को handle करने के लिए एक function लिखें" और यह कुछ technically सही लिखता है एक vacuum में। लेकिन आपका प्रोजेक्ट Supabase का उपयोग करता है, Firebase का नहीं। आपके tokens httpOnly cookies में रहते हैं, localStorage में नहीं। आपका error format { status, message, data } है, जो भी मॉडल के डिफ़ॉल्ट नहीं हैं।Supabase, not Firebase. Your tokens live in httpOnly cookies, not localStorage. Your error format is { status, message, data }, not whatever the model defaulted to.

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

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

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

  • Stack: Next.js 14 (App Router), TypeScript, Supabase, Tailwind CSS 3.4Next.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 फ़ाइल को प्रोजेक्ट root में रखकर करता हूं। दो keystrokes से paste कर दें। आउटपुट quality में ध्यान देने योग्य सुधार होता है -- कम 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 का नाम और signature -- मॉडल को naming conventions invent करने न दें -- don't let the model invent naming conventions
  2. Input types और output types -- TypeScript generics अगर relevant हों -- TypeScript generics if relevant
  3. Data source -- कौन सी table, कौन सा API endpoint, कौन सी cache layer -- which table, which API endpoint, which cache layer
  4. Edge cases जिनके बारे में आप पहले से ही जानते हैं -- "उस case को handle करें जहां 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" नोट रखना शुरू कर दिया है -- जैसे "user interaction जरूरी न हो तो client components न लिखें" -- और मैं उस प्रोजेक्ट के लिए प्रॉम्प्ट में प्रासंगिक लाइनें शामिल करता हूँ।

---

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

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

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

पहला प्रॉम्प्ट: "एक 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?"

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

अब मैं यह routine से करता हूँ। Code लिखो, फिर मॉडल से उसे critique करने के लिए कहो। फिर उससे critique को fix करने के लिए कहो। यह थोड़ा absurd लगता है -- मॉडल से अपने काम का review कराना -- लेकिन यह consistently ऐसी चीजें surface करता है जो मैं सिर्फ एक painful debugging session के बाद catch करता।

आप इसे आगे ले जा सकते हैं। एक 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]."

उदाहरण: "आप एक backend engineer हैं जो database query efficiency की परवाह करते हैं। आपकी constraint यह है कि इस render के लिए जितना चाहिए उससे ज्यादा fetch न करें -- कोई over-fetching नहीं। Admin dashboard के लिए एक Supabase query लिखें जो order count, total revenue, और पाँच most recent orders return करे।""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."

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

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 का इस्तेमाल कर रहे हैं या करने की योजना बना रहे हैं -- लेकिन उसी डेटा से 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 सुनता है। इसने मेरा शायद छह घंटे आखिरी big project पर बचाया है -- एक headless WooCommerce build एक retailer के लिए जो Shopify से move कर रहा था। मैंने एक product query prompt को (minor edits के साथ) चार अलग-अलग components में दुबारा इस्तेमाल किया बजाय हर बार scratch से context को फिर से engineer करने के।

इसे Git में track करो। गंभीरता से। Prompt की quality reproducible होती है अगर तुम prompts को throwaway inputs की बजाय artifacts मानो। LangChain's prompt templates इस idea को framework context में formalize करते हैं, पर तुम्हें कोई framework की जरूरत नहीं -- ज्यादातर agency workflows के लिए Markdown files का एक folder काफी है।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

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

ज्यादातर transferable है। Core principles -- specificity, context-setting, chaining, critique loops -- GPT-4, Claude 3.5 Sonnet, Gemini, जो भी आगे आए, सभी में लागू होते हैं। Syntax कुछ हद तक बदलता है और कुछ models किसी खास framing के लिए बेहतर respond करते हैं, पर underlying logic वही रहता है। मैंने देखा है कि Claude explicit constraints के लिए अच्छी तरह respond करता है; GPT-4 examples के लिए अच्छी तरह respond करता है। छोटे फर्क, एक जैसे fundamentals।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-जेनरेट किए गए कोड को कैसे संभालते हैं?

किसी भी दूसरे code जैसा ही। अगर production में जा रहा है तो review होगा। बस। मैंने Seahawk पर PRs में "यह AI-generated था" flag करना बंद कर दिया क्योंकि यह एक red herring बन गया -- reviewers इसे अलग तरीके से scrutinize करते थे, कभी unfairly, कभी enough नहीं। Code अपनी merits से ही stand या fall करता है। मैं जो flag करता हूँ: कोई भी section जहाँ logic obvious न हो और मैंने inline comments से reasoning explain न की हो।

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

दोनों। Cursor में मैं persistent project-level instructions के लिए .cursorrules file का use करता हूँ -- ऐसी चीजें जो मैं नहीं तो हर बार paste करूँ। ChatGPT या Claude web UI में one-off tasks के लिए सब कुछ chat में ही होता है। .cursorrules approach ने repetition को meaningfully कम किया है और model एक long session के दौरान ज्यादा consistent रहता है।.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 द्वारा डेवलपर्स को बदलने के बारे में आपका ईमानदार विचार क्या है?

यह developers को replace नहीं कर रहा, कुछ tasks को replace कर रहा है। Judgment calls -- क्या build करना है, उसे कैसे architect करना है, किस trade-off को इस client की actual situation में fit करना है -- वह कहीं भी automated नहीं है। अगर कुछ है तो developers जो squeeze हो रहे हैं वह वह हैं जो purely execution-oriented थे, न कि design या architecture-oriented। Judgment layer को sharpen करो। वही defensible bit है।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