アップデートされたAlexa Conversationsを触ってみる


# はじめに

2021年11月末頃、Alexa Conversationsに大きなアップデートがあり、ダイアログの作成方法などに変更が入りました。新しいAlexa Conversationsを使うには、Alexa Developer Console でスキルを開き `今すぐ保存して移行する` をクリックすることでスキルをマイグレーションすることができます。すでにを公開している Alexaa Conversationsスキルの場合は、様子をみた方がいいかもしれません。私もAlexa Conversationsを使用したスキルを１つ公開していますが、今のところはマイグレーションしていません。試しに`Alexa Conversations 入門` スキルというサンプルスキルをマイグレーションしてみましたが、今のところ何のトラブルもなく、スキルも正常に動作しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/b4125632-c7e3-10c7-38cf-179606c6b977.png)

マイグレーションすると、応答がオーディオ応答（APL for Audio）と視覚応答（APL）に分かれます。以前は応答の中で、APL for Audio と APLを作成する仕様でしたが、より分かりやすくなったと思います。

<img width="650" alt="Alexa Conversationsのメニュー" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/664e6d7f-c55b-d7f6-3c9e-2bb62a705af2.png">

2021年12月19日現在、`Alexa Conversations 入門`スキルや、スクラッチでスキルを作成しても、マイグレーション前の状態で作成されます。

【注意】hostedスキルで `Alexa Conversations 入門`スキルを作成すると、Lambdaのコードも付いてきます。ただしLambdaのコードはマイグレーションされないので自身で修正してください。`Alexa Conversations 入門`スキルの修正ヵ所は、API定義名称の先頭に`apis.`を付けるだけです。APIが２つあるので両方とも修正します。

マイグレーション前：util.isApiRequest(handlerInput, 'RecordColor');
マイグレーション後：util.isApiRequest(handlerInput, 'apis.RecordColor');

その他のアップデート情報は [What's New in Alexa Conversations](https://developer.amazon.com/en-US/docs/alexa/conversations/whats-new-alexa-conversations.html#nov-2021) を参照してください。


# Alexa Conversations を簡単に紹介

Alexa Conversations はAI駆動のダイアログ管理モデルを用いて、幅広いフレーズや予期しない会話フローに応答できるようにしたものです。従来のインテントベースモデルのスキルとは別のものになります。これでスキルのモデルが３種類になりました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/fc1ca9e0-01a6-b494-3a30-da554bb2d938.png)



Alexa Conversations モデルの場合は、Lambda側でAlexaのレスポンスを作る必要がなくなっていたり、会話の管理をしなくてよくなっています。以下を見てもらえればわかるように、Alexa Conversations モデルでは、ターンのやりとりは全てスキル側で賄われています。そのためLambdaではビジネスロジックに専念できるようになっています。

|スキルモデル|ターン|Alexa Developer Console|Lambda|
|:--|:--|:--|:--|
|Alexa Conversations|起動時|AlexaConversationsWelcome|－|
||USER:|発話セット|－|
||ALEXA:|オーディオ応答（APL for Audio）<br>視覚応答（APL）|－|
|インテントベース|起動時|－|LaunchRequest|
||USER:|インテント|－|
||ALEXA:|－|.speak<br>.reprompt<br>.addDirective（APL for Audio / APL）<br>.addDirectiveToReprompt（APL for Audio）|

# Alexa Conversations を有効にするには

Alexa Developer Console の インターフェース で Alexa Conversations をオンにするだけです。

<img width="650" alt="インターフェース" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/853dda57-f943-ba7d-e742-77076f53ac18.png">


Alexa Conversations セクションの右上のチェックをオンにする。さらに、スキルを Alexa Conversations モデルで起動（開始）したい場合は、`セッション開始時にAlexa Conversationsをダイアログマネージャーとして使用する` をオンにする。これで Alexa Conversations を使うための準備が整いました。

