הצעות לביקורות על מוצרים באמצעות AI בצד הלקוח

Maud Nalpas
Maud Nalpas

תאריך פרסום: 21 באוקטובר 2024

חנויות וירטואליות יכולות לראות עלייה של 270% בהמרות באמצעות הצגת ביקורות על מוצרים. גם ביקורות שליליות הן חשובות כי הם בונים אמינות. 82% מהקונים אונליין מחפשים אותם לפני שהם קונים.

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

הדגמה וקוד

תוכלו לנסות את הדגמה של בדיקת המוצר ולעיין בקוד ב-GitHub.

איך יצרנו את התכונה הזו

AI בצד הלקוח

לצורך ההדגמה הזו, הטמענו את התכונה בצד הלקוח מהסיבות הבאות:

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

AI גנרטיבי של MediaPipe

בחרנו להשתמש במודל Gemma 2B דרך MediaPipe LLM Inference API (MediaPipe GenAI package) מהסיבות הבאות:

  • דיוק המודל: Gemma 2B מציעה איזון מצוין בין גודל לדיוק. מתי כראוי, היא סיפקה תוצאות שנמצאו שביעות רצון להדגמה הזו.
  • תמיכה בדפדפנים שונים: MediaPipe נתמך בכל הדפדפנים שתומכים ב-WebGPU.

חוויית משתמש

שימוש בשיטות מומלצות לשיפור הביצועים

Gemma 2B הוא LLM קטן, אבל עדיין מדובר בהורדה גדולה. להשתמש בשיטות מומלצות לשיפור הביצועים, כולל שימוש ב-web worker.

הגדרת התכונה כאופציונלית

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

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

מצבים ואנימציות של ממשק המשתמש

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

איור 2. האנימציות מראות שהמודל נטען, ואז "חושב", ובסוף מסיים.

שיקולים נוספים

בסביבת ייצור מומלץ:

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

הטמעה

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

MediaPipe ב-web worker

בעזרת הסקת מסקנות מ-MediaPipe LLM, הקוד של AI הוא רק כמה שורות: יוצרים מקודד קבצים ואובייקט הֶקֵּשׁ מ-LLM על ידי העברת כתובת ה-URL של המודל, ואחר כך משתמשים במופע ההסקה של LLM כדי ליצור תשובה.

עם זאת, דוגמת הקוד שלנו היא מעט מפורטת יותר. כי רק ככה הטמענו ב-Web worker, כך שהוא מעביר הודעות עם הסקריפט הראשי דרך קודים של הודעות בהתאמה אישית. מידע נוסף על התבנית הזו

// Trigger model preparation *before* the first message arrives
self.postMessage({ code: MESSAGE_CODE.PREPARING_MODEL, payload: null });
try {
  // Create a FilesetResolver instance for GenAI tasks
  const genai = await FilesetResolver.forGenAiTasks(MEDIAPIPE_WASM);
  // Create an LLM Inference instance from the specified model path
  llmInference = await LlmInference.createFromModelPath(genai, MODEL_URL);
  self.postMessage({ code: MESSAGE_CODE.MODEL_READY, payload: null });
} catch (error) {
  self.postMessage({ code: MESSAGE_CODE.MODEL_ERROR, payload: null });
}

// Trigger inference upon receiving a message from the main script
self.onmessage = function (message) {
  if (!llmInference) {
    // Just in case. This condition shouldn't normally be hit because
    // the inference UI button is disabled until the model is ready
    throw new Error("Can't run inference, the model is not ready yet");
  }
  (async function () {
    // Run inference = Generate an LLM response
    try {
    const response = await llmInference.generateResponse(
      // Create a prompt based on message.data, which is the actual review
      // draft the user has written. generatePrompt is a local utility function.
      generatePrompt(message.data)
    );
    } catch (error) {
      self.postMessage({ code: MESSAGE_CODE.INFERENCE_ERROR, payload: null });
    }
    // Parse and process the output using a local utility function
    const reviewHelperOutput = generateReviewHelperOutput(response);
    // Post a message to the main thread
    self.postMessage({
      code: MESSAGE_CODE.RESPONSE_READY,
      payload: reviewHelperOutput,
    });
  })();
};

export const MESSAGE_CODE ={
  PREPARING_MODEL: 'preparing-model',
  MODEL_READY: 'model-ready',
  GENERATING_RESPONSE: 'generating-response',
  RESPONSE_READY: 'response-ready',
  MODEL_ERROR: 'model-error',
  INFERENCE_ERROR: 'inference-error',
};

קלט ופלט

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

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

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

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

בפועל, שמנו לב ש-Gemma 2B עושה עבודה טובה יותר באספקת פלט מובנה כטקסט בהשוואה ל-JSON או JavaScript. בהדגמה הזאת, בחרנו בפורמט פלט מבוסס-טקסט. המודל יוצר טקסט, לנתח את הפלט לאובייקט JavaScript להמשך עיבוד אפליקציה.

לשפר את ההנחיה

ההנחיה שלי והתגובה בממשק של Gemini Chat.
איור 4. ביקשנו מ-Gemini Chat לשפר את ההנחיה שלנו, והוא ענה עם הסבר על השיפורים שבוצעו ועל אזהרה לגבי היעילות.

השתמשנו ב-LLM כדי לבצע איטרציות על ההנחיה שלנו.

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

שימוש בהקשר כדי לשפר את האיכות

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

Review: "I love these."
Helpful: No  
Fix: Be more specific, explain why you like these **socks**.
Example: "I love the blend of wool in these socks. Warm and not too heavy."

אחת מהדוגמאות בסעיף מספר תמונות של ההנחיה שלנו: סוג המוצר ("גרביים") כלולה בהצעת התיקון ובביקורת לדוגמה.

תקלות ופתרונות ב-LLM

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

נתקלנו בבעיות מסוימות עם Gemma 2B. כך שיפרנו את התוצאות:

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

    I'll give you example reviews and outputs, and then give you one review
    to analyze. Let's go:
    Examples:
    <... Examples>
    
    Review to analyze:
    <... User input>
    

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

  • יעד שגוי. מדי פעם, המודל הציע שינויים במוצר במקום טקסט הביקורת. לדוגמה, אם בסקירה כתוב "I hate these socks", המודל עשוי להציע את ההצעה "Consider replacing the socks with a different brand or style", שהיא לא ההצעה הרצויה. פיצול ההנחיה עזר להבהיר את המשימה ולשפר את ההתמקדות של המודל בביקורת.