kun432's blog

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

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

Voiceflowでやってみるシチュエーショナルデザイン①柔軟性をもたせる

f:id:kun432:20200714012542p:plain

Alexa道場で紹介されていたシチュエーショナルデザインの話。これを実際にVoiceflowでやってみたいと思います。

シチュエーショナルデザインの日本語ドキュメントは以下にあります。

ポイントは以下の4つ。

  1. 柔軟性を持たせる: ユーザーが自分の言葉で話しかけても対応できること
  2. パーソナライズする: 対話を個人に合わせて最適化すること
  3. わかりやすくする: 階層型のメニューではなく、すべてのオプションをトップに配置すること
  4. 自然な会話にする: 一方的なコミュニケーションではなく、会話ができること

今回は「1. 柔軟性を持たせる: ユーザーが自分の言葉で話しかけても対応できること」をやってみましょう。

この記事は「Voiceflowでやってみるシチュエーショナルデザイン」シリーズの第1回の記事です。他の記事は以下にあります。よろしければあわせて読んでみてください。

第2回 第3回 Part1 第3回 Part2 第4回

さまざまな発話をインテントに一致させる

これはかんたんですね。サンプル発話を充実させるということですね。Choice Blockのサンプル発話をたくさん登録して、なるべく多くのバリエーションに対応するということです。ドキュメントにある「トリップランナー」を題材にやってみましょう。

f:id:kun432:20200713160521p:plain

過剰な応答に対応する/詳細を求める

上の例では「旅行に行きたい」というユーザのインテントを受け取るところで、色んなバリエーションを用意しただけです。実際にはここから、旅行プランを建てるのに必要な「時間(いつ)」「場所(どこ)」「目的(何をしに)」を順に聞いていくことになります。普通に考えるとこんな感じになります。

f:id:kun432:20200713163858p:plain

「時間(いつ)」「場所(どこ)」「目的(何をしに)」を取得するためにそれぞれのインテントを用意してスロットで取得するというのを順番にやっていく感じですね。

ただ、この形だと必ずこの会話の流れでしか動きません。例えば、ユーザが「次の金曜日に札幌でハイキングがしたい」「茅ヶ崎海岸付近にウィンドサーフィンしに行きたい」というような言い方の場合、すでに必要な情報が含まれています。同じことをもう一度ユーザに言わせるのは望ましくありませんよね。また、必要な情報が全て揃ってるとも限りません。

そこで、すべての言い方に対応できるようにしてみましょう。最初のChoice Blockで作ったplan_trip_intentを以下のようなサンプル発話で登録します。

f:id:kun432:20200713170252p:plain

f:id:kun432:20200713170303p:plain

「時間(いつ)」「場所(どこ)」「目的(何をしに)」をそれぞれスロットとして用意して、plan_trip_intentで全部受ける形です。ちょっと縦に長くなってしまいましたが、少なくともこれでどのパターンでも全て受け取れるはずです。あとはそれぞれのスロットの取得状況をチェックして分岐、足りないものを取得すればよいのですが、これを一つづつチェックするようなブロックを並べると結局最初と同じようなことになってしまいます。

そこでダイアログモデルを使います。Choice Blockの一番下にある、Slotsをクリックします。

f:id:kun432:20200713170948p:plain

先ほど作成したスロットが用意されています。とりあえずdestinationスロットをクリックしてみましょう。

f:id:kun432:20200713171647p:plain

destinationスロットがこのインテントを完了させるために必須かどうか、を設定することができます。これをオンにします。

f:id:kun432:20200713171634p:plain

destinationスロットがまだ取得できていない場合、Alexaがユーザに対してどのように聞くか?とそれに対するユーザのサンプル発話を入力します。Slot Confirmationは、スロットの値が取れたあとに確認するかどうかを指定します。今回はOFFにしておきましょう。

f:id:kun432:20200713175025p:plain

同様にして、dateとpurposeスロットも設定します。

