サイト内検索

[NVIDIA DGX Sparkで試すAIペルソナマーケティング]
第1話 デモの概要
第2話 調査対象の抽出
第3話 質問の生成
第4話 回答の生成と収集
第5話 調査結果の可視化
第6話 まとめ

本話の内容

本話では、アンケートの質問文と選択肢をLLM(大規模言語モデル)により生成する過程を解説します。通常のマーケティング活動であれば、マーケティング担当者が、明確な意図を持って、アンケートの質問文と選択肢を自ら考案すると思いますが、本デモでは、この部分においてもAIの可能性を試してみました。なお、LLMはopenai/gpt-oss-120bを利用しました。

LLM APIエンドポイントの立ち上げとクライアントの設定

本デモでは、LLMを含めて、すべての処理をDGX Sparkローカルで実行しますが、クラウドに存在するLLMにアクセスする場合と同様、HTTP APIエンドポイント経由で、LLMにアクセスします。そのため、http://localhostにAPIエンドポイントを立ち上げます。推論サーバーにはvLLMを利用しました。vLLMのインストールと実行に関しては、以下の記事を参照ください。

DGX Spark Playbook : vLLM for Inference

LLMのローカル実行であっても、HTTP APIをインターフェースとすることで、クラウドや別のサーバーでサービングされる別のLLMへアドレス変更とモデル名変更だけで簡単に切り替えることができます。

以下のとおり、クライアント側の設定を行います。LLM APIエンドポイントにアクセスする方法は、いくつか存在しますが、今回は、OpenAI Python APIを利用しました。

import json
from openai import OpenAI
from survey import Survey
# LLM APIエンドポイントの設定
MODEL = "openai/gpt-oss-120b"
BASE_URL = "http://localhost:8000/v1"
# OpenAIクライアントの初期化
client = OpenAI(
  base_url=BASE_URL,
  api_key="None"
)

質問の生成

質問の生成をLLMに指示するために、システムプロンプトとユーザープロンプトを用意します。システムプロンプトで、LLMに役割を与え、ユーザープロンプトで具体的な指示を与えます。

# システムプロンプトの定義
system_prompt = """
あなたは一般消費者向け商品のマーケティング専門家です。
主に一般消費者からの意見をヒアリングし、分析する業務を行っています。
あなたの顧客である企業から、分析したい内容が与えられますので、よく内容を理解した上で、最適な提案を提出してください。
"""
# ユーザープロンプトの定義
user_prompt = """
20代向けグミ菓子を企画しています。
季節商品ではなく、通年販売を予定しています。
以下の項目を決めたいので、一般消費者からヒアリングを行います。
- フレーバー
- パッケージのデザイン
- CMに起用するタレント
最適な調査質問を5問提案してください。
各質問に対して、4個の選択肢も作成してください。
直接的な質問は避け、消費者の潜在意識を見極めるものにしてください。
質問文と選択肢には、考察や補足情報を含めず、それらは理由として別途記載してください。
"""

以下のように、Structured model outputs機能を利用して、生成された質問と選択肢を構造化されたデータとして受け取るように工夫しています。これにより、後続の処理が楽になります。

# LLMによる質問票の生成
response = client.responses.parse(
    model=MODEL,
    input=[
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": user_prompt},
    ],
    text_format=Survey,
    temperature=0.2,
    top_p=0.7,
)
survey = response.output_parsed

生成された質問と選択肢はSurveyクラスのオブジェクトとして出力されます。Surveyクラスは以下のとおり定義しました。

from pydantic import BaseModel
class Choice(BaseModel):
    """質問の選択肢"""
    text: str
class Question(BaseModel):
    """消費者の潜在意識を見極めるための質問"""
    question_text: str      # 質問文
    choices: list[Choice]   # 質問に対する選択肢のリスト
    reason: str             # 質問の意図や背景に関する説明
class Survey(BaseModel):
    """グミ菓子新製品に関する消費者調査票"""
    questions: list[Question]