<img width="650" alt="Alexa Conversations" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/e1c0d856-7a39-565d-625b-90c378115f6e.png">

Alexa Developer Console の左ペインに `Alexa Conversations` セクションが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/0fb8e034-de81-96a7-9107-b117978f0dc6.png)


# Alexa Conversations のスキルを作る

ここでは、`Alexa Converstions 入門` スキルをベースに説明していきます。入門スキルとは、スキルテンプレートで選択できるAlexa Conversationsのサンプルスキルのことです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/5e2b8187-c3d1-487f-1d50-46fa6184d720.png)


マイグレーション前の Alexa Conversations であれば、ダイアログはサンプルダイアログとして `USER:` と `ALEXA:` の会話を入力して、ユーザー発話やAlexa応答は別に作成していました。サンプルダイアログに表示されている文字列はスキルには影響しませんでした。それが、今回のアップデートによってサンプルダイアログを作成するときの、`USER:` と `ALEXA:` の会話は、ユーザー発話と、オーディオ応答から生成されるようになりました。そのため、最初にこのツールでダイアログを作るというよりは、机上でダイアログを考えておいて、各パーツを作った後に、ダイアログを完成するのが良いのではないかと思っています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/e7bc03d3-ae0e-deb5-cb82-93ff47270ff2.png)


# まず最初はダイアログを考える

Alexa Conversationsの要はダイアログです。これまでのスキル作成と同じ要領で机上でダイアログを考えます。ハッピーパスを考えるのと同じ要領です。今回の `Alexa Converstions 入門`スキルのダイアログはこんな感じになっています。

<img width="500" alt="ハッピーパス" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/923998c5-bd72-611b-1b49-2e573dda71a4.png">

Alexa Conversationsのダイアログに、直接`USER:` と `ALEXA:` の会話を入力してしまうのもアリかもしれません。ダイアログに文字を入力することは現在も可能です。しかし、会話を考える時は机上でやっている人の方が多いのではないかと思っているので、まずは机上で！と書いています。

# ダイアログからダイアログアクトを考える

ダイアログが完成したら、次はダイアログアクト（対話の振る舞い方）を考えますが、この時点ではまだ机上で作業します。なぜ、いきなりダイアログアクトが出てきたかと言うと、ダイアログアクトのうちのリクエストアクトを決めておかないとAlexa Conversaationsの部品の１つである発話セットが作れないからです。
それぞれつけ方にルールがあるので詳しくは[リファレンス](https://developer.amazon.com/ja-JP/docs/alexa/conversations/dialog-act-reference.html)を見ていただきたいのですが、リクエストアクトの決め方を簡単に言うと、ダイアログの最初だったら`Invoke APIs`。ダイアログの途中でスロットを拾う場合は`Inform Args`。はいの場合は`Affirm`。いいえの場合は`Deny`でだいたいいけると思います。

<img width="750" alt="ダイアログ　仮" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/863be033-ad46-4496-c706-572dd175dca1.png">

以前のAlexa Conversationsでは、ユーザー入力とAlexa応答を合わせてダイアログアクトと言わていましたが、新しいAlexa Conversationsでは、ユーザー入力ダイアログアクトは、リクエストアクト（Request acts）と名称が変わりました。Alexa応答ダイアログアクトは、応答アクト（Response acts）と名称が変わっています。

リクエストアクトと応答アクトには以下の種類があります。

|No | リクエストアクト | 説明 |
|:--|:--|:--|
|1|Affirm|ユーザーは、前のターンのリクエストを肯定しています。|
|2|Deny|ユーザーは、前のターンのリクエストを否定しています。|
|3​|Inform Args|ユーザーは、前のターンでAlexaがリクエストした引数を提供しています。|
|4​|Invoke APIs|ユーザーは、APIを呼び出すダイアログパス上にいます。|

|No | 応答アクト | 説明 |
|:--|:--|:--|
|1|API Failure|API呼び出しが失敗したことをユーザーに通知しています。|
|2|API Success|API呼び出しが成功したことをユーザーに通知しています。|
|3|Confirm API|必須のAPI引数（すべて）と任意のAPI引数（任意の数）をユーザーに確認しています。|
|4|Confirm Args|1つ以上の引数をユーザーに確認しています。|
|5|Offer Next API|会話を続けるために、別のAPIを呼び出すダイアログパスをユーザーに提供しています。|
|6|Request Alt|同じAPIを呼び出すダイアログパスを提供し、指定された引数をリクエストしています。|
|7|Request Args|1つ以上の引数をユーザーにリクエストしています。


# ダイアログ作成の前にまず部品を作る

ダイアログを作成する前に、まずは必要な部品を作成しておく必要があります。ダイアログを作りながら、その都度、ユーザー発話やAlexa応答を作成することもできますが、予め会話設計したうえで、発話セットやAlexa応答を用意しておくほうが良いと思っています。

入門スキルは以下のような構成になっています。Built-in 以外のAPI定義、発話セット、オーディオ応答、視覚応答とスロットタイプの部品を作る必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/b3251d8e-791d-0485-091b-88694a173086.png)



