kun432's blog

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

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

Voiceflow TIPS #8 いろんなランダム

Voiceflow夏休みAdvent Calendar、遅ればせながら8日目の穴埋めです。

5日目で「重複しないランダムな数字を取得したい」方法をご紹介しました。何かしらのランダムな処理を行いたい場合は、他にも色々方法がありますので、ご紹介します。


Random Block

Random Blockはこんな感じで初期状態だと分岐がない状態です"Add Path"をクリックします。

f:id:kun432:20190812111152p:plain

すると2つに分岐します。どんどん"Add Path"を追加します。

f:id:kun432:20190812111329p:plain

こんな感じで分岐がどんどん増えていきます。

f:id:kun432:20190812111428p:plain

それぞれにSpeak Blockをつなげます。メッセージはこういうふうにそれぞれの分岐で数字を変えておきます。

f:id:kun432:20190812112153p:plain

Interactionを使って、繰り返すかの確認を追加します。「はい」の場合は再度Random Blockに戻るようにします。

f:id:kun432:20190812112400p:plain

ではテストしてみます。

f:id:kun432:20190812112906p:plain

数字がランダムに並んでいるのがわかるかと思います。ただ、重複してる箇所がいくつかありますね。重複しないようにするには、Random Blockにある"No Duplicates"にチェックを入れます。

f:id:kun432:20190812113049p:plain

再度テストしてみます。

f:id:kun432:20190812113342p:plain

今回は分岐を5つ用意したので、最初の5回で重複していないことがわかりますでしょうか?一巡すると再度また繰り返しになり次の5回でも重複していませんね。

こんな感じで、Random Blockはシンプルに分岐だけを作るためのブロックになっています。特に変数も使わずに喋らせる内容をランダムにすることができます。

ただし、喋らせる内容だけをランダムにするならSpeak Blockだけでできます。

Speak Block

Speak Blockの一番下にある"Output Random Entry"にチェックを入れると、"Add Speech"や"Add Audio"で追加したそれぞれをランダムで発話/再生させることができます。

f:id:kun432:20190812114728p:plain

めちゃめちゃブロックとしてはシンプルになります。ただしこの場合は、重複しないようにすることはできません。

Random Block+変数

最初の2つの例は、どちらも変数を使わずに、Speakで発話させる内容を直接変えていました。シンプルでわかりやすいのですが、そこから応用を効かせることはできません。そこでRandom Blockに変数を組み合わせて、少し応用の幅を持たせてみましょう。

変数を作成します。

f:id:kun432:20190812120008p:plain

RandomのあとにSet Blockをおいて、変数をそれぞれセットします。

f:id:kun432:20190812120038p:plain

Speak Blockをつなげて、変数を発話で喋らせます。

f:id:kun432:20190812120114p:plain

この方法だと、変数を別の目的で使うことも可能ですねー。


ユースケースに合わせて最適な方法を選択すればよいかと思いますが、色々やり方があって迷うかもしれませんね。個人的に考えるユースケースはこんな感じかなぁと思います。

  • Speak Block
    • ランダムの数が少ない場合
    • 発話のバリエーションを増やすだけで、複雑な判断が不要で、重複しても問題ない場合
    • 例えば、いつも同じ挨拶ばかりだとロボットっぽくなるので「こんにちは」「お元気ですか」みたいに同じ意味だけど言い方だけを変えたい場合など
  • Random Block
    • ランダムの数が少ない場合
    • 発話の内容を変えたい場合、複雑な判断は不要だけど、重複チェックがほしい場合
    • 例えば、豆知識みたいに話す内容そのものを変えたい場合など
  • Random Block+変数
    • ランダムの数が少ない場合
    • 発話内容以外にも変えたい場合、複雑な判断は不要だけど、重複チェックがほしい場合
    • 発話以外の用途でランダム性を活かしたい場合
    • 例えば、足し算などの問題をランダムに作る場合など
  • TIPS #5のCode Block
    • ランダムの数が多い場合
    • ランダム性をいろんな処理に応用したい場合、複雑な判断を行いたい場合、重複チェックもほしい場合
    • 例えば、Integration BlockでGoogleスプレッドシートからのデータ取得をランダムかつ重複なしでやりたい場合

数が少ないうちやVoiceflowに慣れてないうちは、Random Blockなどを使うほうがわかりやすくて楽かもしれません。ただし、数が増えてきたり複雑な処理をやる場合には、今回ご紹介したやり方は徐々に辛くなっていくので、ケースバイケースで使い分けていただければと思います。

