【2019/2月更新】チャットボットを簡単に作れる！Watson Assistant(旧名: Conversation)の色々なTips（メモ）

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/abe65ee7-9d31-d24c-0d8b-fd7afe52865a.png)

# 記事更新のお知らせ
- :triangular_flag_on_post: 2018/07/12付の [Release Note](https://console.bluemix.net/docs/services/conversation/release-notes.html#release-notes)で**[① Rich response types](#new-リッチレスポンス) ② [Contextual entities (Beta)](#newus-beta-contexual-entity) ③ [Entity recommendations](#newus-entity-recommendations)** が使えるようになったそうなので、機能の紹介を追記しました。ただし日本語環境:jp:で使えるのは①のみです。
- :triangular_flag_on_post: 2018/08/06付の [Release Note](https://console.bluemix.net/docs/services/conversation/release-notes.html#release-notes)によると [Intent Conflict Resolution](#crown-pluspremium限定-intent-conflict-resolution)と[Disambiguation](#crown-pluspremium限定--disambiguation)が使えるようになったそうなので「何それ」程度を書いておきました。
- :triangular_flag_on_post: 2018/11/28付で今までPremium限定だった機能をお得に使える[Plusプランが追加された](https://qiita.com/ishida330/items/86520ffd7b7216d1d471)ので、記述を修正しました。
- :triangular_flag_on_post: 2019/2月時点で内容を見直し、以下を追加・更新しました

    - [バージョニング](#loudspeaker-20192-スキルのバージョン機能が正式公開に)
    - [サービスデスク統合](#loudspeaker-20192-サービスデスク統合)
    - (beta) [サーチ･スキル(Discovery統合)](#loudspeaker-20193-サーチスキルdiscivery統合) 
    - [Watson Assistantの会話の品質を上げるベストプラクティス公開](#loudspeaker-20192-watson-assistantの会話品質改善のベストプラクティス資料)
    - [新機能を試せるベータに参加する方法](#loudspeaker-20192-新機能を早く試せるベータプログラムへの申し込み)

# はじめに
石田です！お蔭様で当記事は長期間にわたり多くの皆様にアクセス頂いているようです。ありがとうございます！:blush: 当記事は前回は2018/8月に更新しましたが、早いものでもう半年が経過して、一部の記述が古くなったので、久々に記事をアップデートしました。

- 当記事は[Assistantのドキュメント](https://console.bluemix.net/docs/services/conversation/index.html)から読み取った「使う上で知っておいた方が良い点、気が付いた点」などをトピック別/ランダムにご紹介したものです。**全機能を網羅的にご紹介するものではありません**。英語のDocumentを全部じっくり読むと、それなりに時間もかかりますので、その入口くらいの感じを目指しています。
- レベル的には「応用編/Tips」的なものにしました。入門編の知識は「[いまさら聞けない!? 簡単にチャットボットをつくれる「Watson Assistant」の基礎知識](https://qiita.com/ishida330/items/666ced65a04243ce286c)」として別記事に分離しました。はじめての方はまずは[基礎知識のほうの記事](https://qiita.com/ishida330/items/666ced65a04243ce286c)をご参照ください
- 今後も機能強化や変更があると思うので、末尾に改定履歴を付けました
- 【凡例】:blue_book: ドキュメントへのリンク　:newspaper:各種記事へのリンク
- Watson Assistantは2018/11月現在もサーチ・スキルなど新機能のベータ中ですが、それらの内容はきちんと公開されたら別途記事に追記しますね！

# まずはConversation -> Assistantで変わったこと

下記が新しいアイコンです。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/a565331a-5b64-64bc-f6d0-6e0681ace37b.png)

- **「名前が変わった＋少し機能強化された」程度**であり、上位互換性は保たれています.　移行などは不要ですので、ご安心ください。
- 機能強化の詳細は[Release Note](https://console.bluemix.net/docs/services/conversation/release-notes.html#release-notes)にありますが、日本語だとIBM ソリューション・ブログ「 [Watson Assistantのご紹介](https://www.ibm.com/blogs/solutions/jp-ja/the-future-of-watson-conversation-watson-assistant/)」の記事がまとまっています。
- １分でご説明するなら、目ぼしい変更/強化点は下記です
 1. :us: 自動車とホテル向けのAssistantの提供 ( 日本語未対応なので関係なし )
 2. コンテンツ・カタログ(:jp: 日本語もありますが、「ないよりまし」って感じ? )
 3. 脱線( Degression ) ～会話の話題が急にそれた時に、元に戻ったりする
 4. ダイアログ・フォルダー　～　フローをもっと綺麗に
 5. コンテキスト変数をUIパネルで設定可能に(JSONを直接編集しなくてもよくなった)
 6. 新しいAPIとSDKも公開（以前のものも使えますが）

# さらに Watson@TokyoとAssistant on ICPも利用可能に!
もう有名ですが、2018/8月=前回の更新以降の大きい話題をいくつか。

### Watson@Tokyo
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/1e313d94-26a2-4394-e6f2-a8fc3d78aff0.png)
Watson Assistantはじめ、主要なWatsonサービスが東京リージョンで利用できるようになってます。「クラウドはいいとしてもデータが国外に出るのは、、」というお客様にも敷居が低くなりました。

### Watson Assistantがオンプレでも動く！（ Watson on ICP )
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/8430a948-c308-0985-f427-c66c782a4061.png)

従来、Watsonはクラウド上のサービスとして提供されてきましたが、Assistantを皮切りに[様々なWatsonサービスがICP上で動くように提供され始めています。](https://www.ibm.com/blogs/watson/2018/10/watson-services-now-available-on-premises/)つまり、ファイアーウオールの内側＝お客様のデータセンターでプライベートにWatsonが使えるようになりつつあります。金融や政府系のお客様など、国外やクラウドの利用が制限されている業種・業務でもWatsonをお使いただけます。(以下は私見です。残念ながら現時点ではかなり大きいICP基盤構成が必要ですので「自社内でWatsonを簡単/手軽に活用！」とはいかなそうですが、それでも大きいお客様向けには朗報かと思います。)

### :loudspeaker: (2019/2) Watson Anywhere
publickey記事: :newspaper: [IBM、WatsonをKubernetes対応にした「Watson Anywhere」発表。オンプレミスでもクラウドでもWatsonを実行可能に。IBM Think 2019](https://www.publickey1.jp/blog/19/ibmwatsonkuberneteswatson_anywherewatsonibm_think_2019.html)
IBM Cloud Blog記事: :newspaper: [Watson Anywhere](https://www.ibm.com/blogs/think/2019/02/enabling-watson-anywhere/)

ちょうど今日(2019/2/13)がThink2019の初日で、上記の発表がありました。まあ、前記のWatson on ICPを新しい名前で宣伝したもの、ですね。

### :loudspeaker: (2019/2) スキルのバージョン機能が正式公開に
標準でスキルのバージョニングおよび保存/復元ができるようになり、本番への反映作業が安心になります。(StandardでもPlusでもご利用いただけます）要は作業中のスキル一式のスナップショットが取れ、簡単に復元できると思ってください。本番でスキルを入れ替え・更新したい場合、従来は①エイヤで本番に対して作業　または　②独立したテスト環境を作り、そちらで更新＆テスト。OKなら定義をインポート　などの面倒な作業が必要でした。今回、スキルのバージョン保存ができるようになったので、本番に影響しない形でのテストや万が一の「本番戻し」がとても楽になりました。

- 昨年、アーキテクチャー面でアシスタントとスキルが分離したので、この辺がすごく簡単になりました。スキルとアシスタントを各々複数バージョン（例えば開発・テスト・本番）持ち、それらの紐つけをUIで変えればいいいいだけ、です
- 先日追加されたPlusプランでは標準で開発・テスト・本番の３つの環境が使えますので、当機能と非常に親和性があります

下記Mediumの記事にバージョン機能の紹介や本番反映のベスト・プラクティスが紹介されていますので、ご一読をおススメします。

Medium記事: :newspaper:[Make Changes With Confidence](https://medium.com/ibm-watson/watson-assistant-versions-announcement-d60869b1f5f)

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/e9648221-8d75-9312-a132-c5e73d52e6d5.png)

ドキュメント: :blue_book: [Creating skill versions](https://console.bluemix.net/docs/services/assistant/versions.html#versions)

### :loudspeaker: (2019/2) サービスデスク統合
Plus&Premium限定ですが、サービスデスク用SaaSを提供されている[Intercom](https://www.intercom.com/)社のサービスとの統合機能が利用可能になりました。近々[ZenDesk](https://www.zendesk.co.jp)社のサービスとの統合も予定されています。例えば以下のようなことが簡単にできるようになります。

- フロントのWatsonから人間のエージェントへのスムースなピッチ
- ピッチ時に顧客との対話内容の伝達(顧客に同じことを何度も言わせない）
- 人間のエージェントが、ある程度まで進んだ対話をWatsonにピッチ
- （キーワードではなく、顧客の意図である）トピック・ベースのエスカレーション
 

他にもいろいろな機能がありますが、下記Mediumの記事が詳しいです。
Medium記事: :newspaper:[Customer Service Just Got Smarter](https://medium.com/ibm-watson/contact-center-post-394dff427c8)
ドキュメント: :blue_book: [Integrating with Intercom](https://console.bluemix.net/docs/services/assistant/deploy-intercom.html#deploy-intercom)


### :loudspeaker: (2019/2) Watson Assistantの会話品質改善のベスト･プラクティス資料

英語で恐縮ですが、2019になってAssistantの会話品質を改善するためのベスト･プラクティスのホワイトペーパーとツール(Jupyter)が公開されましたのでご紹介します。支援ツールもありますが、むしろEffectivenessとCoverageを分けて考える、PrecisonとRecallも分けて考える、段階別にアプローチする、など「ノウハウ」面で得るところが多いかと思います。英語ですがホワイトペーパーは短いものですので、ぜひお目をお通しください。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/8bd782eb-da0d-2b17-fd9b-f026d6aa74b5.png)

- ブログ記事:newspaper: [Continuously Improve Your Watson Assistant with Jupyter Notebooks](https://medium.com/ibm-watson/continuously-improve-your-watson-assistant-with-jupiter-notebooks-60231df4f01f)
- 本丸のホワイトペーパー :blue_book: [Watson Assistant Continuous Improvement Best Practices - IBM](https://www-01.ibm.com/common/ssi/cgi-bin/ssialias?htmlfid=54022554USEN&)
- ブログ記事:newspaper: [A Guide to Always Improve Your Watson Assistant](https://medium.com/ibm-watson/a-guide-to-always-improve-your-watson-assistant-4afd62eeb573)
- Think2019でのセッション資料 ::orange_book: [Best Practices for Continuous Improvement with IBM Watson Assistant](https://1.dam.s81c.com/m/26eee8b01f0dcd09/original/4543-pdf.pdf)

### :loudspeaker: (2019/2) 新機能を早く試せるベータ・プログラムへの申し込み

Watson Assistantは以前から正式公開(GA)前に新機能を試せるベータ・プログラムを一般向けにも実施しています。この申し込みリンクが変わっていたので2019/2月時点での最新申し込み方法をお知らせします。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/2552b21b-0c14-8586-1b8e-b4fb290e17d3.png)

Skillsのパネルの一番下にベータ申し込みのリンクがあります。画面サイズによっては隠れているので気がつかないかもしれません。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/7cd3c3e0-073b-e5e0-ce6c-913211fb9632.png)
T's and C'sに合意(チェック）して「ConfirmRequest」ボタン

- Enrollment not guaranteedとなるように申し込みが受け入れられない場合もあるようです
- OKの場合でも、メールでの連絡は即時ではなく数日かかります
- 当然ですがベータ環境は機能が強化され、振る舞いが変わりますので、**本番には適用しないようにお願いします**。







---
ではここから記事本編です。↓↓↓↓

# ドキュメントに関するTips
### 機能強化・変更の詳細はRelease Noteにまとまっています
IBM Cloud全般にいえることですが、Watsonサービスは継続的な機能強化・変更がなされています。それらの変更はドキュメントの「[Release Note](https://console.bluemix.net/docs/services/conversation/release-notes.html#release-notes)」にまとまっています。

- 新機能の追加の場合はドキュメントにAPIのバージョン（日付）が指定されており、APIで「その日付をセットしたら新機能が使える」形になっていることが多いです。（＝古いAPIバージョン(日付)なら既存の振る舞いのままでアプリに影響を与えない）

### できれば英語で読みましょう
ドキュメントは翻訳されており言語を選べます(デフォルトはブラウザーの言語）が、翻訳が遅れている場合も多いです。ざっくり大筋を理解する目的なら日本語で読んだほうが効率がよいでしょうが、情報は新しいほうが良いですから、ドキュメントはなるべく英語で読むことをお勧めします。特に上記の機能強化の**Release Noteは英語で**読むことを強く(×10)お勧めします。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/72824bf5-fb4a-7a0d-ae66-47cb51701aec.png)

### 機能の日本語サポート状況を調べる
ドキュメント上に新機能の記述があっても（制限があれば書いてあることが多いですが）「英語のみサポートで、日本語では使えない」場合もありえます。 様々な新機能の日本語サポート状況はドキュメント「[Supported languages](https://console.bluemix.net/docs/services/conversation/lang-support.html)」でご確認いただけます。


# ワークスペースのTips
### ワークスペースはインポート/エクスポートできます
AssistantではワークスペースのIntent/Entity/Dialogの一式がJSON形式でエクスポート/インポートできます。
- 作成したワークスペースはJSON形式でダウンロードできます
- JSON形式のファイルをアップロードして「**新規**にワークスペースを作る」こともできます
- 「既存のワークスペースをJSONファイルで置換する」メニューはありません。置換したい場合はワークスペースを一旦消してから上記のアップロード操作を行ってください ( 無理やりインポートした場合は同名のワークスペースが新たに作成されます)

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/2ba688b5-71bb-7f03-c772-362eb9e11234.png)

### デモの中身を見てみるのをお勧めします
ワークスペースにはデフォルトでCustomer Service - Sampleが作られています。営業時間や近くの店舗の問い合わせ、来店予約などのユースケースを扱う際にコンテキストの設定/複数レスポンス/システムエンティティ/フォルダーなど、様々なAssistantの機能を意識的に使っており、一通り読み解くと「ああ、こういう場合は、こうすればいいのか～」などの学びが多いかと思います。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/779ba19b-c5a2-d9d2-aec9-53627c67e83a.png)

- Conversationの時代は車の運転中に口頭で様々な指示を出す「Car Dashboard」のデモだったのですが、AssistantになってCustomer Serviceのデモに変わりました。以前のCarDemoも[Watson conversationのデモ・ページ](https://conversation-demo.mybluemix.net/)に残っていますしGithubでcloneできます。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/7c8afa2c-b73f-7a40-815a-ee7f0f8407e9.png)

### Try it out パネル
 画面の右上にあるTry it Outで、様々な対話を（クライアント・アプリケーションなしで）すぐに実行（テスト）できます。
 ![try-it-out-400.gif](https://qiita-image-store.s3.amazonaws.com/0/108535/b1befe51-09cf-6ecb-d619-e80602621fe3.gif)

- 応答の右側の**ピンのマークをクリック**すると[^4]、左側のダイアログの該当ノードが青くなり「今ここやってるよ！」と教えてくれます(=Dialog node tracing)。

![try-it-out-position-400.gif](https://qiita-image-store.s3.amazonaws.com/0/108535/72a37cb4-d629-2395-ebf1-4d40a98d1581.gif)

[^4]: 以前は対応するノードが自動的に青く表示されていましたが、クリックしたら表示するように変わったようです

- テストのために後述するコンテキスト変数をセットすることもできます。下記の例では応答を「いらっしゃいませ。$(customer-name) さん」としており、実際にはクライアントのアプリからコンテキスト変数にセットされた顧客名を受け取ることを想定していますが、今はアプリが無いのでパネルから一時的にセットしています。結果、きちんとそれらしい応答になっています。（未セットの場合はNULLになります）[^2]
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/e4e1a9fe-46f5-2b6b-789a-f34bf4037b24.png)

[^2]: なお日本語環境で$timezoneが"Asia/Seoul"になっていますが、東京とソウルは時差がありませんので問題ありません。ここを別の都市に変えると「現在時刻」が変わります。

### トレーニングは自動的に起動されます

Assistantではインテントやエンティティの定義を追加変更した場合には、再トレーニングが必要です。(Dialogは変更したら即反映します/トレーニング不要です）

- トレーニングは対話式にも実行できます。たとえば、Try it Out!でのテスト実行の結果、分類されるべきインテントが意図したものと違っていた場合には、その場で正しい意図に変更できます。
- この変更の反映タイミングですが、Assistantとは別のスタンドアロンのWatsonサービスであるNLC(Natural Language Classifier)では自分で「再度トレーニング」する操作を行っていましたが、Assistantに搭載されているNLCでは割り当てるべきインテントを変更したらバックグラウンドで自動的にトレーニングが開始されます。(トレーニング中はその旨がパネルに表示されます）
- 以下の例では、「パソコンが起動しません」との入力に対するインテントが意図せず「修理(#REPAIR)」に分類されてしまったので、「相談(#QUESTION)」に訂正しています。すると自動的にトレーニングが始まり、次回は期待したとおり「相談(#QUESTION)」インテントに分類されます。

![change_intent_min.gif](https://qiita-image-store.s3.amazonaws.com/0/108535/8b625331-b04a-73c0-bd5e-fc0e58126093.gif)

### APIでログを記録しない(オプトアウト)設定が可能

パブリック環境のデフォルトでは会話の内容はログされます[^9]。IBMはログをサービス改善のためにのみ使いますが、ご心配があったり機密保持などの観点で問題になる場合はオプトアウトを設定できます。（これ、他社様ではできなかったりします。) 具体的にはAPIコール時にでヘダーやフラグを設定すればいいだけです。(`X-Watson-Learning-Opt-Out` `learning_opt_out`)  詳しくはAPIリファレンスをご参照ください。

:blue_book: :APIリファレンス [Data collection](https://www.ibm.com/watson/developercloud/conversation/api/v1/curl.html?curl#data-collection)

[^9]: 当然ですがパブリックな共用環境であっても、他人様のログは見えませんのでご安心ください。

### GDPR対応で「特定のユーザーのログを照会/削除する」機能が利用可能

:blue_book: 詳細はドキュメント「[European Union General Data Protection Regulation (GDPR)](https://console.bluemix.net/docs/services/assistant/information-security.html#gdpr)」にありますが、要はアプリケーションで/message APIで会話する際のHTTPヘッダーで X-Watson-Metadata: customer_id プロパティをセットしていただける場合は、後からそのcustomer_idに紐つくログを紹介したり、まとめて削除したりできます。



# インテント(Intent)のTips
### Absolute ScoringとIrrelevant(「不適」)
2017/2月のアップデートで、ユーザー入力に対するインテントの確信度（スコア)の計算方法が相対的なものから絶対的なものに変更されています。今までは他のインテントとの兼ね合い・相対値として確信度のスコアを計算していましたが、今後はユーザーの入力を独立して評価・スコア算出するようになりました。当変更により

- ①１つのユーザー入力に対して複数のインテントを返すことも可能になりました 
- ②確信度が低い入力( スコア=0.2以下 )に関しては応答として「Irrelevant(不適)」を返すようになりました。（要は「ほげ～」的な入力を撥ねることもできるようになった、ってことですね）
 
 別の言い方をすると、今までのNLC=自然言語分類器では、どんな入力であろうと分類の結果として必ず何らかのインテントが割り当てられていたのですが、現在の振る舞いでは**「不適当(Irrelevant)」＝「該当インテントなし」が返る場面もありうる**、ということです。なお「Irrelevant」が返った場合のユーザーへの応答はダイアログでanything_elseノードかtrueノードで救います[^6]。
 
 [^6]: 例えば、「申し訳ありませんが解釈できませんでした。お手数ですが違う言い方で試してみていただけますか。」などど返事することが考えられます

:blue_book: :[Absolute scoring and Mark as irrelevant](https://console.bluemix.net/docs/services/conversation/intents.html#absolute-scoring-and-mark-as-irrelevant)
:newspaper: :[Irrelevant - FEB Update - changed scorine intents - HOW TO HANLDE THIS?](https://stackoverflow.com/questions/42141652/irrelevant-feb-update-changed-scorine-intents-how-to-hanlde-this)

### コンテンツ・カタログ

Assistantでは「Content Catalog」という「サンプル集」が付きました。日本語も4パターンあります。(とはいえ、いくつかの例がインテントに追加されるだけなので、「発話とインテントの関係のニュアンスを理解するにはよいかもね」くらいの感じ[^7]です）

[^7]: EntityもDialogもありませんので、これならサンプルをじっくり読み解いたほうがいいような気もしました。
 
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/bdcb3f00-5e26-8439-de5d-3a3c90f2b5d9.png)

### :crown: (Plus&Premium限定) Intent Conflict Resolution

会話が複雑になりインテントの数が多くなってくると「発話」と「インテント」の関連付けで辻褄が合わなくなってくる場合がありえます。たとえば「同じような発話が異なるインテントに割り振られている場合」など。チームで作業している場合はなおさらです。Intent Conflict Resolutionはこのような「定義上の衝突」を検知してくれる機能です。以下は例ですがインテントの定義パネル上で当機能をONにすると「what do you sell（どんなものを売っているの)」という発話が競合しているよ、と教えてくれます。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/31ba393f-5fe6-7ea7-2581-74cffb9b61ab.png)

実際に詳細を見ると、what do you sellや似たような発話が「会社に関する質問」と「商品に対する質問」の２つのインテントに割り当てられていることがわかります。対応としては「競合をしないようにいずれか（または両方）の発話を直す」ことになります。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/c9372695-fe34-ecd8-0510-fa89d4641f3a.png)

:point_right: 要は「**この定義、似ててぶつかっとるで~**」と教えてくれます。

Youtube動画での細かい説明とマニュアルへのリンクです。
:tv: [Watson Assistant - Intent Conflict Resolution](https://www.youtube.com/watch?time_continue=4&v=9gQtjCBxjdc)
:blue_book: [Resolving intent conflicts](https://console.bluemix.net/docs/services/conversation/intents.html#conflict-intents)
###  :crown: (Plus&Premium限定)  Disambiguation

Intent Conflict Resolutionは「**インテントの定義時**」に競合を発見するものでしたが、Disambiguation(=明確化?)は「**対話の実行時**」に適用できる機能です。現在のAssistantは１つの発話に対し**インテントを（確信度付で）複数返す**場合がありえます。仮に、ある発話に対して２つのインテントが考えられ、確信度が両方ともそれなりに高かったらどうすればよいでしょうか。今まででしたら「確信度の高いほうを選ぶ」など、なんらかの基準で１つを選択したうえで回答することになります。結果、利用者の意図と違っている可能性もあるでしょう。当機能を使うと「どちらの意図か判断に迷うときは積極的に聞き返す」ことができるようになります。（「判断に迷うとき」の条件はドキュメントに細かい記述があります）

以下の例ではピザの注文アプリにてお客様が「ペパロニはありますか ?( Do you have pepparoni ?) 」と聞いていますが、お客様の意図は ①単にメニューの種類を聞いているだけ　②ペパロニのピザを注文したい　のどちらか、わかりません。そこで「有無をわかればいいだけですか、注文したいのですか？」と対話式に選択肢を聞いています。(ここの選択肢の表現も設定可能です）

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/62439d93-2730-afdd-9b69-23377da57360.png)

:point_right: 要は「**どっちの意味やねん**」と聞き返せます。

Youtube動画での細かい説明とマニュアルへのリンクです。
:tv: [Watson Assistant - Disambiguation](https://www.youtube.com/watch?v=VVyklAXlmbA)
:blue_book: [Disambiguation](https://cloud.ibm.com/docs/services/assistant?topic=assistant-dialog-runtime#dialog-runtime-disambiguation)

###  :crown: (Plus&Premium限定)  Intent Recommendations
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/13f0957d-f5d5-2d66-1a09-c8826043479a.png)

 (2018/11/28) Plusプランで「[Intent Recommendations](https://console.bluemix.net/docs/services/assistant/intents.html#intent-recommendations)」という機能がでました。(「Entity Recommendations」と紛らわしいですが、別ものです)　現在は:us:英語のみ＆ベータです。 
[Youtubeの紹介動画](https://console.bluemix.net/docs/services/assistant/intents.html#intent-recommendations)がありますが、要はコールセンターのログなどの「ユーザーの発話」が記録されているCSVファイルをアップロードすると、当該インテントに割り当てる「実際の文例」をお勧めしてくれるものです。(＝「こんなインテントがいいんじゃない」ではなくて、「**このインテントにはこの例文を使うといいんじゃない**」ってこと）実際の発話を簡単に例文に取り込めるのがミソかと。

# エンティティ(Entity)のTips
### 正規表現でのパターン抽出ができます

値のみならず、正規表現でのマッチングによるエンティティの抽出ができます。以下の例では電話番号とメアドが抽出されていますね。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/13b44a98-c07b-d29a-881d-b5cbc31721aa.png)

:blue_book: :[Defining entities](https://console.bluemix.net/docs/services/conversation/entities.html#fuzzy-matching)

### 間違い(ミススペル）があっても一致（あいまい一致:Fuzzy Matching)
エンティティの抽出時にあいまい一致(Fuzzy Matching)が使えます。英語:us:ではミススペル、ステミング、部分一致などが対象ですが、日本語:jp:ではミススペルのみベータとしてサポートしてます。日本語でのミススペルってどうなのかな？と思いやってみたのですが

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/97ac6ff9-be0b-ed61-7990-38a740d62910.png)

以下のような結果でした。(仕様として書いてあるわけではないです）
- 当然ながらFuzzy Matching **OFFの時**は正確に一致しないとヒットしません
一文字でも違ってたら、駄目です。
- **ONの時**は**一文字の違い（不足、多い、間違い）は許容され、ヒットします**。しかし二文字の違いは、だめのようです。（まあ妥当な仕様と思います）

|ケース| 指定|結果|
|:---|:---|:---|
|一文字少ない|ダックフンド| @animal:犬|
|一文字違う|ダックス**ラ**ンド|@animal:犬|
|一文字多い|ダックス**ス**フンド| @animal:犬|
|二文字少ない|ダクフンド| ヒットせず|
|二文字違う|ダックス**ラシ**ド|ヒットせず|
|二文字多い|ダックス**スフ＊＊フンド| @animal:犬|

- 正解「イヌ」に対する「イ**ケ**」など、あまりに短い場合はヒットしません

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/599053f6-e533-055b-7933-e8b16f7b4e59.png)

:blue_book: :[Creating entities](https://console.bluemix.net/docs/services/conversation/entities.html#creating-entities)

### :new::us: Entity Recommendations
(2018/07/12機能追加) 現時点は英語のみ:us:ですが、エンティティの同義語を提案してくれる**Entity Recommendations**が使えるようになりました。エンティティ定義画面で「Show Recommendations」ボタンを押すと候補を提示してくれるので、選択します。以下の例では肉の種類に「チキン」を設定した場合のシノニム候補を表示し、「hends」と「birds」を選択しています。

![entity_recommends_03.gif](https://qiita-image-store.s3.amazonaws.com/0/108535/22a8ba37-37ec-0baa-1970-35113ba267e7.gif)

:blue_book: [Synonyms](https://console.bluemix.net/docs/services/conversation/entities.html#synonyms)


### :new::us: (Beta) Contexual Entity
(2018/07/12機能追加) 現時点は英語のみ:us:かつベータですが、エンティティの定義を発話（文脈）の中の使われかた（単語の位置? )から導き出す**Contexual Entity**が使えるようになりました。具体的にはIntentの定義分で「ここはエンティティだよ！」とアノテートしていくと、エンティティの定義ができあがるというものです。**単語ではなく文脈（位置?)でエンティティを指定できる点が新しい**です。以下の例ではインテントの入力となる文章群で「フライトでの行き先(@destination)はここだよ！」とマークを付けて教えています。すると自動的に@destinationのエンティティの定義が作られます。その後「Ticket to **London**, please」と発話すると、「**London**」という単語がエンティティのシノニムには未登録にもかかわらず、きちんと＠destinationとして認識されています。

![contextual_entity_05.gif](https://qiita-image-store.s3.amazonaws.com/0/108535/ed6c90f6-da67-ed0a-2510-e68802423121.gif)

# ダイアログ(dialog)のTips

### 会話の始まりは welcome で
新規にダイアログを作成するとデフォルトで会話の始まりである「**ようこそ**(welcome)」と、どこにも割り当てられなかった入力を救うための「**その他**(anything_else)」というノードが自動的に作成されます。「**ようこそ**」ノードでは会話の開始（例.　ようこそ！など）やコンテキスト変数の初期化を設定できます。（会話の始まりは「挨拶」をするタイミングなので勿論あったほうがよいでしょうが「必須」ではありません。無ければ無いで構いません。）

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/568c9ace-605d-5f6c-6d2d-efb833882751.png)

※「welcome」や「anything_else」はAssistantが用意している「**Special condition**」という事前に定義された条件の一種です。「welcome」とは別に「conversation_start」というSpecial conditionもあります。両者は「会話の始まりで使う」という意味でほぼ同じと思っていただいてよいですが、少しだけ違いがあります。詳しくは[ドキュメント](https://console.bluemix.net/docs/services/conversation/dialog-build.html#conditions)を。

### 「何もヒットしない」入力=最後は anything_elseノードかtrueで救う
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/1e2cbced-536f-bb1a-0ec0-8785a52326b3.png)

トップ・レベル（一番左）の末尾のノードとして、anything_else条件が設定されたノードが自動的に作られます。**ノードの条件の評価は上から＆左から順番に評価されます**が、条件にまったくマッチしなかった場合の対話はこの anything_elseのノードか、または条件としてtrueを指定したノード(何でも真になる＝何でもアリ）で救います。anything_elseとtrueはいずれも意味は同じなのでしょうが、デモのサンプルなど見るとトップレベルはanything_else、それより下のレベルではtrueのほうを使っているようでした) ご参考までに(そんなことはしないと思いますが）これらの「何もヒットしない場合を救うノード」は必須ではありません。意図的に書かなかったり手で削除してしまうことも可能ですが、その場合はクライアントにレスポンスが何も返りません。その状態で改めてユーザー入力が入ってくると、トップレベルの場合はそのまま再度評価が実行されます。第二レベルより下の層ではいったん上のレベルに戻ってから再度評価が実行されます。（※)いずれにしても全体の制御が失われてハングしまうわけではありませんのでご安心ください。

### 制御のジャンプ( Jump To )

対話の流れ上、別のノードに制御を移したい場合には「 Jump To..」でジャンプ先のノードを指定できます。ジャンプ先のノードには条件(Condition)のパートとレスポンスのパートがありますが、そのどちらから継続するのかも指定できます。**要はgo toだ**と思えばよいでしょう。

定義としては以下の２か所のいずれかでJumpしたい旨を指定します。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/4b54272c-c6bd-d67e-2158-698532f0d8d4.png)

「ジャンプ先のノードを選択してね」と表示されるので、飛びたい先のノードをクリックします。するとノード中のジャンプ先の候補が表示されるので、選択すればオーケーです。簡単です。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/3fbb6d3b-e0c0-48dd-7870-192b3640dd2f.png)

以下はジャンプ先で条件の評価をせずにレスポンスだけ返す場合の例です。パソコンの修理相談が終わって、相談のお礼～改めて別の相談を開始するシナリオです。結びの挨拶から再開の流れは各ノードに逐一書くのではなくて、共通的に処理したほうが何かと便利かと思いclosingというノードを作りました。右側は実際の対話とレスポンスです。Jump Toの流れに沿ってレスポンスが順次出力されていますね？

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/50be3975-9ac9-bb16-dea1-5f52e650d414.png)

### Skip User Inputって何するもの?

新しく**Skip User Input**というJump方式が追加されています。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/80312500-55fe-9c0a-d2c2-3584af79ef3c.png)

これ、ドキュメントには

>when the node is configured to skip user input, it is equivalent to forcing the dialog to process the first child node after the current node in succession.

とあり、「強制的に最初の子のノードに制御がわたる[^8]」ことはわかるのですが、使い道がいまいちわかりません。でCustomer-Serviceのサンプルを見たら、わかりました。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/ed583cfe-98ba-4b81-eaa7-98fad95b1e71.png)

サンプルではオフィスヘの道案内をしていますが、顧客が発話で「**今、タイムズスクエアにいるんだけど、**ここからどういけばいいの？」と｢今いる場所」を言った場合は、現ノードの応答として、その場所からの道筋を示した後で、子ノードに飛んで実際のオフィスの場所を案内しています。｢今いる場所」を言わなかった場合は、何もせず即座に子ノードに飛び同様にオフィスの場所を案内します。このように「最終的には言うことは同じなのだけど、その前にオプション的に何か付け加えて言いたい」場合に使えるのですね。

[^8]: 従来の"Jump_to_next"と同類です

### 制御のジャンプ( Jump To )とWait for User input
実はJump to..にはもうひとつ、Wait for User Inputというモードがあります。前の２つ（条件と応答)はGOTO文として制御が飛んでそのまま評価・実行されますが、Wait for User Inputの場合はいったんユーザーに応答し、その回答をもらってから改めて処理を継続する、という流れになります。例えば、何か処理を進めるに際して「これでよろしいですか？」と確認するような場面が考えられます。
実は私自身も操作含め、ちょっと混乱したのでこの辺を整理します。
まず、ノードの末尾の表示ですが、ここは機能としては「Jumpするか、しないか」の意味しかありません。

- And then Wait for user input(左）はデフォルトの振る舞いで、レスポンスを返して次のユーザー入力を待ちます。次回はこのノードを起点に評価が始まります。
- And Then Jump to .. の場合は勿論制御がJumpします。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/de7ce1e1-69c6-5530-42a3-74a4b64bbba7.png)

前述の通り、Jump先のノードを選ぶと以下の３つの選択肢が表示されます。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/6adbbf47-ad70-64ba-a7f1-63a98facb4ec.png)

以下は②条件(If bot recognizes(condition))と③Respondの場合の動きです。各々、指定された箇所に制御が移り、あとは中断なく処理が進む点は既にご紹介しました。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/ebd53862-ff9a-db18-7582-a7efc866dc71.png)

翻って以下が①Wait for user inputの場合の動きです。Jump元で設定したレスポンス(普通は質問)が一旦ユーザーに返されます。ユーザーが入力すると、その入力に応じて②条件(If bot recognizes(condition)の判断から処理が再開する流れになります。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/e34f7e1b-e4ae-495f-9c38-d1d03ab7755f.png)


#### ノードから外部のサービスを呼び出せます
ノードのJSONエディターで”actions"の構文を書いて、外部の(REST)サービスを呼び出し、結果を入手できます。呼び出し方法は(TYPE) は①Client ②Serverの二通り。①は通常のRESTFUL Webサービスの呼び出し、②はIBM Cloud Functionsを介した呼び出しです。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/9767e791-31e5-9a74-d7ed-caa2a6788b15.png)

下図はドキュメントからの転載ですが、①Clientの場合のフローです。ちとややこしいですね。クライアント側のアプリとの取り決めが多くなりそうで、複雑です。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/b221aedb-14ad-4118-a9e4-d4fdba7f693d.png)

以下は②Cloud Functionsを使う場合ですが、こちらのほうが直感的で良いように思います。
:warning: 現時点(2018/7)でこれが使えるのは米国南部とドイツのみ。またAssistantとCloud Functionsは同一ロケーションである必要があります。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/e589a334-87f8-49bd-9bed-90cd789dfb23.png)

:blue_book: :[Making programmatic calls from a dialog node](https://console.bluemix.net/docs/services/conversation/dialog-actions.html#dialog-actions)
:newspaper: :[@schiyoda](https://qiita.com/schiyoda)さんのQiita記事「[Watson Assistant から IBM Cloud Functions の Action を呼び出す方法](https://qiita.com/schiyoda/items/bceabe327a0c7d08e9e4)」

### ユーザーに複数のことを聞きたいときに- スロット
スロット（slot filling)とは何でしょうか。以下のドキュメントの先頭にあるYouTube動画(6分）を見ていただくのが一番オススメですが、ここでは「何をするものか」だけご紹介します。
:tv: [Gathering information with slots](https://console.bluemix.net/docs/services/conversation/dialog-build.html#slots)

シナリオとしてレストランの予約ボットを考えます。お客様からの予約を正しく受けるには最低でも ①人数 ②来店日 ③来店時間 を聞かなくてはなりませんよね。お客様がチャットで必ずこの３つを一度に伝えてくれればいいのですが、そうはうまくいきません。「x月x日に予約したい」と言われれば、来店日はわかりますが、追加で人数と来店時間を聞かなくてはなりません。要は「お客様が何と言われるか」によって「追加で何を聞くべきか」が変わってくるわけですが、お客様の表現の全ての組合せをダイアログのフローで拾うように実装するのはかなり煩雑です。これを**簡単に１ノードで実装できる**のがスロット機能です。「スロット」の本来の意味は「溝(みぞ), 細長い小さい穴」だそうですが、**要は「スロット・マシーン」のように３つの値が揃ったら予約完了！という感じ**ですかね。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/387f430b-7eab-ed29-96bf-354c3d94a6f0.png)

なおスロット機能はノードに対して設定しますが、デフォルトでは無効になっていますので、使う場合は右上の「Customize」で明示的に有効にする必要があります。詳しくは下記の[@schiyoda](https://qiita.com/schiyoda)さんの記事がオススメです。前述のような場面の実装がとても楽になりますよ！

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/9c08ab42-15f2-4162-9124-6a5ee6720b0c.png)

:newspaper: :[@schiyoda](https://qiita.com/schiyoda)さんのQiita記事「[Watson Assistantのスロット機能の使い方](https://qiita.com/schiyoda/items/a50ea70232382bdcf766)」
:blue_book: :[Gathering information with slots](https://console.bluemix.net/docs/services/conversation/dialog-slots.html#slots-tips)



# レスポンスのTips

### レスポンス(response)のエスケープ
レスポンスはJSON形式ですが、レスポンスの出力中に予約文字 (#, @, $), クオート、改行文字( carriage returns, line feeds) タブなどの文字がある場合は、直前にエスケープ文字 バックスラッシュ(\))を置きます。また、レスポンスのテキスト中に以下のようにエスケープしたhtmlのリンクを埋め込むことで、ユーザーにURLを提示することもできます。なお、ダイアログのエディターから入力する場合はHTML中のダブル・クオートのエスケープは自動的に行われます。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/7bb5f279-5a75-13a5-4b00-f5558031c43e.png)

JSONをご自身で直に書く場合はエスケープが必要です。もしエスケープに問題があればJSONエディター編集中に以下のようにエラーになるので、気が付きます

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/efd768a2-5d0a-872f-89e5-a59f87f96e83.png)

URLの埋め込みはTry it Outでも[^1]、クライアントのWebアプリでも、HTMLとして処理すれば正しくリンクとして表示されます。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/1370a9d8-c64c-1d5b-111a-fefdd8d914c9.png)

[^1]: 以前はTry-it-outではURLがそのままテキストとして表示されていましたが、改善されました

### :new: リッチ・レスポンス
(2018/07/12機能追加) レスポンスで、テキストだけでなくイメージ(image)や選択肢(Option)なども返せるようになりました。以下のようにパネルで設定できますしTry it outでテストできます。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/b6a9b370-0231-1902-a2a1-d6ac2691768c.png)

- 上記の例のように複数のレスポンスを連結して書くこともできます
- 選択肢(Option)の場合は、ひとつを選択すると対応する**Value**の値で発話が発生したものとみなされ、処理が継続されます
- 外部のFunctionsを呼び出した際の処理待ちのために「pause」も設定できます

:blue_book: [Rich Responses](https://console.bluemix.net/docs/services/conversation/dialog-overview.html#multimedia)




### 回答のバリエーション
ボットの回答がいつも同じ物言いでは、つまりませんよね。Assistantでは問いかけに対するレスポンスの文言を複数登録しておけば、色々な言いかたで回答できます。以下の例では挨拶に対して３種類のレスポンスを登録しています。それらの提示の順番も①sequential　②randomのいずれかを下部のスイッチで切り替えられます。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/25f60afa-c86d-c7f6-62f7-b059f53f6fb7.png)

### １ノード内で条件により複数のレスポンスを出しわけ

ユーザーの入力を処理する際には、複数のノードを組み合わせてややこしく判定せずとも、**１ノード内で複数の条件を記述し、各々で異なるレスポンスを返せます**[^2]ので、フローがシンプルになります。

- １ノード内にレスポンスを複数書けます
- 各々のレスポンスに条件を書けます
- ノードの末尾以外に、各々のレスポンスにもJump Toを書けます

[^2]: 以前は複数条件は書けませんでしたので、フローにノードが多く複雑になりがちでした

:warning: 複数レスポンスを許可するにはノード毎に右上の「Customise」パネルを開いて明示的に許可する設定が必要です。デフォルトでは複数レスポンスは利用できない(OFF)ようになっています。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/39dc178f-29dd-7999-567f-bf30960d5238.png)


この方法はCar Dashboardのデモでも多用しています。[Multiple conditioned responses](https://console.bluemix.net/docs/services/conversation/dialog-build.html#multiple)に2分弱の動画があるのでそれを見ていただくとご理解が進みますが、以下はサマリーです。

以下の例ではユーザーの「止めて」との指示での様々なエンティティの言いかたに関して、１ノード中でまとめて別々のレスポンスを返しています。Try it outでの結果と突き合わせてみてください。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/20a4a369-32b9-b213-1cdd-0a0a2b94d983.png)

なお「条件付レスポンス」からもJump toが使えるようになっています。

### 脱線( Digressions )

Assistantになってからの新機能です。会話の最中に現在の文脈と関係の無い発話が行われた場合に、いったん横道に逸れてから元に戻ってくることができます。わかりやすく言うなら**「ああ、そういえば」と言われた時の話**です。たとえばピザの注文中でサイズとトッピングを聞いているときに、急に「トッピングは何があるの？」とか「お店は何時まで開いてる？」とか聞かれた場合に、現在のノードからいったんFAQを扱うノードに制御を移し、回答してから戻ってきて注文のフローを継続する、といった使い方ができます。くわしくは下記の記事が参考になります。

:newspaper: :[@schiyoda](https://qiita.com/schiyoda)さんのQiita記事「[Watson Assistant の Digressions(脱線)機能の使い方](https://qiita.com/schiyoda/items/d47147153a85d42852d7)」
:blue_book: :[Digressions](https://console.bluemix.net/docs/services/conversation/dialog-runtime.html#digressions)


# 会話のステート保持に関するTips
### Assistantは本来はステートレスなサービス
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/30782e2b-a642-8926-760d-9e507446c5f4.png)
Assistantは**ステートレス**なサービスであり、会話の状態を保持しません。**ステート(State=状態)**とは、通常のWebアプリケーションと同じ概念です。チャットボットのような会話アプリは発話-応答のペアを何度もやりとりして会話が進みますが、Assistant本体は発話-応答の１ペアのやりとり(=ターン(Turn)と呼びます) で処理が完結し、以前のこと(ステート)は一切記憶（記録)しません。つまり「ログインの状態」とか「さっき聞いたお客様の名前」とかは次回のターンでは何も覚えていないのです。ITインフラの観点ではステートレスなデザインにすることでスケーラビリティや高可用性を確保しやすくなるのでいいのですが、業務的には対話が成り立たないので困りますよね。。そこで「じゃ、Assistant側は何も覚えなくていいけど、対話で聞いたことをメモして、毎回やりとりすればいじゃん」という考えが出てきます。このメモに該当するのが「**コンテキスト変数**」です。

### コンテキスト変数( Context Variables )で状態を保持
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/e015c948-cd24-36bc-61b7-a40fa167db5d.png)
上図のようにお互いが**コンテキスト変数**に記憶しておきたい内容をセットして毎回やりとりすることで、Assistantをステートレスに保ちながら会話内容に継続性を持たすことができます。具体的にはAssistantのAPIにはコンテキスト用の領域がありますので、クライアントとなるアプリケーションとAssistantは、そこにJSON形式でデータをセットし、その領域を介してステートを保持します。（APIでcontextをセットして送り返すのはクライアントとなるアプリケーション側の責任です）

・コンテキスト変数は[messageのAPI](https://www.ibm.com/watson/developercloud/conversation/api/v1/?node#send_message)にも含まれています。
・ノード中で利用する場合は接頭子 「\$」を付けます。(例. $(customer_name) )

:blue_book: :[Context variables](https://console.bluemix.net/docs/services/conversation/dialog-runtime.html#context-variables)

以下の例では会話の開始時のPOSTリクエストのcontextフィールド経由で顧客名と前回コンタクト日を渡し、応答では受け取った値を使って応答します。たとえばCRMなど外部のシステムからデータを取ってきて、対話に利用するようなシナリオで使えますね。

★welcomeのテキスト
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/74db32a1-ad1e-bb67-640c-ffb1f4f30400.png)

★message APIで渡すJSON構造(node.jsの場合)
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/7d2d10d1-9cbb-cb8b-1bf5-ae05a1948cbd.png)
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/ab4b7045-b455-6dd3-867a-b962e6a7e713.png)

★実行結果　コンテキスト変数に値がセットされています。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/802fbc19-4dc1-df66-9df8-494e5f57b5d1.png)

また、Car Dashboardデモではこんな風にコンテキスト変数をbooleanにして、条件でそのまま使うような使いかたもありました。なるほど~。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/1ed98f99-41aa-8c76-dca7-34fadb5c8e98.png)

- コンテキスト変数はクライアント・アプリケーションとの間だけでなく、Dialogのノード間でjump等で制御の流れがかわる場合のデータのやりとりにも利用できます。（例. あるノードで名前を聞いてコンテキスト変数にセットし、Jump先では呼びかけに使うなど）

:triangular_flag_on_post: (2019/2月) Assistantのアーキテクチャー変更(AssistantとSkillの分離）に伴い、コンテキストの扱いもAPI V1/V2で変わっています。要はV2ではコンテキストをアプリが毎回送り返さなくてもいいようになりました。この辺の話は記事 :newspaper: 「[Watson Assistant API V1/V2の違い](https://qiita.com/ishida330/items/6dcdb664e4724e27764d#%E3%82%BB%E3%83%83%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%A8%E3%82%B3%E3%83%B3%E3%83%86%E3%82%AD%E3%82%B9%E3%83%88%E3%81%AB%E3%81%A4%E3%81%84%E3%81%A6)」をご参照ください。

### コンテキスト変数を設定するエディターが出ました
Dialogのノードでコンテキスト変数を操作する場合、従来のJSONエディター以外にAssistantになってコンテキスト・エディター[^5]が出ました。JSONエディターは後述する”action"などコンテキスト変数以外にも出番がありますが、コンテキスト変数を編集する目的ならContext Editorのほうがパネルで設定できるので使いやすいです。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/d0ed65de-ac07-43c5-39f8-be97bcf09e4e.png)

[^5]: 以前はJSONエディターしかありませんでしたので直に編集してました

### エンティティの値をコンテキスト変数にセットする
前項の例のようにクライアント・アプリケーションからコンテキスト変数が渡されるなら、応答中では$(変数名)で参照すればいいだけですが、発話からエンティティの値を抜いてコンテキスト変数に保管して、応答で使いたいときもあるでしょう。その場合の**Value**の書き方の例をお示しします。

下記のように@animalエンティティがSynonymsで定義されています。ここでコンテキスト・エディターにどう書くと何が抽出できるか、ですが

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/eb4abbd8-f74a-19b3-614a-7dca935397b8.png)

「@animal」のようにエンティティ名だけを書いた場合(左側）は、発話がシノニムでヒットしても、「鳥」という「値(Entity Values)」が返ります。「@animal.literal」のようにエンティティ名**.literal**と書いた場合(右側)は、発話がシノニムでヒットした場合、シノニムの値が返ります。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/82a7b1b1-cb9b-e36f-ea95-b0f71981d76e.png)

なお、エンティティをパターンで定義した場合は .literalを書かないと値が取れませんのでご注意ください。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/25b1f7f6-f9fe-15fe-0828-6c7c07970da1.png)

:blue_book: :[Common context variable tasks](https://console.bluemix.net/docs/services/conversation/dialog-runtime.html#context-common-tasks)

# Spring Expression Language (SpEL) のTips
上記のコンテキスト変数の表現はjsonですが、ノード中では[Spring Expression (SpEL) language](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html)が利用できます。たとえばカウンターを保持してカウントアップする、条件により変数の値を変える、などの処理も行えます。(Assistantのコンテキストで使う時は <? ~ ?>で囲むと「その中に書かれている式を改めて評価しろ」という意味になります。)
以下の例ではノード内でリトライのカウント(retry_count)を＋１したり、リトライの回数が3回以上になったらオペレーター呼び出しのフラグ(call_operator_flag)をONにする、などの操作をしています。SpELでは他にも色々な表現ができるようなので、「こんなことをしたい」というのがあれば[SpELのドキュメント](http://docs.spring.io/spring/docs/current/spring-framework-reference/html/expressions.html)を見てみるとよいかもしれません。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/e32745ef-f27e-2372-6881-b4601a065886.png)

### ノードでの変数の参照
ダイアログのノード中ではコンテキスト変数以外にエンティティの値を参照し、条件で指定できます。たとえば「入力テキストにエンティティの指定があるか（有無）」「入力テキストにエンティティがあり、その値は何か」など。以下にノードの条件での表記方法をまとめます。

|  対象    |  冒頭の記号 | 形式 | 表記例（いずれか） |
|:-----------|:-----------|:-----------|:-----------|
| Entityあり | @ | @entity_name |@appliance |
| Entityの**値**あり | @ | @entity_name:value | @appliance:radio |
|  | @ | @entity_name(value) | @appliance(radio) |
|  | @ | @entity_name == 'value' | @appliance == 'air conditioner' |
| Context | $ |context.variable_name  |context.customer_name |
|  | $ |$variable_name | $customer_name |
|  | $ |$variable_name == 'value'  |$variable_name == 'value'

Car Dashboardデモの例ではユーザーの希望する音楽のジャンルが@genreエンティティの値が"rock"にセットされ、その値をレスポンス内の埋め込みに利用しています。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/5f986a35-501a-1851-cd2f-c43da8290e4e.png)


### レスポンスの確信度(confidence)の判定

記事の前半で「最新のNLCはインテントとしてIrrelevant（不適）を返すことがある」とご紹介しました。Irrelevant(不適)かどうかの判断のスコアのしきい値は0.2で固定であり、結構低めです。つまり、あまりに外した質問は撥ねられるとしても「絶対間違いない」スコアとの間に「ビミョー」な領域が残ります。ユーザーからの問いかけに対して、あまりにハズした回答は好ましくないので、NLCが応答内容に自信が無いようなら（＝NLCの分類結果の確信度が x%以下だったら）、「ユーザーに別の言い方をするようにお願いする」とか「改めて内部的にDiscoveryを呼び出して、そちらの応答を使う」などのシナリオが考えられます。この場合の実装方法ですが、[AssistantのAPI](https://www.ibm.com/watson/developercloud/conversation/api/v1/curl.html?curl#message)のResponseにはintentsのフィールドがあります。ここのconfidenceをクライアントのアプリケーションでチェックすることで、振る舞いを変えることができます。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/aec7e889-9479-4e57-6e77-8d0446f61016.png)
注：この例ではIntentは１つですが、Intent**s**と複数形になっているように、複数のIntentのArrayであり、候補が複数返る可能性がある点にご注意ください
ノードの条件にconfidenceを追加することも可能です。この場合はIntentが決まっても、指定した確信度の閾値以下の場合には条件にヒットしません。
 例) ~ and intents[0].confidence >= 0.XX 

以下の例では「スマホについて聞いてもいい？」との問いかけで「hello」という意味のないインテントになってしまっています。（確信度は0.76）
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/05b55cf0-b03a-aca7-a4d1-799ec4ff207d.png)
ここで「#hello」に対して「確信度が0.8以上であること」との条件を追加指定すると、#helloのノードにはヒットしなくなり、anything_elseに落ちることで再度の入力を促しています。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/6c4f43d2-b18c-69d4-88b7-3acc773c3fa4.png)

ついでですが、条件にエンティティを書いていて＆fuzzy matchingを使うときは[確信度0.3以上でないとヒットしない](https://console.bluemix.net/docs/services/conversation/expression-language.html#entity-properties)そうです。

>The confidence of an entity is either 0 or 1, unless you have activated fuzzy matching of entities. When fuzzy matching is enabled, the default confidence level threshold is 0.3. 


# 基盤/インフラ的なTips

### :loudspeaker: (2019/2) APIの認証はIAMベースに変更されました 

認証に関し、今まではuserid/passwordでしたが、現在は**全リージョンでIAMのAPIKEYを使う方法がデフォルト**になっています。まだUserid/Passwordの認証をお使いのお客様は2019/10/30までに移行してください。記事 :newspaper: [【重要】従来型(古い)Watsonインスタンスをお使いの方は来年(2019)の10/30までに新しい環境に移行しないと、たぶん死にます](https://qiita.com/ishida330/items/bdfe56a757b7439d3754)のでご注意を！

### Assistant向けの新しいSDKとAPI

従来のConversationのAPIも引き続き動きますが、新しいAPI/SDKも出ています。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/44cdd1a0-fde3-0221-5b7f-1b1c9d93e212.png)


:blue_book: 旧: [Watson Assistant API V1](https://cloud.ibm.com/apidocs/assistant)
:orange_book: 新: [Watson Assistant API V2](https://console.bluemix.net/apidocs/assistant-v2)
~~:blue_book: 旧: [Watson Conversation API](https://www.ibm.com/watson/developercloud/conversation/api/v1/curl.html?curl)~~ 削除済み


### SlackやFB Messengerとの統合は簡単です

SlackやFacebook Messengerなどの既存サービスをAssistantのチャットUIとして簡単に統合できます。具体的な方法をネットで検索すると「いったい、どの方法がいいの！」という位あれこれ記事が出てきますが、要はSlackなど既存サービスのWebhookを活用して連携する方法であり、具体的には ①IBM提供の**Botkit**を使う方法(別途、統合のためにNode.jsが必要) ② **IBM Cloud Functions(=Apache OpenWhisk)**を使う方法　のどちらかの方法になると思います。Assistantでは「Deploy」のパネルで方法をご覧いただけます。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/6c7f9f13-0be4-f7f9-1129-d74cdf7f17a6.png)

- [Integrate Watson Assistant With Just About Anything](https://medium.com/ibm-watson/integrate-watson-assistant-with-just-about-anything-695bc1d29875)などの記事を読むと長期的にはCloud Function推しかな？と思います
- 他にも[Nore-REDでやられた方の記事](https://moeka-dev.hatenablog.com/entry/2018/03/18/204322)や[Microsoft BotFrameworkでSkypeと統合した記事](https://developer.ibm.com/recipes/tutorials/how-to-build-a-chatbot-with-watson-conversation-using-microsoft-botframework/)など、まあ色々ありますね。

:newspaper: :[@schiyoda](https://qiita.com/schiyoda)さんのQiita記事「[Watson Assistant の ユーザー・インターフェースに Slack を使用する](https://qiita.com/schiyoda/items/f1dc9766614c28768b15)」
:newspaper: :[@schiyoda](https://qiita.com/schiyoda)さんのQiita記事「[Watson Assistant の ユーザー・インターフェースに Facebook Messenger を使用する](https://qiita.com/schiyoda/items/b96b270ee259a21a8907)」
:blue_book: : [Deploying to a channel with the Conversation connector](https://console.bluemix.net/docs/services/conversation/conversation-connector.html#deploying-to-slack-using-the-watson-assistant-tool)

### Discoveryとの統合
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/9d2459a2-e402-6fb7-9c0c-494c2cf1c840.png)

チャットボットの拡張として、**ロングテールな質問に対応**するためにDiscoveryとの統合も考えられます。要は「**8:2の法則**」を意識して、
① よくある８割のFAQはAssistantで対応する
② あまり頻繁ではない2割のロングテールの質問はDiscoveryで対応する
ようなデザインです。アイデアの肝は 発話に対するインテントの確信度などを基準にして、「**Assistantで答えられない場合は、Discoveryに回す**」ことです。実装はフロントのアプリでやってもよいですし、前述のCloud Functionsで統合することもできます。考慮点としては「ロングテールな質問の答えを、利用者にどのように提示するか」があります。というのもAssistantは基本的に「チャット会話」ですが、Discoveryは「文書の検索」だからです。口語体でチャット会話している最中に、急に硬く長い文章が表示されたら、驚きますよね。ので「生憎ぴったりの回答が無いのですが、ご参考までに文献をお示ししますね」と言ってDiscoveryの検索結果候補を提示する、などなんらかの工夫をしたほうがよろしいでしょう。

### :loudspeaker: (2019/3) サーチ・スキル(Discivery統合)
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/a5ed48c8-fde4-d6d4-5f58-2c89c6ae3cb0.png)

~~まだ限定ベータですが、~~ Watson Discoveryと簡単に統合できる「サーチ・スキル」が2019/3/22 [OpenBetaとして](https://medium.com/ibm-watson/adding-search-to-watson-assistant-99e4e81839e5)）Plus/Premiumで利用できるようになりました。上のようにDiscivery側のメタデータで認識しているフィールドをAssistant側でマッピングしておくと、質問をDiscoveryで検索の上、該当フィールドの値をリスト形式で表示してくれます。

![image](https://qiita-image-store.s3.amazonaws.com/0/108535/6c7130f2-e3b7-c6d3-5880-0dfb0ac4631f.png)
従来のダイアログのスキルとは別に「サーチ」のスキルができ、アシスタントはサーチスキルを使うよう構成できます。

最終的にどのような形でGAするかはわかりませんが、以下のシナリオで、自分でCloud Functionとかで統合しなくても済むのはありがたいですね。


### User Conversationパネル
ユーザーとの対話の内容を記録・集計・検索するパネルが付きました。現状の分析や会話精度の改善に使えます。

【Overview】
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/1f47c81d-a2dd-4d3d-0aeb-eb3c6c0bf62e.png)

【個別の会話内容】
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/3a1321d9-962d-67ef-09c1-ef446a9b4517.png)

- ログの保存期間はレベルに応じて7/30/90日だそうです
- 当ツールからは生ログをダウンロードできませんが、[LOG API](https://www.ibm.com/watson/developercloud/conversation/api/v1/#get_logs)をcurlで叩けばJSON形式で簡単に手に入ります。

### GDPR対応のための新機能
GDPRの「希望があれば顧客の情報を削除する」に対応するために ①顧客のタグ付け(Customer tagging=APIに顧客のIDを追加)　②タグを指定して顧客のログを消す(The ability to delete a customer’s logs based on their label) ことができるようになりました。当機能はオプションであって自動的に適用されるものではない点にはご注意ください。

:newspaper: [New Watson Assistant updates to provide GDPR support](https://www.ibm.com/blogs/watson/2018/05/new-watson-assistant-updates-to-provide-gdpr-support/)
:blue_book: [https://console.bluemix.net/docs/services/conversation/information-security.html](https://console.bluemix.net/docs/services/conversation/information-security.html)
# おまけ

[Niklas Heidloffさん](http://heidloff.net/)がBlogでAssistant関連のツールを公開してくれています。いずれもGitHub上のオープンソースです。①"Deploy to Bluemix"ボタン押して②Conversationのインスタンスをbindして③ツール起動後のUIで対象のワークスペースを選択するだけで普通に動きました。便利かも。。。

:newspaper: : [Introducing the Conversation Inspector for IBM Watson](http://heidloff.net/article/conversation-inspector-ibm-watson)
Conversationのクライアント。指定したワークスペースとやりとりして通信内容(JSON)を表示してくれます。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/fdad7584-aef5-032d-3c6d-f5312dd6500b.png)

:newspaper: :[Introducing the Conversation Optimizer for IBM Watson]
(http://heidloff.net/article/conversation-optimizer-ibm-watson)
ConversationのログAPIを叩いてログを入手し、エラーや確信度の低いインテントなどをリストしてくれる。前述の「User Conversation」パネルみたいなもの。
![image](https://qiita-image-store.s3.amazonaws.com/0/108535/d2887841-7e30-abae-6f33-1204cc0e59ac.png)


# 各種リソースのご紹介
#### :blue_book: ドキュメント
- :us: :jp: [Watson Assistant](https://console.bluemix.net/docs/services/conversation/) - ドキュメント
- :us: [Watson Assistant](https://www.ibm.com/watson/ai-assistant/) - 製品ページ
- :us:[Watson Assistant](https://www.ibm.com/watson/services/conversation/) - サービス紹介
- :us:[Watson Assistant Solutions documentation](https://watson-personal-assistant.github.io/developer/) 
 
#### :newspaper: ブログ記事
- :jp: IBM ソリューション・ブログ [Watson Assistantのご紹介](https://www.ibm.com/blogs/solutions/jp-ja/the-future-of-watson-conversation-watson-assistant/)
- :us: Watson Blog - [Conversational Services](https://www.ibm.com/blogs/watson/category/conversational-services/) -新着ニュースなどを早く入手するのにお勧め

#### :tv: 動画やデモ
- :us: [Watson Assistant](https://www.youtube.com/watch?v=h-u-5f8fZtc&list=PLZDyxLlNKRY8zx37vPh6s_pCtOXIp_5yL) - YouTubeの動画コレクション(15本)

# :clipboard: 改定履歴

| 版| 日付| 変更内容|
|:---|:---|:---|
| 1.0 | 2018-06-26| 初版公開 |
| 1.1 | 2018-07-12| [July 12, 2018 機能追加](https://console.bluemix.net/docs/services/conversation/release-notes.html#release-notes)の反映 |
| 1.2 | 2018-08-14| 2018/08/06付のIntent Conflict ResolutionとDisambiguationの紹介を追記 |
| 1.3 | 2018-11-28| Plusプラン＋Watson@Tokyo Watson on ICPを追記 |