こんにちはAIチームの友松です。本記事はAI Shift Advent Calendar 2021の23日目の記事です。
今回はDialogFlow Essentials(ES)についての基本的な動作の解説を行いたいと思います。
DialogFlowはGoogleが提供する対話エンジンとなっており、Slackやスマートスピーカーなど、様々なチャネルへ接続可能となっております。
また、こちらの記事は連載予定で年明けにFulfillmentを用いた動的なメッセージ作成についても記事を書こうと思っております。
基本動作の解説
まずは、基本的な動作を理解するために、インテント, コンテキスト, エンティティの概念について説明します。
インテント
インテントは対話の状態遷移とシステム発話を制御する仕組みです。

各インテントにはOutput Contextというものを設定することができ、そのインテントを経由すると設定されたコンテキストが付与されます。コンテキストには生存期間(lifespan)を設定することができ、何ターン先までそのコンテキストを持ち続けるかと言うのを制御することができます。
このコンテキストが対話の状態遷移における"状態"を表す役割を担っており、今までの会話を通した現在の状態がコンテキストの集合によって表されます。
対話の状態遷移は現在の状態(コンテキストの集合)と行動(ユーザ発話)によって決まります。
- 現在の状態(state): 現在どんなコンテキストを保持しているか
- 行動(action): ユーザの発話とTrainingPhraseとの一致度(確信度)
各インテントにはInput ContextとTraining Phraseというのを設定することができます。Input ContextではこのIntentに遷移するために必要なコンテキストを、Training Phraseにはユーザ発話として期待される文章を入力します。
また、特殊なインテントとして、Fallback Intentというのを設定することができ、Input Contextと現在の状態が一致するが、Training Phraseによる遷移先が見つからなかったときにこのFallback Intentに遷移します。
具体的に上図で示した対話遷移を行う、簡単なDialogFlowの設定を行ってみます。
1. Welcome Intent

- インテント名: Welcome Intent
- Input Context: なし
- Output Context: Confirmation(生存期間: 1ターン)
- Training Phrase: こんにちは
- Text Response: こんにちは、私と会話を希望ですか?はい、か、いいえでお答えください
こちらのインテントでは、Input Contextを持たないため、どんな状態からも遷移可能なインテントとなっており、ユーザが「こんにちは」と言うとこのインテントが抽出されます。

DialogFlow上のチャット画面で"こんにちは"というとこのように先程指定したレスポンスメッセージが返ってきたり、コンテキストやインテントの項目が入力したものになっています。
2. Yes Intent

- インテント名: Yes Intent
- Input Context: Confirmation
- Output Context: なし
- Training Phrase: はい
- Text Response: ありがとうございます!どんな話をしましょう!
こちらのインテントはConfirmationというコンテキストをもっていて、ユーザが「はい」と言うとこのインテントが抽出されます。

3. No Intent

- インテント名: No Intent
- Input Context: Confirmation
- Output Context: なし
- Training Phrase: いいえ
- Text Response: またの機会にお話しましょう!
こちらのインテントはConfirmationというコンテキストをもっていて、ユーザが「いいえ」と言うとこのインテントが抽出されます。

4. Fallback Intent

- インテント名: Fallback Intent
- Input Context: Confirmation
- Output Context: なし
- Training Phrase: なし
- Text Response: またの機会にお話しましょう!
Fallback Intentは通常のIntentとは作り方が違い、以下の図のようなCreate Fallback Intentを選択することにより作成できます。

今回の例だとConfirmationというコンテキストを保持しており、「はい」, 「いいえ」以外の発話がされたときにこちらのインテントが検出されます。

エンティティ
先程までのインテントとコンテキストの例により、定型文による状態遷移を作るための方法を紹介しました。
"タスク指向対話"と呼ばれる対話においては、ユーザの発話から特定のキーワードを抽出したいというニーズがあります。そこで登場するのがエンティティです。
エンティティは、対話の中で抽出したい辞書のようなものを構築します。
例えばユーザが「渋谷で予約をしたい」と発話したときに"場所=渋谷"という、key, valueで抽出したいシーンが合ったときに、事前に用意した場所のリストのどれに一致するかというのをエンティティとして定義することができます。
このような場合には、placeエンティティを用意して、エンティティの要素として['渋谷', '新宿', '原宿']と用意した場合、この3つのどれかに一致するようなユーザ発話をキャッチすることができます。

このような自前でエンティティのパターンを用意する方式をカスタムエンティティと呼びます。
カスタムエンティティには、上記のような辞書を構築する形式や、正規表現でパターンマッチングする形式が存在します。
システムエンティティ
よく使われるエンティティに関しては、DialogFlow側で事前に用意されており、システムエンティティと呼びます。
例えば、@sys.date-timeで日時に関するユーザ発話をキャッチしたり、@sys.nameで名前に関するユーザ発話をキャッチすることができます。
システムエンティティのリファレンスはこちらを参照ください。
カスタムエンティティを用いてユーザ発話から特定のキーワードを抜き出すシナリオを設計してみます。

Welcome Intent2やFallback Intent2については先程解説した流れと同じになるためPlace Intentのみご紹介します。

- インテント名: Place Intent
- Input Context: RequestPlace
- Output Context: なし
- Training Phrase: 渋谷です
- Action and Parameters: 渋谷 -> place
- Text Response: $placeですね!いいところですよね!
まず、Training Phraseの部分に注目してください。
"渋谷"の部分が色が変わっています。そして、Action and Parametersでエンティティがplaceというアノテーションがされています。
これによって、先程作成したplaceエンティティのどの項目が発話されても拾うことができます。
- 渋谷です
- 新宿です
- 原宿です
また、Text Resopnseで$placeのように抽出したエンティティをレスポンスに含めることができます。



エンティティを使用することで、キーワードとして抽出したい箇所を確実に抽出することができるので、応答文に使用したり、次回紹介させていただく、Fulfillmentを利用した動的なメッセージ生成では、APIやDB照会の値として使うことも可能になり対話の幅が一気に広がります。
まとめ
今回はDialogFlowのインテント、コンテキスト、エンティティの基本的な概念についての解説を行いました。次回はFulfillmentという機能を使って、より複雑な応答生成やデータベース照会などで動的にメッセージを変更する方法について書こうと思います。
明日はAI Shiiftに内定者バイトに来てくれている大場くんのブログが出る予定となっています。
終わりに
AI Shiftも所属する株式会社サイバーエージェント AI事業本部では、
サーバーサイド/ML・DS志望の23~24卒以降の学生の方を対象に3Dayインターンシップの~広告自動生成コンペ "極"~を開催予定です。
本コンペに興味のある方、是非下記よりご応募ください!
https://www.cyberagent.co.jp/careers/students/event/detail/id=26886