kun432's blog

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

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

The first official #VFJUG Voiceflow event in Japan

Yesterday, I held Voiceflow hands-on & workshop with #VFJUG (Voiceflow Japan User Group) at Tokyo. This was the first time for #VFJUG to hold an official event!

f:id:kun432:20191214115244j:plain

The venue was "Pepper Atelier Akihabara", which is a show room of Japanese robot called "Pepper". It was an interesting experience because I had never tried to talk to him(or her? I'm not sure...) and found that he can speak more fluently than I expected. Always fun to try other VUI platforms.

f:id:kun432:20191214121136j:plain

looks they are tired, lol.

f:id:kun432:20191214121519j:plain

Anyway, let's talk about the hands-on session.

First, I introduced about #VFJUG. BTW, #VFJUG got over 100 members now! Yeah!

The theme of the hands-on is 'creating story with Voiceflow'. This time, I put more focus on story-building than technical matters such as how to use variabls or integrating with API, etc. Technical things is also fun, but it would be mainly for engineers. I wanted to appeal more fun side of creating a story, especially for people who had no programming experiences and skills. Using a lot of sounds and music, changing the voices for each character, interacting with users, those are not highly 'technical' skills but important for dramatic presentation.

The sample story for hands-on was based on very famous faily tail, 'Cinderella'.

f:id:kun432:20191214123600j:plain

Begin with basic instruction of canvas and blocks.

f:id:kun432:20191214124011j:plain

How to use sounds and music by uploading MP3s and Alexa skills kit sound libraries,

How to change voices with Polly and SSML.

How to capture users utterance and change stories via users' choice.

Using sounds and music is fun, but important to know those limitations.

Everyone, go for it!

f:id:kun432:20191214123923j:plain

On the same day, Amazon Japan held a big event called 'Alexa Skill Learning Day Tokyo' and many VUI experts gathered there. Fortunately, some of them came to our event as supporting staffs. Thank you all!

a short break.

f:id:kun432:20191214142245j:plain

After the break, move on to the work shop session. The work shop theme was how to make your story more intersting by Rie Motoki from Cybird Co., Ltd, she is one of the professional VUI experts in Japan and has created a lot of entertainment Alexa skills. Actually, this session was not related with Voiceflow itself, but very important for creating story-based skills. Now, I'd like to say thanks to Rie for writing the draft of this sample story for this event!

After all sessioos, introducing additional resources for learning Voiceflow, we had a rock-paper-scissors tournament for getting Voiceflow official T-shirts!!! Actually, we had so many T-shirts and all most everybody got one! lol. (Thanks! Emily from Voiceflow!!!)

f:id:kun432:20191214234859j:plain

Finally, we got a photos! The pose we made means "V" of Voiceflow!

f:id:kun432:20191214115754j:plain


Thanks to every participants, supporting staffs, Pepper Attrie Akihabara, and Voiceflow!!! That was an incredible event and so much fun!!!

See you in next events!!!

DSLでAlexaスキルを作れる"litexa"を試してみる

f:id:kun432:20191213025902p:plain

この記事はスマートスピーカー Advent Calendar 2019 15日目の記事です。

今回は、DSLでAlexaスキルが作れる"litexa"を触ってみたのでその話をします。

litexaとは?

litexaは、Alexaゲームチームが開発した、ゲームのようなマルチターンなAlexaスキルを開発することに特化したDSLドメイン固有言語)です。通常、Alexaスキルの開発は、node.jsやpythonJava等を使うのが一般的だと思いますが、それよりももっとシンプルな記述でスキル開発ができます。実際にAlexaゲームチームではこれを使って20以上のAlexaスキルをリリースしているそうです。

セットアップ

では早速やってみましょう。litexaではコードをコンパイルして最終的にはJavaScrip/Node.jsのコードを生成しますので、Node.js(8.11以上)がインストールされていることが前提になります。またデプロイも行う場合には、いろいろと追加で必要になるものがありますが、それは別途説明します。

まず、litexaのcoreパッケージをインストールします。coreパッケージは、コンパイラコマンドラインのツールセットなどを含んでいます。

$ npm install -g @litexa/core

これでlitexaコマンドが使えるようになりました。

プロジェクトの作成

ではプロジェクトの新規作成をしてみます。

$ litexa generate

質問に答えていきます。

