kun432's blog

Alexaなどスマートスピーカーの話題中心に、Voiceflowの日本語情報を発信してます。たまにAWSやkubernetesなど。

〜スマートスピーカーやVoiceflowの記事は右メニューのカテゴリからどうぞ。〜

Voiceflowにおける会話のコンテキストを考える ⑤過剰なスロット

f:id:kun432:20200724191613p:plain

「Voiceflowにおける会話のコンテキストを考える」シリーズの第5回です。今回は「過剰なスロット」です。

この記事は「Voiceflowにおける会話のコンテキストを考える 」シリーズの第5回の記事です。他の記事は以下にあります。よろしければあわせて読んでみてください。

第1回 第2回 第3回 第4回 第5回(この記事) 第6回

目次

過剰なスロットとは?

以前に「シチュエーショナルデザイン」の第1回でご紹介したトリッププランナーを題材に説明します。

kun432.hatenablog.com

「トリッププランナー」は旅行の「プラン」を作るのを手伝ってくれるスキルです。そのために、ユーザから以下の情報をスロットで取得します。

  • 目的地(どこに行くか?)
  • 日時(いつ行くか?)
  • 目的(何をしに行くか?)

「トリッププランナー」ではこれらのスロットはすべて「必須の」となっていました。複数の必須となるスロットをすべて取得するためには「ダイアログモデル」を使うのが一番効率がよかったですよね。

ただし、目的が単純に航空券の手配だけを行うスキルだとするどうでしょう?「目的地」と「日時」は必須ですが、「目的」は必須というわけでもないですよね。つまり「目的地」と「日時」だけで事足りるわけです。

ということで、「トリッププランナー」を少し簡略化した「エアーチケット」というデモスキルを作ってみました。

f:id:kun432:20201220022124p:plain

場所と日時を尋ねるChoice Blockは以下の通りとなっており、「目的地」と「日時」は両方とも必須になっています。

f:id:kun432:20201220022430p:plain

なので、どちらか片方しかユーザが言わなかった場合はそれぞれを取得するための発話を行い、両方のスロットが埋まったら、次のSpeak Blockに進むようになります。

f:id:kun432:20201220022558p:plain

f:id:kun432:20201220022607p:plain

実際にどうなるかを見てみましょう。まず、「目的地」と「日時」が両方とも発話に含まれている場合。

f:id:kun432:20201220023101p:plain

次に、「目的地」だけの場合。

f:id:kun432:20201220023108p:plain

最後に、「日時」だけの場合。

f:id:kun432:20201220023119p:plain

どの場合も正しくすべてのスロットが揃ってから次のフローに流れていますね。

ただし、ユーザが想定以上のことを言ってきた場合はどうなるでしょうか?例えばこんな感じです。

f:id:kun432:20201220084917p:plain

航空券の予約に必要ではない「目的」をユーザは言ってきましたが、スロットを用意していないので予約完了時のメッセージでそれには触れていません。スキルの目的としては必要はないとはいうものの、ユーザからすると少し無視されたと感じるかもしれませんね。

では「トリッププランナー」と同じように「必須スロット」として追加すべきでしょうか?繰り返しになりますが、スキルの目的である航空券の予約としては必要ではありません。必須でない情報を必須として「すべて」のユーザに発話を強いるというのも変な話ですし、言いたくないことにまで踏み込まれたと考えるユーザもいるかもしれませんね。

そんな場合は、この「目的」スロットを「オプション」として取得するということができます。

「オプション」としてスロットを受け取る

「オプション」としてスロットを受け取る、というのは、単純に言うと「必須にしない」ということです。

f:id:kun432:20201220082514p:plain

ダイアログモデルでは、「必須」スロットが設定されている場合、必ずそのスロット値が取得できるように追加で対話が行われます。逆に「必須ではない」スロットの場合は、ユーザの発話にスロット値が含まれていれば拾いますが、なかったとしてもスルーします。

ではやってみましょう。「目的」を取得するpurposeスロットを使ったサンプル発話を追加します。

f:id:kun432:20201220173510p:plain

purposeスロットは「トリップランナー」のものを流用します。こんな感じです。

f:id:kun432:20201220173700p:plain

で、purposeスロットは「必須」にはせずにそのままにします。

f:id:kun432:20201220173854p:plain

Choice BlockからSpeak Blockにつながっている線を一旦外して、Condition Blockをつなげて以下のような条件を設定します。

f:id:kun432:20201220174750p:plain

{purpose}スロットが0なら、発話の中に「目的」が含まれていなかったということになりますので、もともとあったSpeak Blockにつなげます。

f:id:kun432:20201220175025p:plain

0以外の場合は何かしらの「目的」が含まれていたということになりますので、{purpose}の値に基づいて、発話内容を変えるように分岐します。

f:id:kun432:20201220175227p:plain

あと、これは少しおまけですが、Voiceflowのスロットは永続的な変数として扱われます。「必須」スロットであれば毎回上書きされますが、「必須ではない」スロットの場合は発話に含まれていない場合は上書きされることがないため、前のセッションの情報がそのまま残っている場合があります。そこで会話の最初でSet Blockを使って初期化しておきます。

f:id:kun432:20201220175526p:plain

ではテストしてみましょう。まず目的がない場合。

f:id:kun432:20201220180916p:plain

次に目的が含まれている場合です。

f:id:kun432:20201220180952p:plain

f:id:kun432:20201220181002p:plain

スロットの有無というコンテキストの違いで会話が変化しているのがわかりますね。

このようにスキルとしては必須ではない情報をユーザが過剰に提供してくる場合、その情報が必須でなかったとしても、うまく利用することで、ユーザに対してパーソナライズ感や親密感を与えることができますし、会話フローの後半でそれが「必須」になった場合でも再度問い合わせる必要がなくなります。また必須ではないので、ユーザが発話しなかった場合には余計に聞かないというのも重要です。

まとめ

いかがでしたか?実際には、ユーザがどういうふうに発話するか?というところで、普通は必須のものをきちんと取得するための「言い方」を促すのが普通だと思いますし、最初からこういった設計するのは難しいと思います。ただ、実際にいろんな会話パターンでテストしてみてこういうのを見つけたら、必須ではないということで切り捨てずに何かしら生かせないか?というふうに考えれれば、きっとユーザにとっても想定していなかった驚きや楽しい体験を与えることができるのではないかと思います。

次回は「コンテキストを考える」シリーズの最終回、「環境コンテキスト」です。

続きはこちら