Azure QnA MakerとBot Serviceで歓迎メッセージ＆よくある質問対応のチャットボットを作成する

## やりたいこと
・簡単にヘルプデスクボットを作成したい。
・マニュアルのPDFファイルやFAQページのURLをもとに簡単にチャットボットを作成できるサービス (QnA Maker)を使ってみる。
・ボットにアクセスした際に自動的に歓迎メッセージとよくある質問を表示したい。そのまま複数ターン会話に繋げたい。

QnA Makerを使って簡単にチャットボットを作成するところまでのサンプルはあったので、そのサンプルを改変して自動的に歓迎メッセージとよくある質問 (FAQ)を表示するようにしてみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/5386758f-7a67-df45-ffcd-286715fe2e07.png)
※
・[QnA Makerとは (公式ドキュメント)](https://docs.microsoft.com/ja-jp/azure/cognitive-services/QnAMaker/overview/overview)
・[複数ターン会話とは](https://docs.microsoft.com/ja-jp/azure/cognitive-services/qnamaker/how-to/multiturn-conversation)

## 事前準備
・[Microsoftアカウントの作成](https://support.microsoft.com/ja-jp/help/4026324/microsoft-account-how-to-create)
・[Azureの利用登録](https://azure.microsoft.com/ja-jp/free/)
・[Visual Studioのインストール](https://docs.microsoft.com/ja-jp/visualstudio/install/install-visual-studio?view=vs-2019)

## 1. QnA Makerでのナレッジベース構築
### 1.1 Azure上でのQnAサービスの作成
[QnA Maker](https://www.qnamaker.ai/) にアクセスします。
![コメント 2019-08-13 112601.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/5fd6de89-dc84-c06e-c844-67066d8f186d.png)

上部メニューの Create a knowledge base を選択します。
※質問と回答の対応表をナレッジベースと呼んでいます。

STEP1のCreate a QnA serviceをクリックするとAzure上に画面が移ります。
![コメント 2019-08-13 141905.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/40a0aa1a-a75a-086c-765a-33ee0fab4e15.png)


必要項目を入力し「作成」を押します。
後にSurfaceマニュアルのPDFファイルを読み込ませるため、検索価格レベルは「B (15 indexes)」以上に設定します。

### 1.2 QnAサービスとの連携とナレッジベースの設定
QnA Makerの画面に戻り、STEP2内のRefreshを押してAzure QnA serviceの情報を更新します。Azure上でのデプロイが完了するまで数分かかります。
先程Azure上で作成したQnA serviceが含まれているサブスクリプション名、サービス名を選択します。
STEP3でナレッジベースの名前を入力します。

### 1.3 PDFマニュアルをベースにしたナレッジベースの自動生成
今回はSurface ProユーザーガイドのPDFファイルを読み込ませてナレッジベースを生成します。
STEP4 Populate your KB.内のURLのところに
PDFファイルのURL (https://download.microsoft.com/download/2/9/B/29B20383-302C-4517-A006-B0186F04BE28/surface-pro-4-user-guide_ja-jp.pdf) を入力し、Add URLをクリックします。
またこの際に、「Enable multi-turn extraction from URLs, .pdf or .docx files.」にチェックを入れ、複数のターンを含む会話を有効にします。

STEP5のCreate your KBをクリックしてナレッジベースを作成します。

作成が完了すると以下のように質問と回答の一覧が表示できるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/42964276-d59b-72bf-efb3-4e7c42fbe178.png)

画面右上の「PUBLISH」リンクへ行きます。

PublishボタンをクリックしてナレッジベースをPublishします。

Publish完了画面で、「Create Bot」を選択して、Azure側画面に移動します。

## 2. Azure Bot Serviceの作成
移動先の画面で必要項目を入力してWebアプリボットを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/1b8adc58-cb81-6ae2-26e4-334ef2f0d87f.png)

作成したApp Serviceの画面へ行き、左側パネルの設定→構成を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/601cccb8-8c5c-76be-2101-dc3935c269e6.png)
ここの`MicrosoftAppId`、`MicrosoftAppPassword`、`QnAEndpointHostName`、`QnAAuthKey`、`QnAKnowledgebaseId`の値は後に使用するので記録しておきます。


## 3. コードの編集
Botとのチャット画面に入ると自動的に歓迎メッセージと、よくある質問一覧が表示されるようにコードを編集します。
### 3.1 サンプルコードの取得
C#版とJavascript版があり、今回はC#版を使用します。
以下のサンプルコードをディレクトリごとダウンロードします。
https://github.com/microsoft/BotBuilder-Samples/tree/master/experimental/qnamaker-prompting/csharp_dotnetcore

### 3.2 アプリケーションキーの設定
Visual Studioで`BotBuilder-Samples/experimental/qnamaker-prompting/csharp_dotnetcore/QnAPrompting.sln`を開きます。

appsetings.jsonファイルを開き、先程記録したキーを設定します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/8b64b5e6-cc96-9dd4-b5f1-153b8009471f.png)
(先程記録したQnAAuthKeyの値はQnAEndpointKeyの箇所に入力してください)

### 3.3 歓迎メッセージとよくある質問項目一覧の表示
Botsディレクトリ内のQnABot.csを開きます。

`protected override async Task OnMembersAddedAsync(略)`内に下記コードを追加します。

```c#

// Create a HeroCard with options for the user to interact with the bot.
var card = new HeroCard
{
    Text = "よくある質問を以下に表示します。",
    Buttons = new List<CardAction>
{
// Note that some channels require different values to be used in order to get buttons to display text.
// In this code the emulator is accounted for with the 'title' parameter, but in other channels you may
// need to provide a value for other parameters like 'text' or 'displayText'.
new CardAction(ActionTypes.ImBack, title: "1. Windows 10とは何ですか？", value: "Windows 10"),
new CardAction(ActionTypes.ImBack, title: "2. Surface Proとは何ですか？", value: "Surface Pro"),
new CardAction(ActionTypes.ImBack, title: "3. Cortanaとは何ですか？", value: "Cortana"),
},
};
var reply = MessageFactory.Attachment(card.ToAttachment());
await turnContext.SendActivityAsync(reply, cancellationToken);
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/0f17ca29-9ae7-8cac-f22c-561a1d57b99b.png)

`new CardAction(ActionTypes.ImBack, title: "1. Windows 10とは何ですか？", value: "Windows 10"),`等の行がBotで表示される質問カードを表しており、この行の追加/削除によってカード数を増減させることが可能です。
`title：`内がカードに表示される文章で、`value: `内が、そのカードがクリックした際にBot側へ送信される文字列です。このvalueの値を複数ターンのトリガーとなるような文字列にすることで、歓迎メッセージから複数ターンの会話までスムーズに接続されます。

※挿入したコードは[サンプルコード (ヒーローカードを送信する)](https://docs.microsoft.com/ja-jp/azure/bot-service/bot-builder-howto-add-media-attachments?view=azure-bot-service-4.0&tabs=csharp#send-a-hero-card)をもとに改変しました。

## 4. Azure Bot Serviceへのデプロイ動作確認
### 4.1 デプロイ
Visual Studio画面右側のソリューションエクスプローラー上でプロジェクト名 (QnAPrompting)を右クリックして「発行」を選択します。

「発行」欄内の新規→既存のものを選択→発行
さきほどAzure上で作成したAzure Bot Serviceを選択し、OKをクリックします。

### 4.2 動作確認

Azureポータル上でデプロイしたWebアプリボットの画面へ行き、「Webチャットでテスト」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/8c68d85a-262c-67ed-8e1a-e36860651a01.png)
自動的に「ヘルプデスクへようこそ！」という歓迎メッセージと、それに続いてよくある質問のカードがいくつか表示されました。

質問カードをクリックするとそのまま複数ターン会話へと続いていきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/57724/f5f77804-ae32-e66e-c8ad-9d7018933f8f.png)
完成しました！

何かご不明な点，誤り等ございましたらコメントお願いします。

## 参考リンク
・https://github.com/microsoft/BotBuilder-Samples
・[メッセージにメディアを追加する](https://docs.microsoft.com/ja-jp/azure/bot-service/bot-builder-howto-add-media-attachments?view=azure-bot-service-4.0&tabs=csharp)
・[ユーザーへのウェルカム メッセージの送信](https://docs.microsoft.com/ja-jp/azure/bot-service/bot-builder-send-welcome-message?view=azure-bot-service-4.0&tabs=csharp)