Azure OpenAIのChatGPT APIとGPT-4を利用してFAQチャットボットのようなシステムを作れないか再検証してみた

以前、Azure OpenAIのtext-davinci003を利用し、FAQチャットボットのようなシステムを作れないか試したことがあります。

現在はAzure OpenAIからChatGPT APIが公開されたので、再検証してみた結果をお伝えします。

構築方法

前回と同様、構築方法は下記のブログに記載されています。

blog.jbs.co.jp

下記条件を満たすソースコードを、GPT-4で作成します。

  • ユーザーが質問文を入力
  • Azure OpenAI APIで、質問文からキーフレーズ抽出
  • Azure OpenAI APIで、キーフレーズの同義語生成
  • Azure Cognitive Searchで、キーフレーズと同義語を使い検索(OR条件)
  • Azure OpenAI APIで、質問文と検索結果をもとに回答分析

ソースコードの実行フローは下記の通りです。

検証結果

結論から言うと、検索結果の妥当性をChatGPTに判断させる仕組みはできました。
※チャットボットとして回答する機能の実装はしていません。

GPT-4でソースコードの大部分を自動作成し、Git Hubに公開しています。

github.com

※BlazorApp/Pages/Index.razorに検索処理があります。

※GPT-4で生成したコードは動く程度の内容です。サンプルデータ以外ではエラーが発生する可能性があります。

※Azure OpenAI APIの使用料金に注意してください。

作成したシステムの画面です。

「質問を入力して下さい」に質問を入力し、「回答を見つける」ボタンを押すと、Azure OpenAIのChatGPT APIとAzure Cognitive Searchを利用した検索処理が実行されます。

Azure OpenAIのChatGPT APIで、ユーザーが入力した質問と、Azure Cognitive Searchから取得したコンテキストを使用して分析します。

分析に使用するプロンプトは以下の通りです。

あなたはFAQチャットボットです。
次の文章を読んで、質問に答えて下さい。
文章が質問への回答として適切な内容であればOK適切な内容でなければNGcheckに出力して下さい。
文章が質問への回答として正解であればY正解でなければNanswerに出力して下さい。
質問にはOK、NG、Y、Nしか回答できません。
回答と信頼性スコアはフォーマットに記載された形式で出力して下さい。
信頼性スコアは整数のみ出力して下さい。
段階的に、論理的に考えて下さい。

Desired format:
answer:{Y or N}
check:{OK or NG}
reason:回答
score:信頼性スコア

文章: """

{Azure Cognitive Searchのキーワード検索で取得したコンテキスト(SampleAnswer)}
"""

質問: """
{ユーザーが入力した質問}
"""

検証に使用したデータは前回と同じです。

自治体における「子育てAIチャットボット」の普及に向けたオープンデータ化についての「報告書」及び「FAQデータセット」を公開 | LINE Corporation | CSR活動レポート

ダウンロードしたデータをcsv形式のデータに変換して、Azure Cognitive Searchでインデックスを作成しました。

下記に、検証結果を記載します。

「母子手帳を受け取りたいのですが手続きを教えて下さい。」と質問しました。

Sample Questionと同じ内容の質問ですが、複数個所が正解と判明しました。

手続きについては言及されていない文章(「母子手帳の受け取り場所はどこですか?」)がありますが、受け取り方法に関しては記述があり、適切な回答と判断されたようです。

同じ質問をもう一度実行してみたところ、前回OKだった箇所がなぜかNGに変わり、スコアも0になりました。

さらに、前回出力されていなかった「母子手帳の申請には医師の診断書が必要ですか?」が回答候補として現れました。

ChatGPTで生成される質問のキーフレーズや同義語が変動することで、Azure Cognitive Searchのキーワード分析結果も変わっていると考えられます。

別の質問を試してみました。「里帰り出産の際、受診票は使えますか?」と尋ねたところ、使えないとの回答が得られました。

しかし、チェックの項目はNGと表示されました。スコアが100で、適切な回答ができる文章と判断された場合は、OKと出力して欲しいです。

再度同じ質問を試してみました。

「受診票は使えません」と回答されましたが、チェックはNGのままでした。

