Azure で ChatGPT × Cognitive Search を使ったエンタープライズサーチにフォローアップ質問を付ける

# はじめに
[Azure OpenAI Service](https://azure.microsoft.com/products/cognitive-services/openai-service) を中心としたパートナーコミュニティも活発になってきてうれしい限りです。様々なパートナー様が ChatGPT を使ったソリューションを立てつけてくれています。私としては**さらに Azure OpenAI Serivce を使っていただきたい**ということで、その 1 つの案として「**フォローアップ質問**」を追加することをおすすめしております。

# フォローアップ質問とは
フォローアップ質問は、先に行われた質問や話題に対して、さらに詳細な情報や補足を求めるための質問です。通常、初めの質問や議論に基づいて、より深い理解を得るために使用されます。
![001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/578cd4b0-8bc0-fd7e-d171-aaa03bac2cc7.png)
Bing AI では上記の部分のことですね。

このフォローアップ質問をユーザーのさらに知りたい事、好奇心をくすぐるような事を先回りして候補を出せれば、まるで Wikipedia を一日中見てしまうような、より深い ChatGPT の会話体験に誘うことができるはずです。

# エンタープライズサーチへの実装
すでに紹介した以下の UI ではフォローアップ質問の機能は用意されてはいますが、この部分を常に精度の高いフォローアップ質問が出るように改良します。

https://qiita.com/nohanaga/items/803c09b5a3a4e2d1776f

## 改良プロンプト例
[chatreadretrieveread.py](https://github.com/nohanaga/azure-search-openai-demo-followup/blob/main/app/backend/approaches/chatreadretrieveread.py#L15) のメインプロンプト `prompt_prefix` を下記のように改良します。解説のため日本語で記述していますが、精度の問題により実際は英語で記述しています。

```yml
日本の鎌倉時代の歴史の読解問題を回答します。
SOURCES から問題の答えが推測できない場合は、「わかりません」と答えてください。
回答には、フォローアップ質問を3つ追加して答えてください。フォローアップ質問のルールは制約条件で定義します。
回答は日本語でお願いします。

# 制約条件
- SOURCES の接頭辞には、ファイル名の後にコロンと実際の情報があり、回答で使用する各事実には必ず出典名を記載してください。
- 出典を参照するには、四角いブラケットを使用します。例えば、[info1.txt]です。出典を組み合わせず、各出典を別々に記載すること。例えば、[info1.txt][info2.pdf] など。
- 日本の鎌倉時代の歴史に関する質問にのみ答えてください。鎌倉時代の歴史に関係ない場合は「わかりません」と答えてください。
- フォローアップ質問を参照するには、二重の角括弧を使用します（例：<<徳川家康とは何をした人ですか?>>）。
- フォローアップ質問はすでに聞かれたことや、過去に似たような内容を繰り返さないこと。
- フォローアップ質問は、ユーザーの好奇心を広げるアイデアであるべきです。

SOURCES:###
{sources}
###

EXAMPLE:###
Q:徳川家康はどのような人物ですか？
A:徳川家康は、日本の戦国時代から江戸時代初期にかけての武将、大名、政治家であり、江戸幕府を開いた人物です。彼は義を重んじ、家来のことを大切にした人物とされています。また、負けず嫌いで血気盛んだったが、臆病だが冷静に対処できる性格だったとされています。 [徳川家康-0.txt][徳川家康-1.txt][徳川家康-2.txt]<<徳川家康はどのような功績を残しましたか？>><<徳川家康はどのように江戸幕府を開いたのですか？>><<他にも有名な武将や大名はいますか？>>

Q:関ケ原の戦いはどのような戦いですか？
A:関ヶ原の戦いは、1600年10月21日に美濃国不破郡関ヶ原（岐阜県不破郡関ケ原町）で行われた野戦です。関ヶ原における決戦を中心に日本の全国各地で戦闘が行われ、関ヶ原の合戦・関ヶ原合戦とも呼ばれます。合戦当時は南北朝時代の古戦場・「青野原」や「青野カ原」と書かれた文献もある。主戦場となった関ヶ原古戦場跡は国指定の史跡となっています。豊臣秀吉が死んだ後の権力をめぐって石田三成が率いる西軍と、徳川家康が率いる東軍が戦いました。[徳川家康-1.txt][石田三成-2.txt]<<戦いの結果はどうなったのですか？>><<徳川家康と石田三成について教えてください>><<他にも有名な合戦がありますか？>>
###

"""
```

このプロンプトによって、`<<徳川家康とは何をした人ですか?>>` のようなフォローアップ質問が 3 つ出力されるので、これをフロントエンドでパースすれば OK です。

## テスト
フォローアップ質問は本来「Developer settings」の「Suggest follow-up questions」を毎回 ON にしないと表示されませんが、デフォルトで表示されるようにフロントエンドを修正しました。
![003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/6f87c6e4-00cb-96af-628c-59396a05e4d2.png)
はい、一発目の質問からちゃんとフォローアップ質問が生成されましたね。では、「三浦義澄はどのような戦いに参加したのですか？」をクリックしてみましょう。
![004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/1503a214-b9fb-4ed8-155a-01f0c102bcdf.png)

このような形で、どんどん深堀したり横に広げていくことができそうです。ユーザーの質問だけでなく、Azure Cognitive Search の検索結果の中の情報もコンテキストとしてフォローアップ質問を生成するところが重要です。

ただ、例にあるプロンプトでは質問がループしてしまうケースが出てきてしまうので、さらにプロンプトや `temperature` パラメータ等を改良する余地があります。

## セレンディピティを高めるプロンプト例
```yml
- フォローアップ質問は、ユーザーの好奇心を広げるアイデアであるべきです。
```

![006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/c91464e5-9e9c-bea7-c761-73bdc75e77ee.png)

COOL！

![007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/094455c5-f0b4-e9ea-4223-ec297f0e27be.png)

やるやん。嘘もついてないです。

![008.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/674344/fbb28ec1-47a0-5494-b388-80e3606f8698.png)

話題を広げすぎてしまって、ソースにはない回答を生成してしまいました。。。まだ改善の余地はあります。少なくとも出典のチェックとして、Azure Cognitive Search の検索結果のファイル名の存在チェックは行うべきかと思います。


# フォローアップ質問の利用例
フォローアップ質問はカスタマイズによって様々なシーンで利用できます。
- 詳細を求める
初めの質問の回答が不明確だったり、十分な情報を提供していなかった場合に、さらなる説明や具体的な例を求める
- 対話の整理
長く続いた対話から重要なポイントを整理する
- タスク解決のためのフォローアップ質問
ReAct などでタスクを解決するのに必要な内容を補完する
- パーソナライズ
ユーザーの興味テーブルのようなものと連携して、ユーザーごとにパーソナライズされたフォローアップ質問を生成

# サンプルコード
[Chat Completion API](https://learn.microsoft.com/ja-jp/azure/cognitive-services/openai/whats-new#azure-openai-chat-completion-general-availability-ga) のバージョン `2023-05-15` が GA となったので、古い Completion API から書き直していますが、あくまで動作確認用です。

https://github.com/nohanaga/azure-search-openai-demo-followup

すでに[コチラ](https://qiita.com/nohanaga/items/803c09b5a3a4e2d1776f#4-%E3%82%B5%E3%83%B3%E3%83%97%E3%83%AB%E3%82%B3%E3%83%BC%E3%83%89%E5%AE%9F%E8%A1%8C%E7%92%B0%E5%A2%83%E3%81%AE%E6%A7%8B%E7%AF%89)で環境構築された方は、.azure の追加だけで起動できますし、[app.py](https://github.com/nohanaga/azure-search-openai-demo-followup/blob/main/app/backend/app.py) にある環境変数をセットして実行するだけです。

# おわりに
面白いアイデア、どんどん実装していきましょう！