kun432's blog

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

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

Alexaスキル「神戸あるある」をリリースしました

ちょっと遅くなりましたが、4月分のノルマとして、Alexaスキル「神戸あるある」をリリースしました。

神戸あるある

神戸あるある

内容としては、

  • 神戸市民ならではの「あるある」なネタを話してくれます。
  • それに対して、「あるある」「ないない」で答えると、あなたの神戸市民度を判定してくれます!

という、まあ、よくあるfactスキルに毛が生えたようなものですが、先日アップデートされた Voiceflow の Integration Block を使って、Googleスプレッドシートと連携させながら、今回はいろいろなデータ管理をやってみました。

概要

こんな感じのスキルです。

アレクサ、神戸あるあるを開いて

神戸あるあるを初めてご利用いただきありがとうございます。このスキルでは神戸の「あるある」なエピソードを、5個ご紹介して、最後にあなたの「神戸市民度」を判定します。エピソードが話されたあとに「あるある」か「ないない」で答えてください。では始めますか?

はい

では、神戸あるある、はじめましょう!
最初のあるあるです!

(♪BGM再生)

北のことを、、、、山側と言ってしまう。

あるある?ないない?

あるある

(♪歓声)

では、○個目のあるあるです

・・・繰り返し・・・

あるあるが終了しました。あなたの今回の神戸市民度は!・・・(♪ドラムロール)

〇〇パーセントでした!(♪ファンファーレ)

またご利用くださいね。

Voiceflowの中身

こんな感じです。約50ブロック使ってます。

f:id:kun432:20190504011515p:plain

内訳はこんな感じです。

ブロック名 ブロックの内容 使用数
Speak Alexaに話をさせるためのブロック。BGMや効果音などもここで。 20
Interaction ユーザの発話をインテントに振り分けてスロットを取得するブロック。開始前の確認で「はい」を受け取るところ、エピソードの後に「あるある」「ないない」をうけとるところで。 2
If 変数などを元に条件分岐するブロック 4
Set 変数を設定するブロック 3
Code JavaScriptで直接コードを書くスロット。主に変数の値をフィルタするような処理だけ、ロジック的なものはない。 6
Integration Googleスプレッドシートと連携してデータの登録・参照・更新を行うブロック。今回のキモ。 7
Card Alexaアプリのカードを出力するブロック 2
Flow 共通のフローをまとめるブロック 5

あと、変数は、ビルトインのものを除くと、21個作ってます。

開発期間は4日ぐらいです。設計とか実装とかよりも、

  • 素材探してきてアイコン作成
  • BGMとか効果音素材探してきて加工
  • あるあるネタ探して加工
  • Alexaの変な発話とか読み間違いの調整
  • テスト・デバッグ

の方に手間がかかってます。。。。

Integration Blockを使ったAPI連携について

元々はAPI Blockという外部API連携ができるブロックだったのですが、エンドポイント・リクエスト・レスポンスのパースとかを全部チマチマやらないといけない、直感的ではないというところがありました。これがビルトインでGUIでできるようになったのがIntegration Blockです。どんな感じで設定していくのかは以下のスライドにまとめてます。

今の所使えるのは、Googleスプレッドシートだけなので、これを使って以下のようなことをやっています。

あるあるエピソードのデータ管理

エピソードのデータをJSONなどでスキル内に持たせてしまうと更新するたびにいちいち申請が必要になり面倒です。この部分は別の部分で切り出して申請に関係なく自由に更新したいですよね。

通常のスキル開発ならロジックはLambda+Node.jsとかで実装して、データはS3とかDynamoDBを使うことになるわけですが、非エンジニアの方が簡単に更新できるか?とか、いつでもどこからでも更新できるか?ということを考えると、ちょっと辛い部分もあるのではないかと思います。その点、GoogleスプレッドシートならExcelとほぼ同じ感覚で使えますし、スマホなどからも更新ができて、とても魅力的ですよね。

