kun432's blog

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

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

Voiceflowの新しいステップ、Directive Stepがリリースされました!

f:id:kun432:20210210123614p:plain

Voiceflowの新機能、「Directive Step」がAlexa・Google両方向けにリリースされましたので、ご紹介します。

これまでVoiceflowは各機能のことを「ブロック」といってきましたが、正式には「ステップ」という言い方に変わっていますので、今後は「ステップ」で統一します。

Directive Stepとは?

Directive Stepについては、以前APL for Audioのβテストでご紹介しています。

kun432.hatenablog.com

AlexaもGoogleも基本的に同じですが、スキルから返す発話させたい内容だけではなく、付加情報(例えば画面付きデバイス向けの画像や、回答のヒントなど)もセットにして返すことができます。これを「ディレクティブ」を言います。(厳密には「ディレクティブ」はAlexaでの言い方で、Googleでは発話させる内容も含めて「プロンプト」といいます。)

早速やってみましょう。

サンプルスキル

例によって、コーヒーショップの注文を受け付けるサンプルをGoogle向けプロジェクトで用意しました。

f:id:kun432:20210210185138p:plain

対話モデルもこんな感じで。

f:id:kun432:20210210185207p:plain

f:id:kun432:20210210185223p:plain

Directive Stepを使ってみる

Directive Stepはメニューの一番下にあります。

f:id:kun432:20210210190324p:plain

これをSpeakとChoiceの間に入れます。発話とセットで返すのが基本になるかと思いますので、Speakと一緒に使うことになると思います。

f:id:kun432:20210210190110p:plain

Directive Stepの設定画面はこんな感じです。マルっと入力欄だけがあって何をしていいのかわからないかもしれません。

f:id:kun432:20210210190429p:plain

ここではVoiceflowの公式ドキュメントの手順に従ってやってみましょう。画像つきのカードを表示してみたいと思います。以下のような内容をDirerctive Stepの設定に記載します。

{
  "content":{
    "card":{
      "title":"カードのタイトル",
      "subtitle":"カードのサブタイトル",
      "text":"カードのコンテンツ",
      "image":{
        "alt":"画像の代替名",
        "height":0,
        "url":"https://developers.google.com/assistant/assistant_96.png",
        "width":0
      }
    }
  }
}

f:id:kun432:20210210213447p:plain

アップロードします。

f:id:kun432:20210210192136p:plain

テストシミュレータを開きます。

f:id:kun432:20210210192147p:plain

テストしてみましょう。発話も同時に、カードが表示されているのがわかりますでしょうか?

f:id:kun432:20210210214250p:plain

拡大するとこんな感じです。ちゃんと画像や説明が表示されていますね。

f:id:kun432:20210210214452p:plain

上記はスマートディスプレイ(Nest Hub等)での表示結果でした。一旦テストをキャンセルしてデバイスを"Phone"に変えてみましょう。

f:id:kun432:20210210214944p:plain

f:id:kun432:20210210214954p:plain

再度テストするとこのようにスマホ上での表示イメージが表示されます。

f:id:kun432:20210210215035p:plain

アクションの内容に合わせて内容や画像を変えるととこういう感じに表示できるということですね。

f:id:kun432:20210210215550p:plain

なお、画像は以下を利用させていただきました。ありがとうございます。

https://pixabay.com/images/id-1031526/

Directiveの設定方法

サンプルではカードを表示させるディレクティブを設定しましたが、いきなりではわからないですよね。ディレクティブの設定方法はGoogleのドキュメントを見るとわかります。

ここにプロンプト、つまり、Googleで返せるレスポンスの一覧が載っています。残念ながら日本語訳はまだないようです・・・

f:id:kun432:20210210220554p:plain

カードの場合はどうなっているかを見てみましょう。左のメニューの"Prompts"の"Rich"をクリックします。

f:id:kun432:20210210220711p:plain

少し下にスクロールすると、"Basic Card"というのがあります。表示例からもわかると思いますが、これが先ほどのサンプルで使った「カード」についての説明です。

