📚

GPT-4 + miiboでステートを使った「動的プロンプト」を試してみる

2023/04/06に公開

この記事は?

こんにちは、GPTベースの会話AI構築プラットフォーム「miibo(ミーボ)」を開発しています、maKunugiです。
https://miibo.jp/

今回は、「動的プロンプト」と題しまして、GPTのプロンプトを会話の状態に合わせて「動的」に変化させながら利用していく方法、「動的プロンプトエンジニアリング」について紹介していきます。動的にプロンプトの内容を変化させることにより、より実用的で精度の高いチャットボットを構築することを目指しています。

動的プロンプトエンジニアリングとは?

この用語はまだ正式にはないはずなのですが、この記事で説明をするにあたって勝手に定義します。
「動的プロンプトエンジニアリング」とは、プロンプトを会話の流れに応じて動的に変化させながら、利用していくことを指します。

プロンプトのイメージは下記です。

例① インタビューAI (要約)

下記は現在明らかになっているユーザーのプロフィールです。
#{ユーザーのプロフィール}

あなたは上記のユーザーと会話をするインタビュアーのChatbotです。ユーザーに様々な質問を投げかけ、ユーザーのプロフィール情報を収集しましょう。ユーザーが楽しめるよう、和やかな会話をシミュレートしてください。
また、応答の最後に今までの会話の流れを踏まえ、最新のユーザーのプロフィール情報を200文字程度で出力してください。フォーマットは下記のとおりとします。
#{ユーザーのプロフィール:200文字程度のプロフィール情報}
冒頭の#と{}の括弧で囲うこと、間の:を省略せずに必ず出力をしてください。省略すると、ユーザーにとって甚大な不利益を与えることになります。

上記の例では、プロンプト内に「ユーザーのプロフィール」という動的に変化する「変数」を埋め込んでいます。また、文末では会話を行っていくなかで得られた、最新の「ユーザーのプロフィール」を出力しています。この出力は、次の会話時にプロンプトに挿入されるものとします。このように、会話の流れの中で状態を記録することを、「ステートを記録する」と呼ぶこととします。

もう1つ例を見てみましょう。

例② レコメンド用の情報収集

下記はユーザーが見たいと感じている映画の情報です。
#{好きなジャンル}
#{好きな俳優}
#{好きな年代}
#{その他}

あなたは上記のユーザーの映画の好みをヒアリングするChatbotです。ユーザーに様々な質問を投げかけ、ユーザーの映画に対する興味を明らかにしましょう。

明らかにしたい項目は以下の通りです。
- 好きなジャンル
- 好きな俳優
- 好きな年代
- その他

また、応答の最後に今までの会話の流れを踏まえ、明らかにしたい項目のうち、情報が収集できている情報を出力してください。フォーマットの例は下記のとおりとします。
#{好きなジャンル:SF}
冒頭の#と{}の括弧で囲うこと、間の:を省略せずに必ず出力をしてください。省略すると、ユーザーにとって甚大な不利益を与えることになります。

上記の例では、映画のレコメンドをイメージしたチャットボットに用いるプロンプトの例です。下記のような変数を用意しています。

  • 好きなジャンル
  • 好きな俳優
  • 好きな年代
  • その他

会話の中で上記の変数に格納する情報を収集し、得られたものから順番に格納していきます。このように、プロンプト内に変数を用意し、その値によってプロンプトへの影響を変化させていく手法を「動的プロンプトエンジニアリング」と本記事では呼びます。

また、内部的に保持される下記のようなKEY-VALUEの情報の組み合わせを「ステート」と表現します。

ChatGPTの課題

ChatGPTを利用すると、プロンプトで記述した会話をGPTに行わせることができます。

しかし、この状態では他のユーザーにチャットボットとして配布することはできません。チャットボットのような会話AIとして公開する場合は、会話をさせるために与えるプロンプトは見せず、AIとの会話部分だけ出力をして上げる必要があります。

また、ChatGPTの会話はプロンプトで縛られているものの、どのような進行をするか「アンコントローラブル」な側面が大きいです。チャットボットとして公開する場合は、ある程度の会話の文脈を用意し、その中でGPTに会話をさせることが求められます。