ということで、エピソードの一覧を管理するシートはこんな感じになっています。

f:id:kun432:20190504095953p:plain

スキルから呼び出すと、この中からランダムにエピソードが選択されて発話されます。また、新しいエピソードがあればここにどんどん追加していくだけでコンテンツが更新されていくという感じです。

エピソードを2つに分けているのは、前半と後半に分けて「タメ」を作りたかったからです。「さ○ま御殿」のエピソード紹介をイメージしてもらうとわかりやすいと思います。上の例でいうと、「北のことを、」「・・(タメ)・・」「山側と言ってしまう。」って感じですね。

あと、統計的なデータを取っておけば後々なにか役に立つかも、ということで、「あるある」といった場合・「ないない」といった場合、それぞれの回数を記録するようにしています。ユースケースとしては以下のような感じに使えるのではないかと思ってます。

  • 「ないない」が多いエピソードは楽しくないので消したい
  • 「あるある」エピソードのベスト10を算出したい
  • あまり呼び出されていないエピソードを優先的に呼び出すようにしたい

ユーザの利用度管理

今回少し突っ込んでやってみたかったのはこれです。

f:id:kun432:20190504100042p:plain

ユーザごとに以下の情報を管理しています。

  • ユーザID
  • 初回利用日
  • 最終利用日
  • スキル実行回数
  • 「あるある」といった合計回数
  • 「あるある」「ないない」両方の合計回数

新規ユーザの場合は、各パラメータを初期化した形で新しく追加されます。既存ユーザの場合は、自分のユーザ情報が抽出されてスキルの中で利用され、スキル実行後に最新の状態が保存されます。

なぜこれを実装したか。

このスキルでは、あるあるを話してくれる、という機能の他に、神戸市民度の判定を行うという機能があります。この判定は、毎セッションごとに5個のエピソードのうち何個あるあるだったか?というところから判定します。ただし、セッション中だけの管理であれば変数で管理すればよいし、また、Voiceflowの変数はユーザごとにすべて「永続」扱いになっているので、例えばとあるユーザの過去のセッション全て含めた市民度というのも算出できちゃうので、いちいち外に切り出して管理する必要はありません。

ただ、この場合、すべてVoiceflowの中で処理されてしまうので、ユーザを跨いだ横断的な統計処理を行うことはできません。これを外に切り出すことで、以下のような情報を得られるのではないかというのが狙いです。

  • スキルの初回利用日から有効化数の推移を算出
  • スキルの実行回数ごとのユーザの分布
  • 総あるある率の高いユーザのベスト10

そして、こういうデータの解析は、ExcelGoogleスプレッドシートならお手の物ですよね。まだユーザ数が少ないのでアレですが、簡単なBIツールとして使えるし、こういう情報を活用することでスキルのグロースハック(大げさ)に繋げれるのではないかなと思っています。

あるあるエピソードの募集

今回、スキルの外側の部分で何かしら広がりを作れないか、ということで、あるあるエピソードを募集する仕組みを考えてみました。

登録しているあるあるエピソードはいろいろググったりして集めてきたわけですが、一人でやるのは限界がありますし、モチベーションも続きません。そこで、ユーザの皆様からエピソードを投稿いただければよいのではないか?ということで、Googleフォームを用意しました。

bit.ly

Googleフォームを使うと、フォームから投稿された内容をそのままGoogleスプレッドシートに追記することができます。追記先のシートを直接エピソード一覧管理シートに指定すれば、そのままエピソードが更新されていくということですね。ただ、現状は少しSSMLで加工が必要だったりするので、直接ではなくて一旦別のシートに保存して、更新があった場合はメールで通知されるので、その内容を踏まえてエピソードを更新するって感じで考えています。

Googleフォームへの誘導については、スキルの中から、初回利用時と一定利用回数ごとに以下のようなメッセージを流して、Alexaアプリのカードに誘導するようにしています。