? In which directory would you like to generate your project? (.)

プロジェクトをどこにディレクトリに生成するかを聞いてきます。デフォルトはカレントディレクトリです。今回は "litexa-sample" としました。

? Which language do you want to write your code in? (Use arrow keys)
❯ JavaScript 
  TypeScript 
  CoffeeScript 

おそらくコンパイル後に生成されるコードの言語だと思います。とりあえず今回は"JavaScript"にしておきます。

? How would you like to organize your code? (Use arrow keys)
❯ Inlined in litexa. (useful for small projects with no dependencies) 
  As modules. (useful for organizing code as npm packages) 
  As an application. (useful if you have external dependencies) 

コードをどのように構成するか?を聞いてきます。npmモジュールとして生成したりすることもできるのかな?ちょっとよくわからないので、"Inlined in litexa"を選択します。

? What would you like to name the project? (default: "litexa-sample") (litexa-sample)

プロジェクト名を聞いてきます。デフォルトはフォルダ名と同じになるようです。このまま進めます。

? What would you like the skill store title of the project to be? (default: "litexa-s
ample") (litexa-sample) 

スキルストアでの名前を聞いてきます。残念ながら日本語は通らないようです。このまま進めましょう。これで終わりです。

こんな感じでファイルが生成されます。

litexa-sample/
├── README.md
├── artifacts.json
├── litexa
│   ├── assets
│   │   ├── icon-108.png
│   │   └── icon-512.png
│   ├── main.litexa
│   ├── main.test.litexa
│   ├── utils.js
│   └── utils.test.js
├── litexa.config.js
└── skill.js

サンプルのコードが入った状態になっていますので、少しだけコードを見てみましょう。litexa/main.litexaを開きます。

# start with a launch state
launch
  # greet the user, with their name if we have it
  if @name
    say "Hello again, @name.
         Wait a minute... you could be someone else."
  else
    say "Hi there, human."
  # move on to the askForName state
  -> askForName

askForName
  # add this question to our next response
  say "What's your name?"
  # add an automatic re-prompt, in case the user says nothing
  reprompt "Please tell me your name?"
  -> waitForName

(snip)

なんとなく雰囲気はわかると思うのですが、一番上がlaunch requestです。名前があれば名前を言う、なければ聞く、という流れになっているので、永続セッションみたいなのもできそうです。Alexaスキルのやり取りを知っていると、シンプルで直感的ナノがわかると思います。

この状態でテストが実行できます。

$ litexa test
2019-12-12 2:02:14 AM running tests in /Users/kun432/repository/litexa-sample with no filter
test step 1/3 +0ms: happy path
test step 2/3 +28ms: asking for help
test step 3/3 +10ms: utils.test.js
test steps complete 3/3 40ms total
 
2019-12-12 2:02:15 AM
✔ 3 tests run, all passed (40ms)

Testing in region en-US, language default out of ["default"]
✔ test: happy path
2.  ❢   LaunchRequest     @ 3:01:05 PM
     ◖----------------◗ "Hi there, human. What's your name?" ... "Please tell me your name?"
4.  ❢  MY_NAME_IS_NAME   $name=Dude @ 3:02:10 PM
     ◖----------------◗ "Nice to meet you, Dude. It's a fine Thursday, isn't it? Bye now!" ... NO REPROMPT
  ◣  Voice session ended
8.  ❢   LaunchRequest     @ 3:03:15 PM
     ◖----------------◗ "Hello again, Dude. Wait a minute... you could be someone else. What's your name?" ... "Please tell me your name?"
10.  ❢  MY_NAME_IS_NAME   $name=Rose @ 3:04:20 PM
     ◖----------------◗ "Nice to meet you, Rose. It's a fine Thursday, isn't it? Bye now!" ... NO REPROMPT
  ◣  Voice session ended


✔ test: asking for help
16.  ❢   LaunchRequest     @ 3:01:05 PM
     ◖----------------◗ "Hi there, human. What's your name?" ... "Please tell me your name?"
18.  ❢ AMAZON.HelpIntent   @ 3:02:10 PM
     ◖----------------◗ "Just tell me your name please. I'd like to know it." ... "Please? I'm really curious to know what your name is."
20.  ❢  MY_NAME_IS_NAME   $name=Jimbo @ 3:03:15 PM
     ◖----------------◗ "Nice to meet you, Jimbo. It's a fine Thursday, isn't it? Bye now!" ... NO REPROMPT
  ◣  Voice session ended


✔ utils.test.js, 1 tests passed
  ✔ utils.test.js 'stuff to work'
  c! the arguments are 1,2,3
  t! today is Thursday

✔ 3 tests run, all passed (40ms)

テストは問題ないようです。ハッピーパスのテスト、ヘルプのテスト、あとは自分でユーティリティ的なヘルパーを作った場合などのユニットテストができるようです。

デプロイ

コードをいじりたいところですが、先にデプロイを試してみましょう。デプロイには、

  • Alexa開発者アカウント
  • AWSアカウント
  • AWS CLI
  • ASK CLI

が必要になりますので事前に準備しておいてください。IAMの設定とかも必要です。

litexaでは、デプロイ用のパッケージはcoreとは別になっていますので、npmインストールします。

$ npm install -g @litexa/deploy-aws

では、デプロイ用の設定を行います。litexa.config.jsを開いてください。

'use strict';

module.exports = {
    name: 'litexa-sample',
    deployments: {
        development: {
            module: '@litexa/deploy-aws',
            S3BucketName: null,
            askProfile: null,
            awsProfile: null
        }
    },
    extensionOptions: {}
};

上記のうち、S3BucketNameにS3のバケット名、askProfileにASK CLIのプロファイル名、awsProfileAWS CLIのプロファイル名を設定します。S3のバケットはなければ作成してくれます(ということはIAMでその権限が必要だということになります)。AWS CLIのプロファイル、ASK CLIのプロファイルは以下で確認できます。

AWS CLIのプロファイル確認。プロファイルを設定している方は--profileでプロファイル名を指定する必要があります。

$ aws configure list

ASK CLIのプロファイル確認。

$ ask init -l

私の環境だとこうなりました。

            S3BucketName: 'litexa-sample',
            askProfile: 'default',
            awsProfile: 'ask-cli-user'

では、デプロイしてみます。

$ litexa deploy

こんな感じで処理が行われます。

[deploy] +340ms skill build complete in 340ms
[deploy] +2ms beginning deployment of /Users/kun432/repository/litexa-sample
[deploy] +1140ms loaded deployment module from /Users/kun432/.nodebrew/node/v10.16.0/lib/node_modules/@litexa/deploy-aws
[lambda] +0ms deploying lambda
[lambda] +20ms loaded AWS profile ask-cli-user
[lambda] +350ms considering node_modules
[lambda] +0ms no package.json found at /Users/kun432/repository/litexa-sample/litexa/package.json, skipping node_modules
[lambda] +5ms fetching dynamoDB information
[assets] +413ms all asset conversion complete
[assets] +0ms deploying assets
[assets] +1ms loaded AWS profile ask-cli-user
[lambda] +52ms wrote readme
[lambda] +0ms wrote index.js
[lambda] +777ms dynamoDB table not found, creating litexa-sample_development_litexa_handler_state
[assets] +1992ms created S3 bucket litexa-sample
[assets] +1ms scanning assets, preparing hashes
[assets] +7ms scanned 2 assets in project
[assets] +1ms fetching S3 object metadata [0-1000]
[lambda] +1358ms verified dynamoDB table exists
[lambda] +0ms beginning zip archive
[lambda] +27ms Platform: darwin
[lambda] +1ms zip archiving complete in 28ms
[lambda] +2ms zip SHA: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
[lambda] +0ms fetching Lambda litexa-sample_development_litexa_handler configuration
[assets] +793ms 2 assets need uploading
[assets] +1ms uploading icon-108.png -> litexa-sample/development/default/icon-108.png [9edf69cc]
[assets] +1ms uploading icon-512.png -> litexa-sample/development/default/icon-512.png [c5618ad1]
[assets] +1ms 0 assets remaining in queue
[lambda] +779ms creating Lambda function litexa-sample_development_litexa_handler
[lambda] +74ms ensuring IAM role litexa_handler_lambda
[assets] +1077ms segment uploaded in 1077ms
[assets] +0ms asset deployment complete in 3874ms
[lambda] +876ms creating IAM role litexa_handler_lambda
[lambda] +1684ms pulling attached policies for IAM role litexa_handler_lambda
[lambda] +913ms adding policy AWSLambdaBasicExecutionRole
[lambda] +2ms adding policy AmazonDynamoDBFullAccess
[lambda] +2ms adding policy CloudWatchFullAccess
[lambda] +1ms reconciling IAM role policy differences
[lambda] +10860ms waiting for IAM role to be ready
[lambda] +807ms IAM Role litexa_handler_lambda ready
[lambda] +1947ms creating LIVE alias for Lambda function litexa-sample_development_litexa_handler
[lambda] +2087ms pulling existing policies
[lambda] +547ms adding policies to Lambda litexa-sample_development_litexa_handler
[lambda] +2252ms Created Cloudwatch log group for lambda
[lambda] +846ms Updated CloudWatch retention policy to 30 days
[lambda] +1ms lambda deployment complete in 26270ms
[manifest] +0ms beginning manifest deployment
[manifest] +0ms loading skill.json
[manifest] +2ms building skill manifest
[manifest] +2ms no skillId found in artifacts, creating new skill
[manifest] +4594ms in progress skill id amzn1.ask.skill.XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
[manifest] +0ms waiting for skill status after create-skill
[manifest] +3080ms waiting for skill status after create-skill
[manifest] +1991ms create-skill succeeded
[manifest] +2015ms en-US model mismatch
[manifest] +0ms en-US model update beginning
[manifest] +2471ms waiting for model en-US status after update-model
・・・
[manifest] +3128ms waiting for model en-US status after update-model
[manifest] +2793ms model update-model succeeded
[manifest] +0ms en-US model update complete, total time 35659ms
[manifest] +0ms ensuring skill is enabled for testing
[manifest] +2963ms manifest deployment complete, 48298ms
deploying model
[deploy] +74744ms deployment complete in 76226ms

DynamoDBのテーブル作成、lambdaへのデプロイ、IAMロールの設定、S3バケットへのアップロード、そしてAlexa開発者コンソールへの登録、などが一気に行われているようです。AWSとADCの設定がどうなっているか見てみましょう。

まずADC側。

お、スキルができていますね。特に設定がなければデフォルトは英語のようです。

f:id:kun432:20191212152328p:plain

対話モデルもできています。

f:id:kun432:20191212152340p:plain

エンドポイントの設定もされていますね。us-eastにlambda の関数が作成されているようです。

f:id:kun432:20191212152349p:plain

次はAWS側。まず、DynamoDB。ユーザのセッション情報を保持しておくためのもののようです。

f:id:kun432:20191212183156p:plain

次にS3。とりあえずスキルアイコンが入ってます。

f:id:kun432:20191212183248p:plain

Lambda。ランタイムがNode.8.10なのはいただけないですが、どっかで設定できるのかな?

f:id:kun432:20191212183300p:plain

Lamdbaのコードはこんな感じです。ask-sdkとは全然違いますね。ざっと見た限り、いろいろ実装されてて、スキル内課金とかもできるように見えます。

f:id:kun432:20191212183311p:plain

では実際に動かしてみましょう。Alexa開発者コンソールのシミュレータで試してみます。ロケールは英語なのでその点にご注意ください。

f:id:kun432:20191212183712p:plain

はい、ちゃんと永続セッションも動いてます。

コード

改めて少しコードを見てみます。スキルのコードは、main.litexaになります。

# start with a launch state
launch
  # greet the user, with their name if we have it
  if @name
    say "Hello again, @name.
         Wait a minute... you could be someone else."
  else
    say "Hi there, human."
  # move on to the askForName state
  -> askForName

askForName
  # add this question to our next response
  say "What's your name?"
  # add an automatic re-prompt, in case the user says nothing
  reprompt "Please tell me your name?"
  -> waitForName

waitForName
  # do nothing when we start this state, and go nowhere; this ends the handler,
  # sends our response, and opens the microphone to listen

  when "my name is $name"
    or "call me $name"
    or "$name"
    with $name = AMAZON.US_FIRST_NAME
    # if user answers with a name from our names list

    # save the name in the permanent database
    @name = $name

    say "Nice to meet you, $name. It's a fine {todayName()}, isn't it?"
    -> goodbye

  when AMAZON.HelpIntent
    # if user says something that maps to the built-in help intent
    say "Just tell me your name please. I'd like to know it."
    reprompt "Please? I'm really curious to know what your name is."
    # loop back to waiting for a name
    -> waitForName

  otherwise
    # if user says something that maps to neither of the above intents
    say "Sorry, I didn't understand that."
    # loop back to asking for the name
    -> askForName

goodbye
  say "Bye now!"
  # we're done with the skill; end the skill session
  END

litexaでは、"state" という単位で処理を書いて、stateからstateに行き来することで、フローを作るような感じになっています。上記の例だと、こんな感じの処理になっています。

  • launch
    • 起動時に実行される。
    • 名前がすでに保存されていればその名前で挨拶する。
    • 保存されていなければ名前を聞くためにaskForNameに遷移する。
    • 名前があってもaskForNameに遷移する。
  • askForName
    • 名前を聞く。
    • 名前が言われなければ再度聞く(reprompt)。
    • waitForNameに遷移する。
  • waitForName
    • 名前を受け取り、永続セッションに保存する。
    • 名前を受け取ったらgoodbyに遷移する。
    • Help.Intentが呼ばれたらヘルプメッセージを発話して、再度waitForNameに遷移する。
    • どれにも合致しなければ再度名前を聞くためにaskForNameに遷移する。
  • goodby
    • さよならの挨拶をして終わる。

とてもわかり易いですね。ざっくり見ただけでもこんな感じでかけることがわかります。

  • sayでAlexaが発話、repromptで再度発話
  • -> でstateを遷移
  • @が永続セッションの変数、$がスロット
  • インデントでブロックが定義される。If else
  • Whenでインテント。サンプル発話を条件っぽく並べて、$でスロット、withでスロットタイプを定義。$を@に代入するだけで永続セッションとして扱える。
  • OtherwiseがFallbackIntentっぽい感じ。
  • ENDでセッション終了

日本語

せっかくなので日本語で動かせるかいろいろと試してみたのですが、どうやら日本語はうまく扱えないようで、SMAPIの登録でことごとくエラーになります・・・

  • skill.jsの中で日本語のロケール設定を追加するのですが、日本語がうまく処理できないため、呼び出し名の登録でエラーになる。
  • ja-JP用のmain.litexaを別途用意するも、インテント名はサンプル発話から自動で生成するようになっているため、日本語のサンプル発話だとうまくインテント名を作れない。
  • インテント名を個別に設定することで回避するも、日本語のサンプル発話をそもそもうまく処理できない。

このあたりは今後に期待ですね。ちなみに、ドキュメントを参照しながら、もし正しく動作するならばこうなるだろう、という仮定で、日本語にする場合の手順を以下にまとめておきます。

(もし日本語を正しく扱えるようになった場合の)多言語スキルの設定の仕方

litexaでは複数のロケールを一度で扱えるようになっています。まず、skill.jsを開いてみます。

'use strict';

module.exports = {
    manifest: {
        publishingInformation: {
            isAvailableWorldwide: false,
            distributionCountries: ['US'],
            distributionMode: 'PUBLIC',
            category: 'GAMES',
            testingInstructions: 'replace with testing instructions',
            locales: {
                'en-US': {
                    name: 'Litexa Sample',
                    invocation: 'litexa sample',
                    summary: 'replace with brief description, no longer than 120 characters',
                    description: 'Longer description, goes to the skill store. Line breaks are supported.',
                    examplePhrases: [
                        'Alexa, launch Litexa Sample',
                        'Alexa, open Litexa Sample',
                        'Alexa, play Litexa Sample',
                    ],
                    keywords: [
                        'game',
                        'fun',
                        'single player',
                        'modify this list as appropriate'
                    ]
                }
            }
        },
        privacyAndCompliance: {
            allowsPurchases: false,
            usesPersonalInfo: false,
            isChildDirected: false,
            isExportCompliant: true,
            containsAds: false,
            locales: {
                'en-US': {
                    privacyPolicyUrl: 'https://www.example.com/privacy.html',
                    termsOfUseUrl: 'https://www.example.com/terms.html'
                }
            }
        }
    }
};

これがスキルのマニフェストになりますのでこれを編集します。

distributionCountriesにJPを追加。

            distributionCountries: ['US', 'JP'],

localesに日本語の設定を追加。

            locales: {
                'en-US': {
                  ・・・
                },
                'ja-JP': {
                    name: 'Litexaのサンプル',
                    invocation: 'リテクサのサンプル',
                    summary: 'litexaのサンプルです。',
                    description: 'litexaのサンプルです。',
                    examplePhrases: [
                        'アレクサ, リテクサのサンプルを起動して',
                        'アレクサ, リテクサのサンプルを開いて',
                        'アレクサ, リテクサのサンプルをスタートして',
                    ],
                    keywords: [
                        'litexa',
                        'サンプル',
                    ]
                }
            }

プライバシーポリシーの箇所も同じく。

        privacyAndCompliance: {
            locales: {
                'en-US': {
                    privacyPolicyUrl: 'https://www.example.com/privacy.html',
                    termsOfUseUrl: 'https://www.example.com/terms.html'
                },
                'ja-JP': {
                    privacyPolicyUrl: 'https://www.example.com/privacy.html',
                    termsOfUseUrl: 'https://www.example.com/terms.html'
                }
            }
        }

次にスキル。デフォルトのen-US以外は個別にディレクトリを作成してその中にファイルを置いていきます。これにより各ロケールごとにデフォルトのen-USがオーバーライドされます。

litexa-sample/
├── README.md
├── artifacts.json
├── litexa
│   ├── assets
│   │   ├── icon-108.png
│   │   └── icon-512.png
│   ├── languages ★作成
│   │   ├── ja-JP ★この配下が日本語用になる
│   │   │   ├── assets 
│   │   │   │   └── icon-512.png
│   │   │   │   └── icon-512.png
│   │   │   ├── main.litexa
│   │   │   └── utils.js
│   ├── main.litexa
│   ├── main.test.litexa
│   ├── utils.js
│   └── utils.test.js
├── litexa.config.js
└── skill.js

日本語のmain.litexaはきっとこんな感じです。

# start with a launch state
launch
  if @name
    say "こんにちは、またお会いしましたね、@name さん。
         ちょっと待って下さい。もしかして別の人ですか?"
  else
    say "こんにちは、初めてお会いしますね。"
  -> askForName

askForName
  say "あなたの名前を教えてもらえますか?"
  reprompt "あなたの名前を教えてもらえますか?"
  -> waitForName

waitForName
  when MY_NAME_IS_INTENT
    or "私の名前は $name です。"
    or "$name と呼んでください。"
    or "$name"
    with $name = AMAZON.FirstName

    @name = $name

    say "はじめまして、 $name さん。今日は気持ちのいい {todayName()} 、ですね。"
    -> goodbye

  when AMAZON.HelpIntent
    say "あなたの名前を教えて下さい。"
    reprompt "あなたの名前を教えて下さい。"
    -> waitForName

  otherwise
    say "ごめんなさい、うまく聞き取れませんでした。"
    -> askForName

goodbye
  say "バイバイ。"
  END

もう一箇所、これはあくまでもサンプルコードに限った修正ですが、utils.jsも修正します。この部分はJavaScriptですが、main.litexaから{todayName()}で呼び出されています。自分で直接書いたコードを呼び出すこともきるんですね。

function todayName() {
  let day;
  day = (new Date).getDay();
  return ['日曜日', '月曜日', '火曜日', '水曜日', '木曜日', '金曜日', '土曜日'][day];
}

こんな感じに多分なるだろうという予測ですのであしからずご了承ください。日本語の不具合についてはissue立てておきたいと思います。

まとめ

コードを見てもらうと分かる通り、非常に直感的に書けます。スロットや永続セッションなんかはめちゃめちゃ楽ちんです。逆に複雑なことをやりたい場合も、直接コードを書いて拡張できるし、ドキュメントにはスキル内課金やAPL、ガジェット連携あたりも記載されていて、Alexaでできることは結構カバーされている印象です。

こういうやりたいことだけをなるだけシンプルに・かんたんに実現する、という考え方は、Skill Flow Builderあたりもそうですし、Voiceflowなどのノンコーディングツールにも通じるところがあります。日本語で動かない、などまだこなれてない感はありますが、こういった取り組みでスキル開発のハードルが下がればいいなと思います。

興味がある方はドキュメントを御覧ください。

#VFJUG初のVoiceflowのハンズオン&ワークショップを東京でやってきた

昨日ですが、#VFJUG(Voiceflow Japan User Group)の記念すべき、初のVoiceflowのハンズオン&ワークショップを秋葉原でやってきました。

f:id:kun432:20191214115244j:plain

今回東京に来たのは、AlexaスキルLearning Dayのニック・シュワブさん(Alexaスキルでテスラと家を買った人ですよ!)の話を聞きたいというのが一番の目的でした。ただ、せっかく東京まで来るんだし、東京のVUIerの皆さまとお会いするのであれば、なんか一緒にやりたい!じゃあVoiceflowのハンズオン&ワークショップをやろう!ということで、コツコツと準備をしていたのでした。ではまとめ。


会場はアーツ千代田3311にある「Pepperアトリエ秋葉原」さんです。アーツ千代田3311は、元々中学校だったのを改装してクリエイティブスペースとて提供しているそうで、ところどころ学校テイストがあって面白いです。

f:id:kun432:20191214120701j:plain

「Pepperアトリエ秋葉原」さんにはもちろんPepperがいます!個人的にPepperのしゃべりが思ったより自然だったのは少し発見でした(たぶんここ最近AlexaにSSML色々いじってしゃべらせまくっていたからですね、SSMLでいろいろやるとちょっとイントネーションがおかしくなったりする気がします)。Pepperちょっと欲しくなった!

f:id:kun432:20191214121136j:plain

待機中のPepperは退廃したSF感あるw

f:id:kun432:20191214121519j:plain

ハンズオン&ワークショップ、スタートです!

まず、#VFJUGのご紹介。100人超えました!

今回のテーマは、事前にサイバード元木さんと相談して、技術的なVoiceflowでのスキルの作り方というよりは、何かしらの物語を作るためのツールとしてやろう!というテーマで、選んだのは「シンデレラ」です。シンデレラのお話をベースに、いろいろ脚色したり、ストーリーを分岐したりして楽しくやろう、という感じです。

f:id:kun432:20191214123600j:plain

最初はVoiceflowの基本から。

f:id:kun432:20191214124011j:plain

効果音を使って賑やかにしたり、(そう、たくさんあるので結構選ぶのはたいへんです)

PollyやSSMLを使ってキャラクターのセリフを使い分けたり、

ユーザーの発話で分岐したりしてストーリーをインタラクティブにしていきます。

ただし、効果音やサウンドを使う場合は、こういう制約もあるので、うまくユーザの発話と組み合わせる必要があります。

資料に従って、みなさん、もくもくと頑張ってます!

f:id:kun432:20191214123923j:plain

今回ほんとサポートスタッフが豪華です!VUI界隈の猛者がマンツーマンでサポートしてくれるという、心強い!

休憩中。かしまし娘です。

f:id:kun432:20191214142245j:plain

休憩の後は、元木さんのお話。ストーリーを以下に面白くするか?という、なかなかこの手のイベントでは聞けない内容です!

物語のポイントとなる要素と、キャラクターの性格を紐解いた上で、それらの一部分を妄想的に膨らませていくと新しいストーリーのアイデアが出てくる、このあたりはとても参考になりますね、スキル開発のアイデア出しにももちろん通じる内容でした!

少しその他の参考情報なども補足しつつ、最後はじゃんけん大会。景品は、スタッフと同じ、Voiceflowの公式Tシャツです!(Thanks! Emily from Voiceflow!!!)

f:id:kun432:20191214234859j:plain

最後に記念撮影です、VoiceflowのVのポーズで!

f:id:kun432:20191214115754j:plain


とりあえず、無事終わってホッとしました。少しハンズオン資料が「学習」寄りになっていて、「体験」が少なかったかな、という感は今でもちょっとあって、今回の反省として今後に活かしたいなと思っています。

なお、ハンズオン資料は以下で公開していますので、ご自由にご活用ください。

vf-handson-story-skill.netlify.com

最後になりましたが、参加者の皆様、スタッフの皆様、会場提供のPepperアトリエ秋葉原の皆様、そしてイベント用にTシャツを提供してくれたVoiceflowの皆様、いろいろとありがとうございました。今後もいろんなテーマでハンズオンやTIPSなど発信していきたいと思いますので、

  • こういうテーマでやってほしい
  • うちにハンズオンに来てほしい

というご意見・ご要望等あればぜひご連絡いただければと思います。

それにしてもPepper気になる・・・

f:id:kun432:20191214235217j:plain