Voiceflow TIPS #11 文脈に応じたヘルプインテント

Voiceflow夏休みAdvent Calendarの11日目です。

前回に引き続き、Voiceflowのヘルプについて、少し面白い使い方をやってみたいと思います。


前回のVoiceflowのヘルプインテント説明したとおり、Voiceflowのヘルプは、Flowを使っているので、「ヘルプ」を言ったタイミング(ただしくはその少し前)に戻ってきます。

f:id:kun432:20190811164058p:plain

文脈の流れを途切れさせることなく、ヘルプが動くということですね。であれば、文脈に応じてヘルプのメッセージを変えるとより人間らしくなりますよね?こんな感じのイメージです。

f:id:kun432:20190811164519p:plain

今日はこれをやってみたいと思います。


スキルの全体図

全体図はこんな感じです。前回のフローをベースに、赤枠のところを追加してます。

f:id:kun432:20190811172207p:plain

ヘルプはこんな感じ。コンバインブロックになっていたのを分解して、If Blockで分岐させてます。

f:id:kun432:20190811172148p:plain

では順に見ていきます。

メインのフロー

今回追加したところだけ説明します。それ以外のところは前回のエントリを参考にしてください。(画面キャプチャを追加しておきました!)

基本的な考え方としては、今どの文脈にいるか?を管理するために、ROOTフロー側で変数を用意して、ヘルプに行く前に文脈を表す変数をセット、ヘルプの中ではその変数を参照して分岐する、という形です。そこで再度、Voiceflowのヘルプインテント で説明したことを思い出してください。

抜粋します。

  • Flow Blockの中でしか使えないフロー変数を定義できる。他のFlow Block(ROOTフローも含めて)からも見えない。
  • ROOTフローで作成したプロジェクト変数は、グローバル変数となり、どこからでも読み書きできる。
  • ROOTフローで作成したプロジェクト変数は、永続扱いとなり、セッションを跨いでも維持される。
  • ROOTフローとFlow Blockでフロー変数の受け渡しができる

ヘルプはFlowになっています。なので、ROOTフロー内の変数の受け渡しは、グローバルであるプロジェクト変数にするか、Flowに変数を渡す必要があります。が、デフォルトで用意されているヘルプフローは変数の受け渡しができません。となると、プロジェクト変数で管理するしかありません。

また、プロジェクト変数の場合、永続扱いになります。つまりセッションをまたいでも保持されてしまいます。今回のケースでは、1セッションの中だけで管理すれば良いものなので、セッションをまたいで保持されると想定外のケースが起きる可能性もあります。その場合にはスキル起動時に初期化する必要があります。

前振りが長くなってしまいましたが、上記の点を抑えて、フローを変更していきましょう。

1. 文脈を管理するプロジェクト変数の作成

プロジェクト変数を作成します。ここでは"context"という名前にしました。ユーザの好きな色と数字を保持しておくためのフロー変数"favColor"、”favNumber”と別にプロジェクト変数として作成されているのがわかりますね。

f:id:kun432:20190811180045p:plain

2. プロジェクト変数の初期化

Homeと最初のSpeakの間に一つSet Blockを追加します。ここで”Context”を一旦初期化します。セットする値はなんでもいいんですけど、とりあえず”NONE”という値を入れておくようにしました。

f:id:kun432:20190811180541p:plain

3. 「色」の話の文脈をセット

最初のSpeakとCaptureが、ユーザの好きな「色」の話の「文脈」になりますので、この間に一つSet Blockを追加して”Context”にそれをセットします。ここでは”ASK_COLOR”という値を入れておくようにしました。

f:id:kun432:20190811181339p:plain

4. 「数字」の話の文脈をセット

上と同様にして、2番めのSpeakとCaptureが、ユーザの好きな「数字」の話の「文脈」になるので、ここにも一つSet Blockを追加して”Context”に”ASK_NUMBER”という値を入れるようにします。

f:id:kun432:20190811181137p:plain

メインのフローはこれで終わりです。ヘルプに行きましょう。

ヘルプ

最初にお伝えしたとおり、ここは一旦コンバインブロックになっているのを分解してから直していきます。

1. どの文脈から来たかをチェックして分岐

