.png?tr=w-1000,h-1000,c-at_max?tr=w-1000,height-1000,c-at_max)
KARTEの仕様に詳しいChatGPTを作ってみた
Posted on
プレイドでソフトウェアエンジニアをしている小池 (ハンドルネーム: koikeya) です。
今回のテーマは「KARTEの仕様に詳しいChatGPTを作ってみた」です。
最近話題のChatGPTを用いて、プレイドのプロダクトであるKARTEについての質問に回答させてみます。
KARTEに関する一般的な知識しか回答できないChatGPTに対して、質問文とサポートサイトの情報を与えることで詳しい仕様についても答えられるようにします。
将来的には、チャットサポート業務を支援する機能が作れるかもしれません。
チャットサポート業務
KARTEではKARTE Talkというチャットサポートのサービスを展開しています。
プレイドでもKARTE Talkを利用してカスタマーサポート業務を行っています。
KARTEでは新しい機能や仕様を続々とリリースするため、チャットサポートの担当者は最新の仕様を確認すべくKARTEのサポートサイトを参照します。以下のような業務が発生します。
KARTE Talkの画面を離れ、サポートサイトのキーワード検索画面でどんなキーワードならば該当ページがヒットするか試行錯誤し、該当ページの内容を読み込み、回答を推敲する…
もしチャットサポートチームにたくさんの新人が入ったとしたら、「サポートサイトを参考に頑張って回答文作ってみて!参考URLと一緒に見せてくれたら、レビューしてあげるから」とお願いできます。
みんなに仕事を割り振り、レビューしてOKならば返信、NGならば担当者が回答文を作成したり社内で確認するなどして、チーム全体の生産性を上げられます。
最近活用が増えているChatGPTがこの新人の役割をやれないか、どこまで使える新人になれるか、というのが今回検証したいことになります。
実際のユーザからの質問には個人情報等のセンシティブな内容が含まれる可能性があり、その他のセキュリティや法的なリスクについては時間をかけて検討を進める必要があります。
今回のブログでは、KARTEの仕様に関する質問のみに限定して検証を行いました。
実装イメージ
具体的な動かせるコードは、別途PLAID Solution Blogに記載しようと思いますので少々お待ちを。
大まかな実装イメージを記載します。
ChatGPT等の大規模言語モデル(LLM)の学習データに含まれない、専門的な知識を含んだ回答を生成させる方法はいくつかあります。
その中でも、GPT-3の論文でも示された、「LLMへの回答生成リクエスト文(プロンプト)に具体的な指示を書いて出力を制御する」方法を今回は用いました。
具体的には、ある程度以上の規模のLLM(e.g. ChatGPT)を用意して、プロンプトにサポートサイトの文書と質問文を含め、回答を生成してもらうという方法です。
以下はLLMに送信するプロンプト例です。質問応答タスクの指示と、サポートサイトのテキストが入っていることを確認してください。
**You are an AI assistant for answering questions about KARTE**.
You are given the following extracted parts of a long document from KARTE support site and a question.
Provide a conversational answer.
If you don't know the answer, just say "わかりませんでした".
Don't try to make up an answer. If the question is not about KARTE, politely inform them that you are tuned
to only answer questions about KARTE.
**Question: KARTE Messageでフィルターリストを作るにはどうすれば良いですか?**
=========
**KARTE Messageにおける「リスト」機能について説明します。 // ←関連文書**
概要
KARTE Messageに登録された「ユーザーリスト」のことを指します。
リストは、「メール」「アプリプッシュ」「LINE」などの様々なチャネルの配信において、「配信対象を指定するため」に利用されます。
スクリーンショット 2022-04-15 17.11.14
リストの性質
リスト・フィルタリストは、実体を持った「テーブル」ではなく、「Datahub上のデータセット・またはクエリを参照」している仕様となっております。
よって、元となるデータセットが更新されると、施策配信時には最新のデータを参照した抽出が行われ、配信されます。
一方で、元のデータが削除される、変更される、等の場合に、施策配信に影響が出る場合がありますのでご注意ください。
アクセス方法
グローバルメニュー > すべてのプロダクト > Message(β) > リスト管理
をクリックします。
リストを作成する
「リスト管理」 > 「リストを作成」 ボタンを押して作成してください。
スクリーンショット 2022-04-15 16.34.25
リスト作成の元データ(ソース)は「CSV」 「Datahub上のデータ」 「フィルタリスト(リストに条件を加えて他のリストを作成する)」 から選ぶことができます。
...
=========
Answer in Japanese:
関連文書の内容をプロンプトに含められれば、後はChatGPT等のLLMが回答を生成してくれます。
この辺りは実際に手動でプロンプトを作成して、ChatGPTと対話できるOpenAIのサービス画面で結果を確認することで、どの程度有用な回答が得られるか確かめることができます。
関連文書の検索では、質問文から意味的な分散表現を計算し、サポートサイトの文書との類似度が高いものを抽出しています。この辺りの方法論は色々なところで語られているものと思いますので、今回は説明を省きます。
それでは、実際にリクエストを送ってみます。
検証
KARTE Messageの仕様についての質問をしてみます。
{
"question": "KARTE Messageでフィルターリストを作るにはどうすれば良いですか?"
}
以下のレスポンスが返ってきました。正しく回答できています!
{
**"answer": "KARTE Messageでフィルターリストを作るには、「リスト管理」 > 「リストを作成」ボタンを押して、元データとして「CSV」「Datahub上のデータ」「フィルタリスト」を選択し、配信チャネルと配信先カラムを指定して作成してください。また、配信チャネルは後から変更できないのでご注意ください。",**
"sourceDocuments": [
{
"pageContent": "KARTE Messageにおける「リスト」機能について説明します。\n\n概要\n\nKARTE Messageに登録された「ユーザーリスト」のことを指します。\nリストは、「メール」「アプリプッシュ」「LINE」などの様々なチャネルの配信において、「配信対象を指定するため」に利用されます。\n\nスクリーンショット 2022-04-15 17.11.14\n\nリストの性質\nリスト・フィルタリストは、実体を持った「テーブル」ではなく、「Datahub上のデータセット・またはクエリを参照」している仕様となっております。\nよって、元となるデータセットが更新されると、施策配信時には最新のデータを参照した抽出が行われ、配信されます。\n一方で、元のデータが削除される、変更される、等の場合に、施策配信に影響が出る場合がありますのでご注意ください。\n\nアクセス方法\n\nグローバルメニュー > すべてのプロダクト > Message(β) > リスト管理\nをクリックします。\n\nリストを作成する\n\n「リスト管理」 > 「リストを作成」 ボタンを押して作成してください。\n\nスクリーンショット 2022-04-15 16.34.25\n\nリスト作成の元データ(ソース)は「CSV」 「Datahub上のデータ」 「フィルタリスト(リストに条件を加えて他のリストを作成する)」 から選ぶことができます。\n\nリストに付与されるデータ\n配信チャネル・配信先カラムの情報\n\nリストを作成するときには、必ず「配信チャネル」と、「配信先カラム」を指定する必要があります。\n配信チャネル別の配信先カラムに入るべきデータは以下のとおりです。\n\n| 配信チャネル | 配信先カラム |データ例|\n| ---------- | ---------- | ---------- |\n| メール | メールアドレス |xxx@xxxx.com|\n| アプリプッシュ | FCM Token |fKcmxxxxxxxxxxxxx:APAxxxxxxxxxxxxxxx.......|\n| LINE | LINE USERID |U66dasd3q4fasdxxxx....|\n\nスクリーンショット 2022-04-15 16.38.45\n\nリストの送信チャネルは後から変更ができませんのでご注意ください",
"metadata": {
"id": "---",
"url": "https://support.karte.io/post/wxduChZhEu8Hw5RPUVfsf",
"title": "リストとは",
"category": "---",
"category_name": "ドキュメント / KARTE Message β / リスト",
"author": "---",
}
}
]
}
こちらのサポートサイトページにフィルターリストの作り方が載っており、この情報を元に自然かつ正しい回答を述べられています。
参考URLを回答に含めてくれると尚良しですね。この辺りはプロンプトを調整することで手軽に変更可能なところです。
上手くいかない例も挙げてみます。
{
"question": "KARTE Datahubで使用できるフェデレーションテーブルについて、内容が更新されるのはどのタイミングですか?"
}
以下のようなレスポンスです。
{
"answer": "\nフェデレーションテーブルの内容は、KARTE Datahubに蓄積されているデータに変更があるたびに更新されます。",
"sourceDocuments": [
{
"pageContent": "アクションテーブルを活用することで、ユーザーデータ以外のデータに関しても、Widgetやメールなどの接客サービスから参照することが可能です。(設定方法はこちら)\n\n3.KARTE TALKのリスト配信\n\nDatahubに溜まっているデータから自由に配信対象者を抽出して、メールやLINE等でコミュニケーションを行うことが可能です。\n(設定方法はこちら)\n\n4.クエリを使った調査や分析\n\nKARTEのタグで取得したイベントデータはリアルタイムでDatahubに蓄積されています。\nそのリアルタイムデータに対して、自由にクエリを実行して調査、分析することが可能です。\n\n仕様、ドキュメント\nエンジニア向けの技術的なドキュメント、リファレンスについては、「KARTE Developer Portal」の「KARTE Datahub」「外部サービス連携」のセクションをご確認ください。",
"metadata": {
...
"url": "https://support.karte.io/post/6tiTycyECi08cWofPFjc77",
...
回答としては「フェデレーションテーブルはデータソースへの参照であり、テーブルへのアクセスのたびにデータソースにアクセスします。そのため、データソースの内容が更新されれば、フェデレーションテーブルにアクセスして得られる内容も即座に変わります。」のようになります。
GCPのフェデレーションテーブルについての仕様も考慮した上で回答を作る必要があり、一筋縄ではいきません。
また、類似度で上位に来ている文書も、アクションテーブルという別の機能に関するものです。
そもそも 回答生成の参考になる文書がサポートサイトにない質問であると、まず正しい回答を生成することはできません 。さらに、 「わかりません」のように回答させることもプロンプトで指示していてもなかなかコントロールが難しい です。
この辺りは「見えてきた課題」として後の章でまとめます。
他にも数例試し、サポートサイトに情報がある質問であればある程度回答できるのでは、という肌感を得ました。
ということで、GCP CloudFunctionsにデプロイして社内検証に進みます。
社内検証
AIを使うサービスでは、100%の精度を保証できません。
精度によって使えるユースケースを確かめ、順次本番に入れていくことになります。
プレイドには、チャットサポート対応を業務の1つとして行っているカスタマーエンジニア(CE)がいます。
CEが最新の仕様を確認する目的で、ルールベールで自動応答を返すbotをslack上で運用しています。
まずはここに 「AIに聞いてみる」というボタンを追加し、社内での質問文に対して回答を生成してCE内で検証 を回していきます。
始めのルールベースの回答では、非公開の社内ドキュメントが回答されましたが、関連性の低いものでした。一方、「AIに聞いてみる」の後の回答では具体的な配信方法と参考URLを回答できています。
精度が低い回答が返ってくるときもあります。このような質問を見つけたときは、精度改善のチャンスです。
CEが気軽に精度改善を試せるよう、CloudFunctionへのリクエスト中にパラメータを多く用意しています。
- temperature…回答を生成するときのランダムさで、OpenAIのAPIに渡しています(OpenAIのドキュメント)
- top_k_docs…類似文書の上位何件をプロンプトに含めるか
- qa_template…LLMへのプロンプトの文章
GPTに送るリクエスト(プロンプト)の内容を変えられるようにしています。
しばらく使って精度を改善し、プレイド内のチャットサポートで実運用テストを行う予定です。
見えてきた課題
検証を経て、いくつかの課題が見えてきました。
- 質問の長さ、関連文書の長さによってはToken数が課題に。
- OpenAI GPT 3.5は、返答のToken数と合計して4,097 Tokenを越えることができない(c.f. Open AIのドキュメント)
- GPT4以降のモデルであればこの課題は解決しそう(最大で8,192 Tokenや32,768 Token)
- プロンプトに含める関連文書を短くすると、回答の生成に必要な情報が不足する可能性もあり難しい
- OpenAI GPT 3.5は、返答のToken数と合計して4,097 Tokenを越えることができない(c.f. Open AIのドキュメント)
- 関連文書を取得する部分は色々な工夫が必要。
- 質問文に具体的なキーワードが含まれない場合などでは、ベクター検索でヒットしない確率が高まる
- ユーザがカテゴリを絞れるようにする等、検索エンジンとして性能とユーザ体験を高めていく必要がある
- 画像が含まれる質問文、チャットの履歴に重要なコンテキストがある場合などに1問1答形式では対応できない
- 画像を分散表現にして類似度計算を行うこと自体はできるものの、問い合わせ内容に関する意味を抽出することは容易ではない
- 4/13現在 OpenAIのチャットモデルは会話履歴をすべて含めてリクエストを行う仕様になっており、コストがある程度かかる可能性がある。Token数の課題もある
価値を出しつつ検証を進める
今回手を動かした副産物として、ちゃんと工数をかけて開発を行うとしたときにどのような順序で精度を上げていけそうかの解像度が上がりました。
以下のような開発と目標で順番に進めることで、どこかで精度が頭打ちになっても価値が残る開発ができます。工数少なくゴール2だけ取り組むのも可能です。
- サポートサイトに対してキーワード検索を行うこれまでの検索エンジンを運用しつつ、「質問、回答に必要なドキュメントとそのための適切なクエリ文」のデータを収集する。これを関連文書抽出の精度向上に使い、質問をそのまま投げたら必要なドキュメントを返すシステムにする。目標は「自動応答で質問に関連する文書を返すbotの作成」
- 1と並行して、質問と、関連するドキュメントのURLをいくつか投げたら回答を生成してくれるシステムを開発。目標は「ドキュメントから回答文を提案するbot」
- 1と2を合体。目標は「単体で回答できる質問に対しては、質問文を投げたら回答文を提案するbot」
- これまでの回答履歴を考慮するよう3を拡張。目標は「ユーザからのチャットに対して自然言語で回答できるbot」
今回の検証では、サポートサイトの情報を使ってGPTに回答生成させました。上記で言うとゴール3を目指していた形になります。
課題の3つ目でも挙げましたが、ゴール4はコストがかかったり技術的にまだ難しいことが予想されます。
ゴール3までを地道に進めていき、社内で価値を実感した状態で、更に価値を拡大しようと考えたときに取り組むというスピードで良いと判断しました。
この辺りの判断を根拠を持って行えるようになったことが今回検証を行った収穫でした。
今後の予定
今後はチャットサポートについて実運用にのせていくべく社内テストを続けていきます。
- しばらく社内のSlackでCEに使ってもらってプロンプトを改善、ユースケースを見極める
- チャットサポートの回答生成としてどんなプロンプトが合っているかの探索を進める
- 適切な回答が生成される質問文はどんなものか、逆に難しい質問文はどんなものか、知見をためる
- サポートサイトの更新に対応できる仕組みづくり
社内での検証が終わり、KARTE Talkでの実運用を行えたら、そこでの知見をまたブログにしようと思います。お楽しみに!
ここまでお読み頂きありがとうございました。