前の投稿 で書いたように、Bot Framework Composer では QnA Maker との連携方法が 3通りあります。
簡単なのが、
- Knowledgebase 管理 + QnA Intent Recognizedトリガー
- Connect to QnA Knowledgebase
の二つのやり方。
それらと比べると少しだけテクニックが必要なのが、”Send an HTTP request” アクションを使って QnA Maker からの応答を処理する方法です。
要は REST 呼び出しの応答を仕様にあわせてフォーマットしましょうというものです。
今回は、Send an HTTP request で QnA Maker から回答を受け取るための手順を紹介します。
■ (前提) QnA Maker
前提として、ナレッジベースは QnA Maker ポータル で管理、発行しておきます。
Composer で必要になる情報は [SETTINGS] – [Deployment details] にあるので確認しておきます。

■ Composer の Configuration
QnA Maker で管理しているナレッジベースの情報は Composer の設定ファイルに書き込みます。
[Configure] – [Advanced Settings View (json)] で設定ファイルを開いて、”qna” セクションに必要な情報を設定します。
なお “subscriptionKey” は空にします。今回は Composer から QnA Maker に発行することはないのでこの値は不要です。

さらに必須ではありませんが、私は “qnaoptions” というセクションを追加します。
名前は任意ですが、このあとで使うのでここでは以下の名前にします。
answercount | QnA Maker から上位何件の回答を取得するか |
threshold | 回答とするスコアの下限。例えば 25 とするとスコア 0.25 未満は質問に対する回答としません |
carousel | 複数の回答の並びの方向。carousel を true にすると回答を横スクロールする形でユーザーに応答します。 これは QnA Maker に対するparameterではありませんが、ここに入れてしまいました。 |

■ Send an HTTP request を配置
QnA Maker から回答を得る一連の流れについて。
最初は “Send an HTTP request” アクションです。多分一般的には “Unknown intent” に配置することになるはずです。

プロパティは以下の通り。
QnA Maker の API リファレンス を参考にします。
“${~}” の部分は変数の参照なので設定項目の名前と同じにすることに注意。
HTTP method | POST |
Url | ${settings.qna.hostname}/knowledgebases/${settings.qna.knowledgebaseid}/generateAnswer |
Body | {“question”:”${turn.activity.text}”, “top”:”${settings.qnaoptions.answercount}”, “scoreThreshold”:”${settings.qnaoptions.threshold}”} |
Header Key 一つ目 | Content-Type |
Value 一つ目 | application/json |
Header Key 二つ目 | Authorization |
Header Value 二つ目 | EndpointKey ${settings.qna.endpointKey} |
Result property | dialog.api_response |
Content type | application/json |
Response type | json |

■ QnA Maker からの応答のステータスコードを確認
[Create a condition] – [Branch: If/else] アクションを配置します。
REST 呼び出しなので応答のステートを確認するものです。
ステータスコードが 200 かどうかの判断なのでプロパティは以下の通り。
Condition | =dialog.api_response.statusCode == 200 |

If/else の False 側(ステータスコードが 200 以外)については今回の本題ではないでの、それらしいテキストをユーザーに応答するだけにします。

■ 取得した回答をユーザーに応答
QnA Maker から得られた回答をユーザーに応答します。ユーザーへの応答なので “Send a response” を使いますが、少しだけテクニックが必要です。
If/else の True 側に “Send a response” を配置して、プロパティの [Bot responses] で [Show code] を選択します。これで項目ごとにテキストボックスなどで設定する代わりに応答に関する項目をまとめて設定したり、省略可能な項目を設定したりできます。
[Activity Text = ${count(dialog.api_response.content.answers)}件の回答 Attachments = ${SendActivity_QnaAnswerList_Attachments(dialog.api_response.content.answers)} AttachmentLayout = ${AttachmentLayoutValue(settings.qnaoptions.carousel)} ]
入力すると警告が表示されると思います。すぐ後に解消するので少し我慢。

この領域が狭いなと思ったら [Pop out] アイコンをクリックすると広げて編集できます。

なお正しくは QnA Maker から得られた回答が 0件の場合を考える必要があると思いますが、今回は省略します。
やるとしたら Brance: If/else で見ることになるはずです。
■ ユーザー応答で使用する関数を定義
Composer でユーザー定義の関数を追加します。
[Bot responses] – [Common] で [Show code] を選択します。
ここで関数を 3つ定義します。
# SendActivity_QnaAnswerList_Attachments(answers) - ${foreach(answers, answer, AnswerCardHelper(answer.answer))} # AnswerCardHelper(answerText) [HeroCard Text = ${answerText} ] # AttachmentLayoutValue(isCarousel) - IF: ${isCarousel == 'True'} - carousel - ELSE: - list
Composer の先ほどの警告表示は消えるはずです。

これらの関数は、ひとつ上の手順の “Send a response” で呼び出している関数です。そのためメインダイアログクラスに定義するべきかもしれません。
今回はコードがきれいで見やすいので “Common” に3つとも定義しました。
■ フローの最終形
QnA Maker からの回答をユーザーに応答するフローは以下のようになります。

■ 動作確認
[Start bot] または [Restart bot] でボットを起動します。
ここまでの通りの手順であれば以下のような応答をするはず。
回答が横スクロール(carousel)になっています。

設定ファイルで “qnaoptions” の “carousel” を False にすると以下のようになります。

他に、”qnaoptions” の “answercount” および “threshold” についても変更してみると、それぞれに応じた動きになるはずです。
QnA Maker を REST 呼び出しにすると、ユーザーへの応答をカスタマイズできることが分かったと思います。
シナリオによっては、ユーザーにより使いやすいボットになります。
今回は QnA Maker 連携だけではなく Composer の少しだけ高度な開発にも触れたので、ぜひ実際に同じように捜査して Composer 開発を楽しんでみてください。
「#BotFramework #Composer で “Send an HTTP request” で QnA Maker の応答をカスタマイズする手順」への1件のフィードバック