チャットボットの対話設計ができる対話サービスまとめ 〜Docomo対話サービスからAmazon Lexまで〜

2016年はチャットボットが非常に盛り上がり、たくさんのボットが世の中に登場しました。

ここまでの盛り上がりの理由には今年正式に始まったLINEボットなど、メッセンジャーサービスの登場が欠かせません。LINEだけでなく、Facebook、Slackなどメッセンジャーツールが次々とボットへ対応しました。

SlackボットやTwitterボットを作る際、従来であれば一から自分でプログラミングする必要がありましたが、現在対話ボットを簡単に作れるプラットフォームが次々と登場してきています。GitHub社のHubotで普及し始め、Docomoのサービスや、IBMのWatson、最近発表されたAmazon Lex、GoogleやFacebookに買収されたapi.aiやwit.aiなど、対話ボット開発に非常に注目が集まっています。対話ボットは今後業務での活躍が期待されている証拠です。

対話には大きく2種類あります。特定のタスクを実行するというゴールがあるタスク指向対話と、ゴールを持たない非タスク指向対話。業務と比較的相性が良いのは前者のタスク指向対話になります。従来人間やシステムが行っていたタスクをボットを使って実現することができます。後者は雑談など、エンターテイメントや広告宣伝用途への利用は見られますが、まだ業務への利用は難しいと考えられています。

今回はボットの対話設計の考え方と、実際ボット対話を作成するための対話サービスを特徴とともに紹介します。

