النموذج اللغوي

ميزات الويب: LanguageModel

تتيح واجهة برمجة التطبيقات Prompt API للمطوّرين تنفيذ مهام معالجة اللغة الطبيعية مباشرةً في المتصفّح باستخدام Gemini Nano. يضمن هذا النهج المستند إلى الذكاء الاصطناعي المضمّن خصوصية المستخدم، ويقلّل من تكاليف الخادم، ويتيح العمل بلا إنترنت.

1. البدء ومتطلبات الأجهزة

تتوفّر واجهة Prompt API حاليًا في الإصدار 148 من Chrome (على أجهزة الكمبيوتر المكتبي) لأنظمة التشغيل Windows وmacOS وLinux وChromebook Plus.

المتطلبات الأساسية للأجهزة

  • مساحة التخزين: 22 غيغابايت من المساحة الخالية (للملف الشخصي الأوّلي والنموذج)
  • الذاكرة/وحدة المعالجة المركزية: ذاكرة وصول عشوائي (RAM) بسعة 16 غيغابايت و4 نوى أو أكثر لوحدة المعالجة المركزية
  • وحدة معالجة الرسومات: ذاكرة وصول عشوائي للفيديو (VRAM) بسعة 4 غيغابايت أو أكثر (مطلوبة لإدخال الصوت)
  • الشبكة: مطلوبة فقط لتنزيل النموذج الأولي.

تهيئة واجهة برمجة التطبيقات

تحقَّق من توفّر النموذج قبل بدء عملية التنزيل:

const availability = await LanguageModel.availability();

// Do not call create() when unavailable — the model cannot run on this device.
if (availability !== 'unavailable') {
    const session = await LanguageModel.create({
        monitor(m) {
            // Inform the user while the model downloads so the UI doesn't appear frozen.
            m.addEventListener('downloadprogress', (e) => {
                console.log(`Downloaded ${e.loaded * 100}%`);
            });
        },
    });
}

2. الإمكانات الأساسية لإنشاء الطلبات

تحذف أمثلة الجلسات في هذا القسم session.destroy() للإيجاز. يجب دائمًا استدعاء session.destroy() عندما لا تكون هناك حاجة إلى جلسة لإخلاء ذاكرة الجهاز (يُرجى الاطّلاع على القسم 5).

الردود الأساسية والمتدفقة

للردود القصيرة، استخدِم prompt(). بالنسبة إلى المحتوى الأطول، استخدِم promptStreaming() لتوفير واجهة مستخدم أكثر استجابة.

MANDATORY: Never assign model output to innerHTML. مخرجات النموذج غير موثوقة ويمكن أن تحتوي على ترميز تم حقنه. استخدِم دائمًا textContent أو معقّمًا.

const session = await LanguageModel.create();

// prompt() accumulates the full response before resolving — use for short, one-shot output.
const result = await session.prompt('Write a haiku about coding.');
// textContent, not innerHTML — model output is untrusted and must not be parsed as markup.
outputEl.textContent = result;

// promptStreaming() yields independent chunks that must be concatenated;
// use for longer content so each chunk can be rendered progressively.
const stream = session.promptStreaming('Write a long story about a robot.');
let completeResult = '';
for await (const chunk of stream) {
    completeResult += chunk;
    outputEl.append(chunk);
}
console.log('Full story:', completeResult);

إدخال متعدد الوسائط

تتيح واجهة Prompt API إدخال النصوص والمقاطع الصوتية والمحتوى المرئي (الصور ولوحات الرسم وإطارات الفيديو).

const session = await LanguageModel.create({
    // Declaring expected input types lets the browser optimize model loading.
    expectedInputs: [{ type: 'text' }, { type: 'image' }],
    expectedOutputs: [{ type: 'text' }],
});

const response = await session.prompt([
    {
        role: 'user',
        content: [
            { type: 'text', value: 'What is in this image?' },
            { type: 'image', value: document.querySelector('canvas') },
        ],
    },
]);