プロンプトの内容については、改善が必要かもしれません。

別の質問をしてみます。

「予防接種の問い合わせ窓口を教えてください。」と質問しました。

これも複数個所が正解であるとの結果になりました。

ChatGPTがNGと判断したケースで、人間がOKと評価できる場合、どのように気づくか?

質問への回答が多い状況で、ユーザーへ通知する方法は?

Azure Cognitive Searchのキーワード分析結果の変動にどう対応する?

ChatGPTを用いた検索システム運用においては、これらの課題の解決策を見つけ出すことが重要ですね。

ソースコードの作成手順

ソースコードは、下記のプロンプトをGPT-4で順番に実行して作成しました。

ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

あなたはWebアプリケーションエンジニアです。
下記の条件を満たす、MSのBlazor Server用のC#プログラムを作成して下さい。
プログラムは.NET Core 6で使用します。
開発環境にはVisual Studioを使用します。
段階的に、論理的に考えて下さい。

条件: """
1,ユーザーの質問を入力するテキストボックスを画面上部に配置する。
2,ユーザーの質問への回答結果を表示するテキストボックスを画面下部に配置する。
3,ユーザーの質問を引数にして、キーフレーズ分析する関数
4,上記3の結果を引数にして、同義語を作成する関数
5,上記3と4の結果を引数にして、検索を実行する関数
6,ユーザーの質問と上記5の結果を引数にして、分析を実行する関数
"""
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
AnalyzeKeyPhrases関数を作成して下さい。
AzureのOpenAIのAPIに接続してキーフレーズ分析を実行するC#のソースコードを書いて下さい。
AzureのOpenAIのAPIに接続する方法は、下記のサンプルコードを参考にして作成して下さい。
HttpClientを使用して作成して下さい。
段階的に、論理的に考えて下さい。

サンプルコード: """
curl https://*************.openai.azure.com/openai/deployments/************/chat/completions?api-version=2023-03-15-preview \
  -H "Content-Type: application/json" \
  -H "api-key: YOUR_API_KEY" \
  -d '{
  "messages": "[{\"role\":\"system\",\"content\":\"You are an AI assistant that helps people find information.\"}]",
  "max_tokens": 800,
  "temperature": 0.5,
  "frequency_penalty": 0,
  "presence_penalty": 0,
  "top_p": 0.95,
  "stop": null
}'
"""
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
GenerateSynonyms関数を作成して下さい。
AzureのOpenAIのAPIに接続する方法は、AnalyzeKeyPhrases関数を参考にして下さい。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
AnalyzeKeyPhrases関数とGenerateSynonyms関数は内容がほぼ同じなので、共通化して下さい。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
ExecuteSearch関数を作成して下さい。
検索は、Azure Cognitive Searchを使用します。
引数に、AnalyzeKeyPhrases関数とGenerateSynonyms関数の実行結果を使用します。
Azure Cognitive Searchに検索した結果は、下記のサンプルの形式で配列に保存して下さい。
段階的に、論理的に考えて下さい。

サンプル: """
{
      "@search.score": 1,
      "ID": "044",
      "SampleID": "00044",
      "SampleQuestion": "療育医療の申請は誰がすればいいのですか?",
      "SampleAnswer": "療育医療の申請者はお子さんの健康保険の被保険者です。\n例)父(母)の加入している健康保険の被扶養者⇒父(母)が申請者"
}
"""
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
AnalyzeResults関数を作成して下さい。
引数に、ExecuteSearch関数の実行結果とuserQuestionを使用します。
CallOpenAIAPI関数を使用して、分析して下さい。
CallOpenAIAPI関数のsystemMessageには、下記のsystem_messageを文字列として使用して下さい。
CallOpenAIAPI関数のuserMessageには、下記のuser_messageを文字列として使用して下さい。
CallOpenAIAPI関数の分析結果の文字列を:と,で分割し、下記のサンプルの形式で配列に保存して下さい。
配列には、SearchResult配列の属性を含めて下さい。
段階的に、論理的に考えて下さい。

サンプル: """
{
      "answer": "Y",
      "check": "OK",
      "reason": "回答",
      "score": 10
}
"""