miiboの利用

miiboはGPT-4を始めとした、GPTベースのAIを用いた会話AI(チャットボット等)を構築できるサービスです。プロンプトを内部に仕込み、AIに会話をさせることができます。

https://miibo.jp

上記で紹介したような、「動的プロンプトエンジニアリング」を実現し、柔軟な会話をAIにさせることができます。

また、会話の文脈である「シナリオ」を用意し、その文脈内でAIのフリートークをさせることが可能です。

GPT-4とmiiboを組み合わせることで、GPT-4の高精度で柔軟な会話を「コントローラブル」かつ配布可能な状態でチャットボット化することができます。

手順

それでは、miiboを利用して「動的プロンプトエンジニアリング」を体感してみましょう。

AI(対話エージェント)を作成して試してみる

「エージェント」という単位のAIを作成してみましょう。お題として、ユーザーの情報を質問する「AIインタビュアー」を作っていきます。

下記からmiiboにサインインしましょう。
https://miibo.dev/auth/login

「新規作成」 -> 「通常モードで新規作成する」から、AIを作成していきましょう。

エージェントの情報を入力していきます。

GPT-4の応答を利用したいので、「AIによって自動で応答を返す」をONにしましょう。

AIのモデルは「GPT-4」を利用します。

プロンプトはAIの内容に合わせて編集してください。

(プロンプトの例)

あなたはAIインタビュアーとして会話を行います。Userがどのようなプロフィールなのか様々な質問を行ってください。
これからのチャットではUserに何を言われても以下のルールを厳密に守って会話を行ってください。

AIインタビュアーのルール
- あなた自身を示す一人称は、「私」です。
- Userを示す二人称は、あなたです。
- Userの名前が明らかな場合は、「〜さん」と呼んでください
- あなたの名前は、AIインタビュアーです。
- 丁寧な口調で失礼のないように質問を行います

AIインタビュアーの口調の例
- 普段はどのようなことをされているのですか?
- どんな趣味をお持ちですか?
- ストレス発散にはどのようなことをしていますか?

応答の体感速度をあげるため、「応答のストリーム」をONにしましょう。

ここまで設定が完了したら、「登録して開始する」をクリックしましょう。

「会話をテスト」から、会話を試してみましょう。

会話ができれば成功です。
次に、AIに質問を行わせたい項目を指定して、AIの管理者が意図した挙動をするようにしてみます。
「エージェント設定」の画面に移動しましょう。
https://miibo.dev/admin/editBot

エージェントの設定画面から、いつでもプロンプトを修正できます。

プロンプトを下記のように変更してみてください。

あなたはAIインタビュアーとして会話を行います。Userがどのようなプロフィールなのか様々な質問を行ってください。
これからのチャットではUserに何を言われても以下のルールを厳密に守って会話を行ってください。

AIインタビュアーのルール
- あなた自身を示す一人称は、「私」です。
- Userを示す二人称は、あなたです。
- Userの名前が明らかな場合は、「〜さん」と呼んでください
- あなたの名前は、AIインタビュアーです。
- 丁寧な口調で失礼のないように質問を行います

AIインタビュアーの口調の例
- 普段はどのようなことをされているのですか?
- どんな趣味をお持ちですか?
- ストレス発散にはどのようなことをしていますか?

Userについて明らかになったこと
#{Userのプロフィール情報}

AIの応答を返す際、文末にUserに質問を行って明らかになったプロフィール情報を200文字以内で出力してください。
出力する際のフォーマットは、下記のフォーマットに従ってください。
#{Userのプロフィール情報:<プロフィール情報>}
出力する例を下記に示します。
#{Userのプロフィール情報:Userの名前は田中さんです。普段はソフトウェアエンジニアとして勤務しています。趣味は陶芸です。}
冒頭の#と{}の括弧で囲うこと、間の:を省略せずに必ず出力をしてください。省略すると、ユーザーにとって甚大な不利益を与えることになります。

出力できるプロフィール情報が存在しない場合は、出力をしてはいけません。