#### API定義を作成する

API定義画面で１つずつ作成していきます。`Alexa Conversations 入門`スキルでは、以下の２つのAPIが定義されています。
API名と引数と戻り値を設定する作業は、関数定義みたいなものです。

|No.|API定義名|引数（スロットタイプ）|戻り値|
|:--|:--|:--|:--|
|1|GetFavoriteColor|なし|FavoriteColor|
|2|RecordColor|color（AMAZON.color）|FavoriteColor|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/5ed2e555-afcd-9709-ff1f-883e5c126606.png)



#### 発話セットを作成する

発話セット画面で１つずつ作成していきます。`Alexa Conversations 入門`スキルでは、以下の３つの発話セットが定義されています。
発話セットの注意点は、１つの発話に対してリクエストアクトを設定しなければならない点です。つまり、Affirm用の発話セットなのか、Invoke APIsの発話セットなのかを明確に指定してあげる必要があります。なので、最初に机上でダイアログアクトを検討する必要があったわけです。

作り方は、インテントを作るようなイメージです。マイグレーション後は、スロットではなくプロパティと表現されるようになりました。

スロットを使う場合は、タイプのコンフィギュレーションで、対象のスロットタイプを選択することで、必要なスロットが自動的にプロパティに表示されます。ここではcolorというプロパティが欲しいのでSpecifyFavoriteColorTypeを選択しています。

|No.|発話セット名|リクエストアクト|タイプのコンフィギュレーション|
|:--|:--|:--|:--|
|1|RecordFavoriteColor|Invoke APIs|なし|
|2|GetFavoriteColor|Invoke APIs|なし|
|3|SpecifyFavoriteColor|Inform Args|SpecifyFavoriteColorType|


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/46e8f2ff-24b5-cfca-efc5-620a08c5dc3e.png)

#### オーディオ応答を作成する

オーディオ応答画面で１つずつ作成していきます。`Alexa Conversations 入門`スキルでは、以下の３つのオーディオ応答が定義されています。
オーディオ応答の実態はAPL for Audio です。Alexa Conversations のAlexa の応答は全て APL for Audio で作成することになります。ですのでオーディオ応答は必須となります。

タイプのコンフィギュレーションでスロットタイプを指定しておくと、APL for Audioのpayloadでプロパティが参照できるようになります。
例：${payload.favoriteColor.color}


|No.|オーディオ応答名|タイプのコンフィギュレーション|プロパティ（スロットタイプ）|
|:--|:--|:--|:--|
|1|RecordColorSuccessPrompt|GetFavoriteColorSuccessResponseType|favoriteColor（FavoriteColor）|
|2|RequestFavoriteColorPrompt|なし|なし|
|3|GetFavoriteColorSuccessPrompt|GetFavoriteColorSuccessResponseType|favoriteColor（FavoriteColor）|



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/3b19df38-0cc7-d11d-9d84-6216552e8a09.png)

