Explorer des suggestions d'avis sur les produits avec l'IA côté client

Maud Nalpas
Maud Nalpas

Publié le 21 octobre 2024

Les magasins en ligne peuvent voir 270% d'augmentation de conversions en affichant des avis sur les produits. Les avis négatifs sont également essentiels, à mesure qu’ils acquièrent leur crédibilité. 82 % des acheteurs en ligne les recherchent avant d'acheter.

Il peut être difficile d'encourager les clients à rédiger des avis sur les produits, en particulier lorsqu'ils sont négatifs. Nous allons voir ici comment utiliser l'IA générative Les utilisateurs rédigent des avis informatifs qui aident les autres décisions d'achat.

Démonstration et code

Jouez avec notre démonstration des avis sur les produits et à étudier du code sur GitHub.

Comment nous avons créé cette fonctionnalité

IA côté client

Pour cette démonstration, nous avons implémenté la fonctionnalité côté client pour les raisons suivantes:

  • Latence. Nous souhaitons proposer des suggestions rapidement, dès que l'utilisateur arrête de saisir du texte. Pour ce faire, nous évitons les aller-retours vers le serveur.
  • Coût S'il s'agit d'une démonstration, si vous envisagez de lancer une campagne en production, il est intéressant de faire des tests sans frais côté serveur jusqu'à vous pouvez vérifier si la fonctionnalité est adaptée à vos utilisateurs.

IA générative MediaPipe

Nous avons choisi d'utiliser Gemma 2B via la classe API MediaPipe LLM Inference (package MediaPipe GenAI), pour les raisons suivantes:

  • Précision du modèle: Gemma 2B offre un excellent compromis entre taille et précision. Quand ? la bonne réponse, elle a donné des résultats que nous avons trouvés satisfaisants pour cette démonstration.
  • Compatibilité multinavigateur: MediaPipe est compatible avec tous les navigateurs compatibles avec WebGPU

Expérience utilisateur

Appliquer les bonnes pratiques concernant les performances

Bien que Gemma 2B soit un petit LLM, il s'agit tout de même d'un téléchargement volumineux. Appliquez les bonnes pratiques en matière de performances, y compris l'utilisation d'un worker Web.

Rendre la fonctionnalité facultative

Nous voulons que les suggestions d'avis basées sur l'IA améliorent le workflow de l'utilisateur un avis sur un produit. Dans notre implémentation, l'utilisateur peut publier un avis même si le modèle n'a pas été chargé et qu'il n'offre donc pas de conseils d'amélioration.

Figure 1 Les utilisateurs peuvent toujours publier leur avis, même lorsque la fonctionnalité d'IA n'est pas encore prête.

États et animations de l'interface utilisateur

L'inférence prend généralement plus de temps que ce qui semble immédiat. Nous signalons donc à l'utilisateur que le modèle effectue une inférence, ou "réfléchit". Nous utilisons des animations pour faciliter l'attente, tout en assurant à l'utilisateur que l'application fonctionne comme prévu. Découvrez les différents états de l'interface utilisateur que nous avons implémentés dans notre démonstration, conçus par Adam Argyle.

Figure 2. Les animations montrent que le modèle se charge, puis "réfléchit" et est enfin terminé.

Autres points à prendre en compte

Dans un environnement de production, vous pouvez:

  • Fournissez un mécanisme de commentaires. Que faire si les suggestions sont médiocres ou n'ont aucun sens ? Mettez en place un mécanisme de retour d'information rapide (le bouton "J'aime", par exemple) et "Je n'aime pas") et s'appuyer sur des méthodes heuristiques pour déterminer ce que les utilisateurs trouvent utiles. Par exemple, évaluez le nombre d'utilisateurs qui interagissent avec et la désactiver s'il la désactive.
  • Autoriser la désactivation. Que se passe-t-il si l'utilisateur préfère utiliser ses propres mots sans l'aide de l'IA ou s'il trouve la fonctionnalité gênante ? permettre à l'utilisateur de désactiver et de réactiver comme vous le souhaitez.
  • Expliquez l'intérêt de cette fonctionnalité. Une brève explication peut encourager vos utilisateurs à utiliser l'outil d'envoi de commentaires. Par exemple : "De meilleurs commentaires aident les autres acheteurs à choisir ce qu'ils veulent acheter et nous aident à créer les produits que vous souhaitez." Toi vous pourriez ajouter une longue explication du fonctionnement de cette fonctionnalité fourni, peut-être pour en savoir plus.
  • Indiquez l'utilisation de l'IA, le cas échéant. Avec l'IA côté client, le contenu de l'utilisateur n'est pas envoyé à un serveur pour traitement et peut donc rester privé. Toutefois, si vous créez un plan de secours côté serveur ou que vous collectez d'autres informations à l'aide de l'IA, envisagez de l'ajouter à votre politique de confidentialité, à vos conditions d'utilisation ou ailleurs.

Implémentation

