🎙️

【Nvidia】ジャパニーズペルソナに対しバーチャルインタビュー【Ollama】

に公開

概要

「バーチャルインタビュー(調査)」という言葉をご存知だろうか?
マーケティングでは, 商品開発にむけターゲットセグメントのニーズ調査を行う. 試作品(サンプル)の提供や, 出店での体験会など, リアル空間でそうしたシーンに出会した人も多いのでは?

しかし,実際にやると, 1)求めたターゲットセグメントのユーザーがなかなか見つからない, 2)見つかったとしても良い回答が得られるとは限らない, という悩みがでてくる.

そこで一つのアイデアは, リアルなペルソナをもったバーチャルヒューマンに, デジタル上でインタビューしよう!! というものがある. デジタル上であれば, 時間や費用を気にせず, 好きなだけ質問ができてしまう.

生成AIを活用した市場調査の有効性については, 近年多くの研究がなされその可能性と限界が徐々に明らかになってきているようだ.

https://gaaaon.jp/blog/nvidia-persona#10fcaf6d9a4d1bb83b3a9b22

博報堂がリアルデータから作った7,000名の仮想ペルソナを使ったアンケート調査を行うサービスを作っていることは有名かもしれない.

https://www.hakuhodo.co.jp/news/newsrelease/109174/

今回は, 最近公開された日本人🇯🇵ペルソナデータを使ったインタビューUIを作ったお話.

準備

今回, 日本人(ただし現実ではない)にインタビューする...とのことで, 日本人のペルソナデータを活用する. 利用するデータは, Nvidiaが公開しているNemotron-Personas-Japan である.
https://huggingface.co/datasets/nvidia/Nemotron-Personas-Japan

このデータセットは,

日本における人口の多様性と豊かさを捉えることを目的とし、実世界の人口統計、地理的分布、性格特性の分布に基づいて合成的に生成されたペルソナのオープンソースデータセット

であり, 統計情報をもとに作成された, "実に日本人らしい" 背景情報をもった擬似ペルソナデータである.

中身はテーブル形式で表現されており, 個人ごとに以下の21の情報をもっている.

フィールド名:型 説明
uuid:string グローバル識別子
professional_persona:string 主な職業分野、主要な専門スキル、特性や行動を捉える職業的ペルソナ
sports_persona: string スポーツへの関心、チームへの所属、フィットネスや運動への取り組み方を表すスポーツ・ペルソナ
arts_persona: string 創造的表現への関わりや芸術が自己認識に与える影響を特徴づけるアート・ペルソナ
travel_persona: string 旅行に関する関心やスタイルを捉えるトラベル・ペルソナ
culinary_persona: string 食や料理の好み、料理スキルレベル、食体験への取り組み方を示す料理ペルソナ
persona: string 人生に対する視点や姿勢の本質を簡潔に捉える汎用的なペルソナ
cultural_background: string 個人の文化的背景の説明
skills_and_expertise: string 職業的および個人的スキルを記述形式で表現
hobbies_and_interests: string 個人的な関心や余暇活動を記述形式で表現
skills_and_expertise_list: string[] スキルや専門分野の一覧
hobbies_and_interests_list: string[] 趣味や個人的関心の一覧 職業上の目標や長期的なキャリアの展望
sex: string 生物学的性別(例:男性、女性)
age: string 年齢(歲)
marital_status: string 婚姻状況(例:既婚、未婚、離婚、死別)
education_level: string 最終学歴
occupation: string 包括的な職業分類
region: string 日本の伝統的な地域区分(関東、関西など)
area: string 広域的な文化圏(東日本、西日本)
prefecture: string 日本の主要な行政区分(都道府県)
country: sttring 居住国

professional_persona

"水本 侑美は、診療所で長年培った患者対応と健康相談のノウハウを、退職後のボランティア活動と地域介護リーダー育成に結びつけ、組織運営の実務経験と実用主義のバランスを保ちながら、若い医療志願者に伝統的健康方法と帳簿管理の実践を指導している。"

sports_persona

"水本 侑美は、里山の低強度トレッキングと季節ごとの花畑での軽い体操を、写真撮影で記録しながら、自然と身体リズムを合わせる養生散策を日課にし、外向性と開放性が育む柔軟なフィットネス習慣で、他世代への体力モチベーションを伝えている。"

persona

"水本 侑美は、診療所の運営と地域支援の実務経験、自然との調和を重んじる季節感、手芸と書道の創作活動、そして安定した対人協調性が融合した独自の高齢者リーダー像を示す人物である。"