`！オーディオ応答を編集する` というリンクとは気づきにくい文字列をクリックすると、お馴染みのAPL for Audioエディタが別画面で開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/28f4b7bf-2004-1178-bea5-7aa60c647d12.png)


#### 視覚応答を作成する

視覚応答画面で１つずつ作成していきます。`Alexa Conversations 入門`スキルでは、以下の３つの視覚応答が定義されています。
視覚応答の実態はAPLです。視覚的な応答が不要な場合は、APL の作成は不要です。

タイプのコンフィギュレーションでスロットタイプを指定しておくと、APLのpayloadでプロパティが参照できるようになります。


|No.|視覚応答名|タイプのコンフィギュレーション|プロパティ（スロットタイプ）|
|:--|:--|:--|:--|
|1|RecordColorSuccessView|GetFavoriteColorSuccessResponseType|favoriteColor（FavoriteColor）|
|2|RequestFavoriteColorView|なし|なし|
|3|GetFavoriteColorView|GetFavoriteColorSuccessResponseType|favoriteColor（FavoriteColor）|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/19e2547f-693b-bfb0-1147-922e91ca6626.png)

こちらも同じで、`！APLツール` をクリックするとAPLエディターが起動します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/f502ee2d-5fc6-113d-7216-351605e40023.png)


#### スロットタイプを作成する

スロットタイプ画面で１つずつ作成していきます。`Alexa Conversations 入門`スキルでは、以下の３つのプロパティーが持てるスロットタイプと、１つの値を持つカスタムスロットが定義されています。
`プロパティーが持てるスロットタイプは`Alexa Conversations 用のスロットタイプです。

タイプ：プロパティを持つカスタムスロット

|No.|スロットタイプ名|プロパティ（スロットタイプ）|
|:--|:--|:--|
|1|FavoriteColor|displayLocale（ResponseString）<br>color（AMAZON.color）|
|2|GetFavoriteColorSuccessResponseType|favoriteColor（FavoriteColor）|
|3|SpecifyFavoriteColorType|color（AMAZON.color）|

タイプ：値を持つカスタムスロット

|No.|スロットタイプ名|スロット値|
|:--|:--|:--|
|1|ResponseString|これはアウトプットの際、複合スロットプロパティーのラベルにのみ使用されます|


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/5fc6fccf-83c8-4bcb-b0ef-ec290e7e3121.png)


# ダイアログを仕上げる

部品が揃ったらダイアログを作り上げていきます。
`Alexa Conversations 入門`スキルでは、以下の２つのダイアログが定義されています。ダイアログの作成画面では、１つのダイアログ毎にダイアログを作成していきます。

|No.|ダイアログ名|
|:--|:--|
|1|dialogName_GetFavoriteColor|
|2|dialogName_RecordFavoriteColor|

#### Step by Step 風で

ここでは`dialogName_RecordFavoriteColor`ダイアログを作る流れを記載します。

`USER:`と`ALEXA:`を１行１行設定していく必要があります。まずは `USER:` を作成するのですが、この`USER:`はダイアログの最初のターンなので、リクエストアクトは`Invoke APIs`となります。`Invoke APIs`を選択すると、`Invoke APIs` 用の発話セットがリスト表示されるので、対象の発話セット（RecordFavoriteColor）を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/4d9fb088-b29b-4935-2ff6-d49f3e925765.png)

発話セットを選択すると、`USER:` に自動的にサンプル発話が表示されます。これは、発話セット（RecordFavoriteColor）に定義されている一番上のサンプル発話が表示されています。そして、ミドリのチェックが付けば設定完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/2468b4e5-997c-f5bd-4c0c-ca6ba7eeb238.png)