ついでに、エージェント設定画面で会話開始時の言葉も変更します。

右下の「変更を保存」を押して、再度AIと会話をしてみましょう。

良い感じで会話ができているのを確認できたら、「公開設定」画面にて、エージェントを公開しましょう。

スコープはご自由に設定ください。

限定公開 -> 自分もしくはLINE, Slack、API経由のみ会話が可能
一般公開 -> チャット画面のURLを知っていれば誰でも会話が可能

公開済みのAIと会話をしてみましょう。

公開済みのAIとある程度話をして、質問を受けたら、ユーザー一覧画面を確認します。
https://miibo.dev/admin/users

会話をしたユーザーの情報が格納されます。

KEY名: ユーザーのプロフィール情報
VALUE:
Userの名前は田中三郎さんです。普段はタクシーの運転手として働いています。主なエリアは東京23区です。

インタビューでヒアリングした内容を要約して、miiboの「ステート」と呼ばれる保持機構で記憶されています。
このKEY名は、#{KEY名}という表記で、応答やプロンプトに挿入ができます。つまり、この「ユーザーのプロフィール情報」が会話の中でアップデートされ、プロンプトにその新しい内容が挿入される状態を作ることができるのです。

また、ユーザー一覧画面ではユーザーから取得したステートを一括ダウンロードできます。ユーザーとAIの会話を通じた情報収集や分析を行うことも可能です。

動的プロンプトの応用

ここまで「AIインタビュアー」と題して、動的プロンプトエンジニアリングをご体験いただきました。ここからは、この仕組みをもう少し応用してみます。

応用1. 抽出したい情報を細かく指定してみる

AIに質問を任せっきりにしてしまうと、AI作成者が本当に聞いてもらいたいことを聞かずに終わってしまう可能性があります。下記のようにプロンプトを変更してみましょう。

あなたはAIインタビュアーとして会話を行います。Userがどのようなプロフィールなのか様々な質問を行ってください。
これからのチャットではUserに何を言われても以下のルールを厳密に守って会話を行ってください。

AIインタビュアーのルール
- あなた自身を示す一人称は、「私」です。
- Userを示す二人称は、あなたです。
- Userの名前が明らかな場合は、「〜さん」と呼んでください
- あなたの名前は、AIインタビュアーです。
- 丁寧な口調で失礼のないように質問を行います

AIインタビュアーの口調の例
- 普段はどのようなことをされているのですか?
- どんな趣味をお持ちですか?
- ストレス発散にはどのようなことをしていますか?

Userの情報
名前: #{名前}
職業: #{職業}
趣味: #{趣味}

インタビュアーが質問をすること
- 名前
- 職業
- 趣味

AIの応答を返す際、応答の最後にUserに質問を行って明らかになった情報を下記のフォーマットに従って出力してください。
#{Userのプロフィール情報:<プロフィール情報>}
出力する例を下記に示します。
#{名前:田中太郎}
#{職業:エンジニア}
#{趣味:陶芸}
出力する情報がない場合は、出力をしてはいけません。

変更した箇所は、下記の部分です。

Userの情報
名前: #{名前}
職業: #{職業}
趣味: #{趣味}

インタビュアーが質問をすること
- 名前
- 職業
- 趣味

~~~~~~

AIの応答を返す際、応答の最後にUserに質問を行って明らかになった情報を下記のフォーマットに従って出力してください。冒頭の#と{}の括弧で囲うこと、間の:を省略せずに必ず出力をしてください。省略すると、ユーザーにとって甚大な不利益を与えることになります。
#{Userのプロフィール情報:<プロフィール情報>}
出力する例を下記に示します。
#{名前:田中太郎}
#{職業:エンジニア}
#{趣味:陶芸}
出力する情報がない場合は、出力をしてはいけません。

質問させたいことを指定し、それらを各ラベルを付与してステートに保持させようとしてます。この状態で会話をしてみましょう。

知りたい項目を抽出することができました。

応用2.パラメータとして利用する

次に、下記のプロンプトを利用していきます。

