מודל שפה

תכונות באינטרנט: LanguageModel

‫Prompt API מאפשר למפתחים להריץ משימות של עיבוד שפה טבעית ישירות בדפדפן באמצעות Gemini Nano. הגישה הזו של AI מובנה שומרת על פרטיות המשתמשים, מפחיתה את עלויות השרת ומאפשרת פונקציונליות אופליין.

1. תחילת העבודה ודרישות החומרה

‫Prompt API זמין כרגע ב-Chrome החל מגרסה 148 (למחשב) ל-Windows, ל-macOS, ל-Linux ול-Chromebook Plus.

דרישות סף לחומרה

  • אחסון: 22GB של שטח פנוי (לפרופיל ולמודל הראשוניים).
  • זיכרון/מעבד (CPU): זיכרון RAM בנפח 16GB ו-4 ליבות מעבד או יותר.
  • מעבד גרפי (GPU): זיכרון VRAM בנפח 4GB או יותר (נדרש לקלט אודיו).
  • רשת: נדרשת רק להורדה הראשונית של המודל.

הפעלת ה-API

בודקים אם המודל זמין לפני שמפעילים הורדה:

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() כדי לספק ממשק משתמש רספונסיבי יותר.

חובה: אף פעם אל תקצו את הפלט מהמודל ל-innerHTML. הפלט מהמודל לא מהימן ויכול להכיל תגי עיצוב מוזרקים. תמיד צריך להשתמש ב-textContent או ב-sanitizer.

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 לא מוצפן וקבוע. היסטוריית השיחות שנשמרת עשויה לכלול פרטים אישיים מזהים (PII) של המשתמשים. חשוב להביא בחשבון את ההשלכות על הפרטיות לפני ששומרים את היסטוריית הצ'אט.

// || '[]' 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

אילוצים ותחיליות

אפשר להנחות את המודל עוד יותר על ידי מילוי מראש של התשובה של Assistant באמצעות prefix: true.

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

5. שיטות מומלצות ובטיחות

  • ניקוי משאבים: תמיד צריך להפעיל את session.destroy() כשהשיחה מסתיימת כדי לפנות זיכרון.
  • בטיחות הפלט: הפלט מהמודל לא מהימן. כדי למנוע הזרקת XSS מפלט זדוני של המודל, תמיד צריך לכתוב את התוצאות ב-textContent ולא ב-innerHTML.
  • אם אתם צריכים לאפשר HTML מוגבל, השתמשו בכלי לניקוי קוד כמו Sanitizer API או DOMPurify.
  • ביטול משימות: משתמשים ב-AbortController כדי לאפשר למשתמשים להפסיק תהליכי יצירה ארוכים. צריך להעביר את signal אל prompt() או promptStreaming(), ולא אל LanguageModel.create().
  • אבטחה: משתמשים במדיניות הרשאות כדי לשלוט בגישה ב-iframes: ‏<iframe src="..." allow="language-model"></iframe>.
  • עיצוב: כדאי לעיין במדריך People + AI כדי לוודא שהטמעת ה-AI מתבצעת באופן אחראי.

כשמשלבים פלט מובנה עם ניהול סשנים יעיל, המפתחים יכולים ליצור אפליקציות AI מורכבות עם שמירת מצב שפועלות לגמרי במכשיר של המשתמש.

מה לעשות ומה לא לעשות

הרשימה המלאה של מה שמותר ומה שאסור לעשות מופיעה בכתובת https://developer.chrome.com/docs/ai/built-in-ai-dos-donts.md.txt. הנה תקציר של מה שקרה:

הכנת המודל בזמן סביר

רלוונטי לכל ממשקי ה-API, למשל Summarizer,‏ Translator ו-Writer.

מה כן לעשות: להפעיל את הסשן ברגע שברור שהמשתמש מתכוון להשתמש בפיצ'ר ה-AI. למשל, כשהמשתמש נכנס לממשק רלוונטי של כלי AI, מעביר את העכבר מעל סביבת עבודה של AI או יוצר אינטראקציה עם ממשק המשתמש שמסביב לפיצ'ר. הכנה מוקדמת של הסשן מאפשרת למודל להיטען לזיכרון בשקט ברקע בזמן שהמשתמש מגדיר את המשימה שלו, וכך למנוע זמן אחזור מיותר של הפעלה קרה. נסו להיות צעד אחד קדימה ולהתחיל את משימת ה-AI הבאה עם הסבירות הגבוהה ביותר ברגע שאתם מתחילים לעבד את התוצאה הנוכחית, למשל, אם התכונה מיועדת לשימוש איטרטיבי.