If Blockで”Context”の中身をチェックして、分岐させます。"Context"はプロジェクト変数なのでフローの中かららでも参照できます。"ASK_COLOR"なら色の文脈ということで1へ、"ASK_COLOR"なら数字の文脈ということで2へ、それ以外はElseというふうに分岐します。

f:id:kun432:20190811182035p:plain

2. 分岐に応じたメッセージの設定

あとは、分岐に応じてメッセージを変えるだけです。

f:id:kun432:20190811182620j:plain

f:id:kun432:20190811182633j:plain

f:id:kun432:20190811182643j:plain

テスト

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

f:id:kun432:20190811183030p:plain

こんな感じで文脈に応じて、ヘルプの内容が変わっているがわかりますでしょうか?ユーザがどうすればいいかわからないタイミングに応じて、適切なヘルプを返せるようにすると面白いですね。

おまけ

ただ、ちょっといちいち「続けますか?」って確認するのウザいですね。ヘルプフローのChoiceとExitは取ってしまいましょう。併せて3つのSpeak Blockから「続けますか?」という部分もカットして、代わりに少し無音を入れてみます。

f:id:kun432:20190811190042p:plain

で再度テスト。

f:id:kun432:20190811190403p:plain

自然な感じになりましたね。

Exitしなければ元の場所に戻るというFlowの特徴を逆手に取るとこういうこともできます。ただし、ブロックの並べ方によっては戻る場所が適切でない・自然な会話にならない可能性もあると思うので、そのあたりは事前に検証してみることをおすすめします。

おまけ その2

メインのフロー、ブロックが増えちゃって見づらくなりましたね。一方通行のフローなので、こういう場合はコンバインブロックを使ってまとめましょう。ブロックの上にブロックをドラッグアンドドロップすればOKです。

f:id:kun432:20190811191128p:plain

コンバインブロックを右クリックすると名前の変更ができます。

非常にスッキリしますね!

まとめ

ということで、地味だけど奥が深いヘルプの話を2回に分けて説明しました。参考になれば幸いです。

Voiceflow TIPS #10 Voiceflowのヘルプインテント

Voiceflow夏休みAdvent Calendarの10日目です。8日目はあとから・・・

今日は、Voiceflowのヘルプの挙動をご紹介します。


Alexaスキルを公開された方ならわかると思うのですが、スキルの申請にはヘルプインテントを用意する必要があります。Voiceflowでも、予めデフォルトでヘルプインテントがFlowとして用意されています。

f:id:kun432:20190811010758p:plain

Help Flowの中身はこんな感じになってます。

f:id:kun432:20190811011706p:plain

少しブロックの中身を見てみましょう。

ところで、Help Messageのところ、Homeと同じような感じになっていますね、よく見ると中に2つの四角(Continuous MessageとChoice)があることがわかります。これ、どちらでもよいので、ドラッグ&ドロップして別の場所に動かしてみてください。こうなります。

f:id:kun432:20190811012321p:plain

別々のブロックに別れましたね?Voiceflowでは複数のブロックをくっつけて一つの大きなブロックにまとめることができます。これを「コンバインブロック」といいます。このコンバインブロック、Continuous MessageというSpeak BlockとChoice Blockを一つにまとめたブロックになっていたというわけですね。ブロックが多くなってくると、どのブロックで何をしていたかもわかりにくくなるし、線も多数重なったりして、非常に見にくくなるので、こうやってまとめるとスッキリしますね。もちろん今やったようにまとめたものを再度分割してもとに戻すこともできます。

あと、もう一つ、今分割したContinous MessageとChoice、線でつながっていないですね?

f:id:kun432:20190811013020p:plain

もちろんこれつながってないと動作しないのですけど、コンバインブロックとして一つにまとめると、上から順に実行されます。つまり、複数のブロックをまとめた場合には、内部的に線が引かれた状態になるということです。

なので、例えば、

f:id:kun432:20190811013445p:plain

これ、5個のブロックが一つにまとめられている形で上から順に実行されます。普通に同じことを通常のブロックでやろうとすると、ブロックを5個並べて、全てを線で繋げないといけないので、とても楽ちんですね。

ただし、制約もあります。

  • コンバインブロックの中では、一方通行になりますので、If BlockやChoice Blockなどの「分岐」が発生するブロックを途中に置くことはできず、一番最後にしか置けません。
  • Code BlockやIntegration Blockも分岐のように見えますが、実際は分岐ではなく、正常に動作しない場合のみの挙動になりますので、途中に置くことができます。ただし、その場合、エラー処理が一切ないのと同じことになります。
  • CaptureやInteractionなど、ユーザの発話が発生するものも途中には置けません。