Notre implémentation du générateur d'avis sur les produits peut fonctionner de cas d'utilisation. Considérez les informations suivantes comme base pour votre avenir des fonctionnalités d'IA côté client.

MediaPipe dans un nœud de calcul Web

Avec l'inférence LLM MediaPipe, le code d'IA ne compte que quelques lignes : créez un résolveur de fichiers et un objet d'inférence LLM en lui transmettant une URL de modèle, puis utilisez cette instance d'inférence LLM pour générer une réponse.

Toutefois, notre exemple de code est un peu plus long. En effet, il est implémenté dans un nœud de calcul Web. Il transmet donc les messages avec le script principal via des codes de message personnalisés. En savoir plus sur ce modèle

// 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',
};

Entrées et sorties

Figure 3 Schéma illustrant le traitement de la requête par l'inférence vers une sortie LLM brute, qui est ensuite analysée pour obtenir une recommandation de lecture sur écran.

Notre invite complète a été créée avec des invites few-shot. Elle inclut les commentaires de l'utilisateur, c'est-à-dire la version préliminaire de l'avis que l'utilisateur a rédigée. n'est pas rédigée.

Pour générer notre requête en fonction de l'entrée utilisateur, nous appelons au moment de l'exécution notre utilitaire fonction generatePrompt.

Les bibliothèques et les modèles d'IA côté client ont généralement moins d'utilitaires IA côté serveur. Par exemple : Mode JSON est rarement disponible. Cela signifie que nous devons fournir le résultat souhaité dans notre requête. Cette approche est moins claire, moins facile à gérer et moins fiable que de fournir un schéma via la configuration du modèle. De plus, les modèles côté client ont tendance à être plus petits, ce qui signifie qu'ils sont plus sujets aux erreurs structurelles dans leur sortie.

En pratique, nous avons observé que Gemma 2B fournit un meilleur score une sortie structurée sous forme de texte par rapport à JSON ou JavaScript. Pour cette démonstration, nous avons opté pour un format de sortie basé sur le texte. Le modèle génère du texte, que nous le résultat dans un objet JavaScript pour un traitement ultérieur dans notre l'application.

Améliorer notre requête

Ma requête et la réponse dans l'interface Gemini Chat.
Figure 4. Nous avons demandé à Gemini Chat d'améliorer notre requête, et il répond ainsi qu'une explication des améliorations apportées et une mise en garde sur l'efficacité.

Nous avons utilisé un LLM pour itérer sur notre requête.

  • Requête few-shot : Pour générer les exemples de nos requêtes few-shot, nous nous sommes appuyés sur Gemini Chat. Gemini Chat utilise le plus plus puissants de Gemini. Cela nous a permis de générer des exemples de haute qualité.
  • Finition des requêtes Une fois la structure de requête prête, Gemini Chat pour affiner la requête. Cela a amélioré la qualité du résultat.

Utiliser le contexte pour améliorer la qualité

Le fait d'inclure le type de produit dans notre requête a permis au modèle de fournir plus des suggestions pertinentes et de meilleure qualité. Dans cette démonstration, le type de produit est statique. Dans une application réelle, vous pouvez inclure le produit de manière dynamique dans votre invite, en fonction de la page que l'utilisateur consulte.

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."

Voici l'un des exemples de la section "few-shots" de notre requête : le type de produit ("chaussettes") est inclus dans la solution suggérée et dans l'exemple d'avis.

Erreurs et corrections des LLM

Gemma 2B nécessite généralement plus d'ingénierie de requête qu'un modèle côté serveur plus puissant et plus volumineux.

Nous avons rencontré quelques difficultés avec Gemma 2B. Voici comment nous avons amélioré résultats:

  • Trop sympa. Gemma 2B a eu du mal à marquer les avis comme "non utiles", semblant hésiter à les juger. Nous avons essayé de rendre le langage des libellés plus neutre ("spécifique" et "non spécifique" au lieu de "utile" et "non utile") et avons ajouté des exemples, mais cela n'a pas amélioré les résultats. Ce qui a amélioré les résultats, c'est l'insistance et la répétition dans l'invite. Une approche en chaîne de pensée est également susceptible de générer des améliorations.
  • Instructions peu claires. Le modèle a parfois surinterprété la requête. Au lieu d'évaluer l'examen, il a continué la liste d'exemples. Pour résoudre ce problème, nous avons inclus une transition claire dans l'invite :

    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>
    

    Une structuration claire de l'invite aide le modèle à différencier la liste d'exemples (quelques prises de vue) de l'entrée réelle.

  • Cible incorrecte. Parfois, le modèle suggérait des modifications à apporter au produit au lieu du texte de l'avis. Par exemple, pour un avis indiquant "Je déteste ces vous pourriez les suggérer, le modèle peut suggérer "Envisagez de remplacer les chaussettes par un autre marque ou style", ce qui n'est pas l'effet souhaité. La division de l'invite a permis de clarifier la tâche et d'améliorer la concentration du modèle sur l'avis.