게시일: 2024년 10월 21일
온라인 상점은 제품 리뷰를 표시하여 전환수를 270% 증가시킬 수 있습니다. 부정적인 리뷰는 신뢰를 형성하기 때문에 매우 중요합니다 온라인 쇼핑객의 82%가 구매 전에 리뷰를 확인합니다.
특히 부정적인 리뷰인 경우 고객이 유용한 제품 리뷰를 남기도록 유도하는 것은 쉽지 않을 수 있습니다. 여기서는 생성형 AI를 사용하여 사용자가 다른 사람의 구매 결정에 도움이 되는 유익한 리뷰를 작성하도록 돕는 방법을 살펴보겠습니다.
데모 및 코드
제품 리뷰 데모를 사용해 보고 GitHub의 코드를 살펴보세요.
빌드 방법
클라이언트 측 AI
이 데모에서는 다음과 같은 이유로 클라이언트 측에 기능을 구현했습니다.
- 지연 시간. 사용자가 입력을 멈추는 즉시 신속하게 추천을 제공하려고 합니다. 서버 왕복을 피하여 이를 제공할 수 있습니다.
- 비용. 데모 버전이지만 프로덕션에서 유사한 기능을 출시하려는 경우 해당 기능이 사용자에게 적합한지 확인할 수 있을 때까지 서버 측 비용 없이 실험하는 것이 좋습니다.
MediaPipe 생성형 AI
Google에서는 다음과 같은 이유로 MediaPipe LLM Inference API(MediaPipe GenAI 패키지)를 통해 Gemma 2B 모델을 사용하도록 선택했습니다.
- 모델 정확성: Gemma 2B는 크기와 정확성 간에 균형이 잘 잡혀 있습니다. 올바른 메시지가 표시되면 이 데모에 적합한 결과를 제공했습니다.
- 교차 브라우저 지원: MediaPipe는 WebGPU를 지원하는 모든 브라우저에서 지원됩니다.
사용자 환경
성능 권장사항 적용
Gemma 2B는 소규모 LLM이지만 다운로드 크기가 큽니다. 웹 워커 사용을 비롯한 성능 권장사항 적용
기능을 선택사항으로 설정
AI 기반 리뷰 제안을 통해 사용자가 제품 리뷰를 게시하는 워크플로를 개선하고자 합니다. Google의 구현에서는 모델이 로드되지 않아 개선 도움말이 제공되지 않더라도 사용자가 리뷰를 게시할 수 있습니다.
UI 상태 및 애니메이션
추론은 일반적으로 즉각적으로 느껴지는 것보다 시간이 더 걸리므로 모델이 추론을 실행 중임을 사용자에게 알립니다. 애니메이션을 사용하여 대기를 용이하게 하는 동시에 사용자에게 애플리케이션이 정상적으로 작동하는지 확인합니다. Adam Argyle이 디자인한 데모에서 구현한 다양한 UI 상태를 살펴보세요.
기타 고려사항
프로덕션 환경에서는 다음을 수행할 수 있습니다.
- 의견 메커니즘을 제공합니다. 제안이 평범하거나 말이 되지 않으면 어떻게 해야 할까요? 빠른 의견 메커니즘(예: 좋아요 및 싫어요)을 구현하고 휴리스틱을 사용하여 사용자가 유용하다고 생각하는 항목을 결정합니다. 예를 들어 이 기능을 사용하는 사용자 수가 얼마나 되는지, 이 기능을 사용 중지하는지 평가합니다.
- 선택 해제 허용. 사용자가 AI 지원 없이 직접 말을 사용하고 싶어 하거나 이 기능이 불편하다고 생각하는 경우 어떻게 해야 하나요? 사용자가 원하는 경우 선택 해제하고 다시 선택할 수 있도록 허용합니다.
- 이 기능이 있는 이유를 설명합니다. 간단한 설명을 제공하면 사용자에게 의견 도구를 사용하도록 유도할 수 있습니다. 예를 들어 '더 나은 의견은 다른 쇼핑객이 무엇을 구매할지 결정하는 데 도움이 되며 Google이 원하는 제품을 만드는 데 도움이 됩니다.' 이 기능의 작동 방식과 제공한 이유에 대한 자세한 설명을 링크로 추가할 수 있습니다. 링크를 통해 자세히 알아볼 수 있습니다.
- 해당하는 경우 AI 사용 사실 공개 클라이언트 측 AI를 사용하면 사용자의 콘텐츠가 처리를 위해 서버로 전송되지 않으므로 비공개로 유지할 수 있습니다. 하지만 서버 측 대체 솔루션을 빌드하거나 다른 방식으로 AI로 정보를 수집하는 경우 개인정보처리방침, 서비스 약관 또는 기타 위치에 이를 추가하는 것이 좋습니다.
구현
제품 리뷰 제안 도구의 구현은 다양한 사용 사례에 적용할 수 있습니다. 다음 정보를 향후 클라이언트 측 AI 기능의 기반으로 고려하세요.
웹 작업자의 MediaPipe
MediaPipe LLM 추론을 사용하면 AI 코드는 몇 줄 밖에 되지 않습니다. 모델 URL을 전달하여 파일 리졸버와 LLM 추론 객체를 만들고 나중에 이 LLM 추론 인스턴스를 사용하여 응답을 생성합니다.
그러나 코드 샘플은 좀 더 광범위합니다. 이는 웹 워커에 구현되어 있으므로 맞춤 메시지 코드를 통해 메인 스크립트와 함께 메시지를 전달하기 때문입니다. 이 패턴에 대해 자세히 알아보세요.
// 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에 비해 구조화된 출력을 텍스트로 제공하는 데 더 효과적입니다. 따라서 이 데모에서는 텍스트 기반 출력 형식을 선택했습니다. 모델은 텍스트를 생성하고, 웹 앱 내에서 추가로 처리할 수 있도록 출력을 자바스크립트 객체로 파싱합니다.
프롬프트 개선
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>프롬프트를 명확하게 구성하면 모델이 예시 목록(몇 장의 샷)과 실제 입력을 구분하는 데 도움이 됩니다.
잘못된 타겟. 경우에 따라 모델이 리뷰 텍스트 대신 제품 변경을 제안하기도 했습니다. 예를 들어 '이 양말이 싫어요'라는 리뷰의 경우 모델이 원하는 효과가 아닌 '양말을 다른 브랜드나 스타일로 교체해 보세요'를 제안할 수 있습니다. 프롬프트를 분할하면 작업이 명료해지고 검토에 대한 모델의 집중도가 높아집니다.