3- الإدارة المتقدّمة للجلسات

تسمح الجلسات للنموذج بالحفاظ على السياق في تفاعلات متعددة.

السياق والحصة

لكل جلسة حد أقصى لعدد الرموز المميّزة. يمكنك مراقبة الاستخدام من خلال session.contextUsage وsession.contextWindow. إذا تجاوزت النافذة الحدّ الأقصى، يتم تجاهل الرسائل الأقدم (باستثناء طلب النظام).

استنساخ الجلسات

يُعدّ الاستنساخ طريقة فعّالة لبدء محادثات متوازية تشترك في السياق الأولي نفسه (مثل شخصية "النظام") بدون إعادة الإعداد.

const mainSession = await LanguageModel.create({
    initialPrompts: [{ role: 'system', content: 'You speak like a pirate.' }],
});

const branchA = await mainSession.clone();
const branchB = await mainSession.clone();
// Destroy the base after cloning — the clones own their own context from here.
mainSession.destroy();

استعادة الجلسات السابقة

نعمل حاليًا على تطوير ميزة "استعادة" أصلية، ولكن يمكنك إعادة إنشاء جلسة من خلال إدخال السجلّ السابق في initialPrompts.

ملاحظة: localStorage غير مشفّر ودائم. قد يتضمّن سجلّ المحادثات المخزَّن معلومات تكشف الهوية الشخصية للمستخدم، لذا يُرجى مراعاة الآثار المترتبة على الخصوصية قبل الاحتفاظ بسجلّ المحادثات.

// || '[]' ensures JSON.parse never receives null when the key doesn't exist yet.
const history = JSON.parse(localStorage.getItem('chat_history') || '[]');
const session = await LanguageModel.create({
    initialPrompts: history, // Array of {role, content} objects
});

4. الناتج المنظَّم باستخدام مخطّط JSON

لمنع النموذج من إضافة "ثرثرة" (مثل "بالتأكيد، إليك ملف JSON:")، استخدِم مخطّط JSON من خلال الحقل responseConstraint. يضمن ذلك أن يكون الناتج بتنسيق JSON صالح يمكن تحليله على الفور.

مثال: تصنيف الآراء

// Pass the schema as a plain object — do not JSON.stringify() it first.
const schema = {
    type: 'object',
    properties: {
        rating: { type: 'number', minimum: 1, maximum: 5 },
        is_positive: { type: 'boolean' },
    },
    required: ['rating', 'is_positive'],
};

const result = await session.prompt(
    "Rate the following feedback: 'The food was great!'",
    { responseConstraint: schema },
);

const data = JSON.parse(result);
console.log(data.rating); // 5

القيود والبادئات

يمكنك توجيه النموذج بشكل أكبر من خلال ملء ردّ المساعد مسبقًا باستخدام prefix: true.

const character = await session.prompt([
    { role: 'user', content: 'Create a character sheet' },
    { role: 'assistant', content: '```json\n', prefix: true },
]);

5- أفضل الممارسات والأمان

  • تنظيف الموارد: يجب دائمًا استدعاء session.destroy() عند انتهاء المحادثة لإخلاء الذاكرة.
  • أمان المخرجات: مخرجات النموذج غير موثوقة. يجب دائمًا كتابة النتائج في textContent، وليس في innerHTML، لمنع حقن XSS من مخرجات النموذج الضارة.
  • استخدِم أداة تنقية مثل Sanitizer API أو DOMPurify إذا كنت بحاجة إلى السماح باستخدام HTML محدود.
  • إلغاء المهام: استخدِم AbortController للسماح للمستخدمين بإيقاف عمليات إنشاء المحتوى التي تستغرق وقتًا طويلاً. مرِّر signal إلى prompt() أو promptStreaming()، وليس إلى LanguageModel.create().
  • الأمان: يمكنك استخدام "سياسات الأذونات" للتحكّم في الوصول إلى إطارات iframe: <iframe src="..." allow="language-model"></iframe>.
  • التصميم: راجِع دليل People + AI لضمان استخدام الذكاء الاصطناعي بشكل مسؤول.