f:id:kun432:20210210221024p:plain

さらにスクロールすると、設定できるプロパティの一覧があって・・・

f:id:kun432:20210210221700p:plain

さらに下にスクロールするとありました、サンプルコードです。

f:id:kun432:20210210222013p:plain

コードの種類がいくつかあるのですが、"JSON Builder"を選択します。

f:id:kun432:20210210222325p:plain

はい、これがカードのサンプルのレスポンスです。

f:id:kun432:20210210222551p:plain

ただし、これはレスポンス全体です。つまり、ディレクティブで設定するカード部分だけでなく、発話部分も含んでいます。Voiceflowの場合、発話はSpeak Stepがやってくれるので、こういうことになります。

f:id:kun432:20210210223034p:plain

つまり、発話以外の部分をコピーして、Directive Stepにペーストして修正すればよいということです。1点だけ注意すべきなのは、JSONはカッコにより階層構造が表現されています。Directive Stepに設定する場合は、

"content": {
  "card": {
    "title": "Card Title",
    "subtitle": "Card Subtitle",
    "text": "Card Content",
    "image": {
      "url": "https://developers.google.com/assistant/assistant_96.png",
      "alt": "Google Assistant logo"
    }
  }
}

ではなく、以下のように外側を"{}"で囲んで、1階層下に設定する必要がある点にご注意ください。

{      // ココが必要
  "content": {
    "card": {
      "title": "Card Title",
      "subtitle": "Card Subtitle",
      "text": "Card Content",
      "image": {
        "url": "https://developers.google.com/assistant/assistant_96.png",
        "alt": "Google Assistant logo"
      }
    }
  }
}      // ココが必要

いろいろなディレクティブがあるので、ぜひドキュメントを見て試してみてください!

まとめ

Alexaの場合、VoiceflowがいろいろなAlexa専用機能のステップを予め用意していることもあり、APL for Audioを使わない限り、Directive Stepを利用することは(現時点では)あまりないかもしれません。 Googleの場合は、独自のStepがあまり用意されていないこともあり、Directive Stepを使うと表現の幅が増えますし、特にスマホのGoogleアシスタントでリッチな表現ができるのが大きいです。

JSONのフォーマットを理解する必要があるため、少し技術的な内容になってしまいますが、がんばってぜひトライしてみてください!

いまさらながらAPLを理解する ①ことはじめ

f:id:kun432:20210131175240p:plain

もうホントいまさらですが、ずっと食わず嫌いだったAlexaのマルチモーダル用言語『APL(Alexa Presentation Language)』をきちんとやって理解しようと思います。

目次

APLとは?

上でも書いていますが、乱暴に言っちゃうと「Alexaで画面付きデバイスに表示する画面のデザインを行うための言語」です。こんな感じで画面を作ると、ディスプレイ付きデバイスだと表示されます。

f:id:kun432:20210131180527p:plain

さらに、単純なデザインだけでなく、タッチによるイベントやアニメーションなど凝ったこともできますが、凝ったことをやろうと思うと一気にハードルが上がり、Alexaの通信の仕組みや制約を理解しないと厳しくなります(だから見ないふりをしてきたのです・・・)。ということで、基本的なところから理解を深めていきたいと思います。

ということで2年前(もうそんなになるのか・・・・)のAlexa道場を見ていきます。

APLとは?

f:id:kun432:20210210002003p:plain

  • JSONベースの宣言的なUI記述言語
    • 特徴
      • GUIのコンポーネントが揃っている
        • テキストやイメージ、コンテナなど
      • 柔軟にレイアウトできる
        • GUIコンポーネントを組み合わせたり並べたり
      • データバインディングによるデザインとデータの分離
        • デザインをテンプレートとして、あとからデータを差し込む
      • コマンドによる動的な画面生成

APLの主なコンポーネント