次に`ALEXA:`の設定です。ここでは引数（color）を拾いたいので、その引数をユーザーにリクエストすることになります。ですので、応答アクトは`Request Args`となり、リクエストするAPIはRecordColorとなります。APIを選択するとリクエストするAPI引数に自動的に必要な引数（color）が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/5437ee2d-9875-3925-d39d-0049a760747c.png)

さらにオーディオ応答（RequestFavoriteColorPrompt）を選択すると、`ALEXA:`にAPL for Audioへのリンクが表示されます。このサンプルスキルは視覚応答もあるので、視覚応答（RequestFavoriteColorView）も選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/7d6fe7eb-f195-6abf-fb6c-30d69a4f6a19.png)

ダイアログはまだ続くので、`追加：ユーザーの発話` ボタンをクリックして`USER:`を１行増やします。Alexa Conversationsでは`ALEXA:`で終わるルールがあるので、この時点ではエラーが表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/678399f2-719c-8fb9-2749-668e28fe5814.png)

ですので、とりあえず`追加：ALEXAのセリフ`もクリックしてしまいましょう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/e7511bd0-9727-fe69-b78c-565647a2ffe7.png)

さて、２つ目の`USER:`を設定します。これは`Invoke APIs`と`API Success`の間に挟まれたターンのため`Inform Args`となります。`Inform Args`を選択すると、`Inform Args`用の発話セットがリスト表示されるので、対象の発話セット（SpecifyFavoriteColor）を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/25c99d64-4430-dd6a-5e5c-3983068fb6a0.png)

`USER:` に自動的にサンプル発話が表示されるとともに、ユーザー入力には自動的に`出力変数`が設定されます。これは次の`ALEXA:`に値を渡すために使用するもので、ここではcolorを保持するために使用しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/6d69d4f7-4e1c-78ab-a7eb-580cecae1e0e.png)

このダイアログの最後です。この`ALEXA:` でAPIを起動しますので、応答アクトは`API Success`となります。呼び出すAPIでRecordColorを選択すると変数名のドロップダウンが表示されますので、ここに先ほどの`出力変数`を選択して引数にcolorをセットしています（ここでAPIが呼ばれる）。レスポンスはFavoriteColorが返却されるので、それを変数にセットしています。
オーディオ応答と視覚応答は先ほどと同じです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/7509485e-1a60-6400-eaeb-160cdede4361.png)

変数をAPL for Audio、APLで使えるようにするために、GetFavoriteColorSuccessResponseTypeのプロパティ（favoriteColor）セットします。こでれ、APL for Audio、APL内のpayloadでプロパティ値が使えるようになります。
例：${payload.favoriteColor.color}

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/edef181e-5f01-57e5-443e-aba70d0ed2cc.png)


全ての設定を終えると、こんな感じになります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/0ac40230-bc6a-d69a-7864-c8a49f34c7b0.png)

もう一つのダイアログ`dialogName_GetFavoriteColor`を作ったら完成です。ビルドしてスキル試してみましょう。

# 入門スキルの動きはこんな感じ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/426739/5d5cc4a2-ea37-ebe7-e80c-0be5e6d54d98.png)


なんとなくおわかりいただけたでしょうか？
一部、新旧版を比較している部分もありますが、日本語版ベータは公開されて間もなくアップデートがありましたので旧版でスキルを作ることはないかもしれませんね。

おわりです。

# 参考
[What's New in Alexa Conversations / November 2021](https://developer.amazon.com/en-US/docs/alexa/conversations/whats-new-alexa-conversations.html#nov-2021)
[Alexa Conversationsとは](https://developer.amazon.com/ja-JP/docs/alexa/conversations/about-alexa-conversations.html)
[Tutorial: Annotate a Dialog for Alexa Conversations](https://developer.amazon.com/ja-JP/docs/alexa/conversations/tutorial-annotate-a-dialog-migrated.html#tie-together-elements)