system_message: """
あなたはFAQチャットボットです。
次の文章を読んで、質問に答えて下さい。
文章が質問への回答として適切な内容であればOK、適切な内容でなければNGをcheckに出力して下さい。
文章が質問への回答として正解であればY、正解でなければNをanswerに出力して下さい。
質問にはOK、NG、Y、Nしか回答できません。
回答と信頼性スコアはフォーマットに記載された形式で出力して下さい。
信頼性スコアは整数のみ出力して下さい。
段階的に、論理的に考えて下さい。

Desired format:
answer:{Y or N}
check:{OK or NG}
reason:回答
score:信頼性スコア

文章:
{SearchResults配列のSampleAnswer}
"""

user_message: """
質問:
{userQuestion}
"""
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
ユーザーの質問への回答結果はテキストボックスで表示する予定でしたが、それではわかりにくいです。
AnalysisResultをテーブル形式で表示するように修正して下さい。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
これまで質問した内容をすべて反映したWebアプリケーションのソースコードを作成して下さい。
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー

最初のプロンプトの実行結果をVisual Studioに張り付けました。

大まかな処理の流れはできています。

変数や関数名は実行する度に変動する可能性があります。

Azure OpenAIのChatGPT用APIに接続するC#のソースコードを記述したドキュメントはどこかにあると思います。

今回は面倒なので、Azure OpenAI StudioのChatGPT プレイグラウンドで取得できるCurlコマンドのサンプルコードを使用して、GPT-4でC#用ソースコードを作成しました。

ChatGPTプレイグラウンドのコードの表示ボタンを押すと、下記のサンプルコードが表示されます。

AnalyzeKeyPhrases と GenerateSynonyms の内容はほぼ同じだったので、共通化させました。

きれいにリファクタリングしてくれます。

Azure Cognitive Searchに接続する関数は、403エラーなどが出てうまく動きませんでした。

今回はAzure.Search.Documentsを使用して接続する関数に修正しました。

当初の予定では、テキストボックスに分析結果を出力する予定でした。

※ユーザーの質問への回答結果を表示するテキストボックスを画面下部に配置する。

テキストボックスではわかりにくいと思ったので、表形式で配列の内容を表示するように修正しました。

まとめ

ChatGPTを利用すると、Cognitive Search が返した結果が、ユーザーの問い合わせに対し妥当であるかを判断する仕組みを作れることが分かりました。これを利用すれば、問い合わせ内容に対して妥当性が高い返答を返すFAQチャットボットの構築が可能になると考えます。

さらに、GPT-4を使えば自動でソースコードが生成できることも確認できました。

ただし、GPT-4が作成するソースコードは完全に自動化することは難しいです。

作成された関数を実行する際、エラーが起こることがありますが、GPT-4に質問することで解決策が見つかります。

今回は公開されているFAQデータを利用しましたが、社内のPDFファイルなどのデータもチャンク処理してAzure Cognitive Searchに格納すれば、同様のシステムが実現できます。

最近、MicrosoftからMicrosoft 365 Copilotが発表され、Business Chatを使うことで同様の機能が得られるかもしれません。

https://blogs.windows.com/japan/2023/03/28/introducing-microsoft-365-copilot-a-whole-new-way-to-work/

また、OpenAIからも社内データ活用が可能なプラグイン機能が発表されています。

※下記リンク先のLearn how to build a semantic search and retrieval pluginに記載されています。

platform.openai.com

Microsoftはsemantic-kernelも公開しています。

github.com

これにより、データ検索の常識が変わることが予想されます。

どのサービスを使って課題解決に繋がるアプリケーションを作成するか、今後も検証を進めていきます。

4月14日追記:

・Business Chatについては、明確な情報ではないので記述内容を修正しました。

・タイトルの「FAQチャットボットができた」という表現は不適切な為、「FAQチャットボットのようなシステムを作れないか再検証してみた」に修正しました。

執筆担当者プロフィール
株木 誠

株木 誠

先端技術部の株木です。 Azure OpenAI Service を活用するアプリ開発を担当しています。

担当記事一覧