من خلال الجمع بين النتائج المنظَّمة والإدارة الفعّالة للجلسات، يمكن للمطوّرين إنشاء تطبيقات ذكاء اصطناعي معقّدة وقائمة على الحالة تعمل بالكامل على جهاز المستخدم.

الإجراءات المطلوبة وغير المسموح بها

للاطّلاع على القائمة الكاملة والمفصّلة للممارسات التي يجب اتّباعها وتلك التي يجب تجنّبها، يُرجى الانتقال إلى https://developer.chrome.com/docs/ai/built-in-ai-dos-donts.md.txt. في ما يلي الخلاصة:

تحضير النموذج في وقت مناسب

ينطبق ذلك على: جميع واجهات برمجة التطبيقات، مثل Summarizer وTranslator وWriter.

ما يجب فعله: ابدأ الجلسة فور تحديد نية المستخدم في استخدام الميزة التي تستخدم الذكاء الاصطناعي، مثلاً عندما ينتقل المستخدم إلى مساحة أدوات ذكاء اصطناعي ذات صلة، أو يمرّر مؤشر الماوس فوق مساحة عمل تستخدم الذكاء الاصطناعي، أو يتفاعل مع واجهة المستخدم المحيطة بالميزة. يسمح الإعداد المسبق للجلسة بتحميل النموذج في الذاكرة بهدوء في الخلفية أثناء إعداد المستخدم لمهمته، ما يزيل وقت الاستجابة الذي يمكن تجنُّبه عند بدء التشغيل على البارد. حاوِل أن تكون متقدّمًا بخطوة من خلال بدء مهمة الذكاء الاصطناعي التالية الأكثر احتمالاً فور بدء عرض النتيجة الحالية، على سبيل المثال، إذا كانت الميزة مصمّمة للاستخدام التكراري.

ما يجب تجنّبه: ما لم يكن ذلك ضروريًا، لا تنتظر حتى ينقر المستخدم على "إنشاء" لبدء الجلسة. يؤدي ذلك إلى تأخير في بدء التشغيل على البارد، لأنّ النموذج يجب أن يتم تحميله أولاً في الذاكرة وإعداد مسار التنفيذ.

ضبط الطلبات الأولية أثناء إنشاء التطبيق

ينطبق ذلك على: Prompt API.

ننصحك بتقديم تعليمات النظام أثناء بدء الجلسة لتحسين سرعة الطلب الأول.

ما يجب تجنُّبه: بدء جلسة فارغة وإرسال تعليمات النظام كجزء من طلب prompt() الأول. يؤدي ذلك إلى زيادة وقت الاستجابة لأنّه يفرض على النموذج معالجة هذه التعليمات في اللحظة الأخيرة.

استنساخ الجلسات للمهام المتكررة

ينطبق ذلك على: Prompt API.

في Prompt API، تتتبّع كل جلسة سياق المحادثة، مع مراعاة جميع التفاعلات السابقة. بما أنّ النسخة المكرّرة تكتسب كل شيء من الجلسة الرئيسية، بما في ذلك الطلبات الأولية وجميع سجلّ التفاعل حتى نقطة النسخ، عليك تنظيم استخدامك لاكتساب ما تحتاجه فقط.

ما يجب فعله:

  • إنشاء جلسة أساسية: للتعامل مع المهام غير المرتبطة ببعضها بكفاءة، أنشئ جلسة أساسية تحتوي فقط على تعليمات النظام ولا تتضمّن أي سياق محادثة سابق.
  • استنسِخ الأساس: استخدِم clone() في تلك الجلسة الأساسية للمهام الجديدة لتوفير الوقت والجهد اللازمَين لإعادة تحليل تعليمات النظام. يتيح لك ذلك إنشاء محادثات موازية أو إعادة ضبط مهمة على حالتها الأساسية.