f:id:kun432:20200713191420p:plain

f:id:kun432:20200713191431p:plain

最後にAlexaが確認するためのSpeak Blockを追加して、正しくスロットが取得できているか試してみましょう。

f:id:kun432:20200713192435p:plain

最初は、単に「旅行に行きたい」とだけ言ってみます。

f:id:kun432:20200713192811p:plain

はい、必要な情報を一通り取得するように問い合わせてますね。では、次にすべての情報が含まれている場合です。

f:id:kun432:20200713193107p:plain

はい、これなら一発ですべての情報が取れています。では、一部の情報だけが指定されている場合です。

f:id:kun432:20200713193255p:plain

足りないものだけ聞き返しています。このようにして、情報がすでに提供されている場合・足りない場合の両方に対応ができると、とてもスムーズかつ処理もシンプルに済みます。ただし、その分サンプル発話のバリエーションは増えると思いますので、色々工夫も必要ですね。

訂正を受け入れる

最初に話した時にやっぱりあとから変更したくなった場合に変更できるようにしてみましょう。ここはやり方も色々あると思いますが、最後に確認のところに変更用のインテントを追加するようにしてみます。

まず、最初にそのまま変更がない場合です。YesIntentからSpeak Blockにつなげてスキルを終了させます。

f:id:kun432:20200713202354p:plain

次に、変更です。日付を変更するためのfix_date_intentを用意します。

f:id:kun432:20200713213245p:plain

インテントのサンプル発話はこんな感じです。ここもダイアログモデルを使って、単に「日付を変更」と言われた場合と、「日付を指定して変更」の両方に対応できるようにします。dateスロットは必須にします。

f:id:kun432:20200713213405p:plain

日付が指定されていない場合のAlexaの発話とそれに対するユーザの発話を設定しておきます。

f:id:kun432:20200713213539p:plain

ちょっと見にくいですが、fix_date_intentから予約内容を伝えるSpeak Blockにつなげます。

f:id:kun432:20200713213929p:plain

テストしてみましょう。

f:id:kun432:20200713213109p:plain

はい、きちんと変更ができていますね。同じように行き先と目的を変更するためのインテントを追加すれば、どの変更にも対応できると思います。ちょっとブロックの場所をずらして見やすくするとこんな感じになると思います。

f:id:kun432:20200714000309p:plain

エラーに適切に対応する

この「エラー」というのは、インテントが全く想定外、ということではなくて、スロットが想定外ということですね。ダイアログモデルを使っている場合は「スロット検証」を使うとスロット値を特定の値に限定したりしてその場でチェックできるのですが、残念ながらVoiceflowのダイアログモデルではスロット検証に対応していません。したがって、ちょっとユーザにとっては不便なのですが、スロットが全部揃ったあとでチェックすることにしましょう。

ここでは場所が国内に限るという条件を、シンプルに「カタカナが含まれていない」というチェックで追加してみたいと思います。plan_trip_intentのChoice Blockと確認のSpeak Blockの線を一旦外して少し離してください。

f:id:kun432:20200714000837p:plain

カタカナが含まれているかどうかをCode Blockでチェックします。Code BlockのFailureは本来はプログラム実行上のエラーの場合なのですが、destinationスロットにカタカナが含まれていれば throw new Error();で意図的にエラーを起こすことで分岐させるようにします。

f:id:kun432:20200714001736p:plain

エラーが起きない(Success)場合は、destinationにカタカナが含まれていない、つまり「国内」ということになるのでそのまま元のSpeak Blockにつなげます。エラーが起きた場合(Failure)は「国外」になるので、Speak Blockでそれを説明して、もう一度destinationを聞き直すためのChoice Blockにつなげます。

f:id:kun432:20200714001619p:plain

Choice Blockでdestinationを再度取得するためのインテントはこんな感じです。

f:id:kun432:20200714001819p:plain

destinationを取得し直したあとも再度チェックは必要なので、そこからCode Blockにつなげておきます。

