הודעה למשתמשים על הורדת מודל

פורסם: 1 באוקטובר 2025

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

מעקב אחרי התקדמות ההורדה ושיתוף שלה

לכל API מובנה של AI יש את הפונקציה create() להפעלת סשן. לפונקציה create() יש אפשרות monitor, כך שתוכלו לגשת להתקדמות ההורדה ולשתף אותה עם המשתמש.

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

בצד הלקוח בלבד

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

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

<style>
  progress[hidden] ~ label {
    display: none;
  }
</style>

<button type="button">Create LanguageModel session</button>
<progress hidden id="progress" value="0"></progress>
<label for="progress">Model download progress</label>

בזמן ההורדה של המודל המובנה, אי אפשר להשתמש באפליקציה.

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

  • ממשק ה-API הוא 'unavailable': אי אפשר להשתמש באפליקציה בצד הלקוח במכשיר הזה. להתריע למשתמש שהתכונה לא זמינה.
  • ה-API הוא 'available': אפשר להשתמש ב-API באופן מיידי, אין צורך להציג את ממשק המשתמש של ההתקדמות.
  • ה-API הוא 'downloadable' או 'downloading': אפשר להשתמש ב-API אחרי שההורדה מסתיימת. להציג אינדיקטור התקדמות ולעדכן אותו בכל פעם שהאירוע downloadprogress מופעל. אחרי ההורדה, מוצג מצב לא מוגדר כדי לסמן למשתמש שהדפדפן מקבל את המודל שחולץ ונטען לזיכרון.
const createButton = document.querySelector('.create');
const promptButton = document.querySelector('.prompt');
const progress = document.querySelector('progress');
const output = document.querySelector('output');

let sessionCreationTriggered = false;
let session = null;

const createSession = async (options = {}) => {
  if (sessionCreationTriggered) {
    return;
  }

  progress.hidden = true;
  progress.value = 0;

  try {
    if (!('LanguageModel' in self)) {
      throw new Error('LanguageModel is not supported.');
    }

    const availability = await LanguageModel.availability();
    if (availability === 'unavailable') {
      throw new Error('LanguageModel is not available.');
    }

    let modelNewlyDownloaded = false;
    if (availability !== 'available') {
      modelNewlyDownloaded = true;
      progress.hidden = false;
    }
    console.log(`LanguageModel is ${availability}.`);
    sessionCreationTriggered = true;

    const llmSession = await LanguageModel.create({
      monitor(m) {
        m.addEventListener('downloadprogress', (e) => {
          progress.value = e.loaded;
          if (modelNewlyDownloaded && e.loaded === 1) {
            // The model was newly downloaded and needs to be extracted
            // and loaded into memory, so show the undetermined state.
            progress.removeAttribute('value');
          }
        });
      },
      ...options,
    });

    sessionCreationTriggered = false;
    return llmSession;
  } catch (error) {
    throw error;
  } finally {
    progress.hidden = true;
    progress.value = 0;
  }
};

createButton.addEventListener('click', async () => {
  try {
    localSession = await createSession({
      expectedInputs: [{ type: 'text', languages: ['en'] }],
      expectedOutputs: [{ type: 'text', languages: ['en'] }],
    });
    promptButton.disabled = false;
  } catch (error) {
    output.textContent = error.message;
  }
});

promptButton.addEventListener('click', async () => {
  output.innerHTML = '';
  try {
    const stream = localSession.promptStreaming('Write me a poem');
    for await (const chunk of stream) {
      output.append(chunk);
    }
  } catch (err) {
    output.textContent = err.message;
  }
});

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

מומלץ לצפות בהדגמה שבה מוצג התהליך הזה בפועל. אם ה-API המובנה של ה-AI (בדוגמה הזו, Prompt API) לא זמין, אי אפשר להשתמש באפליקציה. אם עדיין צריך להוריד את מודל ה-AI המובנה, יוצג למשתמש מד התקדמות. אפשר לראות את קוד המקור ב-GitHub.

הטמעה היברידית

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

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

בזמן שהמודל המובנה יורד, האפליקציה עוברת למודל בענן וכבר אפשר להשתמש בה.

ההדגמה מציגה את התהליך הזה בפעולה. אם ה-API המובנה של ה-AI לא זמין, ההדגמה תשתמש ב-Gemini API בענן. אם עדיין צריך להוריד את המודל המובנה, מוצג למשתמש אינדיקטור התקדמות, והאפליקציה משתמשת ב-Gemini API בענן עד שהמודל יורד. אפשר לעיין בקוד המקור המלא ב-GitHub.

סיכום

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

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

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