LLM आउटपुट वैलिडेशन
LLM output validation वह code है जो language model के response को application के इस्तेमाल से पहले जाँचता है, और साथ में वे tests जो साबित करते हैं कि ये checks काम करते हैं। जब output सिर्फ़ किसी इंसान के पढ़ने के लिए नहीं बल्कि दूसरे software को जाता है, तो उसे एक contract चाहिए: आम तौर पर JSON जो JSON Schema से match करे, साथ में business rules और policy checks। Contract तोड़ने वाला response database, screen या किसी दूसरे system तक पहुँचने से पहले reject, retry या किसी safe fallback से replace किया जाता है।
उदाहरण: एक store का support inbox model से हर customer message को triage करके intent, priority, order_id और एक draft reply लौटाने को कहता है। Backend ticket को intent के हिसाब से route करता है और reply support agent को दिखाता है। Validation जाँचता है कि response JSON है, intent चार allowed values में से एक है, order number सच में message में मौजूद है, और reply text के रूप में दिखता है, markup के रूप में कभी नहीं।
यह क्यों ज़रूरी है
Hallucination testing वाले lesson में आपने पूछा था कि जवाब अपने sources के प्रति सच्चा है या नहीं। यह lesson पूछता है कि क्या application उसे सुरक्षित तरीके से इस्तेमाल कर सकता है। एक missing field parser को crash कर देता है, "refund" की जगह "Refund" ticket को गलत queue में भेज देता है, गढ़ा हुआ order number किसी और के order पर action चला देता है, और reply में छिपा script agent के browser में चल जाता है। ये आम defects हैं, बस इनका source असामान्य है।
Tester के लिए contract धुंधले output को ऐसी चीज़ में बदल देता है जिस पर assert किया जा सके। Schema check deterministic होता है, भले wording न हो, इसलिए वह हर build पर चल सकता है। और क्योंकि prompt कितना भी अच्छा हो, model कभी-कभी खराब output देगा ही, इसलिए काम का सवाल यह नहीं कि "क्या model हमेशा मानता है?" बल्कि यह है कि "जब नहीं मानता तब application क्या करता है?" — और इसे टेस्ट किया जा सकता है।
Structured output: response को एक contract दें
Structured output का मतलब है कि model machine-readable format में जवाब दे, लगभग हमेशा JSON में, तय field names और allowed values के साथ। Prompt में "सिर्फ़ JSON में जवाब दो" जैसी line एक request है, guarantee नहीं। कई model APIs JSON mode, structured-output option या tool calling भी देती हैं, जो response को अलग-अलग हद तक valid JSON या आपके दिए schema तक सीमित करते हैं। पढ़ें कि आपका provider असल में क्या guarantee करता है: हो सकता है वह सिर्फ़ syntax या JSON Schema के एक हिस्से को cover करे, और response फिर भी output token limit पर कट सकता है या data की जगह refusal हो सकता है।
Contract को repository में रखे JSON Schema के रूप में लिखें, जिसे application का validator और tests दोनों इस्तेमाल करें। नीचे के schema में additionalProperties: false उन fields को reject करता है जो किसी ने माँगे नहीं, enum allowed values तय करता है (case-sensitive), और pattern order number को सीमित करता है। order_id required है, पर null हो सकता है: जिस message में order number नहीं है उसे साफ़ null मिलता है, न कि missing field या गढ़ा हुआ number। JSON वाली guide समझाती है कि schema validation सिर्फ़ यह जाँचने से आगे कैसे जाता है कि text valid JSON है। ध्यान दें कि date जैसी format values हाल के drafts में default रूप से सिर्फ़ annotations हैं, इसलिए कई validators configure किए बिना उन्हें enforce नहीं करते; जब format मायने रखे तो pattern या code check इस्तेमाल करें।
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"required": ["intent", "priority", "order_id", "reply"],
"additionalProperties": false,
"properties": {
"intent": { "enum": ["refund", "delivery", "account", "other"] },
"priority": { "enum": ["high", "normal", "low"] },
"order_id": { "type": ["string", "null"], "pattern": "^ORD-[0-9]{6}$" },
"reply": { "type": "string", "minLength": 1, "maxLength": 800 }
}
}Layers में validate करें: parse, schema, rules, guardrails
हर layer वह पकड़ती है जो उससे पहले वाली नहीं पकड़ सकती। किसी भी layer में fail होने वाला response consumer तक जस का तस कभी नहीं पहुँचता: उसे prompt और model versions के साथ log किया जाता है, और application एक सख़्त limit के अंदर retry करता है या किसी safe fallback पर जाता है, जैसे human queue। Failure path को उतनी ही सावधानी से टेस्ट करें जितनी सावधानी से happy path को: user क्या देखता है, retry limit टिकती है या नहीं, और log case reproduce करने के लिए काफ़ी है या नहीं।
- Parse: क्या यह JSON है भी? JSON से पहले का text, Markdown code fence या कटा हुआ object यहीं fail होता है। अगर application output repair करता है, जैसे fence हटाना, तो वह repair specified behaviour है जिसे टेस्ट करना है।
- Schema: required fields, types, allowed values, lengths, और कोई extra field नहीं। Schema failure से output इस्तेमाल के लायक नहीं रहता, wording चाहे कितनी भी अच्छी हो।
- Business rules: क्या values इस input और इस data के लिए समझ में आती हैं?
order_idmessage में मौजूद होना चाहिए और उसी customer का होना चाहिए। यह layer उन गढ़ी हुई values को पकड़ती है जो schema के हिसाब से बिल्कुल valid हैं। - Guardrails: model के चारों ओर policy checks जो output को block, redact या replace करते हैं — reply में personal data, मना किया गया topic, allow-list से बाहर का link। दोनों दिशाओं में टेस्ट करें: खराब output रुकता है, और सामान्य output गलती से block नहीं होता।
- 1Model responseModel का raw text: untrusted input
{"intent":"refund",…} - 2Parseक्या यह JSON है भी?
शाखा: Prose, code fence या कटा हुआ JSON: rejectफ़ेल
- 3Schema checkRequired fields, types,
enumvalues, कोई extra field नहींशाखा: Missing field या
enumसे बाहर की value: rejectफ़ेल - 4Business rulesValues इस input से मेल खाती हैं: order number message में है
शाखा: गढ़ी हुई या असंभव value: reject और logफ़ेल
- 5GuardrailsPolicy: personal data, मना किए गए topics, link allow-list
शाखा: Block, redact या replace, और logसावधानी
गेट: हर layer पास
- 6Accept, फिर भी untrustedहर consumer अपने context के हिसाब से encode करे: HTML, SQL parameters, allow-listsपास
- किसी भी rejection परPrompt और model versions के साथ log करें; सख़्त limit में retry करें या human queue पर fallback करें
Runs के बीच consistency
एक ही input अलग-अलग calls पर अलग output दे सकता है। Temperature कम करने से variation घटता है, लेकिन identical responses की guarantee नहीं मिलती, इसलिए एक pass run से ज़्यादा कुछ साबित नहीं होता। हर important case को कई बार चलाएँ, जैसे 10 बार, production वाले model version, prompt version और parameters के साथ, और N व हर result record करें।
पूरे responses की strings की तरह तुलना न करें। तय करें कि कौन-से fields stable रहने चाहिए — intent, priority, extracted IDs और amounts — और कौन-से बदल सकते हैं, जैसे reply की wording। Runs के बीच बदलता decision एक defect है, भले हर जवाब अपने आप में ठीक लगे, क्योंकि एक ही request को अलग treatment मिलता है। Output consistent होकर भी लगातार गलत हो सकता है, इसलिए consistency checks correctness checks के पूरक हैं; उनका विकल्प कभी नहीं।
- Schema validity: हर run pass होना चाहिए। Production volume पर हर 10 calls में एक failure का मतलब है हर दिन बहुत-सी failed requests।
- Decision agreement: गिनें कि हर stable field ने runs में कितनी अलग values लीं।
- जब कोई decision बदलता है, तो पूछें कि rule परिभाषित भी है या नहीं। अक्सर fix यह है कि rule prompt में लिखा जाए, या वह field सामान्य code में calculate किया जाए।
Model output को untrusted input मानें
OWASP Top 10 for LLM Applications 2025 improper output handling (LLM05) को एक अलग risk के रूप में रखता है: model output जो पर्याप्त validation, sanitisation और handling के बिना दूसरे components को दे दिया जाता है। Input लिखने वाला, या model ने जो documents पढ़े उन्हें लिखने वाला, model के लिखे पर असर डाल सकता है, इसलिए receiving code को output पर सिर्फ़ इसलिए भरोसा नहीं करना चाहिए कि "यह हमारे अपने model से आया है"।
Schema validity safety नहीं है: "reply": "<b>Sorry</b>" एक valid string है। हर consumer output को अपने context के हिसाब से handle करे: HTML में दिखाने से पहले encode करें या strict sanitiser लगाएँ; SQL में parameter के रूप में भेजें, string जोड़कर कभी नहीं; URLs, file names और commands को allow-list से जाँचें; और model को कभी ऐसा action trigger न करने दें जिसकी user को अनुमति नहीं। Harmless markup और metacharacters से टेस्ट करें, और सिर्फ़ उन systems पर जो आपके हैं या जिन्हें टेस्ट करने की आपके पास लिखित अनुमति है। LLM security testing वाली guide हर context के लिए harmless test cases देती है।
आज़माएँ: स्पेशल कैरेक्टर डेटासेट जनरेटर आज़माएँ: HTML एंटिटी एन्कोडर
Worked example: एक triage case, दस runs
Input: "नमस्ते, order ORD-204913 टूटा हुआ पहुँचा। मुझे पैसे वापस चाहिए।" Tester ने यह case ऊपर वाले schema के सामने 10 बार चलाया और हर अलग response के लिए वह पहली layer record की जिसमें वह fail हुआ, अगर हुआ। पाँच patterns दिखे (नीचे)। R4 से सबसे ज़्यादा सीख मिलती है: उसका order number pattern से match करता है, पर उसके दो अंक आपस में बदले हुए हैं, इसलिए उसे सिर्फ़ business rule पकड़ता है।
सभी 10 runs में intent refund था, लेकिन priority 7 बार normal और 3 बार high आई। Bug report में input, N = 10, यह split, model और prompt versions, और product owner के लिए एक सवाल होता है: क्या damaged goods high priority हैं? Rule तय होने के बाद या तो उसे examples के साथ prompt में लिखें, या model से सिर्फ़ fact extract करवाएँ (क्या item टूटा हुआ पहुँचा?) और उससे priority सामान्य code में calculate करें, जिसे एक exact test जाँच सकता है।
R1 {"intent":"refund","priority":"normal","order_id":"ORD-204913","reply":"..."}
parse ok, schema ok, rules ok -> accept
R2 Here is the JSON: {"intent":"refund", ...}
parse fails: text before the JSON -> reject, one retry
R3 {"intent":"refund","priority":"normal","reply":"..."}
schema fails: required field order_id is missing -> reject, one retry
R4 {..., "order_id":"ORD-204931", ...}
rules fail: order number is not in the message -> reject, human queue
R5 {..., "reply":"<b>Sorry</b>, the item arrived broken..."}
all layers pass -> accept, show as textआम गलतियाँ
- Prompt में लिखे "सिर्फ़ JSON में जवाब दो" या provider के JSON mode पर भरोसा करके code में validation छोड़ देना।
- Schema-valid response को सही मान लेना: schema सिर्फ़ shape जाँचता है, इसलिए pattern से match करता गढ़ा हुआ order number भी pass हो जाता है।
- Case को एक ही बार चलाना, या पूरे responses की strings की तरह तुलना करना, बजाय runs दोहराने और stable रहने वाले fields जाँचने के।
- सिर्फ़ यह टेस्ट करना कि guardrail खराब output रोकता है, यह कभी नहीं कि सामान्य output निकल जाता है, और यह भी नहीं कि rejection के बाद user क्या देखता है।
- Output को उसके context के हिसाब से encode किए बिना render, store या execute करना, क्योंकि वह team के अपने model से आया है।
QA का नज़रिया
शुरुआत refinement या design review में करें: output contract माँगें, पूछें कि उसका owner कौन है, कौन-से fields stable रहने चाहिए, और हर तरह के rejection पर क्या होता है। अगर कोई जवाब न दे सके, तो वही आपकी पहली finding है। Schema के हर बदलाव को API contract के बदलाव की तरह review करें, क्योंकि prompt, backend और tests सब उस पर निर्भर हैं।
Deterministic layers को हर pull request पर एक fixed test set के साथ automate करें, और repeated-run consistency suite को nightly या release से पहले, पहले से तय thresholds के साथ चलाएँ। Release के बाद production logs से हर layer के rejections की गिनती माँगें: model या prompt बदलने के बाद schema failure rate का बढ़ना regression का संकेत है। Output के हर consumer के review में security team को, और model जो भी business rule लागू करता है उसमें product owner को शामिल करें।
अभ्यास
Receipt extraction के output को validate करें
एक expense app receipt का text model को भेजता है और लौटा हुआ JSON save करता है; merchant एक HTML expense list में दिखता है। Contract: merchant 1 से 80 characters की string है, date YYYY-MM-DD में लिखी है, total 0 से बड़ा number है, currency SAR, USD या EUR है, category travel, meals, office या other है, और कोई दूसरा field allowed नहीं। Business rule: total receipt की TOTAL line के बराबर है।
नीचे के responses A से G में से हर एक के लिए वह पहली layer बताएँ जिसमें वह fail होता है (parse, schema या business rule) या "accept" लिखें, और बताएँ कि app को क्या करना चाहिए। फिर: वही receipt 10 बार चलाने पर category 6 बार meals और 4 बार other आई। आप क्या report करेंगे और क्या सुझाव देंगे?
Receipt: AL NOOR CAFE, Riyadh. Date: 2026-09-14. 2 x Coffee @ 18.00. TOTAL: SAR 36.00
A {"merchant":"Al Noor Cafe","date":"2026-09-14","total":36.00,
"currency":"SAR","category":"meals"}
B Here is the data: {"merchant":"Al Noor Cafe", ...}
C as A, but "date":"14/09/2026"
D as A, but "total":"36.00"
E as A, but "total":18.00
F as A, but "merchant":"<i>Al Noor</i> Cafe"
G as A, plus "tip":0- Contract और business rule पढ़ें।
- हर response को layer-by-layer जाँचें और पहली failure पर रुकें।
- Accept हुए responses के लिए तय करें कि expense list values को कैसे दिखाए।
- Consistency finding को एक छोटी bug report के रूप में लिखें।
मॉडल उत्तर दिखाएँ
A: accept। B: parse fail, JSON से पहले text है; reject करें और एक बार retry करें, या prefix तभी हटाएँ जब वह repair specified हो। C: schema fail, date YYYY-MM-DD से match नहीं करती। D: schema fail, total number नहीं, string है। G: schema fail, tip ऐसा field है जिसकी contract अनुमति नहीं देता। C, D और G के लिए reject करें और limit के अंदर एक बार retry करें; अगर retry भी fail हो, तो receipt को manual entry पर भेजें।
E: parse और schema पास करता है, पर business rule में fail होता है: 18.00 एक coffee की कीमत है, receipt का TOTAL 36.00 नहीं। Reject और log करें, और receipt को manual review पर भेजें; ऐसी plausible, schema-valid value सिर्फ़ rule check पकड़ता है।
F: accept, क्योंकि merchant name में markup होने पर भी वह valid string है। Expense list को उसे text के रूप में दिखाना चाहिए — <i>Al Noor</i> Cafe को हूबहू दिखाकर, या allow-list वाले sanitiser से tags हटाकर — HTML के रूप में render करके कभी नहीं।
Consistency: receipt, N = 10, split (meals 6, other 4), और model, prompt version व parameters report करें। एक ही receipt अलग runs में अलग categories में file होती है। Product owner से category rule तय करने को कहें (जैसे cafes और restaurants meals में), उसे examples के साथ prompt में या code में रखें, और release से पहले test set के लिए consistency threshold पर सहमति बनाएँ।
अक्सर पूछे जाने वाले सवाल
अगर मेरा provider schema-conformant output की guarantee देता है, तो क्या फिर भी validate करना ज़रूरी है?
हाँ। Guarantee ध्यान से पढ़ें: वह JSON Schema के सिर्फ़ एक हिस्से को cover कर सकती है, response फिर भी कट सकता है या refusal हो सकता है, और models व providers बदलते रहते हैं। Business rules और guardrails हर हाल में आपकी ज़िम्मेदारी हैं। अपने code में validation सस्ता है, और उसके tests provider बदलने पर भी काम करते रहते हैं।
Validation और guardrail में क्या फ़र्क है?
Validation output को आपके contract और business rules से जाँचता है और इस सवाल का जवाब देता है कि "क्या application इसे इस्तेमाल कर सकता है?"। Guardrail एक policy लागू करता है, जैसे personal data या scope से बाहर की सलाह नहीं, और output को block, redact या replace कर सकता है। दोनों model के चारों ओर code में चलते हैं, और दोनों को ऐसे tests चाहिए जो दिखाएँ कि वे खराब output रोकते हैं और सामान्य output जाने देते हैं।
Validation fail होने पर क्या application को अपने आप retry करना चाहिए?
Parse और schema failures के लिए सीमित retry एक आम design है, कभी-कभी validation error को नई request में जोड़कर। उसकी एक सख़्त limit होनी चाहिए, क्योंकि हर retry में समय और पैसा लगता है। Business rule और policy failures आम तौर पर किसी safe fallback पर जाते हैं, जैसे human queue या safe message, बजाय तब तक retry करने के जब तक model मान न जाए।
संदर्भ
- OWASP Top 10 for LLM Applications 2025LLM एप्लिकेशन के दस सबसे गंभीर सुरक्षा जोखिम (LLM01:2025–LLM10:2025), prompt injection और संवेदनशील जानकारी के खुलासे से शुरू।
- JSON Schema SpecificationJSON दस्तावेज़ की संरचना का वर्णन और वैलिडेशन करने की शब्दावली (टाइप, आवश्यक प्रॉपर्टी, फ़ॉर्मेट)।
- OWASP Cheat Sheet Series: Cross Site Scripting PreventionXSS से बचाव: हर context के अनुसार output encoding, उपयोगकर्ता के लिखे HTML का sanitization, सुरक्षित DOM sinks और framework सुरक्षा, और CSP केवल defence in depth के रूप में।
- Define success criteria and build evaluationsएक मॉडल प्रदाता की गाइडेंस: मापने योग्य success criteria और ऐसे evaluation सेट लिखना जिन्हें कोड, exact match या मॉडल ग्रेड करे।
Mutqan tools से अभ्यास करें
JSON डॉक्यूमेंट को JSON Schema (draft-07 / 2019-09 / 2020-12 के मुख्य कीवर्ड) के विरुद्ध वैलिडेट करें।
JSON सिंटैक्स वैलिडेट करें और गलतियों की सटीक जगह के साथ सुधार के उपयोगी सुझाव पाएँ।
दो JSON डॉक्यूमेंट की सिमैंटिक तुलना करें और जोड़ी गई, हटाई गई तथा बदली गई वैल्यू हाइलाइट करें।
रेगुलर एक्सप्रेशन को लाइव टेस्ट करें — मैच हाइलाइटिंग, कैप्चर ग्रुप और रिप्लेस प्रीव्यू के साथ।
स्पेशल कैरेक्टर से भरे इनपुट जनरेट करें: कोट, SQL/HTML/JSON मेटाकैरेक्टर, कंट्रोल कैरेक्टर, emoji और path की चालाकियाँ।
XSS रोकने के लिए HTML के विशेष कैरेक्टर (<, >, &, कोट्स) को एंटिटी में एस्केप करें।
और गहराई से
- LLM Security Testing और Prompt InjectionImproper output handling: मॉडल output को अविश्वसनीय input मानें
- LLM टेस्टिंग: LLM एप्लिकेशन कैसे टेस्ट करेंNon-deterministic output पर assertion कैसे लिखें
- LLM Evaluation: LLM output कैसे evaluate करेंचरण 5: चलाएँ, दोहराएँ और thresholds तय करें
- JSON क्या है?JSON को वैलिडेट कैसे करें
इस topic में आपकी प्रगति
प्रगति ट्रैक करने के लिए साइन इन करें
Topics पूर्ण चिह्नित करें, जहाँ छोड़ा था वहीं से जारी रखें और specialisation परीक्षाएँ खोलें।