まあこのあたりは実際に触ってみるとわかるのではないかと思います。

話が少し脱線しましたが、ヘルプブロックの中身の話に戻りましょう。ヘルプブロックはSpeak BlockとChoice Blockで構成されています。まず、Speak Block。

f:id:kun432:20190811015803p:plain

サンプルのメッセージなので、実際にはここを書き換えるわけです。ただ後半部分に「続けますか?」と書いてあります。これってどういうことでしょう?

さらに、Choice Block。

f:id:kun432:20190811015820p:plain

これ、「はい」「いいえ」の分岐になっています。「続けますか?」と聞かれて「はい」「いいえ」で答える流れですね。「いいえ」の場合は、Exit Blockというスキルを終了するためのブロックに飛びます。質問と回答としてはあっているように思えますが、この後ってどうなるのでしょうか?

それを理解するには少しサンプルを作ってみます。スキルの挙動としてはこんな感じです。

アレクサ、ヘルプテストをひらいて

ヘルプテストです。好きな色を言ってください。

次に好きな数字を言ってください。

24

あなたの好きな色は「赤」で、好きな数字は「24」ですね、へぇー

いい例じゃなくて申し訳ないですが、これをフローにするとこうなります。順に見ていきます。

f:id:kun432:20190811020755p:plain

  1. 予めユーザからの発話を入れておく変数を用意しておきます。ここでは"favColor"、"favNumber"としました。 f:id:kun432:20190811170543p:plain

  2. 最初のSpeak Blockで好きな色を聞きます。 f:id:kun432:20190811165935p:plain

  3. Capture Blockで、ユーザの発話をAMAZON.Colorとして取得し、変数に入れます。 f:id:kun432:20190811170039p:plain

  4. 2番目のSpeak Blockで好きな数字を聞きます。 f:id:kun432:20190811170057p:plain

  5. Capture Blockで、ユーザの発話をAMAZON.Numberとして取得し、変数に入れます。 f:id:kun432:20190811170217p:plain

  6. 最後のSpeak Blockで、取得した変数をもとに結果を話します。

f:id:kun432:20190811170230p:plain

こんな感じですね。これに合わせてヘルプの文言も変更しておきましょう。

f:id:kun432:20190811021832p:plain

f:id:kun432:20190811021846p:plain

テストしてみます。

f:id:kun432:20190811022449p:plain

普通に動いてますね。では、途中で「ヘルプ」と言ってみます。

f:id:kun432:20190811022508p:plain

わかりますか?

ここで、以前のTIPSで紹介したFlow Block、を思い出してください。Flow Blockでは、ブロックを置いたところから別のフローにジャンプ、Flow内の処理が終わったらもとのところに戻って来るという仕組みです。そしてVoiceflowのヘルプはFlowを使って実現しています。つまり、Voiceflowのヘルプは、ヘルプの説明を行った後、ヘルプを呼び出した時点、厳密に言うと、ユーザ発話が発生する手前のブロックに戻ってくるのですね。だから「続けますか?」になっていたわけですね。

さらに、上の例だと、「色」を聞いたあとのヘルプでは、「色」を聞くところに戻ってくるし、「数字」を聞いたあとのヘルプでは、「数字」を聞くところに戻ってきていますね。会話の中で急に違う話をすると、「あれ?さっきまでなんの話してたんだっけ?」ってことは日常でもありがちですが、Voiceflowのヘルプではそういうことが起きにくいようになっているというわけです。図にするとこんな感じ。

f:id:kun432:20190811164058p:plain

非常に地味な感じなんですけど、これ、真面目にコードでやろうとすると、今会話のどこにいるか?という「状態管理」をしないといけなくて、かなり面倒なんですよね。それが特に意識することなく実現されていて、開発者としては文言を変えるぐらいだけで簡単にできてしまうのはほんとすごいなーと思いますね!

こういうところもVoiceflowは凄いよ、というのが今日のTIPSでした。


今回の話、何がすごいの、これ?と思われる方も結構いらっしゃると思うんですが、上記の挙動がいかに重要か?というところを次回、少し補足的に説明したいと思います。よろしければ次回もご覧ください!