पब्लिश किया गया: 30 अप्रैल, 2026
एआई की सुविधा वाले मॉडल को डिप्लॉय, मैनेज या सेल्फ़-होस्ट किए बिना, आपकी वेबसाइट या वेब ऐप्लिकेशन, एआई की मदद से टास्क पूरे कर सकते हैं. डेमो से प्रोडक्शन-रेडी सुविधा पर माइग्रेट करना मुश्किल हो सकता है. इस दस्तावेज़ में, तकनीकी और यूएक्स से जुड़ी ज़रूरी बातों के बारे में बताया गया है, ताकि आपको अक्सर होने वाली गलतियों से बचने में मदद मिल सके.
मॉडल को पहले से तैयार करना
इस पर लागू होता है: सभी एपीआई. जैसे, Summarizer, Translator, और Writer.
यह करें: उपयोगकर्ता की दिलचस्पी का पता चलते ही, सेशन शुरू करें. सेशन शुरू करने के लिए, उपयोगकर्ता की सहमति ज़रूरी होती है. इसलिए, किसी भी इंटरैक्शन का इस्तेमाल किया जा सकता है. जैसे, एआई की सुविधा वाले किसी पेज पर कहीं भी क्लिक करना. इससे मॉडल और रनटाइम तैयार हो जाता है, जबकि उपयोगकर्ता यूज़र इंटरफ़ेस (यूआई) से इंटरैक्ट करता है. अगर ज़रूरी हो, तो नतीजा रेंडर करना शुरू करते ही, एआई का अगला टास्क शुरू करें.
यह न करें: सेशन शुरू करने के लिए, उपयोगकर्ता के "जनरेट करें" पर क्लिक करने का इंतज़ार न करें. इससे कोल्ड स्टार्ट में कई सेकंड की देरी हो सकती है, क्योंकि मॉडल को पहले मेमोरी में लोड करना होता है और फिर अपना एक्ज़ीक्यूशन पाइपलाइन तैयार करना होता है.
सेशन बनाते समय शुरुआती प्रॉम्प्ट सेट करना
इस पर लागू होता है: Prompt API.
यह करें: सेशन शुरू करते समय, सिस्टम के निर्देश दें, ताकि पहले प्रॉम्प्ट की स्पीड बेहतर हो सके.
यह न करें: खाली सेशन से शुरुआत न करें और
पहले prompt() कॉल के हिस्से के तौर पर, सिस्टम के निर्देश न भेजें. इससे लेटेंसी बढ़ जाती है, क्योंकि मॉडल को उन निर्देशों को आखिरी समय में प्रोसेस करना पड़ता है.
// ✅ DO: Create the session as early as possible (tip on warming up the model early) and use initialPrompts for system instructions in the create call
const session = await LanguageModel.create({
initialPrompts: [
{ role: 'system', content: 'You are a helpful assistant specialized in code reviews.' }
]
});
// A few moments later, when the user triggers the AI feature
const review = await session.prompt(`Review the following code:\n\n${code}`);
// ❌ DON'T: Send instructions using prompt() after creation
// const slowerSession = await LanguageModel.create();
// await slowerSession.prompt(`You are a helpful assistant specialized in code reviews.\n\nReview the following code:\n\n${code}`); // Higher latency
बार-बार किए जाने वाले टास्क के लिए सेशन क्लोन करना
इस पर लागू होता है: Prompt API.
Prompt API के लिए, हर सेशन बातचीत के कॉन्टेक्स्ट को ट्रैक करता है . इसमें पहले के सभी इंटरैक्शन को ध्यान में रखा जाता है. क्लोन, अपने पैरंट सेशन से सब कुछ इनहेरिट करता है. इसमें शुरुआती प्रॉम्प्ट और क्लोन किए जाने तक का पूरा इंटरैक्शन इतिहास शामिल होता है. इसलिए, सिर्फ़ ज़रूरी चीज़ें इनहेरिट करने के लिए, अपने इस्तेमाल को इस तरह से स्ट्रक्चर करें.
यह करें:
- बेस सेशन बनाना: अलग-अलग टास्क को बेहतर तरीके से मैनेज करने के लिए, एक बेस सेशन बनाएं. इसमें सिर्फ़ आपके सिस्टम के निर्देश शामिल हों और बातचीत का कोई पिछला कॉन्टेक्स्ट न हो.
- बेसलाइन क्लोन करना: नए टास्क के लिए, उस बेस सेशन पर
clone()का इस्तेमाल करें, ताकि सिस्टम के मुश्किल निर्देशों को फिर से पार्स करने की ज़रूरत न पड़े. इससे, पैरलल बातचीत की जा सकती है या किसी टास्क को उसकी बेसलाइन पर रीसेट किया जा सकता है.
यह न करें:
- अलग-अलग टास्क के लिए एक ही सेशन का दोबारा इस्तेमाल न करें. साथ ही, ऐसे किसी भी सेशन को क्लोन न करें जिसमें पहले से ही गैर-ज़रूरी इंटरैक्शन इतिहास मौजूद हो. इन दोनों पैटर्न की वजह से, मौजूदा टास्क में बातचीत का पिछला कॉन्टेक्स्ट शामिल हो सकता है.
- एक जैसे और मुश्किल सिस्टम निर्देशों के साथ,
create()को बार-बार कॉल न करें. परफ़ॉर्मेंस को ऑप्टिमाइज़ करने के लिए, इसके बजाय क्लोनिंग पैटर्न का इस्तेमाल करें.
// ✅ DO: Create a baseline session and clone it for each new task
const baseSession = await LanguageModel.create({
initialPrompts: [{
role: 'system',
content: 'You are a technical editor...',
}],
});
// Clone the base session once for the first task
const task1 = await baseSession.clone();
const response1 = await task1.prompt("Review this first draft...");
// ... Repeat the cloning pattern for subsequent independent tasks
// Each task starts fresh from the baseline system instructions
// ❌ DON'T:
// Bad performance pattern: repeated create() calls for identical tasks.
// This forces the model to re-parse instructions every time, increasing latency.
// const sessionA = await LanguageModel.create({ initialPrompts: [...] });
// await sessionA.prompt("Task 1...");
// const sessionB = await LanguageModel.create({ initialPrompts: [...] });
// await sessionB.prompt("Task 2...");
// Bad quality pattern: reusing the same session for unrelated tasks.
// const session = await LanguageModel.create();
// await session.prompt("Analyze this financial report...");
// Unrelated task in the same session:
// await session.prompt("Now write a children's story...");
इस्तेमाल न किए गए सेशन मिटाना
इस पर लागू होता है: सभी एपीआई.
यह करें: जिन सेशन की अब ज़रूरत नहीं है उनके लिए, साफ़ तौर पर destroy() को कॉल करें, ताकि किसी सुविधा का इस्तेमाल न होने पर मेमोरी खाली की जा सके. अगर क्लोनिंग पैटर्न का इस्तेमाल किया जाता है, तो बेस सेशन को सेव रखें और जिन क्लोन की अब ज़रूरत नहीं है उन्हें मिटा दें.
यह न करें: एक साथ कई बड़े सेशन को ऐक्टिव न रखें. हर सेशन मेमोरी का इस्तेमाल करता है. इससे संसाधनों का गैर-ज़रूरी इस्तेमाल होता है और यह समस्या बन सकती है. सेशन, कचरा इकट्ठा करने वाले टूल की मदद से अपने-आप साफ़ हो जाएंगे. हालांकि, destroy() को कॉल करने से मेमोरी ज़्यादा तेज़ी से खाली हो जाती है.
// ✅ DO: Use the clone and destroy it immediately after
const clone = await baseSession.clone();
const response = await clone.prompt("Quick task...");
// Free memory right away: destry the clone, keep the baseSession
clone.destroy();
स्ट्रीमिंग वाले जवाबों को सुरक्षित और बेहतर तरीके से रेंडर करना
इस पर लागू होता है: स्ट्रीमिंग की सुविधा वाले सभी एपीआई (Prompt, Summarizer, Writer, Rewriter, और Translator).
यह करें: एलएलएम के सभी आउटपुट को, भरोसेमंद न माने जाने वाले कॉन्टेंट के तौर पर लें. सिर्फ़ चंक नहीं, बल्कि पूरे कंबाइंड आउटपुट को सैनिटाइज़ करें, क्योंकि अपडेट के दौरान, नुकसान पहुंचाने वाला कोड अलग-अलग हिस्सों में बांटा जा सकता है. रेंडर करने से पहले, Sanitizer API का इस्तेमाल करें. यह सुविधा कुछ एपीआई के लिए उपलब्ध है. परफ़ॉर्मेंस में गिरावट से बचने के लिए, स्ट्रीमिंग मार्कडाउन पार्सर का इस्तेमाल करें जैसे स्ट्रीमिंग-मार्कडाउन.
यह न करें: हर चंक अपडेट पर, सीधे innerHTML सेट न करें. यह प्रोसेस धीमी होती है. खास तौर पर, सिंटैक्स हाइलाइटिंग जैसे मुश्किल फ़ॉर्मैटिंग के साथ. साथ ही, इसमें इंजेक्शन का खतरा भी होता है.
import * as smd from "streaming-markdown";
// Set up virtual buffer and Sanitizer API
const sanitizer = new Sanitizer({
allowElements: ['figure', 'figcaption', 'p', 'br', 'strong', 'em', 'img', 'a'],
allowAttributes: {
'loading': ['img'], 'decoding': ['img'], 'src': ['img'], 'href': ['a']
}
});
// Create an off-screen fragment so the parser doesn't cause flicker
// or trigger XSS in the live DOM during the building process.
const buffer = new DocumentFragment();
const parser = smd.parser_new(buffer);
// Use sanitizer as a gatekeeper / cleaner function so we can combine it with the streaming Markdown parser
function syncSanitized(target, sourceFragment) {
// .sanitize() returns a fresh, clean DocumentFragment
const cleanFragment = sanitizer.sanitize(sourceFragment);
// replaceChildren is the modern high-performance way to swap DOM content
target.replaceChildren(cleanFragment);
}
// Streaming Logic
// `chunks` keeps track of the raw string (useful for logs/debug)
chunks += chunk;
// Let the parser build the DOM incrementally in the buffer.
// This is high-performance because the buffer is not live
smd.parser_write(parser, chunk);
// Use the Sanitizer API to port the content safely to the container.
syncSanitized(container, buffer);
स्पीड के लिए इनपुट ऑप्टिमाइज़ करना
इस पर लागू होता है: सभी एपीआई.
यह करें: मॉडल को सिर्फ़ ज़रूरी जानकारी दें. मौजूदा टास्क से जुड़ी जानकारी के अलावा, बाकी सब कुछ हटा दें. बड़े डेटासेट के लिए, खास जानकारी और काम की चुनिंदा चीज़ें उपलब्ध कराएं.
यह न करें: एपीआई को, प्रोसेस न किया गया रॉ टेक्स्ट, गैर-ज़रूरी मेटाडेटा, एचटीएमएल टैग या फ़िल्टर न की गई बड़ी सूचियां न भेजें. इनपुट के साइज़ के साथ लेटेंसी काफ़ी बढ़ जाती है. इससे कई डिवाइसों पर, एआई की सुविधा काम नहीं करती.
// ✅ DO: Send only relevant text
const cleanText = document.querySelector('#article').innerText;
const summary = await Summarizer.summarize(cleanText);
// ❌ DON'T: Send the entire DOM structure
// const dirtyText = document.querySelector('#article').innerHTML;
अनुमान के मुताबिक नतीजे पाने के लिए, स्ट्रक्चर्ड आउटपुट का इस्तेमाल करना
इस पर लागू होता है: Prompt API.
यह करें: अगर आपको मॉडल से किसी खास फ़ॉर्मैट में डेटा चाहिए, तो JSON स्कीमा उपलब्ध कराने के लिए, responseConstraint फ़ील्ड देकर
स्ट्रक्चर्ड
आउटपुट
का इस्तेमाल करें. इससे यह पक्का होता है कि आउटपुट अनुमान के मुताबिक हो और आपको मुश्किल पोस्ट-प्रोसेसिंग या मैन्युअल पार्सिंग की ज़रूरत न पड़े.
यह न करें: सिर्फ़ नैचुरल लैंग्वेज के निर्देशों (जैसे, "सिर्फ़ JSON आउटपुट करें") पर भरोसा न करें. मॉडल में बातचीत के दौरान इस्तेमाल होने वाले ऐसे फ़िलर शामिल हो सकते हैं जो आपके पार्सर को तोड़ सकते हैं.
// ✅ DO: Use a JSON Schema for predictable results
const schema = {
type: "object",
properties: {
isTopicCats: { type: "boolean" }
}
};
const result = await session.prompt(`Is this post about cats?\n\n${post}`, {
responseConstraint: schema,
});
console.log(JSON.parse(result).isTopicCats);
जनरेशन को लंबाई की पाबंदियों से अलग करना
इस पर लागू होता है: Prompt API, क्योंकि यह इकलौता ऐसा एपीआई है जो स्ट्रक्चर्ड आउटपुट स्कीमा के साथ काम करता है.
यह करें: मॉडल को अपना जवाब नैचुरल तरीके से जनरेट करने दें. इसके बाद, क्लाइंट-साइड लॉजिक का इस्तेमाल करके, टेक्स्ट को अपने यूज़र इंटरफ़ेस (यूआई) के हिसाब से छोटा करें.
यह न करें: स्ट्रक्चर्ड आउटपुट स्कीमा
का इस्तेमाल करके, maxLength: 125 जैसी सख्त वर्ण सीमाएं लागू न करें. जब किसी मॉडल का जवाब, सेट की गई सीमा से ज़्यादा लंबा होता है, तो मॉडल, मतलब को कंप्रेस करने के लिए, ज़्यादा डेंसिटी वाले टोकन पर स्विच कर सकता है. जैसे, दूसरी भाषाएं या इमोजी. इससे बेतुका आउटपुट मिल सकता है.
/* DO: Handle overflow using CSS */
.result {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis; /* Displays '…' */
}
// ❌ DON'T: Force length in the prompt
const result = await session.prompt("Write a bio in exactly 50 characters.");
उपयोगकर्ता के इंतज़ार करने की क्षमता को मैनेज करना
इस पर लागू होता है: सभी एपीआई.
यह करें: उपयोगकर्ता के इंतज़ार करने की क्षमता को मैनेज करने के लिए, ऐनिमेशन और यूज़र इंटरफ़ेस (यूआई) की तकनीकों का इस्तेमाल करें. सबसे सही तरीका, आपके इस्तेमाल के उदाहरण और एपीआई के आउटपुट की अनुमानित लंबाई पर निर्भर करता है. कुछ आइडिया:
- लंबे कॉन्टेंट के लिए स्ट्रीमिंग: खास जानकारी या चैट के लिए, स्ट्रीमिंग डिफ़ॉल्ट रूप से हर टोकन के लिए टाइपराइटर इफ़ेक्ट बनाती है. इससे नैचुरल और तुरंत फ़ीडबैक मिल सकता है.
- छोटे टास्क (या लंबे एसिंक्रोनस टास्क) के लिए नॉन-स्ट्रीमिंग: छोटे आउटपुट के लिए, जैसे कि ऑल्ट-टेक्स्ट, नॉन-स्ट्रीमिंग से ज़्यादा बेहतर यूज़र इंटरफ़ेस (यूआई) बनाया जा सकता है. इससे, मौजूदा टास्क के रेंडर होने के दौरान, एआई के अगले टास्क को तैयार करने के लिए समय भी मिलता है. यह तरीका, लंबे एसिंक्रोनस या बैकग्राउंड टास्क के लिए भी काम करता है. अगर उपयोगकर्ता को अपनी यात्रा जारी रखने के लिए, आउटपुट का इंतज़ार नहीं करना पड़ता है, तो आउटपुट को तुरंत जनरेट करने की कोई ज़रूरत नहीं है. यूज़र इंटरफ़ेस (यूआई) में यह सिग्नल दें कि प्रोसेस जारी है.
- अपडेट के लिए विज़ुअल ट्रांज़िशन: टेक्स्ट का अनुवाद या उसे दोबारा लिखने के दौरान, ऐनिमेशन का इस्तेमाल करें. जैसे, वर्ड-मॉर्फिंग.
यह न करें: विज़ुअल क्यू के बिना, यूज़र इंटरफ़ेस (यूआई) को अपडेट न करें.
समय और काम के बारे में उपयोगकर्ता के मेंटल मॉडल के हिसाब से काम करना
इस पर लागू होता है: सभी एपीआई.
यह करें: अगर कोई जवाब तुरंत मिलता है, तो एक या दो सेकंड की देरी करें. विरोधाभास के तौर पर, उपयोगकर्ताओं को नतीजे ज़्यादा भरोसेमंद लग सकते हैं, जब उन्हें लगता है कि जनरेशन की प्रोसेस, टास्क की मुश्किल के हिसाब से है. यह सिग्नल देने के लिए ऐनिमेशन का इस्तेमाल करें कि एआई की कोई प्रोसेस हुई है.
यह न करें: यूज़र इंटरफ़ेस (यूआई) में तुरंत बदलाव करके, उपयोगकर्ताओं को हैरान न करें.
उपयोगकर्ताओं को एआई के किए गए बदलावों पर तुरंत नेविगेट करने और उन्हें पहले जैसा करने की अनुमति देना
इस पर लागू होता है: सभी एपीआई.
यह करें: अपने यूज़र इंटरफ़ेस (यूआई) में स्टेपर या नेविगेशन इतिहास शामिल करें, ताकि उपयोगकर्ता अलग-अलग नतीजों को भरोसे के साथ एक्सप्लोर कर सकें. साथ ही, उन्हें एआई के किए गए बदलावों को तुरंत पहले जैसा करने की अनुमति दें. इससे यह पक्का होता है कि अलग-अलग वर्शन आसानी से उपलब्ध हों.
यह न करें: उपयोगकर्ता के पिछले ड्राफ़्ट या एआई के किसी ऐसे नतीजे को ओवरराइट न करें जो उन्हें पसंद आया हो. साथ ही, उन्हें वर्शन की तुलना करने, उन्हें पहले जैसा करने या वापस जाने का कोई तरीका न दें.
उपयोगकर्ताओं को कंट्रोल करने और ओवरराइड करने की अनुमति देना
इस पर लागू होता है: सभी एपीआई.
यह करें: हमेशा उपयोगकर्ता को फ़ाइनल कंट्रोल दें. सुझावों को मैन्युअल तरीके से ओवरराइड करने का तरीका उपलब्ध कराएं. एपीआई से गलत नतीजे मिल सकते हैं.
यह न करें: एआई से जनरेट किए गए नतीजे को, इकलौते विकल्प के तौर पर न दिखाएं.
बार-बार किए जाने वाले टास्क के लिए नतीजों को कैश मेमोरी में सेव करना
इस पर लागू होता है: सभी एपीआई.
यह करें: बार-बार किए जाने वाले इनपुट या क्वेरी के लिए, नतीजों को स्थानीय कैश मेमोरी में सेव करने की सुविधा लागू करें. जैसे, sessionStorage या IndexedDB का इस्तेमाल करके. कैश मेमोरी में सेव किए गए नतीजों की संख्या बढ़ाने के लिए, सफ़ेद जगहें हटाकर और लोअरकेस में बदलकर, इनपुट को सामान्य करें. मुश्किल इनपुट के लिए, जैसे कि इमेज, कैश मेमोरी की कुंजी के तौर पर इस्तेमाल करने के लिए हैश जनरेट करें. अपनी कैश मेमोरी के लिए, टाइम टू लिव (टीटीएल) को कम सेट करें. इसके अलावा, बैकग्राउंड में अपडेट करते समय, कैश मेमोरी में सेव किए गए नतीजों को दिखाएं. अगर नतीजा संतोषजनक नहीं है, तो उपयोगकर्ता को नया अनुमान लगाने की सुविधा दें.
यह न करें: बार-बार की जाने वाली खोज क्वेरी या एक जैसे डेटा इनपुट के लिए, एक ही अनुमान को दोबारा न चलाएं. जैसे, जब कोई उपयोगकर्ता खोज के नतीजों के बीच आगे-पीछे नेविगेट करता है. डिवाइस पर अनुमान लगाने की सुविधा, क्लाउड के खर्च के मामले में मुफ़्त है. हालांकि, उपयोगकर्ता के समय और बैटरी लाइफ़ के मामले में यह महंगी है.
// ✅ DO: Check a local cache before running inference
async function getAiResponse(userInput, forceRefresh = false) {
// Normalize the query to increase cache hits
const query = userInput.trim().toLowerCase();
const cacheKey = `ai_results_${query}`;
const TTL_MS = 3600000; // 1 hour conservative TTL
if (!forceRefresh) {
const itemStr = localStorage.getItem(cacheKey);
if (itemStr) {
const item = JSON.parse(itemStr);
const now = Date.now();
// Check if the item has expired
if (now < item.expiry) {
// Lightweight safety check before rendering
if (isValid(item.value)) return item.value;
} else {
// Delete the stale entry if the TTL has passed
localStorage.removeItem(cacheKey);
}
}
}
// Fallback: Run inference if no valid cache exists
const session = await LanguageModel.create();
const response = await session.prompt(userInput);
// Store the result for future use (with an expiration)
const cacheData = {
value: response,
expiry: Date.now() + TTL_MS
};
localStorage.setItem(cacheKey, JSON.stringify(cacheData));
return response;
}