מה לא לעשות: אלא אם זה הכרחי, אל תחכו שהמשתמש ילחץ על "יצירה" כדי להתחיל את הסשן. זה מוביל לעיכוב בהפעלה במצב התחלתי, כי קודם צריך לטעון את המודל לזיכרון ולהכין את צינור עיבוד הנתונים שלו.

הגדרת הנחיות ראשוניות במהלך היצירה

רלוונטי ל-Prompt API.

מומלץ: לספק הוראות מערכת במהלך אתחול הסשן כדי לשפר את מהירות ההנחיה הראשונה.

מה לא לעשות: להתחיל סשן ריק ולשלוח הוראות מערכת כחלק מהקריאה הראשונה ל-prompt(). זה מאריך את זמן האחזור כי המודל נאלץ לעבד את ההוראות האלה ברגע האחרון.

שכפול סשנים למשימות שחוזרות על עצמן

רלוונטי ל-Prompt API.

ב-Prompt API, כל סשן עוקב אחרי ההקשר של השיחה, ומביא בחשבון את כל האינטראקציות הקודמות. מכיוון ששיחה משוכפלת יורשת את כל מה שקיים בשיחת ההורה, כולל ההנחיות הראשוניות וכל היסטוריית האינטראקציות עד לנקודת השכפול, כדאי לתכנן את השימוש כך שהשיחה המשוכפלת תירש רק את מה שאתם צריכים.

מומלץ:

  • יצירת סשן בסיסי: כדי לטפל במשימות לא קשורות ביעילות, צרו סשן בסיסי שמכיל רק את ההוראות למערכת, בלי הקשר של שיחות קודמות.
  • שכפול של הסשן הבסיסי: משתמשים ב-clone() בסשן הבסיסי הזה למשימות חדשות כדי לחסוך את התקורה של ניתוח מחדש של הוראות המערכת. כך אתם יכולים ליצור שיחות מקבילות או לאפס משימה למצב הבסיסי שלה.

מה אסור לעשות:

  • אל תשתמשו באותו סשן למשימות לא קשורות, ואל תשכפלו סשן שכבר מכיל היסטוריית אינטראקציות מיותרת. שני הדפוסים האלה יכולים לגרום להקשר קודם שלא קשור למשימה הנוכחית להפריע לה.
  • אל תפעילו את create() שוב ושוב עם הוראות מערכת זהות. כדי לשפר את הביצועים, כדאי להשתמש בתבנית השכפול.

השמדת סשנים שלא בשימוש

רלוונטי לכל ממשקי ה-API.

מה כן לעשות: להפעיל באופן מפורש את destroy() בסשנים שכבר לא צריך, כדי לפנות זיכרון כשלא משתמשים יותר בתכונה. אם אתם משתמשים בתבנית שכפול, שמרו את הסשן הבסיסי והשמידו את השכפולים שאתם לא צריכים יותר.

מה לא לעשות: להשאיר כמה פגישות גדולות פעילות. כל סשן צורך זיכרון, מה שיוצר שימוש מיותר במשאבים ועלול להפוך לבעיה. הסשנים ינוקו באופן טבעי על ידי אוסף האשפה, אבל קריאה ל-destroy() מפנה זיכרון מהר יותר.

עיבוד תשובות בסטרימינג בצורה בטוחה ויעילה

רלוונטי ל: כל ממשקי ה-API עם תמיכה בסטרימינג (Prompt,‏ Summarizer,‏ Writer,‏ Rewriter ו-Translator).

מה לעשות: להתייחס לכל פלט של LLM כתוכן לא מהימן. חשוב להסיר תוכן זדוני או רגיש מהפלט המשולב המלא, ולא רק מחלקים ממנו, כי קוד זדוני יכול להיות מפוצל בין עדכונים. לפני העיבוד, משתמשים ב-Sanitizer API אם הוא נתמך. כדי למנוע ירידה בביצועים, השתמשו במנתח Markdown בסטרימינג כמו streaming-markdown.

