تاريخ النشر: 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 في الأماكن التي تتوفّر فيها. لتجنُّب انخفاض الأداء، استخدِم محلّل Markdown للبث، مثل streaming-markdown.
لا تفعل ما يلي: لا تضبط 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);
تحسين الإدخال لزيادة السرعة
ينطبق على: جميع واجهات برمجة التطبيقات.
الإجراءات التي يجب اتّخاذها: لا ترسِل إلى النموذج سوى المعلومات الضرورية للغاية. احذف كل ما لا صلة له بالمهمة الحالية. بالنسبة إلى مجموعات البيانات الكبيرة، قدِّم نظرة عامة موجزة ومجموعة صغيرة من العناصر ذات الصلة.
لا تفعل ما يلي: لا تُرسِل إلى واجهات برمجة التطبيقات نصًا أوليًا غير معالج أو بيانات وصفية غير ضرورية أو علامات HTML أو قوائم كبيرة غير مفلترة. يزداد وقت الاستجابة بشكل كبير مع حجم الإدخال، ما قد يجعل ميزة الذكاء الاصطناعي تبدو غير صالحة للاستخدام على العديد من الأجهزة.
// ✅ 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.
يجب: عندما تحتاج إلى أن يعرض النموذج البيانات بتنسيق معيّن، استخدِم النتائج المنظَّمة من خلال توفير الحقل responseConstraint لتقديم مخطط JSON. يضمن ذلك أن تكون النتائج قابلة للتوقّع ويمنع الحاجة إلى إجراء معالجة لاحقة معقّدة أو تحليل يدوي.
لا تفعل ما يلي: لا تعتمد على تعليمات اللغة الطبيعية (مثل "إخراج 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) للإدخالات أو طلبات البحث المتكرّرة. يمكنك توحيد تنسيق الإدخال عن طريق إزالة المسافات البيضاء وتحويل الأحرف إلى أحرف صغيرة لزيادة عدد مرات الوصول إلى ذاكرة التخزين المؤقت. بالنسبة إلى المدخلات الكبيرة الحجم، مثل الصور، أنشئ قيمة تجزئة لاستخدامها كمفتاح ذاكرة تخزين مؤقت. اضبط مدة بقاء (TTL) معقولة لذاكرة التخزين المؤقتة (أو اعرض النتائج المخزّنة مؤقتًا أثناء تعديلها في الخلفية). السماح للمستخدم بتشغيل استنتاج جديد إذا كانت النتيجة غير مرضية.
لا تفعل ما يلي: لا تعِد تشغيل الاستنتاج نفسه لطلب بحث متكرّر أو إدخال بيانات مطابق حيث لا يكون التغيّر مطلوبًا، مثلاً عندما يتنقّل المستخدم ذهابًا وإيابًا بين نتائج البحث. يؤدي ذلك إلى تحسين سرعة الاستجابة والاستخدام الفعّال لقدرات الحوسبة المحلية.
// ✅ 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;
}