上記のNemotron-Personas-Japanは Hugging Faceにて公開されており, 自由にダウンロードできるため使わせてもらう.[1]

↓詳細なデータ設計を知りたければこちら
https://zenn.dev/yuto_mo/articles/fad63e2994fbb4
https://qiita.com/__miyata-yy__/items/6e848aae3a9e864cf24a

https://programming-school.dream-target.jp/python_parquet

実装

まずは全体の完成イメージを共有しておく.

作るものは、

  • UI部分では, ①ペルソナの選択画面+説明文, ②チャットスペース
  • Agent部分では, ③①で選択したペルソナ, および②で受けた質問をもとに対話する処理
    である.

②のチャットスペースについては, chat-ui-kit-react/stylesを使用している.
チャット画面をReactで作成する方法は以前の記事で紹介しているためここでは省く.
https://zenn.dev/akitek/articles/e702dd8869acc5

ペルソナの選択画面+説明文①

ペルソナデータセットからランダムに抽出した有限個のペルソナデータを表示、説明内容をリスト形式で並べている.

デザインに関しては, "react-bootstrap"のButtonCard, OverlayTrigger, Tooltipを活用.

OverlayTrigger, Tooltipは, ヘッダー横の「?」マークから, フィールドの説明を確認できるUIを簡単につくれる.

Alertを, 外部サーバーへの送信リクエストの成否メッセージに使用.
以下は失敗した例である. z-indexを調整し, 画面要素を崩さないようにしている.

Agent部分③

次にAgentの部分を説明する.
今回は手軽にローカルLLMのOllamaをLLMとして採用. APIなどの代替手段でもOk.

  1. ユーザーのペルソナ選択により, Agentのペルソナを決定し, まずは自己紹介
  2. 続いて, ユーザーからの質問に対し,保持しているペルソナに即して回答しつづける.

主な構成は以前の記事と似ている. 今回は,日本人ペルソナデータセットを活用し,よりリアルなペルソナ情報をAgentに持たせている点が異なる.

https://zenn.dev/akitek/articles/4dcf81dff67587

from langchain_core.prompts import ChatPromptTemplate
from langchain_community.llms import Ollama

class Agent:
    def __init__(self, persona):
        # ローカルLLMを搭載する
        self.llm        = Ollama(
                            base_url="http://localhost:11434",
                            model="elyza:jp8b")
        
        self.persona    = persona
    
    def self_introduction(self):
        template = """Persona: {persona}

        Answer: 自身のペルソナを意識して自己紹介してください."""
        prompt = ChatPromptTemplate.from_template(template)
        chain = prompt | self.llm
        return chain.invoke({"persona": self.persona["persona"]})
    
    def conversation(self, text):
        template = """Persona: {persona}

        Answer: 自身のペルソナを意識して次のインタビュー質問に端的に答えてください.
                {interview}"""
        prompt = ChatPromptTemplate.from_template(template)
        chain = prompt | self.llm
        return chain.invoke({"persona": self.persona["persona"], "interview": text})

対話方法については chain形式でかけると便利である.
https://python.langchain.com/docs/integrations/llms/ollama/

完成物

最後に今回作成したものの動作確認をする. ペルソナとして、「豊原さん」を選択.

いろいろ質問してみると、基本的にペルソナ情報に沿った回答がされていることがわかる.[2]
ペルソナ情報にない、「すき家の牛丼のうちどのメニューが好きか」質問すると, 「テリタマ牛丼」とされた. ちなみに, すき家の牛丼メニューには「テリタマ牛丼」はなさそう😇...

https://www.sukiya.jp/menu/in/gyudon/

今回はUIの開発だったので気にはしないが, ハルシネーションはまだまだ強い。
このままインタビューしても、よい結果は得られなさそうだが...笑

まとめ

最近公開された日本人🇯🇵ペルソナデータを使ったインタビューUIを作った, という記事でした.
LLM自体の回答をよりリアルにするという根本的な課題はあるが, バーチャルインタビューという概念はとても面白いと感じる.

UIに関しては, 音声や3Dモデルなどを, テキスト応答生成と連動して動かせるようにできないかなぁーと検討中

脚注
  1. 商用利用も可能という太っ腹なご対応🙇 ↩︎

  2. 気づいたのだが, "professional_persona"と"persona"の年齢表記が違うのに気づいた ↩︎

Discussion