ما ننصحك بتجنّبه:

  • لا تُعِد استخدام الجلسة نفسها لمهام غير مرتبطة، وتجنَّب استنساخ أي جلسة تحتوي على سجلّ تفاعل غير ضروري. يمكن أن يتسبب كلا النمطين في تداخل السياق السابق غير ذي الصلة مع مهمتك الحالية.
  • لا تطلب create() بشكل متكرر باستخدام تعليمات النظام نفسها. استخدِم نمط الاستنساخ بدلاً من ذلك لتحسين الأداء.

إلغاء الجلسات غير المستخدَمة

تنطبق على: جميع واجهات برمجة التطبيقات.

الإجراء المطلوب: استدعاء destroy() بشكل صريح في الجلسات التي لم تعد بحاجة إليها لإخلاء مساحة في الذاكرة عند توقّف استخدام ميزة معيّنة. إذا كنت تستخدم نمط استنساخ، احتفظ بالجلسة الأساسية ودمّر النسخ التي لم تعد بحاجة إليها.

ما يجب تجنّبه: إبقاء عدة جلسات كبيرة نشطة. تستهلك كل جلسة ذاكرة، ما يؤدي إلى استخدام غير ضروري للموارد وقد يصبح مشكلة. سيتم تنظيف الجلسات بشكل طبيعي من خلال أداة تجميع المهملات، ولكن استدعاء destroy() يؤدي إلى إخلاء الذاكرة بسرعة أكبر.

عرض الردود المتسلسلة بأمان وكفاءة

ينطبق ذلك على: جميع واجهات برمجة التطبيقات التي تتيح البث (Prompt وSummarizer وWriter وRewriter وTranslator).

ما يجب فعله: يجب التعامل مع جميع مخرجات النماذج اللغوية الكبيرة على أنّها محتوى غير موثوق به. يجب تنظيف الناتج المجمّع بالكامل، وليس فقط أجزاء منه، لأنّ الرمز البرمجي الضار قد يكون مقسّمًا على عدة تعديلات. قبل العرض، استخدِم واجهة برمجة التطبيقات Sanitizer حيثما كان ذلك متاحًا. لتجنُّب انخفاض الأداء، استخدِم محلّل لغة Markdown للبث، مثل streaming-markdown.

ما يجب تجنّبه: ضبط innerHTML مباشرةً عند كل تعديل على الأجزاء هذا بطيء، خاصة مع التنسيق المعقد مثل تمييز بناء الجملة، وعرضة للحقن.

تحسين الإدخال لزيادة السرعة

تنطبق على: جميع واجهات برمجة التطبيقات.

ما يجب فعله: لا تُرسِل إلى النموذج سوى ما هو ضروري للغاية. أزِل كل ما لا يتعلّق بالمهمة الحالية. بالنسبة إلى مجموعات البيانات الكبيرة، قدِّم نظرة عامة موجزة ومجموعة صغيرة من العناصر ذات الصلة.

ما يجب تجنُّبه: إرسال نصوص أولية غير معالَجة أو بيانات وصفية غير ضرورية أو علامات HTML أو قوائم كبيرة غير مفلترة إلى واجهات برمجة التطبيقات يزداد وقت الاستجابة بشكل كبير مع حجم الإدخال، ما قد يجعل الميزة التي تستخدم الذكاء الاصطناعي تبدو معطّلة على العديد من الأجهزة.

استخدام المخرجات المنظَّمة للحصول على نتائج متوقّعة

ينطبق ذلك على: Prompt API.

ننصحك بما يلي: عندما تحتاج إلى أن يعرض النموذج البيانات بتنسيق معيّن، استخدِم المخرجات المنظَّمة من خلال توفير حقل responseConstraint لتقديم مخطط JSON. يضمن ذلك أن تكون النتائج متوقعة ويغنيك عن الحاجة إلى إجراء معالجة لاحقة معقّدة أو تحليل لغوي يدوي.