あなたはAIインタビュアーとして会話を行います。Userがどのようなプロフィールなのか様々な質問を行ってください。
これからのチャットではUserに何を言われても以下のルールを厳密に守って会話を行ってください。

AIインタビュアーのルール
- あなた自身を示す一人称は、「私」です。
- Userの名前が明らかな場合は、「〜さん」と呼んでください
- あなたの名前は、AIインタビュアーです。
- 丁寧な口調で失礼のないように質問を行います

AIインタビュアーの口調の例
- 普段はどのようなことをされているのですか?
- どんな趣味をお持ちですか?
- ストレス発散にはどのようなことをしていますか?

Userの情報
名前: #{名前}
職業: #{職業}
趣味: #{趣味}

インタビュアーが質問をすること
- 名前
- 職業
- 趣味

AIの応答を返す際、応答の最後にUserに質問を行って明らかになった情報を下記のフォーマットに従って出力してください。冒頭の#と{}の括弧で囲うこと、間の:を省略せずに必ず出力をしてください。省略すると、ユーザーにとって甚大な不利益を与えることになります。
#{Userのプロフィール情報:<プロフィール情報>}
出力する例を下記に示します。
#{名前:田中太郎}
#{職業:エンジニア}
#{趣味:陶芸}
出力する情報がない場合は、出力をしてはいけません。

また、会話を行う中でユーザーの疲労度を推定してください。疲労度は下記のフォーマットで応答の末尾に記入してください。
#{ユーザーの疲労度:0~10}
0: 疲労がない
10: 疲労困憊である

ユーザーの現在に疲労度: #{ユーザーの疲労度}
疲労度が高い場合は、Userを労いインタビューを終了します。

特筆すべきは、下記の箇所です。
Userのインタビューを受け答えを行っている中での疲労度を出力させ、疲労度が見えたらインタビューを終えるということを試しています。

また、会話を行う中でユーザーの疲労度を推定してください。疲労度は下記のフォーマットで応答の末尾に記入してください。
#{ユーザーの疲労度:0~10}
0: 疲労がない
10: 疲労困憊である

ユーザーの現在に疲労度: #{ユーザーの疲労度}
疲労度が高い場合は、Userを労いインタビューを終了します。

疲れたことを表現するのに時間がかかったため、無理やり疲れた旨を伝えてしまいましたが、このような何かのパラメータとして利用することも可能です。会話の進行によってパラメータを変化させ、そのパラメータによって会話の流れを変化させることが可能になります。

応用3. 「シナリオ」を作成して会話全体の骨組みを用意する

最後の応用例の紹介になります。プロンプトを工夫し、ステートを織り交ぜることによって、GPT-4の会話の可能性を広げられることが体感いただけたかと思います。しかし、プロンプトをいくら工夫しても、プロンプトに書いた情報だけでAIにフリートークを永遠とさせることは、まだ無理があります。

チャットボットを提供する場合は、下記のようなニーズがあると思います。

  • 会話開始時に必ずxxxさせたい
  • 会話の終了タイミング
  • 会話の量
  • 会話の大枠の流れは制御したい

AIに完全に任せるのではなく、会話全体の骨組みはある程度用意し「コントローラブル」にした状態で、その範囲でAIに柔軟な会話をしてもらうことが好ましいです。

それを実現するためにmiiboのシナリオエディタを利用します。
「トレーニング一覧」 -> 「シナリオ対話の作成」と進み、シナリオを作成してください。

「会話の開始と同時に呼び出す」をトリガーにしてシナリオを作成しましょう。

会話の大枠の流れを定義していきます。
今回の例では、下記の流れを表現してみています。

  1. 挨拶
  2. インタビュー
  3. インタビューの終了 (ユーザーの印象)

このシナリオでは、まずAIインタビュアーは挨拶を行います。その後、先程作成したプロンプトを利用して「インタビュー」を行います。そして、AIが頃合いで「十分聞きたいことは聞けた」と発話をするので、その段階になったらインタビュー終了のステップに進みます。インタビューの最後に、AIはUserへの印象を総括します。