生成された質問と選択肢は、以下のようにJSON形式で受け取ります。

# 結果をJSON形式で取得
json_data =json.loads(survey.model_dump_json(ensure_ascii=False))
json_data

生成された質問と選択肢は以下のようになりました。

{'questions': [{'question_text': '朝の目覚めに、あなたが思い浮かべる“さわやかさ”はどのシーンですか?',
   'choices': [{'text': '海辺の朝日が水平線から顔を出す瞬間'},
    {'text': '高原の風が葉を揺らす音と共に吹く瞬間'},
    {'text': '都会のカフェで、窓の外に映るネオンが光る瞬間'},
    {'text': '秋の森の中で、落ち葉がカサカサと音を立てる瞬間'}],
   'reason': 'フレーバーのイメージ(トロピカル、ミント系、シトラス系、秋味)を直接聞かずに、自然・都市・季節の連想から好みを測る。'},
  {'question_text': 'コンビニで新しいスナックを選ぶとき、どのパッケージが最初に手に取られそうですか?',
   'choices': [{'text': '淡いパステルカラーでシンプルなロゴが配置されたデザイン'},
    {'text': '鮮やかなネオンカラーとダイナミックなパターンが走るデザイン'},
    {'text': 'レトロなイラストと温かみのあるトーンでまとめられたデザイン'},
    {'text': '黒を基調にメタリックなアクセントが入ったモダンなデザイン'}],
   'reason': '色彩・スタイルの好みを直接聞かず、視覚的な第一印象からパッケージデザインの嗜好を把握する。'},
  {'question_text': '友達と週末に新しいお菓子をシェアするとしたら、どんなシチュエーションが一番楽しいですか?',
   'choices': [{'text': '自然の中でハイキングやピクニックをしながら'},
    {'text': '屋外フェスやライブで音楽に合わせて'},
    {'text': 'カフェでゆっくりおしゃべりしながら'},
    {'text': '自宅でゲームや映画鑑賞をしながら'}],
   'reason': 'シーン別のライフスタイルを通じて、フレーバーのイメージ(フルーツ系、エナジー系、リラックス系、甘さ重視)とパッケージの使用シーンを間接的に探る。'},
  {'question_text': 'テレビやSNSで有名人が商品を紹介しているとき、あなたが「信頼できる」と感じるのはどんな雰囲気ですか?',
   'choices': [{'text': '自然体で笑いを交えたユーモラスな雰囲気'},
    {'text': '自分の経験や感情を率直に語る誠実さ'},
    {'text': '専門的な知識やスキルを活かした説得力'},
    {'text': '最新トレンドを先取りするクールさ'}],
   'reason': 'タレント選定の指標となる「信頼感」の要素(ユーモア、誠実さ、専門性、トレンド感)を直接的に尋ねず、感情的な評価で測定する。'},
  {'question_text': '新しいスナックを食べるとき、どのような音楽が流れていると最もリラックスできますか?',
   'choices': [{'text': '軽快なポップス'},
    {'text': 'リズミカルなヒップホップ'},
    {'text': '落ち着いたインディー・アコースティック'},
    {'text': 'エレガントなジャズやクラシック'}],
   'reason': 'CMに起用するタレントの音楽的イメージ(明るさ、エネルギー、落ち着き、上品さ)を音楽好みから間接的に把握し、タレントのパーソナリティ選定に活かす。'}]}

最後に、生成された質問と選択肢のデータをファイルに保存します。

# 結果をファイルに保存
with open("survey.json", "w", encoding="utf-8") as f:
    json.dump(json_data, f, indent=4, ensure_ascii=False)

本話のまとめ

LLMによりアンケートの質問文と選択肢を生成する方法をご紹介しました。LLMのStructured Output機能を利用することにより、LLMから容易に構造化データを取得することが可能で、得られたデータの整形などの後処理が楽になります。

次話では、ペルソナデータを考慮して、LLMにアンケート回答を指示する方法について解説します。

お問い合わせはこちら