מה לא לעשות: להגדיר את innerHTML ישירות בכל עדכון של מקטע. התהליך הזה איטי, במיוחד עם עיצוב מורכב כמו הדגשת תחביר, והוא חשוף להזרקה.

אופטימיזציה של הקלט למהירות

רלוונטי ל: כל ממשקי ה-API.

מה כדאי לעשות: להעביר למודל רק את מה שבאמת נחוץ. הסירו את כל מה שלא רלוונטי למשימה. אם יש לכם קבוצות נתונים גדולות, תנו סקירה כללית קצרה ומבחר קטן של פריטים רלוונטיים.

מה לא לעשות: לשלוח לממשקי ה-API טקסט גולמי שלא עבר עיבוד, מטא-נתונים מיותרים, תגי HTML או רשימות גדולות שלא עברו סינון. זמן האחזור גדל באופן משמעותי ככל שגודל הקלט גדל, מה שעלול לגרום לתכונת ה-AI להיראות מקולקלת במכשירים רבים.

שימוש בפלט מובנה כדי לקבל תוצאות צפויות

רלוונטי ל-Prompt API.

מה כן לעשות: אם אתם צריכים שהמודל יחזיר נתונים בפורמט ספציפי, השתמשו בפלט מובנה על ידי הוספת שדה responseConstraint כדי לספק סכימת JSON. כך הפלט יהיה צפוי ולא תצטרכו לבצע עיבוד מורכב לאחר מכן או ניתוח ידני.

מה לא לעשות: להסתמך רק על הוראות בשפה טבעית (כמו "פלט רק ב-JSON"). המודלים עשויים לכלול מילות קישור שמשבשות את המנתח.

הפרדה בין יצירת התוכן לבין מגבלות האורך

רלוונטי ל: Prompt API, כי הוא ה-API היחיד שתומך בסכימות פלט מובנות.

מה כן לעשות: מאפשרים למודל ליצור את התשובה באופן טבעי, ואז משתמשים בלוגיקה בצד הלקוח כדי לחתוך את הטקסט כך שיתאים לממשק המשתמש.

מה לא לעשות: לאכוף מגבלות תווים מחמירות כמו maxLength: 125 באמצעות סכימות פלט מובנות. אם התשובה של המודל ארוכה מהמגבלה שהגדרתם, יכול להיות שהמודל יעבור לטוקנים בצפיפות גבוהה, כמו שפות זרות או אמוג'י, כדי לדחוס את המשמעות, וכתוצאה מכך הפלט יהיה חסר משמעות.

עדכון המשתמשים

רלוונטי ל: כל ממשקי ה-API.

מה כן לעשות: בהתאם למורכבות ולמשך הזמן הצפוי של המשימה, כדאי להשתמש באנימציות, בסימנים חזותיים ובאינדיקטורים של התקדמות כדי לעדכן את המשתמש. הגישה האופטימלית תלויה בתרחיש לדוגמה ובאורך הצפוי של הפלט מה-API. הנה כמה רעיונות:

  • סטרימינג של תוכן ארוך: בסיכומים או בצ'אט, הסטרימינג יוצר אפקט של מכונת כתיבה לכל אסימון כברירת מחדל. זה יכול להרגיש טבעי ולספק משוב מיידי.
  • בלי סטרימינג למשימות קצרות (או למשימות אסינכרוניות ארוכות): לפלטים קצרים, כמו טקסט חלופי, אפשר להשתמש במצב בלי סטרימינג כדי ליצור ממשק משתמש מלוטש יותר. בנוסף, הוא מאפשר להכין מראש את משימת ה-AI הבאה בזמן שהמשימה הנוכחית מעובדת. הגישה הזו מתאימה גם למשימות אסינכרוניות או למשימות ברקע שנמשכות זמן רב יותר. אם המשתמש לא צריך את הפלט כדי להמשיך בתהליך, אין צורך דחוף להפיק את הפלט בזמן אמת. מציינים בממשק המשתמש שהתהליך נמשך.
  • מעברים חזותיים לעדכונים: כשמתרגמים או משכתבים טקסט, משתמשים באנימציות, למשל שינוי צורה של מילים.