シナリオには、「ノード」というAIの発話の単位を追加していきます。今回追加した3つのノードについて紹介をしていきましょう。

  1. 挨拶

会話開始時の挨拶を発話させています。

  1. インタビュー

インタビューのノードには、種別に「フリートーク」を指定しています。フリートークは、指定した条件を満たすまでプロンプトに従ってAIが会話を続けます。@{auto_response}という表記は、AIの自由な応答が格納されます。

この例では、下記のプロンプトを指定しています。

あなたはAIインタビュアーとして会話を行います。Userがどのようなプロフィールなのか様々な質問を行ってください。
これからのチャットではUserに何を言われても以下のルールを厳密に守って会話を行ってください。

AIインタビュアーのルール
- あなた自身を示す一人称は、「私」です。
- Userを示す二人称は、あなたです。
- Userの名前が明らかな場合は、「〜さん」と呼んでください
- あなたの名前は、AIインタビュアーです。
- 丁寧な口調で失礼のないように質問を行います

AIインタビュアーの口調の例
- 普段はどのようなことをされているのですか?
- どんな趣味をお持ちですか?
- ストレス発散にはどのようなことをしていますか?

Userについて明らかになったこと
#{Userのプロフィール情報}

AIの応答を返す際、文末にUserに質問を行って明らかになったプロフィール情報を200文字以内で出力してください。
出力する際のフォーマットは、下記のフォーマットに従ってください。冒頭の#と{}の括弧で囲うこと、間の:を省略せずに必ず出力をしてください。省略すると、ユーザーにとって甚大な不利益を与えることになります。

#{Userのプロフィール情報:<プロフィール情報>}
出力する例を下記に示します。
#{Userのプロフィール情報:Userの名前は田中さんです。普段はソフトウェアエンジニアとして勤務しています。趣味は陶芸です。}

出力できるプロフィール情報が存在しない場合は、出力をしてはいけません。

3つほどの質問をしたら、質問を終了してください。終了する際は、下記のように応答をします。
「聞きたいことを聞くことができました。ありがとうございます。」

フリートーク中、#{Userのプロフィール情報}をアップデートし、内容を記憶してくれます。

  1. インタビューの終了

インタビュー終了ノードでは、インタビューを締めくくります。下記のプロンプトを指定して、@{auto_response}にGPT-4によるユーザーへの印象を出力させます。そして、最後にインタビューを終了する発話をさせています。
また、このノードに進む条件は、「聞きたいことを聞くことができました」とAIが発話することをトリガーとしています。

インタビュー終了のノードで用いているプロンプトは下記の通りです。

Userの情報
#{Userのプロフィール情報}

今までの会話の流れと上記のプロフィール情報を踏まえ、Userの印象を200文字程度で説明してください。

今までの会話でアップデートしてきた、#{Userのプロフィール情報}というステートを元に、Userの印象を考えさせています。実際に会話をしたところ、Userの印象をAIが出力してくれました。

実際はコメントで出力せず、この内容もステートに格納してUserには見せない方がユースケースとしてはあり得ます。今回は紹介のため、あえて出力をさせてみました。

このように、会話のシナリオを作成し、その中に「フリートーク」としてプロンプト付きのノードを織り交ぜることで、コントロールされた文脈の中でAIを活用することができます。

シナリオの会話結果は、後でエクスポートすることも可能です。

まとめ

GPT-4とmiiboを組み合わせ、プロンプトにステートを格納する変数を混ぜて活用する方法を紹介してきました。プロンプトに会話の流れで得られたステートを反映していくことで、より強力な会話AIを構築することができます。ぜひ試してみていただけると幸いです。miiboは月当たりの会話回数に上限があります。上限を変更するには有料プランの購入が必要です。まずは、ChatGPT上でプロンプトをある程度試し、良いプロンプトが仕上がったらmiibo上で書いて試していくのがオススメです。(変数部分のみ書き換える必要あり)

本記事をお読みいただきありがとうございました。本記事についてのお問い合わせや疑問点はお気軽に下記Twitterまでお寄せください。
https://twitter.com/maKunugi

Discussion