תאריך פרסום: 21 באוקטובר 2024
חנויות אונליין יכולות להציג ביקורות על מוצרים כדי להגדיל את מספר ההמרות ב270%. גם ביקורות שליליות חשובות, כי הן תורמות ליצירת אמינות. 82% מהקונים אונליין מחפשים אותם לפני שהם קונים.
יכול להיות שיהיה לכם קשה לעודד לקוחות לכתוב ביקורות מועילות על המוצרים שלכם, במיוחד אם הן שליליות. כאן נסביר איך משתמשים בבינה מלאכותית גנרטיבית כדי לעזור למשתמשים לכתוב ביקורות מפורטות שיעזרו לאחרים לקבל החלטות קנייה.
הדגמה וקוד
מומלץ להתנסות בהדגמה של ביקורת המוצר ולבדוק את הקוד ב-GitHub.
איך יצרנו את התכונה הזו
AI בצד הלקוח
בדמו הזה הטמענו את התכונה בצד הלקוח מהסיבות הבאות:
- זמן אחזור. אנחנו רוצים לספק הצעות במהירות, ברגע שהמשתמש מפסיק להקליד. אנחנו יכולים להציע את זה על ידי הימנעות מנסיעות הלוך ושוב לשרת.
- עלות הדגמה הזו היא ניסיון, אבל אם אתם שוקלים להשיק תכונה דומה בסביבת הייצור, כדאי להתנסות בה ללא עלות בצד השרת עד שתהיה לכם אפשרות לאמת אם התכונה מתאימה למשתמשים שלכם.
AI גנרטיבי של MediaPipe
בחרנו להשתמש במודל Gemma 2B דרך MediaPipe LLM Inference API (חבילת MediaPipe GenAI), מהסיבות הבאות:
- דיוק המודל: Gemma 2B מציע איזון מצוין בין גודל לדיוק. כשהתבקשה בצורה נכונה, היא הניבה תוצאות שהיו לנו מספיק טובות לדמו הזה.
- תמיכה בדפדפנים שונים: MediaPipe נתמך בכל הדפדפנים שתומכים ב-WebGPU.
חוויית משתמש
שימוש בשיטות מומלצות לשיפור הביצועים
Gemma 2B הוא LLM קטן, אבל הוא עדיין הורדה גדולה. להשתמש בשיטות מומלצות לשיפור הביצועים, כולל שימוש ב-web worker.
להפוך את התכונה לאופציונלית
אנחנו רוצים לקבל הצעות לביקורות שמבוססות על AI כדי לשפר את תהליך העבודה של המשתמשים בפרסום ביקורת על מוצר. בהטמעה שלנו, המשתמשים יכולים לפרסם ביקורת גם אם המודל לא נטען, ולכן הוא לא מציע טיפים לשיפור.
מצבים ואנימציות של ממשק המשתמש
בדרך כלל, תהליך ההסקה נמשך יותר זמן ממה שנדמה מיידי, ולכן אנחנו מסמנים למשתמש שהמודל מבצע הסקה, או 'חושב'. אנחנו משתמשים באנימציות כדי להקל על ההמתנה, תוך הבטחה למשתמש שהאפליקציה פועלת כמצופה. המצבים השונים של ממשק המשתמש שהטמענו בדמו שלנו, כפי שעיצב Adam Argyle.
שיקולים נוספים
בסביבת ייצור, מומלץ:
- הוספת מנגנון משוב מה קורה אם ההצעות לא טובות או לא הגיוניות? כדאי להטמיע מנגנון משוב מהיר (כמו סימן 'לייק' וסימן 'לא לייק') ולהסתמך על שיטות ניתוח נתונים (heuristics) כדי לקבוע מה שימושי למשתמשים. לדוגמה, אפשר להעריך כמה מהמשתמשים שלכם מקיימים אינטראקציה עם התכונה ואם הם השביתו אותה.
- מתן אפשרות לביטול ההסכמה מה קורה אם המשתמש מעדיף להשתמש במילים שלו ללא עזרה מ-AI, או שהוא מוצא את התכונה מעצבנת? מאפשרים למשתמש לבטל את ההסכמה ולהסכים מחדש לפי הצורך.
- מסבירים למה התכונה הזו קיימת. הסבר קצר עשוי לעודד את המשתמשים להשתמש בכלי למשוב. לדוגמה, "המשוב שלכם עוזר לקונים אחרים להחליט מה לקנות, ועוזר לנו ליצור את המוצרים שאתם רוצים". תוכלו להוסיף הסבר ארוך על אופן הפעולה של התכונה והסיבה לכך שבחרתם לספק אותה, אולי כקישור למידע נוסף.
- גילוי נאות לגבי השימוש ב-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 });
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 });
} catch (error) {
self.postMessage({ code: MESSAGE_CODE.MODEL_ERROR });
}
// Trigger inference upon receiving a message from the main script
self.onmessage = async function (message) {
// Run inference = Generate an LLM response
let response = null;
try {
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 });
return;
}
// 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',
};
קלט ופלט
ההנחיה המלאה שלנו נוצרה בעזרת הנחיות מכמה דוגמאות. הוא כולל את הקלט של המשתמש, כלומר טיוטת הביקורת שהמשתמש כתב.
כדי ליצור את ההנחיה על סמך הקלט של המשתמש, אנחנו קוראים בפועל לפונקציית השירות generatePrompt
.
בדרך כלל, ספריות מודלים של AI בצד הלקוח מגיעות עם פחות שירותים מאשר AI בצד השרת. לדוגמה, לעיתים קרובות מצב JSON לא זמין. המשמעות היא שאנחנו צריכים לספק את מבנה הפלט הרצוי בהנחיה. הפתרון הזה פחות נקי, פחות אמין וקשה יותר לתחזוקה מאשר לספק סכימה דרך הגדרת המודל. בנוסף, מודלים בצד הלקוח נוטים להיות קטנים יותר, ולכן הם נוטים יותר לשגיאות מבניות בפלט שלהם.
בפועל, שמנו לב ש-Gemma 2B מספקת פלט מובנה כטקסט טוב יותר בהשוואה ל-JSON או ל-JavaScript. לכן, בדגמה הזו בחרנו בפורמט פלט מבוסס-טקסט. המודל יוצר טקסט, ואז אנחנו מנתחים את הפלט לאובייקט JavaScript לצורך עיבוד נוסף באפליקציית האינטרנט שלנו.
לשפר את ההנחיה
השתמשנו ב-LLM כדי לבצע איטרציות על ההנחיה שלנו.
- הנחיה עם כמה דוגמאות (Few-shot). כדי ליצור דוגמאות להנחיות עם כמה דוגמאות, התבססנו על 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", שהיא לא ההצעה הרצויה. פיצול ההנחיה עזר להבהיר את המשימה, ושפר את המיקוד של המודל בבדיקת הנתונים.