מה לא לעשות: לעדכן את ממשק המשתמש בלי רמזים חזותיים.

התאמה למודל המנטלי של המשתמשים לגבי זמן ועבודה

רלוונטי לכל ממשקי ה-API.

מומלץ: אם התשובה מתקבלת כמעט באופן מיידי, כדאי להוסיף השהיה מלאכותית של שנייה או שתיים. באופן פרדוקסלי, יכול להיות שהמשתמשים יתפסו את התוצאות כאמינות יותר אם תהליך היצירה יתאים לקושי של המשימה כפי שהם תופסים אותו. השתמשו באנימציות כדי לאותת שהתרחש עיבוד באמצעות AI.

מה לא לעשות: להפתיע את המשתמשים עם החלפה מיידית של ממשק המשתמש.

המשתמשים יכולים לנווט במהירות ולבטל עריכות שבוצעו באמצעות AI

רלוונטי לכל ממשקי ה-API.

מה כדאי לעשות: הוסיפו לממשק המשתמש שלכם היסטוריית ניווט או כפתור "הבא" כדי לאפשר למשתמשים לבחון תוצאות שונות בביטחון, ולבטל במהירות עריכות של ה-AI. כך אפשר להבטיח שגרסאות שונות עדיין יהיו זמינות.

מה לא לעשות: אל תחליפו את הטיוטה הקודמת של המשתמש או תוצאה של AI שהוא אהב בלי לתת לו אפשרות לחזור אחורה, לבטל את הפעולה או להשוות בין הגרסאות.

המשתמשים יכולים לשלוט בהגדרות ולשנות אותן

רלוונטי לכל ממשקי ה-API.

מה כן לעשות: המשתמש צריך להיות העורך הסופי של כל התוכן שנוצר. לספק אפשרויות אינטואיטיביות לשינוי הפלט, כדי שהמשתמשים יוכלו לשלוט באופן מלא בתוצאה הסופית. יכול להיות שהתוצאות של ממשקי ה-API לא יהיו נכונות.

מה לא לעשות: לאלץ תוצאה שנוצרה על ידי AI כאפשרות היחידה.

שמירת תוצאות במטמון למשימות חוזרות

רלוונטי לכל ממשקי ה-API.

מה כדאי לעשות: להטמיע מטמון של תוצאות מקומיות (לדוגמה, באמצעות sessionStorage או IndexedDB) לקלטים או לשאילתות שחוזרים על עצמם. כדי להגדיל את מספר המציאות במטמון, כדאי לנרמל את הקלט על ידי חיתוך רווחים לבנים והמרת אותיות רישיות לאותיות קטנות. בקלט כבד, למשל תמונות, צריך ליצור גיבוב (hash) שישמש כמפתח מטמון. הגדירו אורך חיים (TTL) שמרני למטמון (או הציגו תוצאות מהמטמון בזמן שאתם מעדכנים אותן ברקע). אם התוצאה לא מספקת, אפשרו למשתמש להפעיל הסקה חדשה.

מה לא לעשות: להריץ מחדש את אותה הסקה לשאילתת חיפוש חוזרת או לקלט נתונים זהה, במקרים שבהם לא רוצים שיהיו שינויים. לדוגמה, כשמשתמש מנווט קדימה ואחורה בין תוצאות החיפוש. כך אפשר לשפר את מהירות התגובה ואת יעילות השימוש במחשוב המקומי.

6. אסטרטגיות חלופיות

לפני השימוש, בודקים אם האובייקט LanguageModel זמין ברמה הגלובלית:

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

אם אין תמיכה ב-Prompt API או שבדיקות הזמינות מחזירות את הערך "לא זמין", צריך להשתמש באפשרות חלופית:

  • ‫Remote API Fallback: הפניית בקשת הזיהוי לנקודת קצה של שרת או ל-Cloud APIs (כמו Vertex AI Gemini API).
  • חלופה ל-API מקומי: הפניית בקשת הזיהוי לנקודת קצה מקומית, למשל באמצעות Transformers.js.