なお、本記事は[Tech-Circle Advent Calendar](http://qiita.com/advent-calendar/2016/techcircle)の24日目の記事です。

2016/12/24時点の情報になります。誤りなどもし有りましたらご指摘お願いします。

# 対話ボットと対話エンジン

基本的にボットに対話をさせるには、話者（ユーザー）の発話に対してボットが自動応答できるように対話を設計する必要があります。対話ボットが応答する流れは以下の図の通りになります。

![dialog-service.png](https://qiita-image-store.s3.amazonaws.com/0/5707/7d928208-63dc-1530-a957-681024c25cbc.png "dialog-service.png")

メッセージング基盤はLINEボットの場合のLINE messaging APIなどの対話ボットがユーザーの発話を聞いてまず投げる先のシステムになります。

# ボット対話設計

タスク指向ボットの自動応答対話をデザインする場合、意図理解やシナリオ対話を組み合わせて対話を作ることができます。

## 意図理解

意図理解は、ユーザー発話からユーザーの意図（タスク）を抽出するものです。抽出された意図によってパラメータが必要になることがあります。

例えば、「スケジューラーを起動して」というユーザー発話であれば、「スケジューラー起動」という意図が選択されることが期待され、パラメータが必要としないです。

* ユーザー発話：「スケジューラーを起動して」
* タスク　　　：スケジューラー起動

↓

* ボット発話：「スケジューラーを起動しました」

別の例も考えてみます。「西新宿から品川までの行き方を教えてください」というユーザー発話の場合、「乗換案内」というタスクになり、パラメータとしては、発駅（西新宿）と着駅（品川）が必要になってきます。
必須のパラメータが全てわかるまでボットはパラメータを聞き続けて、タスクを実行することになるでしょう。タスクを推定するのをタスク推定、パラメータでスロットを埋めていくのをスロットフィリングと呼ぶこともあります。この全てのパラメータを定義したものをフレームと呼ぶことがあります。

* ユーザー発話　　：「西新宿から東京までの行き方を教えてください」
* タスク　　　　　：乗換案内
* 乗換案内フレーム：発駅スロット／着駅スロット

↓

* ボット発話　　　：「東京メトロ丸ノ内線で行けます」

対話サービスによっては、タスクの種類や、タスクごとに必要になるパラメータの定義や、実際に実行する処理についても、新規で作成ができるものとできないものがあります。

## シナリオ対話（対話管理）

シナリオ対話は、対話管理の中の機能で、ユーザー発話に応じてボットがどう答えるか制御構造を定義できます。

例えば、ボットが「もう昼食は食べましたか？」と聞いてきた場合に、ユーザーの発話次第でその後のボットの行動を変えたいようなシナリオがあったとします。

* ボット発話：「もう昼食は食べましたか？」

↓ 

* ボット発話：「何を食べましたか？」（ユーザー発話：「はい」の場合）
* ボット発話：「おすすめのランチをご案内しましょうか？」（ユーザー発話：「いいえ」の場合 ）

上記のシナリオのようにユーザーの発話に応じて分岐を定義していきます。シナリオは、GUIのフローチャートや、XMLベースのAIMLというスクリプトなどで作成することができます。

シナリオ対話ではあらかじめ対話シナリオを作成しておく必要があります。特定業務など、対話シナリオが想定できる範囲で利用するのが現実的です。逆に業務が広い場合、膨大な数の対話シナリオの作成が必要になり対話シナリオの作成が現実的ではありません。

シナリオ対話のバリエーションを限定的にするために、ユーザーに全く自由に対話させるずに、ボットが対話の主導権を取る（システム主導対話）にすることが有効です。そうすることで、PCサポートのヘルプデスクの対話システムで占いシナリオを考える手間が省けます。シナリオ対話でカバーする範囲を限定的にすることで、効果的に対話シナリオを作成することができます。

また、テキスト対話では一般的なWebシステムと異なりユーザーの発話に制約をもたせにくいです。LINEなどの選択式ボタンインターフェイスを使ったりしない限りは、あらゆるテキストがユーザー発話として得られる可能性があります。そのため、ユーザー発話に完全に一致しなくても、つまり、表記が「はい」、「ハイ」、「Yes」のようにゆらいだとしても、ユーザーの意図が読み取れるようロバスト（強固）なシナリオとして設計することが重要になります。

対話サービスによっては、各社が提供するサービスによって新規シナリオの作成ができるものできないものがあります。

# 対話技術

対話技術はさまざまな自然言語処理技術がベースとなって実現します。

シナリオ対話には通常のプログラミング同様、対話制御を扱えます。また、ユーザー発話から意図理解し、タスク実行するためには、前述の通り、タスクの推定（分類）とパラメータ抽出を行う必要があります。それぞれ以下で説明します。

## 対話制御

シナリオ対話を実現する方法としては、GUIのフローチャートや、AIML（Artificial Intellegence Markup Language）で対話ルールを設計することが多いです。

GUIのフローチャートは小さなシナリオであれば比較的直感的に作成できます。IoT／ロボット系のプログラミングにも多く採用されていて、ロボットとIoTを組み合わせるのにも相性が良いです。しかし、大規模になると階層化したり工夫しないと見通しづらくなってきます。

一方、AIMLはCatalogという単位のタグの中にユーザーがどう発話したら、ボットがどう返すか定義します。このCatalogをたくさん定義して、シナリオを組み立てていきます。フローチャート同様、大規模になると見通しが悪くなります。

フローチャートとAIMLは排他的なものではなく、相互に変換する仕組みを備えているサービスもあります。

## タスク推定
### テキスト分類

タスク推定ではユーザー発話を受けてあらかじめ定義済みの複数のタスクに振り分けます。ボットが受け入れるタスクが「スケジューラ起動」、「乗換案内」、「レストラン推薦」があったとして、キーワードマッチング、機械学習的な分類手法を用いてユーザー発話に近いタスクに振り分けます。タスクごとにユーザー発話との類似度（確信度）を計算しています。あらかじめしきい値などを設定しておいて、類似度がしきい値に満たなかったら、聞き直したりすることが有効だったりします。

テキスト分類のAPIとしてはWatson NLC（Natulal Language Classifier）などがあります。

## パラメータ抽出
### 固有表現抽出（エンティティ抽出）

テキスト分類をした結果、タスクによってはパラメータが必要になってきます。このパラメータはタスクによって異なります。レストラン推薦タスクであれば、 **地名** とか **ジャンル** を抽出しなければなりません。地名であっても、乗換案内のための **地名（駅名）** のように有限の場合は辞書をあらかじめ作っておこうとすれば作れますが、レストラン推薦のための **地名** であれば、あらかじめ辞書を用意することは現実的ではなくなってきます。そのため、発話文から、地名っぽい場所を特定しなければなりません。例えば、

* 「新宿で美味しいレストランありますか？」

とユーザー発話があれば、〜で、の前は **地名** の可能性が高いというような推定をして抽出することになるでしょう。このように、自然文からパラメータを抽出する固有表現抽出という技術が必要になってきます。

----
# 対話サービス提供事業者各社の対話サービスと特徴

上記まででボット対話の設計と、その技術について少し触れてきました。この先は具体的なサービスを紹介しつつ、そのサービスの場合の特徴や対話の設計について触れていくことにします。

なお、個別のサービスについては未検証のものもあります。

## NTTドコモ (docomo Developer support)

* url: https://dev.smt.docomo.ne.jp/?p=docs.api.index&ref=toppage_service_secton

NTTドコモには開発者が気軽に使える対話APIが用意されています。これらのAPIは基本的には学習済みのモデルを呼び出します。そのため、シナリオを追加したりすることはできませんが、ボット対話を設計する際の考え方は参考になるので最初にご紹介します。

### docomo Developer support の対話サービス（API）

ドコモが提供している代表的な対話APIは以下のものがあります。

#### シナリオ対話API

フローチャートに沿った流れのある対話をしてくれます。

![flowchart.png](https://qiita-image-store.s3.amazonaws.com/0/5707/cc109fa0-bfa0-c70f-dcc1-bfc74f8d4703.png "flowchart.png")

> 画像引用： [dev.smt.docomo.ne.jp](https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=scenario_dialogue&p_name=api_usage_scenario)

ただし前述の通り、[定義済のはじめましてシナリオ、ニュース取得シナリオ](https://dev.smt.docomo.ne.jp/?p=common_page&p_name=scenario_sample_flowchart)のみにしか対応していないとのことです。そのため、実験的な位置づけになるでしょう。

#### シナリオ対話API (Repl-AI)

* url: https://repl-ai.jp

また、ドコモは有償になりますが、Repl-AIというサービスでもシナリオ対話の機能を提供しています。こちらを使うことでシナリオを作成することができます。

![authoring.png](https://qiita-image-store.s3.amazonaws.com/0/5707/b4653d96-2a8f-edd9-05d7-614156803d8f.png "authoring.png")

> 画像引用： [repl-ai.jp](https://repl-ai.jp/)

#### 発話理解API (意図理解)

要求を理解して、適切な機能を提示します。

![contents_7140522162331-1.jpg](https://qiita-image-store.s3.amazonaws.com/0/5707/c1669fb9-8c77-fa57-a1d0-75c532a96875.jpeg "contents_7140522162331-1.jpg")

> 画像引用： [dev.smt.docomo.ne.jp](https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=speech_understanding&p_name=api_usage_scenario#tag01)

こちらは定義済のタスクのみ実行できます。

乗換案内、グルメ検索、スケジュール登録などといった、スマートフォンの操作などを行うタスクなどが事前に定義されています。
定義済タスクは[こちら](https://dev.smt.docomo.ne.jp/?p=docs.api.page&api_name=speech_understanding&p_name=api_1#tag01)から確認することができます。

#### （参考）雑談対話API

ボットとの雑談ができます。

おそらくドコモのDeveloper supportの中で一番使われている対話APIだと思います。シンプルなので使いやすく、どんな対話にもボットがそれっぽい返答することが出来ますが、ボットの返答がコントロールできないので業務では扱うのが難しいです。使うとすれば雑談自体が目的になる場合や、ユーザーがボットとの対話を脱線させたときに雑談を挟むというような限定的な使い方になるような気がします。

### docomoを使った対話設計

docomo Developer supportを使った対話はシナリオを新規で作成できないので、発話理解中心の定義済みタスク実行の対話設計中心になります。

ただし、NTTドコモは「しゃべってコンシェル」で利用されている言語解析技術にもとづき、自然な対話を実現することができるエンジンを有償で提供しています。

* [自然対話エンジン | NTTドコモ](http://www.docomo.biz/html/service/ito_asp/)

![img_06.jpg](https://qiita-image-store.s3.amazonaws.com/0/5707/2c674e37-9c0a-228e-c030-f9ea58956be5.jpeg "img_06.jpg")
> 画像引用： [www.docomo.biz](http://www.docomo.biz/html/service/ito_asp/)

自然対話エンジンを使うことで、ユーザー発話から意図理解をしてタスクを実行することができます。タスクはDeveloper supportと異なり、定義済のタスクだけでなく、オリジナルのタスクを作ることができます。例えば、ショッピングモール内の施設案内などのタスクを定義し、対話で実行することができます。

## IBM Watson

* url: http://www.ibm.com/smarterplanet/jp/ja/ibmwatson/developercloud/conversation.html

IBM Watsonは自然言語分類のNatural Language Classifierを始めとして、様々な自然言語処理技術を提供しています。
その中でも対話を作成するためにはConversationを使うことで対話を作成することができます。

Watson Conversationを使って対話を設計する事ができます。ConversationはGUIベースのフローチャートで対話を設計できます。
以下の3つの概念があります。

* Intent
* Entity
* Dialog

ユーザー発話の意図を Intent、抽出したいキーワードを Entity と呼びます。Dialogは対話シナリオを定義することができます。

Conversationの特徴の一つとして、Intent推定（タスク推定）を行う際、Watson NLCの高いテキスト分類の技術が利用可能であるということがあげられます。結果として、意図理解を高い精度で行うことができます。

## Microsoft LUIS (preview)

* url: https://azure.microsoft.com/ja-jp/services/cognitive-services/language-understanding-intelligent-service/

LUIS (Language Understanding Intelligent Service) は自然言語を解析するツールで、入力された文章の分類、およびキーワードの抽出を行うエンジンをGUIで作成できます。
[Cognitive Services](https://azure.microsoft.com/ja-jp/services/cognitive-services/)の中の一つで、ユーザーが入力したコマンドをアプリケーションが理解できるようにします。

ユーザー発話の意図を Intent、抽出したいキーワードを Entity と呼びます。文字列、日付など汎用的なものは、予めPre-Built Entityとして用意されています。

* Intent
* Entity

## Amazon Lex (preview)

* url: https://aws.amazon.com/jp/lex/

Amazon Lexは[Amazon AI](https://aws.amazon.com/jp/amazon-ai/)の内の一つで、音声やテキストを使用した会話型インターフェイスをさまざまなアプリケーションに構築するためのサービスです。Amazon Lexは現時点でプレビュー版であり、利用するためには申請して連絡を待つ必要があります。(2016/12/24時点)

![Diagrams_lex_bookhotel.png](https://qiita-image-store.s3.amazonaws.com/0/5707/0bd80e3d-ceb0-b54a-368f-1592fa44f12b.png "Diagrams_lex_bookhotel.png")
> 画像引用: [aws.amazon.com](https://aws.amazon.com/jp/lex/details/)

Amazon Lexは以下の概念で構成されています。

> * Intent(意図) – インテントはbotのユーザーが達成したいゴールを表す(飛行機のチケットを買う、アポイントメントを調整する、天気予報を取得する、等)
> * Utterance(発話) – 発話は、インテントを呼び出すために発声あるいはタイプされるフレーズ 。“ホテルを予約したい” 、 “花を注文したい” はシンプルな発話の例
> * Slots – 各スロットは、インテントを満たすためにユーザーが提供しなければならないデータの断片。旅行用botは、都市、州、空港などのスロットを持つ
> * Prompt – プロンプトは(slotに対して)インテントを満たすために必要なデータを提供するためのユーザーに尋ねる質問
> * Fulfillment – フルフィルメントは、ユーザーのインテントを実行するためのビジネスロジック。Lexは、 フルフィルメントのためにLamda ファンクションの利用をサポート
> 
> 引用： https://aws.amazon.com/jp/blogs/news/amazon-lex-build-conversational-voice-text-interfaces/

その他の、Amazon Lexの大きな特徴として、AWS プラットフォームとの組み込み統合があげられます。下図のように、意図理解した結果、オリジナルのタスクを定義する際にAWS Lambdaを利用できるのは大きなアドバンテージとなるでしょう。

![Diagrams_lex_messaging-platform-1.png](https://qiita-image-store.s3.amazonaws.com/0/5707/c762b027-75bc-e580-c47a-b32f2f397a96.png "Diagrams_lex_messaging-platform-1.png")
> 画像引用： [aws.amazon.com](https://aws.amazon.com/jp/lex/)

----
# まとめ

今回紹介したサービスをまとめると以下のとおりになります。

|  | NTT Docomo (dev) | NTT Docomo (自然対話エンジン) |  IBM Watson | MS LUIS | Amazon Lex |
|-----------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|:------------:|
| 意図理解 (タスク推定)    | △ | ◯ | ◯ | ◯ | ◯ |
| 意図理解 (スロットフィリング)    | △ | ◯ | ? | ◯ | ◯ |
| シナリオ対話 | △[^1] | ◯ | ◯ | ？ | ✕？ |
| 日本語      | ◯ | ◯ | ◯ | ◯ | ✕？ |

* 凡例
	* ◯： 可
	* △： 作成は不可
	* ✕： 不可

[^1]: 有料サービス[Repl-AI](https://repl-ai.jp/)を利用することでシナリオ対話の作成が可能

今回紹介した対話サービスの中でNTTドコモのdeveloper supportは学習済のAPIなので他の対話サービスと比べると少し扱いが異なりますが、他のサービスは対話設計の考え方がほぼ同じで、同等のことが同じようにできるようになってきています。

ただし、現実問題として、対話だけだとなかなか価値を出すのも難しいので、外部連携など、他のシステムとの連携を前提としなければ差別化も難しいのも事実です。また、今回取り上げたサービスもDocomo以外はほぼ今年に登場したものです。また、数ヶ月たてばより優れたサービスが出てきている可能性も高いです。

Facebookに買収された[wit.ai](https://wit.ai)や、Googleに買収された[api.ai](https://api.ai)もまた、さらには国内だとトランスコスモスと提携した[Reply.ai](https://reply.ai)からも目が離せません。これらも機会があれば紹介できればと思います。

----
# 参考資料
* [対話システム (自然言語処理シリーズ) : 中野 幹生, 駒谷 和範, 船越 孝太郎, 中野 有紀子, 奥村 学 : 本 : Amazon.co.jp](https://www.amazon.co.jp/dp/433902757X)
* [自然対話エンジン | サービス・ソリューション | ドコモビジネスオンライン | NTTドコモ](http://www.docomo.biz/html/service/ito_asp/)
* [LUIS (Language Understanding Intelligent Service) 日本語対応 ~ 解析エンジン作成＆利用方法 – 青い空の向こうへ](https://blogs.msdn.microsoft.com/bluesky/2016/09/21/luis-language-understanding-intelligent-service-japanese-available/)
* [LUIS (Language Understanding Intelligent Service) で天気情報 BOT を作ろう！&#91;日本語解析エンジン作成編&#93; - Qiita](http://qiita.com/annie/items/a7c8c18beb42930c8a4c)
* [Amazon Lex – 対話的音声＆テキストインターフェースを構築 | Amazon Web Services ブログ](https://aws.amazon.com/jp/blogs/news/amazon-lex-build-conversational-voice-text-interfaces/)
* [チャットボットを簡単に作れる！Watson Conversationの色々なTips（メモ） - Qiita](http://qiita.com/ishida330/items/ae7277598cd3e08fc3a2)