Amazon Web Services ブログ

【寄稿】Amazon ConnectとAmazon Bedrockを活用したチャットボット構築におけるタイムアウトの回避策

この投稿はアクセンチュア株式会社 テクノロジーコンサルティング本部所属の金 敬源氏と、マネージャー 竹内 誠一 氏に、Amazon Connect と Amazon Bedrock を活用したチャットボット構成におけるタイムアウトの制約とその回避策について寄稿いただいたものです。


はじめに

このブログでは、Amazon Connect と Amazon Bedrock を活用したチャットボットの構成におけるタイムアウトの制約とその回避案について紹介します。

以下は、このブログの構成です:

  • 背景
  • チャットボット構成と制約
  • タイムアウト回避のアプローチ
  • タイムアウトの回避策
  • 結論

背景

あるクライアントから、「Amazon Bedrock を活用してチャットボット回答の作成・メンテナンスの手間を減らしたい」「Amazon Bedrock の回答に納得できない場合はコンタクトセンターのオペレータとリアルタイムでチャットしたい」という要件をいただき、新たなチャットボットのプロトタイプを作成しました。

このプロトタイプの特徴は以下の通りです:

  • Amazon Bedrock を活用してチャットボット回答の作成・メンテナンスの手間削減
    • 検索拡張生成 (RAG、Retrieval Augmented Generation) と呼ばれる手法を採用
    • データストア として Amazon Kendra を活用
    • Amazon Bedrock のモデルとして Anthropic Claude 2 を活用
  • Amazon Bedrock の回答に納得できない場合はコンタクトセンターのオペレータとリアルタイムでチャット
    • コンタクトセンター・ソリューションとして Amazon Connect を活用
    • チャットボットからオペレータへの引き継ぎを Amazon Connect のコンタクトフローで実装

データストアとして Amazon Kendra を採用した検索拡張生成(RAG)である点が大きな特徴ですが、その技術的な要点についてはこちらの AWS ブログを始めとして多くの解説記事がありますので、本ブログでは省略します。

[高精度な生成系 AI アプリケーションを Amazon Kendra、LangChain、大規模言語モデルを使って作る]

このプロトタイプではチャットボットの応答のタイムアウトが課題となったのですが、Amazon Connect 固有の制約によるものなので一般にはあまり知られていないと思います。本ブログではこの課題と回避策に焦点をあてて私たちの知見を紹介します。

チャットボットの構成と制約

今回のチャットボットのアーキテクチャは以下の通りです。

Amazon Connect と Amazon Bedrock を活用したチャットボットのアーキテクチャ(タイムアウト回避策実装前)

図1. Amazon Connect と Amazon Bedrock を活用したチャットボットのアーキテクチャ(タイムアウト回避策実装前)

質問者からの入力テキストは一旦 Amazon Connect が受信し、状況に応じてチャットボットやオペレータに転送します。Amazon Connect では、電話やチャットの着信があった時、その処理の流れを定義するコンタクトフローがあります。コンタクトフローのブロックの1つに「顧客の入力を取得する」があり、入力テキストを受け取って条件によって Amazon Lex や他のブロックに分岐することができます。

ただし、このブロックの Amazon Lex 呼び出しには、「Amazon Connect の機能仕様」の「チャットの機能仕様」に記述されているように、Amazon Connect から Amazon Lex チャットを呼び出した場合には、6秒以内に応答がないとタイムアウトになる、という制約があります。この制約は、上限緩和の申請をしても変更することができません。ただし、これはチャット限定の制約で、電話から音声で呼び出された場合には該当しません。ちなみに今回のコンタクトフローでは、「顧客の入力を取得する」ブロックがタイムアウトを検知するとエラーに分岐され、「切断」ブロックに遷移し、チャット UI に”Chat has ended!”を返してフローを終了します。

図2. タイムアウト検知時のチャット UI 画面 (Amazon Connect のチャットウィジェットを使用)

図2. タイムアウト検知時のチャット UI 画面 (Amazon Connect のチャットウィジェットを使用)

タイムアウト回避のアプローチ

FAQ を検索して結果を応答するという従来型のチャットボットであれば、6秒というタイムアウトは厳しい制約ではありません。しかし、大規模言語モデルを使った Amazon Bedrock のようなサービスは応答時間が6秒を超えることがあるため、Amazon Connect チャットから呼び出す場合にはタイムアウトも想定して設計する必要があります。

このタイムアウトの回避策として、2つのアプローチを考えられます。

  1. 6秒以内に回答を生成できるようにAmazon Kendra と Amazon Bedrock を最適化
  2. Amazon Lex は Amazon Bedrock を呼び出したら直ちに「顧客の入力を取得する」ブロックにリターンし、非同期の処理で Amazon Bedrock の応答をチャット UI に送付

チャットボットの場合、質問内容、つまり Amazon Bedrock に引き渡されるプロンプトのチューニングがしづらく、1は PoV (Proof of Value) の期間内に実現できない可能性が高いと判断し、今回は2を追求することにしました。

タイムアウトの回避策

以下は、2つ目の方法のアーキテクチャを示しています。

図3. タイムアウト回避策実装後のチャットボットのアーキテクチャ

図3. タイムアウト回避策実装後のチャットボットのアーキテクチャ