f:id:kun432:20210210002405p:plain

  • 基本コンポーネント
    • Image
    • Text
    • Frame(枠)
    • TouchWrapper(コンポーネントをタッチ可能にする)
  • 複数コンポーネントのレイアウト
    • Container
      • 複数のコンポーネントをまとめるコンポーネント。レイアウトのキモ。
  • 複数項目の切り替え
    • Pager/Sequenceなど
      • ページの切り替えや複数項目を並べたり

レイアウト

f:id:kun432:20210210002456p:plain

  • Container
    • コンポーネントを一方向(縦 or 横)に配置
      • directionで方向。columnにすると縦にならぶ。
      • justifyContentで縦方向の寄せ。endにすると下寄せになる。
      • alignItemsで横方向の寄せ。centerにすると中央寄せになる。

f:id:kun432:20210210004448p:plain

  • レイアウトのサンプル
    • 1行目でContainerを定義
    • width/heightでviewport width/height
      • 100vw/100vhで100%定義
    • 4〜6行目でレイアウト要素(direction/justifyContent/alignItems)
    • 7行目のitemsで子要素
      • 例ではヘッダー、テキスト、画像が縦に並んでいる
      • ヘッダー部分の"headerLayout"はビルトインではなく、自分でFrameとtextを使って別で作ったもの。このようにレイアウトを自分で定義して使うこともできる。
    • 10行目や17行目にある${payload.....}がデータバインディングにより、外部データが差し込まれる
    • 5行目のjustifyContentにあるような${viewport.shape == 'round' ? 'end': 'center'} ところで画面形により分岐というようなこともできる(roundはEcho Spot)

f:id:kun432:20210210005344p:plain

  • レイアウトの作り分け
    • whenを使ってコンポーネント単位で表示・非表示させるやり方もある。

項目の切り替え

f:id:kun432:20210210005645p:plain

  • Pager

f:id:kun432:20210210005749p:plain

  • シンプルに書く場合と凝った書き方の場合
    • Pagerコンポーネントでitemsにいれる
    • Pagerコンポーネントにdataをバインディングさせて、itemsの中でそれを順に表示する

f:id:kun432:20210210010056p:plain

  • Sequence
    • Pagerは順にスライド
    • Sequenceはスクロールに近い

f:id:kun432:20210210010212p:plain

  • Sequence
    • scrollDiretionでスクロールの方向を指定

APLオーサリングツール

f:id:kun432:20210210010412p:plain

コマンド

f:id:kun432:20210210010453p:plain

  • コマンドのユースケース
    • タッチでイベントを飛ばす
    • ページ送りやスクロールの制御をタッチではなく「自動」で
    • 発話コマンドを使って画面上のテキストと発話を動悸させる
      • カラオケ的なやつ
タッチ操作

f:id:kun432:20210210010735p:plain

f:id:kun432:20210210010919p:plain

  • TouchWrapperコンポーネント
    • TouchWrapperの下のitemに紐づく
    • onPressで「タッチした」ときにSendEventでイベントをスキルバックエンドに送信。argumentsで送るデータを指定。
    • スキル側でそのイベントを拾うハンドラを用意しておく
スライドショー

f:id:kun432:20210210011445p:plain

f:id:kun432:20210210011617p:plain

  • タッチでスライドするのではなく、自動でスライドさせる
  • SetPageコマンド
    • Pagerにおけるページを指定する
      • componentIdで該当のPagerを指定する
      • positionでページを指定
        • relativeで相対指定(次のページへ)
        • absoluteで絶対指定(何ページへ)
      • delayでタイミング
    • ParallelやSequentialで実行方法を指定
      • Parallelで並列実行
      • Sequentialで順次実行
      • ページを切り替えるごとにしゃべるとか
      • 長い文章を発話させる間に画面をスライドさせるとか
読み上げ・テキスト同期

f:id:kun432:20210210012311p:plain

f:id:kun432:20210210012807p:plain

  • 3つの要素
    • APLデータ
      • 読み上げデータをSSMLで用意する
        • transformerでSSMLを音声に変換する
        • 同時にtransformerでSSMLをテキストに変換する
    • APLドキュメント
      • データをバインディングする
    • APLコマンド
      • SpeakItemコマンドでテキストを読ませる
      • highliteModeでハイライトさせる

