Bot Framework Composer でボット開発 : その 7 エンティティの取得

[前回](https://qiita.com/kenakamu/items/87cf57267be213653129) の記事ではボットの記憶であるメモリオブジェクトを見ていきました。今回は LUIS のより高度な使い方について見ていきます。

# インテントとエンティティ

[ユーザー入力の理解:LUIS](https://qiita.com/kenakamu/items/11bae087ca93f5a6d997#luis) で試したように、LUIS を使うとユーザーのインテント (意図) を取得することができました。LUIS ではインテントに加え、エンティティ (キーワード) を取得することもできます。

エンティティには以下のタイプがあります。

- シンプル: 種類は同じだが、リストにはできないもの。料理名や世界中の都市名など
- リスト: 事前に定義したリストのみ利用。都道府県など
- 正規表現: 正規表現にマッチするものを対象とする
- コンポジット: 複数のプロパティをもつオブジェクト

## lu 形式

LUIS のインテントやエンティティ登録は LUIS ポータルからも行えますが、Bot Framework Composer は [lu 形式](https://github.com/microsoft/botframework-cli/blob/master/packages/luis/docs/lu-file-format.md)のフォーマットを使って、より簡単に作成できるようにしています。

**インテント**
インテントの指定には **#** を使います。既に追加している Profile インテントを例にすると、以下のようになります。

```text
# Profile
- 登録
- プロファイル登録
- プロファイル作成
- ユーザー登録
```

**エンティティ**
タイプによって定義の仕方が異なりますが、よく使うものとしてシンプルとリストを紹介します。

シンプルの場合: 以下の例では country エンティティが作成されます。

```text
- 私の出身は{country=日本}です。
```
リストの場合: 以下の例では platform エンティティが作成され、リストとして 4 つの項目が含まれます。

```text
# CloudPreference
- 私は Azure を使います。

$CloudPreference:platform=
    - Azure
    - GCP
    - AWS
    - その他
```

# ToDo リスト

よくある例として To Do リストを追加してみます。またユーザー入力の編集は、「User Input」メニューを中心に使っていきます。

## リストの追加

1\. AddToDo ダイアログを追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/fdd175e8-a514-f027-c1d7-4ab5732b6ca0.png)

2\. BeginDialog トリガーに「Text Input」アクションを追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/afe20f9f-0b5f-af38-bddb-aab8ea0f127d.png)

3\. メッセージを入力。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/04bc66b7-78cb-01cf-23fb-5caf57f7c1ed.png)

4\.「User Input」で ```dialog.item``` に結果を保存するように設定。また「Value」に ```=@item``` を指定。@item は LUIS で取得されたエンティティが保存される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/26b5462a-2662-05b0-d7b9-9cc6d9624fa8.png)

5\. プロパティ管理より配列の編集追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/e37ad7a4-c869-5117-5219-4ca8ffcf97c6.png)

6\. Push を選択し、配列用のプロパティと値を設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/5ec0faa9-8a36-ca6a-b1a1-20e97c0f760c.png)

7\. メインダイアログで AddToDo トリガーを追加。フレーズは後から補充。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/bd043d05-6ed8-02ba-4d42-7867e2dfcac2.png)

8\. ダイアログ開始アクションを追加して、AddToDo ダイアログを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/faad5607-4d5a-39be-1e48-23cd63c89532.png)

9\. メニューの「User Input」よりメインダイアログを選択し、「Edit Mode」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/192e9163-f20c-a174-a136-17c76b09c573.png)

10\. 一番下にスクロールし、# AddToDo を以下のように変更。

```text
# AddToDo
- やることリストに追加して
- リストに追加して
- やることに追加して
- リストに {item=ブログを書く}と追加して 
- {item=ブログを書く}をリストに追加して 
- やることに {item=ウナギ買う}と追加して 
- {item=ウナギ買う}をやること追加して 
- リストに {item=朝9時に起きる}と追加して 
- リストに {item=午後2時から会議}と追加して 
```
11\. ボットを再起動してエミュレーターから検証。LUIS で意図したとおりに取れているか確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/1e1905b5-8313-4a00-1596-6de57baaa66a.png)