最初のアーキテクチャと同様に、質問者の入力をコンタクトフローの「顧客の入力を取得する」ブロックにて受け取り、Amazon Lex に送信します。Amazon Lex から呼び出された AWS Lambda 関数(以下、Lambda 関数)は、別の Lambda 関数を非同期に呼び出し、「AI 検索中」のメッセージを返して、直ちに終了します。これにより「顧客の入力を取得する」ブロックのタイムアウトを回避します。

非同期に呼び出された Lambda 関数は、質問者の入力で Amazon Kendra を検索し、質問と検索結果を Amazon Bedrock に渡して回答文を生成させ、生成した回答文を Amazon DynamoDB に保存します。

この仕組みにより、タイムアウトの制約を回避しながら Amazon Bedrock を呼び出すことができるようになりました。

次に、Amazon DynamoDB に保存された回答文をチャット UI に届ける仕組みを説明します。上図のループの部分に Amazon Connect が Lambda 関数を介して回答文を入手していることを示しましたが、仕組みの大部分は Amazon Connect のコンタクトフローで実装されているので、ここからはコンタクトフローを参照しながら説明することにします。

非同期に実行する処理の完了を検知したい時の常とう手段として、「処理完了時にイベントを発行させる方法」と、「定期的に処理の状態をチェックする方法」がありますが、今回は後者を採用しました。前者はイベントを発行する仕組みと受け取る仕組みが必要で、Amazon DynamoDB はテーブル更新時に Amazon EventBridge イベントを発行できるのですが、コンタクトフロー側にこのイベントを受け取る手段がありませんでした。

後者の方式はコンタクトフローでも簡単に実装できます。以下に今回実装した仕組みを紹介します。

まずコンタクトフローを示します。

図4. タイムアウト回避策を実装した Amazon Connect コンタクトフロー

図4. タイムアウト回避策を実装した Amazon Connect コンタクトフロー

次に、このコンタクトフローの処理の流れを順に説明します。

1.「顧客の入力を取得する」ブロック

    • 質問者からの入力を受け取り、Amazon Lex を内部で呼び出します。Amazon Lex は Amazon Bedrock の応答を待たずにリターンするので、タイムアウトすることはありません。Amazon Lex から正常応答を受け取ったら2に遷移します。

2.「待機」ブロック

    • 2~5でループを構成し、そのループを1秒間隔で20回繰り返すことにしました。その1秒間隔をここで定義しています。

3.「AWS Lambda 関数を呼び出す」ブロック

    • Amazon DynamoDB に保存された回答文を取りに行く Lambda 関数を呼び出します。

4.「コンタクト属性を確認する」ブロック

    • 3の Lambda 関数の戻り値を確認し、条件分岐します。「回答文待機中」の場合は5に遷移し、「回答文有」の場合は6-Bに遷移します。

5.「ループ」ブロック

    • ループ回数をカウントして条件分岐します。回数上限は20としました(最大100でセット可能)。ループ回数が20回に到達するまでは2に遷移し、20回に到達したら6-Aに遷移します。

6-A.「プロンプトの再生」ブロック

    • チャット UI への応答にタイムアウトメッセージをセットして1に戻ります。

6-B.「プロンプトの再生」ブロック

    • チャット UI への応答に、Amazon DynamoDB から Lambda 関数経由で
    • 受け取った回答文をセットして、1に戻ります。

チャットボットの実行例

最後に、今回紹介した方法を組み込んだチャットボットの実行例を紹介します。質問をチャット UI に入力すると、Amazon Connect コンタクトフローが Lambda 関数を呼び出し、Lambda 関数が Amazon Kendra の検索とジェネレーティブ AI による回答文の生成を実行し、ループしながら待機していたコンタクトフローが回答文を受け取って、タイムアウトすることなくチャット UI に回答文を表示できました。Amazon Kendra にはあらかじめ本ブログのドラフトが保存してあり、これを要約したものが回答文として生成されました。

図5. タイムアウトを回避して応答を返した時のチャット UI 画面 (Amazon Connect のチャットウィジェットを使用)

図5. タイムアウトを回避して応答を返した時のチャット UI 画面 (Amazon Connect のチャットウィジェットを使用)

結論

本ブログでは、Amazon Connect のチャットボットから Amazon Bedrock を呼び出す場合に、Amazon Lex 呼び出しが6秒でタイムアウトするという制約が課題になることを指摘し、Lambda 関数の非同期化とコンタクトフローの工夫による現実的なタイムアウト回避策を提示しました。一般的にはチャットボットを実装する際にわざわざ Amazon Connect を経由させたりしませんが、コンタクトセンターのオムニチャネル戦略構想では電話とチャットの併用はよくあることですし、電話やチャットへの自動応答への期待も Amazon Bedrock の普及により益々高まっています。

今後の新たなモデルの登場・サービスの改善により今回指摘した制約が回避できるようになる可能性も期待していますが、今回あげたケースのようにタイムアウトの可能性が排除できない時には、本ブログで紹介した方法が参考になれば幸いです。

著者について

金 敬源

金 敬源

アクセンチュア株式会社 テクノロジーコンサルティング本部
インテリジェントクラウド アンド インフラストラクチャー グループ所属

竹内 誠一

竹内 誠一

アクセンチュア株式会社
マネジャー テクノロジーコンサルティング本部
インテリジェントクラウド アンド インフラストラクチャー グループ所属