لا ننصحك بما يلي: الاعتماد على تعليمات اللغة الطبيعية (مثل "إخراج JSON فقط") وحدها. قد تتضمّن النماذج عبارات حشو في المحادثة تؤدي إلى تعطُّل المحلل اللغوي.

فصل عملية الإنشاء عن قيود الطول

ينطبق ذلك على: Prompt API، لأنّها واجهة برمجة التطبيقات الوحيدة التي تتيح استخدام مخططات الإخراج المنظَّمة.

ما يجب فعله: اسمح للنموذج بإنشاء ردّه بشكل طبيعي، ثم استخدِم منطق جهة العميل لاقتطاع النص ليتناسب مع واجهة المستخدم.

ما يجب تجنُّبه: فرض حدود صارمة على عدد الأحرف المسموح به، مثل maxLength: 125، باستخدام مخططات المخرجات المنظَّمة. عندما يكون ردّ النموذج أطول من الحدّ الذي وضعته، قد ينتقل النموذج إلى الرموز المميّزة العالية الكثافة، مثل اللغات الأجنبية أو الإيموجي، لضغط المعنى، ما يؤدي إلى تقديم ردود غير منطقية.

إبقاء المستخدم على علم

تنطبق على: جميع واجهات برمجة التطبيقات.

ما يجب فعله: استخدِم الرسوم المتحركة والإشارات المرئية ومؤشرات مستوى التقدّم لإبقاء المستخدم على عِلم بما يحدث، وذلك حسب مدى تعقيد المهمة ومدتها المتوقعة. يعتمد النهج الأمثل على حالة الاستخدام والطول المتوقّع لناتج واجهة برمجة التطبيقات. بعض الأفكار:

  • العرض التدريجي للمحتوى الطويل: بالنسبة إلى الملخّصات أو المحادثات، يؤدي العرض التدريجي إلى إنشاء تأثير آلة كاتبة لكل رمز مميّز تلقائيًا. يمكن أن يبدو هذا طبيعيًا ويقدّم ملاحظات فورية.
  • عدم استخدام البث للمهام القصيرة (أو المهام الطويلة غير المتزامنة): بالنسبة إلى النتائج القصيرة، مثل النص البديل، يمكن أن يؤدي عدم استخدام البث إلى إنشاء واجهة مستخدم أكثر أناقة. ويوفّر أيضًا الوقت لإعداد مهمة الذكاء الاصطناعي التالية بشكل تخميني أثناء عرض المهمة الحالية. ينطبق هذا النهج أيضًا على المهام الطويلة غير المتزامنة أو التي يتم تنفيذها في الخلفية. إذا لم يكن المستخدم محظورًا من مواصلة رحلته في انتظار المخرجات، لن تكون هناك حاجة ملحّة لإنتاج المخرجات فورًا. أشِر إلى أنّ العملية جارية في واجهة المستخدم.
  • الانتقالات المرئية للتحديثات: عند ترجمة النص أو إعادة كتابته، استخدِم الصور المتحركة، مثل تحويل الكلمات.

ما يجب تجنّبه: تعديل واجهة المستخدم بدون إشارات مرئية

التوافق مع النموذج الذهني للمستخدم في ما يتعلّق بالوقت والعمل

تنطبق على: جميع واجهات برمجة التطبيقات.

ما يجب فعله: ننصحك بتأخير الردّ بشكل اصطناعي لمدة ثانية أو ثانيتين إذا كان الردّ فوريًا تقريبًا. ومن المفارقات أنّ المستخدمين قد يجدون النتائج أكثر موثوقية عندما يلاحظون أنّ عملية إنشاء المحتوى تتوافق مع صعوبة المهمة التي يتصوّرونها. استخدِم الصور المتحركة للإشارة إلى حدوث المعالجة بالذكاء الاصطناعي.