12\. user スコープにデータが追加されたか確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/c6a6af07-0ccc-1a2f-347c-e11e3e069186.png)

### LUIS を確認

現時点での LUIS を確認してみます。

1\. [LUIS ポータル](https://www.luis.ai) に接続してアプリを選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/5d95fd48-2efb-586b-fee4-822f1fb8621b.png)

2\. AddToDo インテントをクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/c25018a7-9ea5-daff-275f-25b2b1c1c9c2.png)

3\. エンティティとして指定した箇所が「item」をなっている事を確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/c1872777-0d22-d9db-886b-23b8fcadce80.png)

4\. エンティティより item があることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/de3b4c89-820d-0d62-7d35-616cf836bfd8.png)

## リストの削除

同じ要領でリストの削除を行います。LUIS でエンティティを取得することもできますが、ここでは複数選択を使ってみます。

1\. RemoveToDo ダイアログを追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/5d1698f6-4480-2cd8-bc8a-bcdff9d48b6b.png)

2\.「Multiple choice」アクションを追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/fa6fe90b-a212-e4dd-2296-a742a8c9cb0e.png)

3\. ボットからの文言を追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/4c670a64-3b3e-b39c-30b8-7ae7627d5fc8.png)

4\.「User Input」で結果を ```dialog.removeitem``` に保存するように設定。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/38f2fee6-8831-1cd2-fc74-76b3a6fa4684.png)

5\.「Choice Options」で **dynamic** を選択し ```user.todos``` を設定。これによりリストのアイテムが候補として表示される。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/a3825ebc-4822-918f-1a3e-27b561ba37b3.png)

6\. 配列の編集アクションを追加。Remove 操作でアイテムを削除する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/5268233f-0db4-4bdf-781a-17a96456bb25.png)

7\. 前回同様 RemoveToDo トリガーを追加し、RemoveToDo ダイアログの開始アクションを追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/355ce334-ed21-4669-0767-c6f7d35ca9cc.png)

8\. ボットを再起動して、エミュレーターで検証。選択肢が正しく出ることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/5d6b587f-8893-328f-7b2e-5a9a601373a6.png)

9\. 選択したアイテムが削除されることを確認。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/47b7dcf4-9a95-6725-76f7-0561a83be6df.png)

## リストの表示

最後にリストの表示を実装します。

1\. ListToDo　ダイアログを追加。

2\.「Send a response」アクションを追加。回答でカードを設定。todo-line 関数が無いためエラーとなるが無視。

```shell
- ${join(foreach(user.todos, item, todo-line(item)),"")}
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/2fd1bf24-3ce3-4b48-277d-e207e7c1a2d6.png)

3\.「Bot Response」メニューより ListToDo を選択し、「Edit mode」をクリック。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/7809469c-d5b0-5169-f8fa-95b14b4c449b.png)

4\. todo-line 関数を追加。複数行の機能を使って改行を追加。

```shell
# todo-line(item)
-```
${item}```
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/09b0b6bc-f4f4-439e-3ecb-bf2ae07a3929.png)

5\. AddToDo ダイアログの BeginDialog トリガー最後に ListToDo ダイアログを開始アクションを追加。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/478e729e-b0ad-e5dd-cddd-5d25289de520.png)

6\. ボットを再起動してエミュレーターで検証。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/214116/93a24f0b-616b-dc35-db40-e1e398a1f31e.png)

7\. RemoveToDo の最後にも同じ作業を繰り返す。

# まとめ

今回は LUIS を利用してエンティティを取得してみました。LUIS は機能が豊富でさらに高度な使い方もできるため、是非色々試してください。

[次の記事へ](https://qiita.com/kenakamu/items/750d6a0de2da05e8851d)
[目次へ戻る](https://qiita.com/kenakamu/items/6dc043cfc1f199032883#bot-framework-composer)