สำรวจคำแนะนำรีวิวผลิตภัณฑ์ด้วย AI ฝั่งไคลเอ็นต์

Maud Nalpas
Maud Nalpas

เผยแพร่เมื่อวันที่ 21 ตุลาคม 2024

ร้านค้าออนไลน์จะเห็น เพิ่มขึ้น 270% ใน Conversion โดยแสดงรีวิวผลิตภัณฑ์ รีวิวเชิงลบก็สำคัญเช่นกันเนื่องจากช่วยสร้างความน่าเชื่อถือ 82% ของนักช็อปออนไลน์จะมองหาพวกเขาก่อนซื้อ

การกระตุ้นให้ลูกค้าเขียนรีวิวผลิตภัณฑ์ที่เป็นประโยชน์ โดยเฉพาะเมื่อรีวิวเชิงลบนั้นเป็นเรื่องยาก เราจะมาสำรวจวิธีใช้ Generative AI เพื่อช่วยผู้ใช้เขียนรีวิวที่ให้ข้อมูลซึ่งช่วยในการตัดสินใจซื้อของผู้อื่น

การสาธิตและโค้ด

ลองใช้ การสาธิตรีวิวผลิตภัณฑ์ และตรวจสอบ ใน GitHub

วิธีการที่เราสร้าง

AI ฝั่งไคลเอ็นต์

ในการสาธิตนี้ เราติดตั้งใช้งานฟีเจอร์ฝั่งไคลเอ็นต์ด้วยเหตุผลต่อไปนี้

  • เวลาในการตอบสนอง เราต้องการให้คำแนะนำอย่างรวดเร็วทันทีที่ผู้ใช้ หยุดพิมพ์ ซึ่งทำได้โดยการหลีกเลี่ยงการรับส่งข้อมูลไปกลับของเซิร์ฟเวอร์
  • ต้นทุน แม้ว่านี่จะเป็นการสาธิต หากคุณต้องการเปิดตัว ในการใช้งานจริง คุณควรทดสอบโดยใช้ต้นทุนฝั่งเซิร์ฟเวอร์เป็นศูนย์จนกว่า คุณจะตรวจสอบได้ว่าฟีเจอร์นี้เหมาะกับผู้ใช้หรือไม่

Generative AI ของ MediaPipe

เราเลือกใช้รูปแบบ Gemma 2B ผ่าน MediaPipe LLM Inference API (MediaPipe GenAI package) ด้วยเหตุผลต่อไปนี้

  • ความแม่นยำของโมเดล: Gemma 2B มีขนาดและความแม่นยำที่ยอดเยี่ยม วันและเวลา ส่งข้อความแจ้งอย่างเหมาะสม โมเดลจะให้ผลลัพธ์ที่เราเห็นว่าน่าพอใจสำหรับการสาธิตนี้
  • รองรับหลายเบราว์เซอร์: MediaPipe ใช้ได้ใน เบราว์เซอร์ทั้งหมดที่รองรับ WebGPU

ประสบการณ์ของผู้ใช้

ใช้แนวทางปฏิบัติแนะนำด้านประสิทธิภาพ

แม้ว่า Gemma 2B จะเป็น LLM ขนาดเล็ก แต่ก็ยังเป็นการดาวน์โหลดขนาดใหญ่ ใช้แนวทางปฏิบัติแนะนำด้านประสิทธิภาพ ซึ่งรวมถึงการใช้ Web Worker

กำหนดให้ฟีเจอร์เป็นแบบไม่บังคับ

เราอยากให้คำแนะนำในการรีวิวที่ใช้ AI ช่วยปรับปรุงเวิร์กโฟลว์ของผู้ใช้ในการโพสต์ รีวิวผลิตภัณฑ์ ในการใช้งานของเรา ผู้ใช้สามารถโพสต์รีวิวได้แม้ว่าระบบจะยังไม่ได้โหลดโมเดลและไม่ได้แสดงเคล็ดลับการปรับปรุง

รูปที่ 1 ผู้ใช้ยังคงโพสต์รีวิวได้แม้ว่า AI ฟีเจอร์ยังไม่พร้อม

สถานะและภาพเคลื่อนไหวของ UI

โดยทั่วไปแล้ว การทำนายผลจะใช้เวลานานกว่าที่ผู้ใช้จะรู้สึกว่าทันที เราจึงแจ้งให้ผู้ใช้ทราบว่าโมเดลกำลังทำนายผลหรือ "กำลังคิด" เราใช้ภาพเคลื่อนไหวเพื่อลดความน่าเบื่อในการรอ พร้อมทั้งช่วยให้ผู้ใช้มั่นใจว่าแอปพลิเคชันทำงานได้ตามที่ต้องการ ดูสถานะ UI ต่างๆ ที่เราได้นำไปใช้ในการสาธิต ตามที่ออกแบบโดย Adam Argyle

รูปที่ 2 ภาพเคลื่อนไหวแสดงให้เห็นว่าโมเดลกำลังโหลด จากนั้น "กำลังคิด" และสุดท้ายก็เสร็จสิ้น

