Watson Assistant の Digressions(脱線)機能の使い方

# Digressions(脱線)機能とは
チャットボットをデザインする際には、ユーザーとの会話のシナリオを設定し、そのシナリオにそうように会話フローを構築していきますが、ユーザーが必ずしも想定しているフローに合わせた発言をしてくれるとは限らず、本来の会話の流れとは無関係の発言をしてくることもあります。Digressions機能はトピックを別の会話に切り替える、あるいは元の会話に戻るといったことを実現するための機能になります。例えば以下のように、レンタカー予約を自動化する場合、本来の会話の流れは「貸出/返却日時」「オプション」等の情報を収集し、予約をするという流れになりますが、「キャンセル料金はいつから発生するの？」のように、ユーザーが本来の流れとは異なる発話をした場合に、これに回答した上で、本来の会話の流れに戻すという複雑な会話の流れを制御することができるようになります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/89193066-1049-5d39-c6aa-68da75196597.png)


同様の機能はスロット機能の使い方の[記事](https://qiita.com/schiyoda/items/a50ea70232382bdcf766)で、スロット・ハンドラーを紹介していますが、Digressionsはスロットが定義されたノードだけでなく、一般のノードでも適用可能なより汎用的な機能になります。ここではレンタカー予約を題材に、Waton Assistant（以下Assistant）のDigressions機能の設定の方法を紹介します。

# 事前準備
以下からダウンロードしたJSONファイルをAssistantにインポートしてワークスペースを作成します。
[https://raw.githubusercontent.com/schiyoda/wa_digression_test/master/wa_digression_test.json](https://raw.githubusercontent.com/schiyoda/wa_digression_test/master/wa_digression_test.json)

ワークスペースにはレンタカー予約の簡単なスロットが定義されており、下図のような会話が可能です。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/a86312e3-3410-59d7-96f9-1b95f1434ef3.png)

# スロットを含むノードからのDigressionsの設定
先の説明で出て来たように、予約の途中でキャンセルポリシーを確認し、その後また予約の会話に戻るという Digressions の設定をします。

まずDisgression元となる「予約」ノードの![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/64cc9272-7721-7853-5808-3757458f2d84.png)をクリックし、Digressions タブを開きます。「Digressions can **go away** from this node」で「Allow digressions away while slot filling」を「On」にします。これによりスロット内での会話中に、Digressions機能により他のノードに遷移することが可能になります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/a9f1e5f7-6555-cc2b-a061-4bb01cd2c98b.png)

Digressions先となるノードを「予約」ノードの下に作成します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/4ab514f7-9e2d-b030-1704-313b664d77ad.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/64cc9272-7721-7853-5808-3757458f2d84.png)をクリックし、Digressions タブを開きます。「Digressions can come **into** this node」を開くと「Allow digressions into this node」が「On」になっており、デフォルトでDigressions先として有効になっていることが分かります。「Return after digression」をチェックし、このノードを実行後に、Digressions元のノードに戻るように設定します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/40bef04b-23a8-853a-aef7-1f8fe5f09acf.png)

それではテストしてみます。Disgressions機能により「キャンセルポリシー確認」に会話フローが遷移し、再び元の会話に戻って来ていることが分かります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/50c3548a-691b-d3a6-86e4-2660903c09fc.png)

Digressionsでトピックを切り替えた後に、元の会話に戻さないことも可能です。先ほど作成した「キャンセルポリシー確認」ノードの下に新規ノードを作成します。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/77b7ff82-50ea-190c-15c1-101f6f31c20d.png)

今回はDigressions の「Digressions can come **into** this node」の「Return after digression」は、チェックしないでおきます。この設定では、以下のようにDigressions機能で「キャンセル」に会話フローが遷移した後、元の会話には戻って来ていないことが分かります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/b1553714-cb61-bd08-d7fa-fa3cecebf784.png)

# 一般ノードからのDigressionsの設定
スロットを含まない一般のノードからのDigressionsも可能です。ここでは「予約」ノードの子の「true」ノードを使って設定をしていきます。「true」ノードの「And respond with」（応答文）に以下のように入力します。

```
支払いは現金かクレジットカードになります。どちらがご希望ですか？
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/a61f730e-802d-51ee-7560-9286e8b1ec96.png)

子ノードを2つ作成し、各々以下のような設定をします。

|If bot recognizes|Then respond with|
|---|---|
|@支払い方法:現金|貸し出し時に店舗でお支払いください。|
|@支払い方法:クレジットカード|クレジットカード決済の画面に遷移します。|

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/6c00cee3-e5c7-bd68-2682-d06fa84a27e3.png)

「true」ノードの![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/64cc9272-7721-7853-5808-3757458f2d84.png)をクリックし、Digressions タブを開きます。「Digressions can **go away** from this node」で「Allow return from digressions triggered after this node's response」が「On」になっており、デフォルトでDigressions元として有効であることが分かります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/ea96dfe1-1159-8f55-99c2-4af3d04b5c31.png)

では、テストをしてみます。設定に応じてDigressionsの動作が変わっていることが分かります。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/cee28beb-78e1-e8f5-e20c-b754abf19a29.png)

![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/1a5c9ff9-d144-8a11-6001-e6b5f54123e6.png)

> ## 補足
先ほど追加した2つの子ノードに加えて、さらにtrueノードを追加した場合、親ノードで設定した Digressionsの設定は無効とになります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/0e5cd91e-1687-a133-d840-d57171dfb690.png)
>
![image.png](https://qiita-image-store.s3.amazonaws.com/0/235649/f8311d31-7121-35c0-ff19-5619c340f36c.png)

>このように、子ノードで「true」「anything_else」が定義されている場合は、無関係な発言はこのノードで処理されるため、Digressions機能が無効化されます。

> このように各ノードでの Digressions の使用可否やデフォルトの動作はその他のノードの設定に応じて変わってきます。