Azure QnA Makerを使ってローカルで動くQ&A ChatBotを作ってみた

# 前提
- ローカルにNode.js環境があること（ない人はNode.jsをインストールしておいてください）

# 概要
QnA Makerとは、[公式](https://docs.microsoft.com/ja-jp/azure/cognitive-services/qnamaker/overview/overview)に下記のように定義されています。
> データに自然な会話レイヤーを簡単に作成するクラウドベースの自然言語処理 (NLP) サービスです。 これは、特定の自然言語入力に対して、カスタム ナレッジ ベース (KB) の情報から最も適切な回答を見つけるのに使用できます。

要は、Q&Aを事前に登録しておくと、ユーザーの質問に対してAPIコールによりベストな回答を選んで返してくれるというものです。日本語に対応しているのでQ&A Chatbotを作成することに適しています。

この記事では、Azure QnA Makerを使ってローカルで動くChatBotを作成し、Emulatorを使って実際にBotと会話することをゴールとしています。
![chatbot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/f089cd09-65ff-c3f1-9758-6f3453bb6efc.png)

以下の手順でローカルにBotを構築していきます。この回でコーディングは特にしませんが、Botアプリで利用する言語はNode.jsです。

- 1. QnA Maker ServiceとKnowledge baseの構築
- 2. ローカルでBotアプリを構築
- 3. Bot Framework EmulatorをインストールしてBotに接続
- 4. リソースの後片付け（お金がかからないように）

下記についてはこの記事で説明しないのでご注意ください。

- Botアプリのロジックについて
- 生成されるAzureリソースの役割について

# 1. QnA Maker ServiceとKnowledge base（KB）の構築
QnA Portalにログインして、「Create a Knowledge base」を押下。
基本は、遷移先のページに書いてあるSTEP通りに進めていきます。
![create-kb-overview.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/0b4e8f39-aa9b-3952-f99d-699de70488f2.png)
※画面は見切れてるけどSTEP4まであるよ。

### STEP1 Create a QnA service in Microsoft Azure.
「Create a QnA service」を押下すると、AzureのQnA Maker作成画面に遷移します。そこで下記のように入力し、作成をクリック。
価格レベルはF0とFを選択すれば無料になります。僕の場合は無料枠を既に使ってしまったので、S0とBを選択しました。
とはいえお金がかかるのは嫌なので、このチュートリアル後にすぐに消そうと思います。記事の後半でそのことに触れているのでお金かかる怖いやりたくないって思う人も不安がらなくて大丈夫です。

**無料の場合↓**
![create-qna-service-for-free.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/0bd0252b-a03e-2133-26ac-5d97618ba104.png)

**ちょっとお金かかるよって場合↓**
![create-qna-service-for-fee.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/2d1d4cf3-7dc1-fbc2-af05-85e906f3efa6.png)

しばらくすると、「デプロイが完了しました」と画面に表示されます。先ほど指定したリソースグループをみると下記のようにいくつかのリソースが作られていることが分かります。成功です。
![azure-resources.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/55dea8fa-7a18-8861-d2ff-5bae84a72a5b.png)

### STEP2 Connect your QnA service to your KB.
QnA Portalに戻って「Refresh」すると、Azure QnA Service欄で先ほど作ったリソースが選べるようになります。
日本語のQnAを作りたいのでLanguageはJapaneseにします。
![connect-to-kb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/05acf910-99dc-78f9-0b1f-4bf62e5fb39c.png)

### STEP3 Name your KB.
ここはなんでもいいです。好きな名前をつけてください。
![name-kb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/b5b397ef-f22f-8c01-4260-d8032412111e.png)

### STEP4 Populate your KB.
KBにQnAを登録します。QnAが記載されたページのURLを指定してもいいんですが、実用的な側面を考えて今回はTSVファイルを指定することにします。使うTSVファイルは手抜きですがこんな感じでいきます。
![kb-data-tsv.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/64fe0d0b-cc50-8330-3be3-e4b35536c044.png)
「＋ Add file」を押下し、作成したTSVファイルを指定しましょう。
Chit-chatはなくてもいいですが、愛着のあるBotを作成したいのでひとまずFriendlyを選択します。
![populate-kb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/1280d414-f169-1001-088b-3d1452cf5654.png)

### STEP5 Create your KB
「Create your KB」を押下してKBを作成しましょう。完了すると、今回作成されたKnowledge baseのEDIT画面に遷移します。
先ほど作成したTSVファイルの内容と、Chit-chatで指定したFriendlyなQnAが登録されているのが分かります。
![kb.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/f2a69a4f-e9dc-d775-74b9-5e2d0b934139.png)

右上の「Save and train」を押下して学習を行い、「Publish」タブの「Publish」を押下してエンドポイントを発行します。エンドポイントは後程使います（SETTINGタブからいつでも見れるので、画面をそのままにしておく必要はありません）。
KBの構築は以上になります。


# 2. ローカルでBotアプリを構築
ソースコードはSampleとして提供されているものを使用します（1から書くとめちゃくちゃ大変）。

### 1. [BotBuilder-Samplesリポジトリ](https://github.com/microsoft/BotBuilder-Samples)をクローン
実際に利用するソースはQnAの呼び出しまで提供してくれている下記のSampleになります。
https://github.com/microsoft/BotBuilder-Samples/tree/master/samples/javascript_nodejs/11.qnamaker

### 2. KBへの接続情報を記述
QnA Maker Portal画面を開き、作ったKBのSETTINGタブの「Deployment details」を参照しながら、`.env`ファイルに下記のように記述します。

```properties
MicrosoftAppId=
MicrosoftAppPassword=
QnAKnowledgebaseId=[POST /knowledgebases/{この部分}/generateAnswer]
QnAEndpointKey=[Authorization: EndpointKey {この部分}]
QnAEndpointHostName=[Host: {この部分}]
```

### 3. パッケージのインストール
TerminalやCMDなどで`11.qnamaker`ディレクリに移動し、`npm install`コマンドを実行します。

### 4. Botの起動
続いて`npm start`でBotを起動します。


# 3. Bot Framework EmulatorをインストールしてBotに接続
[このページ](https://github.com/Microsoft/BotFramework-Emulator/releases/tag/v4.8.1)からご自身の環境に合わせたAssetsをダウンロードし、インストールします。
Bot Framework Emulatorとは、主にローカルでチャットクライアントとして動作するテスト用のデスクトップアプリ（ツール）です。
Emulatorを立ち上げると、Visual Studio Codeを触っている人には見慣れた画面が現れます。Microsoft製品なので当然ですが。
![bot-framework-emulator.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/2aa14959-c8d3-4f3b-ef39-d72aa1a7f3a7.png)

「Open Bot」を押下し、Bot URLに`http://localhost:3978/api/messages`と入力して「Connect」をクリックすると、EmulatorからローカルのBotにアクセスできるようになります。
![connect-to-bot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/db215a46-95f9-ff1d-af85-34939ad2bd70.png)

試しに「Qiitaとは」などとBotに話しかけてみましょう。期待通りに返してくれるはずです。
また、「こんにちは」などと話しかけると、Friendlyに応答してくれます。
![chatbot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/f089cd09-65ff-c3f1-9758-6f3453bb6efc.png)


# 4. リソースの後片付け（お金がかからないように）
無料枠で構築した人は特にお金はかからないのでそのまま放置しても大丈夫です。

Azureのリソースグループ画面へ移動し、今回構築したすべてのリソースにチェックをつけ、削除ボタンを押します。
確認のための質問がありますが「はい」を入力して削除してしまいましょう。
![resource-group.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310081/fb40efd6-2809-98c0-3b29-60b38860693c.png)

# おわりに
AzureのQnA Makerを使ってかなり簡単に機械学習を用いたQ&A Chatbotを作ることができました。
KBにいろいろなQnAを登録することで、いい感じに表記ゆれを吸収し、目的の回答を得ることができるので是非試してみてください。

ただ正直Microsoftのドキュメントが分かりにくい…
なのでこのような記事を書きましたが、もっとQiitaにChatbot系の記事が増えると嬉しい限りです。