公開日: 2024 年 10 月 21 日
オンライン ショップは、商品レビューを表示することで、コンバージョンが 270% 増加する可能性があります。否定的なレビューも重要です。信頼を築くうえで役立ちます。オンライン ショッピング ユーザーの 82% が購入前にクーポンを探しています。
特にネガティブな場合は、役に立つ商品レビューを投稿するようお客様に促すのは難しい場合があります。ここでは、生成 AI を使用して、他のユーザーの購入判断に役立つ有益なレビューをユーザーが作成できるようにする方法を説明します。
デモとコード
商品レビューのデモを試して、GitHub のコードを調べてみましょう。
作成方法
クライアントサイド AI
このデモでは、以下の理由からクライアントサイドに機能を実装しました。
- レイテンシ。ユーザーが入力を停止した直後に、候補をすばやく表示したいと考えております。これは、サーバー ラウンドトリップを回避することで実現できます。
- 費用。これはデモですが、同様の機能を本番環境でリリースすることを検討している場合は、この機能がユーザーにとって有用かどうかを検証するまで、サーバーサイドの費用なしでテストすることをおすすめします。
MediaPipe 生成 AI
次の理由から、MediaPipe LLM 推論 API(MediaPipe GenAI パッケージ)を介して Gemma 2B モデルを使用することを選択しました。
- モデルの精度: Gemma 2B は、サイズと精度のバランスが優れています。適切なプロンプトを与えると、このデモで満足できる結果が得られました。
- クロスブラウザ サポート: MediaPipe は、WebGPU をサポートするすべてのブラウザでサポートされています。
ユーザー エクスペリエンス
パフォーマンスに関するベスト プラクティスを適用する
Gemma 2B は小規模な LLM ですが、ダウンロードサイズは大きいです。パフォーマンスのベスト プラクティスを適用する(ウェブワーカーの使用など)。
機能をオプションにする
AI ベースのレビュー候補は、商品レビューを投稿するユーザーのワークフローを改善することを目的としています。実装では、モデルが読み込まれていない場合でもユーザーはレビューを投稿できるため、改善のヒントは提供されません。
UI の状態とアニメーション
通常、推論は即時に実行されるものではありません。そのため、モデルが推論を実行中であることをユーザーに知らせます。アニメーションを使用して待機時間を短縮し、アプリケーションが意図したとおりに動作していることをユーザーに示します。Adam Argyle が設計したデモで、実装されているさまざまな UI 状態を確認しましょう。
その他の考慮事項
本番環境では、次のことを検討してください。
- フィードバック メカニズムを提供します。候補が適切でない、または意味がわからない場合はどうすればよいですか?簡単なフィードバック メカニズム(高評価や低評価など)を実装し、ヒューリスティクスに基づいてユーザーにとって有用なものを判断します。たとえば、この機能を使用しているユーザーの数や、オフにしているかどうかを評価します。
- オプトアウトを許可する。ユーザーが AI の支援なしで自分の言葉を使いたい場合や、この機能が煩わしい場合はどうすればよいですか?ユーザーがオプトアウトとオプトインを自由にできるようにします。
- この機能が存在する理由を説明します。簡単な説明を追加すると、ユーザーがフィードバック ツールを使用するよう促すことができます。たとえば、「より良いフィードバックは、他の買い物客が何を買うかを決める際に役立ち、Google がお客様が望む商品を開発する際に役立ちます」などです。リンク先の詳細情報として、この機能の仕組みと提供理由について詳しく説明できます。
- 関連する場合は AI の使用を開示する。クライアントサイド AI では、ユーザーのコンテンツは処理のためにサーバーに送信されないため、プライバシーを保護できます。ただし、サーバーサイドのフォールバックを作成する、または AI で情報を収集する場合は、プライバシー ポリシーや利用規約などに追加することを検討してください。
実装
Google が実装した商品レビューの候補生成ツールは、幅広いユースケースに対応できます。今後のクライアントサイド AI 機能のベースとして、次の情報を検討してください。
ウェブワーカーでの MediaPipe
MediaPipe LLM 推論では、AI コードは数行で済みます。モデル URL を渡してファイル リゾルバと LLM 推論オブジェクトを作成し、後でその 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 を使用してプロンプトを反復処理しました。
- 少数ショット プロンプト。少数ショット プロンプトの例を生成するために、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."
プロンプトの少数ショット セクションの例の 1 つ: 推奨される修正とサンプル レビューに商品タイプ(「靴下」)が含まれています。
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>
プロンプトを明確に構造化すると、モデルがサンプルリスト(少数ショット)と実際の入力を区別しやすくなります。
ターゲットが間違っている。モデルが、レビュー テキストではなく商品の変更を提案することがあります。たとえば、「この靴下は嫌い」というレビューに対して、モデルは「靴下を別のブランドやスタイルに交換することを検討してください」と提案する可能性がありますが、これは望ましい効果ではありません。プロンプトを分割することで、タスクが明確になり、モデルのレビューへのフォーカスが改善されました。