ちょっとどういうことかわからなかったのだけど、ここのtopicTextはpayloadで渡されるtopicTextではなくて、APLドキュメントのidで指定されているtopicTextの方みたい。でこれにより、topicTextのSpeechで指定されている、ssmlToSpeechでオーディオ化されたデータが再生されるということだと思う。 以下のほうがわかりやすい。 テキストブロックでのAPL音声およびテキストの同期 | Alexa Skills Kit

バックエンド

f:id:kun432:20210210014851p:plain

  • responseBuilderにaddDirectiveでAPLドキュメントやAPLコマンドを追加する

まとめ

これまでは見様見真似で適当にAPLやってきたのですが、改めてAlexa道場を見てみると、当時リアルタイムで見ていたときよりは理解できている気がしました。多少は成長しているのかな、と。ただ依然として腹落ち感がないので、次回以降で手を動かしてやっていこうと思います。

2021年1月ふりかえり

f:id:kun432:20210205221503p:plain

今年一発目の振り返りです。

音声関連

  • 自作スキル・アクションの開発に力を入れる
  • Googleアシスタント向けアクションを作って公開する
  • スマホアプリを作って公開する

スキル開発はまだ何もできていないけど、いろいろGoogle周りを確認中。あと、ちょっと気になってるのはこれ。

結構タイトル的には衝撃的だけど、ここから学ぶこともあると思ってて、ABテスト的に違いが出るか?というのを試してみたいなぁと思ってます。

仕事

  • AWSやK8S関連のアウトプットを増やしていく
  • 管理職としてもっとスキルを高めていく

1月すこしK8S周りのアウトプットもできたし、ブログには書いてないけどTransit Gateway周りもちょっといじってたり。Terraform使っての構築を試したら後でまとめる予定。

今年はこのあたり増やしていきます。

アウトプット

  • Voiceflowの日本語チュートリアルを充実させる
  • Voiceflowの動画チュートリアルを作る
  • AWSやK8Sのチュートリアルを作る
  • ブログを年間100記事以上書く
  • Advent Calendarに参加する
  • 技術同人誌を出す

とりまブログは11件。

内容的にバリエーションも多くできたし良かったかな。2月も頑張ります。

勉強会はこのあたりに参加させてもらいました。ありがとうございました。

これ以外にも、VoiceLunch GlobalやAWS re:InventのAlexaトラックも参加してました。VoiceLunchGlobalについては以下にもまとめてます。

この記事は、当日のイベントの中で"kawaii"というキーワードが出てきたので、国内の「可愛い」音声アシスタントについてまとめたんだけど、LinkedInとかTwitterとかで結構反響があって、とても良かった。

イベントに参加した内容をブログでまとめたら、それが知らないところでシェアされる、みたいなのはホントインターネットらしいなと思うし、「ブログ書くまでが勉強会」というのはこういうことだなと。同時に、上のコメントくれた人たちは言語学の専門家ばかりで、教えてもらった論文を読んだりして、ちょっとまた違った分野の人と通じることができるのは良いなぁと。あらためてアウトプットは重要だなと思います。

その他

  • ボカロPに俺はなる!
  • 住みやすい・仕事しやすいリモートワーク環境づくりをすすめる
  • 月に1冊本を読む

ちょうどリモートワーク環境づくりを今進めてるところです。

f:id:kun432:20210207012815j:plain

f:id:kun432:20210207012923j:plain

今週はコツコツ断捨離してました。明日はやるぞー。

読書は以下を読みました。日頃慣れ親しんでる音声周りの話なのでとても興味深く読めました。今月は他のジャンルを読んでみる予定。

まとめ

2月も忙しそうだけど、いろいろ・コツコツやっていきます。今年もよろしくお願いします。

そうそう、2020年も選んでもらいました。ありがとうございます!

f:id:kun432:20210207023054p:plain