最後にお知らせです。

神戸あるあるでは、皆様のあるあるなエピソードを募集しています。アレクサアプリを起動して、メニューからアクティビティを選択して、カードに表示されているURLにアクセスしていただくとエピソードの投稿ができます。よろしければぜひ投稿してください。

皆様の「神戸あるある」なネタ、お待ちしております!

カードはこんな感じです。

f:id:kun432:20190504120550p:plain

ただ、これ、非常に辛いのは、

  • AlexaアプリのカードにURLを含めてもリンクが有効にならない、、、
  • なのでコピペして貰うしかないのですが、コピペも効かない、、、
  • 短縮URLでできる限り短くはしました、、、

というところでして、、、さらに、そもそも現時点のVUIの課題として、レビューがされないというのがあるところに、さらに別の口を用意しても投稿が増えることは全く期待できないと思います。

画面付きデバイスQRコード表示するとかいろいろ考えてはみたものの、やはり音声でできるのが一番良いと思います。今後改善したいと思っています。(余談ですが、VoiceflowだとSearchQueryで発話をマルッと取ることができないので、何かしらサンプル発話のフォーマットが必要にはなります)

感想

Integration Blockを使うとちょっと凝ったスキルが簡単にできてしまうので、ハンズオン資料作るのも兼ねて実際にリリースまでやってみよう、というところからスタートしてます。が、作ってる最中に、こういうデータ取ったらいろいろ活用できるんじゃないか、みたいなアイデアがチラホラ出てきて、当初よりもだいぶやることが増えてしまい、すっかりハンズオン資料のことは忘れていました、、、

言えるのは、やっぱりデータベース的なものと連携させるとスキルの幅が広がります、それがGoogleスプレッドシートのような誰でも使えるものを活用できて、かつ、ノンコーディングでクリックしていくだけで使えちゃうというのは、ほんとVoiceflowの素晴らしいところです!スキルの中で直接使うデータはもちろんですが、今回のような統計的なデータの活用とかも、やろうと思えばできるということがは少しでも伝われば幸いかなと思います。

ただし、デメリットと言うか、辛いところもあります。

  • GUIで簡単にできるとはいいつつも、何個もIntegration Blockを用意して、いちいち設定していくのはやっぱり手間です。ブロックのコピペでできるんですけど、コピペして中身変えるとたまにおかしな動きする場合があったので、手間ですが確実にやるべくチマチマやってます。
  • 上と関係しますが、作ってからGoogleスプレッドシート側のシート名とかカラム名とか変えると、めちゃめちゃめんどくさいことになります。ある程度、名前は最初のうちに固めておいたほうがいいです。
  • Integration Blockで、Googleスプレッドシート側のデータを取得した後、各カラムごとに変数を用意してマッピングするのですが、この特性上、変数が多くなりがちで見通しが悪いです。ハッシュとか使えるともう少し見やすいんですが。
  • 上と関係しますが、Voiceflowの変数はすべて「永続」です。すなわち、一度でもスキルを起動した事がある場合は前のセッションで持っていた変数の値をそのまま引き継ぎます。スプレッドシートから取得すれば上書きされますけど、初期化すべきものについてはスキル起動直後に初期化しとくべきです。
  • デバッグやエラー処理が非常にやりにくいです。ログ機能のようなものはあるんですけどクリティカルなエラーしか記録されないので、APIのエラーとかはエラー時の分岐はできるものの、エラーが起きた理由がわかりません。Integration Blockを使えば使うほどエラーが起きうる場所が増えることになるので、このあたりはもう少し改善していってもらえるといいなーと。

こういった部分で注意は必要なものの、シンプルなスキルであればほとんど気にならないと思いますし、本当に簡単にできちゃうので、ぜひVoiceflowでスキル開発を始める方が増えればいいなーと思います。

今後の予定

ということで、ハンズオン資料については、GW中になんとか公開すべく、この後、作成します。。。