ข้อควรพิจารณาอื่นๆ

ในสภาพแวดล้อมเวอร์ชันที่ใช้งานจริง คุณอาจต้องดำเนินการต่อไปนี้

  • จัดให้มีกลไกแสดงความคิดเห็น จะเกิดอะไรขึ้นหากคําแนะนํานั้นไม่ดีนักหรือไม่สมเหตุสมผล ใช้กลไกการแสดงความคิดเห็นอย่างรวดเร็ว (เช่น การยกนิ้วโป้ง) และไม่ชอบ) และอาศัยการเรียนรู้ในการกำหนดสิ่งที่ผู้ใช้ค้นพบ มีประโยชน์ เช่น ประเมินจํานวนผู้ใช้ที่โต้ตอบกับฟีเจอร์ และดูว่าผู้ใช้ปิดฟีเจอร์หรือไม่
  • อนุญาตให้เลือกไม่ใช้ จะเกิดอะไรขึ้นหากผู้ใช้ต้องการใช้คำของตนเองโดยไม่รับความช่วยเหลือจาก AI หรือพบว่าฟีเจอร์นี้น่ารำคาญ อนุญาตให้ผู้ใช้เลือกไม่ใช้และ เลือกใช้อีกครั้งได้ตามต้องการ
  • อธิบายเหตุผลที่ฟีเจอร์นี้มีอยู่ คำอธิบายสั้นๆ อาจกระตุ้นให้ผู้ใช้ใช้เครื่องมือแสดงความคิดเห็น เช่น "ความคิดเห็นที่ดีขึ้นช่วยเพื่อน ผู้เลือกซื้อจะตัดสินใจได้ว่าจะซื้ออะไร และช่วยเราสร้างผลิตภัณฑ์ที่คุณต้องการ" คุณ อาจเพิ่มคำอธิบายยาวๆ เกี่ยวกับวิธีการทำงานของฟีเจอร์นี้ และเหตุผลที่คุณ ให้ไว้ บางทีอาจเป็นการดูข้อมูลเพิ่มเติมที่ลิงก์ไว้
  • เปิดเผยการใช้งาน AI ตามความเกี่ยวข้อง เมื่อใช้ AI ฝั่งไคลเอ็นต์ ระบบจะไม่ส่งเนื้อหาของผู้ใช้ไปยังเซิร์ฟเวอร์เพื่อประมวลผล จึงเก็บเนื้อหาดังกล่าวไว้เป็นส่วนตัวได้ อย่างไรก็ตาม หากคุณสร้างทางเลือกฝั่งเซิร์ฟเวอร์หรือรวบรวมข้อมูลด้วย AI ให้พิจารณาเพิ่มข้อมูลดังกล่าวลงในนโยบายความเป็นส่วนตัว ข้อกำหนดในการให้บริการ หรือที่อื่นๆ

การใช้งาน

การใช้งานเครื่องมือแนะนำรีวิวผลิตภัณฑ์ของเราใช้ได้กับ Use Case หลากหลาย โปรดใช้ข้อมูลต่อไปนี้เป็นพื้นฐานสําหรับฟีเจอร์ AI ฝั่งไคลเอ็นต์ในอนาคต

MediaPipe ในเว็บเวิร์กเกอร์

เมื่อใช้การอนุมาน LLM ของ MediaPipe โค้ด 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 ดิบ จากนั้นจะแยกวิเคราะห์เป็นคําแนะนําที่พร้อมแสดง

พรอมต์แบบเต็มสร้างขึ้นด้วยพรอมต์แบบ Few-Shot ความคิดเห็นนี้มีข้อมูลที่ผู้ใช้ป้อน หรือกล่าวคือ ร่างรีวิวที่ผู้ใช้มี เขียนไว้

หากต้องการสร้างพรอมต์ตามข้อมูลที่ผู้ใช้ป้อน เราจะเรียกใช้ฟังก์ชันยูทิลิตี generatePrompt ของเราที่รันไทม์

โดยปกติแล้วโมเดลและไลบรารี AI ฝั่งไคลเอ็นต์จะมียูทิลิตีน้อยกว่า 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>
    

    การจัดโครงสร้างพรอมต์อย่างชัดเจนจะช่วยให้โมเดลแยกความแตกต่างระหว่างรายการตัวอย่าง (ภาพไม่กี่ภาพ) กับอินพุตจริงได้

  • เป้าหมายไม่ถูกต้อง ในบางครั้ง โมเดลจะแนะนำการเปลี่ยนแปลงผลิตภัณฑ์แทนข้อความรีวิว เช่น สำหรับรีวิวที่ระบุว่า "ฉันเกลียดถุงเท้าเหล่านี้" โมเดลอาจแนะนำว่า "ลองเปลี่ยนถุงเท้าเป็นแบรนด์หรือสไตล์อื่น" ซึ่งไม่ใช่ผลลัพธ์ที่ต้องการ การแยกข้อความแจ้งช่วยได้ ชี้แจงงานและปรับปรุงจุดมุ่งเน้นของโมเดลในการตรวจสอบ