لا ننصحك بما يلي: مفاجأة المستخدمين باستبدال واجهة المستخدم على الفور.

السماح للمستخدمين بالتنقّل بسرعة والتراجع عن التعديلات التي أجراها الذكاء الاصطناعي

تنطبق على: جميع واجهات برمجة التطبيقات.

ما يجب فعله: زوِّد واجهة المستخدم بمؤشر تقدّم أو سجلّ تنقّل يتيح للمستخدمين استكشاف نتائج مختلفة بثقة، واسمح لهم بالتراجع بسرعة عن التعديلات التي أجراها الذكاء الاصطناعي. يضمن ذلك أن الإصدارات المختلفة لا تزال متاحة بسهولة.

لا يُنصح بما يلي: استبدال المسودة السابقة للمستخدم أو نتيجة الذكاء الاصطناعي التي قد تكون نالت إعجابه بدون توفير طريقة للرجوع إلى الإصدارات السابقة أو مقارنتها.

تعزيز تحكّم المستخدمين وإمكانية تجاوزهم للإعدادات

تنطبق على: جميع واجهات برمجة التطبيقات.

ما يجب فعله: اجعل المستخدم هو المحرِّر النهائي لكل المحتوى الذي يتم إنشاؤه. توفير خيارات تجاوز بديهية لكي يحتفظ المستخدم بالملكية الكاملة للنتيجة النهائية قد تقدّم واجهات برمجة التطبيقات نتائج غير صحيحة.

ما يجب تجنُّبه: فرض نتيجة من إنشاء الذكاء الاصطناعي كخيار وحيد.

تخزين نتائج المهام المتكررة مؤقتًا

تنطبق على: جميع واجهات برمجة التطبيقات.

الإجراء الصحيح: يمكنك استخدام ذاكرة تخزين مؤقت محلية للنتائج (على سبيل المثال، باستخدام sessionStorage أو IndexedDB) للإدخالات أو طلبات البحث المتكررة. Normalize the input by trimming whitespace and lowercasing to increase cache hits. بالنسبة إلى المدخلات الكبيرة، مثل الصور، يمكنك إنشاء تجزئة لاستخدامها كمفتاح ذاكرة تخزين مؤقت. اضبط مدة بقاء (TTL) متحفظة لذاكرة التخزين المؤقت (أو اعرض النتائج المخزّنة مؤقتًا أثناء تحديثها في الخلفية). السماح للمستخدم ببدء استنتاج جديد إذا كانت النتيجة غير مرضية.

ما يجب تجنّبه: إعادة تشغيل الاستنتاج نفسه لطلب بحث متكرر أو إدخال بيانات متطابقة عندما لا يكون التباين مرغوبًا فيه، على سبيل المثال عندما يتنقّل المستخدم ذهابًا وإيابًا بين نتائج البحث. ويؤدي ذلك إلى تحسين معدّل الاستجابة والاستخدام الفعّال للحوسبة المحلية.

6. استراتيجيات احتياطية

قبل الاستخدام، تحقَّق مما إذا كان عنصر LanguageModel متاحًا في النطاق العام:

if ('LanguageModel' in self) {
  // The Prompt API is supported.
} else {
  // Execute fallback strategy
}

إذا كانت واجهة برمجة التطبيقات Prompt API غير متوافقة أو إذا أظهرت عمليات التحقّق من مدى التوفّر أنّها "غير متاحة"، عليك استخدام بديل مناسب:

  • الاستعانة بواجهة برمجة تطبيقات عن بُعد: إعادة توجيه طلب الرصد إلى نقطة نهاية خادم أو Cloud APIs (مثل Vertex AI Gemini API).
  • استخدام واجهة برمجة تطبيقات محلية كحلّ احتياطي: يمكنك إعادة توجيه طلب الرصد إلى نقطة نهاية محلية، مثلاً باستخدام Transformers.js.