f:id:kun432:20200714002030p:plain

同様に、ユーザが目的地を訂正した場合のインテントでチェックを通す必要があるので、こちらの線もCode Blockにつなぎ直します。

f:id:kun432:20200714002408p:plain

ではテストしてみましょう。

f:id:kun432:20200714002717p:plain

はい、チェックができていますね。何がエラーになっていて、ユーザにどう言ってほしいのかをきちんと説明できています。

Alexaが理解できない場合のデザイン

ここは想定外の発話ですね。ダイアログモデルを使っているので、例にあるような、

ユーザー: 「アレクサ、トリッププランナーを開いて」
Alexa: 「どこに行きたいですか?」
ユーザー: 「乗馬しに行きたい」
(「乗馬」はサポートする都市に含まれていないことをスキルが検知)
Alexa: 「理解できませんでした。どの都市に行きたいですか?」

だとしても、行きたい「場所」ではなく「目的」として取ってくれます。なので、ここでは最初のインテントで想定していないようなインテントが呼ばれた場合にしてみましょう。

plan_trip_intentのChoice BlockのElseを以下のように設定します。

f:id:kun432:20200714004321p:plain

これでユーザが関係ない事を言った場合でも、旅行プランを建てるきっかけとなる発話をAlexaが促すことで会話を続けることができますね。

f:id:kun432:20200714010601p:plain

Alexaが理解できても対応できない場合のデザイン

ひとつ上とも絡みますが、「わかりません」「理解できません」というよりも「サポートしていません」という方が、少なくとも理解はしているということがユーザに伝わります。したがって、これは、スキルがすでに使われていて、ある程度そういう要望があるけどまだサポートできていないという前提になります。開発者コンソールで「インテント履歴」をチェックして、実装していないけどよく言われているサンプル発話などがあれば、未サポートであることを伝えるインテントを用意しておけばよいと思います。

f:id:kun432:20200714005240p:plain

unsupported_intentを用意して、「ホテルを予約して」「タクシーを予約して」などと言われた場合には、それが未サポートであることを伝えると同時に、今できることを伝えてユーザに発話を促すような感じですね。

f:id:kun432:20200714010341p:plain

ユーザーが応答しないときに再プロンプトを出す

ユーザーが一定時間内に応答しないとき、つまりどうしていいかわからないということが考えられるわけですね。その場合にはAlexaが再度発話してユーザへの再プロンプトを促しますが、ここで具体的にユーザに対して、できることやどうすればできるか?を説明してあげると、スムーズにユーザの発話を引き出すことができます。

VoiceflowではChoice Blockで再プロンプトを設定することができます。plan_trip_intentのChoice Blockでやってみましょう。

Choice Blockをクリックし、設定の一番下にある"…"をクリックします。"Add No Reply Response"というのが表示されますので、これをクリックします。

f:id:kun432:20200714005854p:plain

No Reply Responseが設定画面に追加されるのでこれをクリックします。

f:id:kun432:20200714010141p:plain

応答がない場合のAlexaの発話を設定します。

f:id:kun432:20200714010154p:plain

これはシミュレータではできないため、サンプルはありません。ご了承ください。

コンテキストに合ったヘルプを提供する

ユーザが発話するタイミングでコンテキストが異なることがよくあります。その場合、ユーザが発話するヘルプも意味が変わってくるわけですね。それに合わせてヘルプも変えましょう、ということです。これは以前ご紹介しているので、詳細はそちらをご覧ください。


はい、ということでシチュエーショナルデザインの第1回「柔軟性を持たせる: ユーザーが自分の言葉で話しかけても対応できること」でした。いろいろなユーザの発話に対応しようと思うと結構大変ですが、ダイアログモデルなどをうまく活用して、柔軟なスキルを目指しましょう!

次回は「2. パーソナライズする: 対話を個人に合わせて最適化すること」です。

続きはこちら