この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
1 はじめに
AIソリューション部の平内(SIN)です。
先日、カスタムリストを動的に操作できるDynamic Entitiesという機能が追加されました。
Use Dynamic Entities to Create Personalized Voice Experiences
Dynamic Entitiesを使用すると、実行時に動的にカスタムリストに新しい値を追加することができます。
これの利用例としては、以下のようなものが上げられます。
- 期間限定のメニュー追加する
- パーソナライズされた商品リスト
- 状況に応じた選択
ということで、早速試してみます。
2 クラメソ亭
テストのために作成したスキルは、ラーメンの注文受けるものです。
提供される味は、「塩」、「味噌」、「醤油」の3種類となるため、「豚骨」を注文すると断られてしまします。
メインのインテントOrderIntentは、「ラーメンを下さい」と発話すると突入できるようになっています。
OrderIntentは、必須のスロットとしてflavorがあり、そのタイプはカスタムスロットであるlist_of_flavorとなっています。
カスタムスロットlist_of_flavorは、次のように、「塩」、「味噌」、「醤油」が定義されています。
ここで、OrderIntentを処理するコードは、以下のようになっています。スロットに無効な値が入ったときは、選択できる味を提案できるように、ER_SUCCESS_MATCHを確認しています。
const OrderIntentHandler = {
canHandle(h) {
return isMatch(h, 'OrderIntent');
},
handle(h) {
let flavor = '';
const resolutionsPerAuthority = h.requestEnvelope.request.intent.slots.flavor.resolutions.resolutionsPerAuthority;
resolutionsPerAuthority.forEach( authority => {
if(flavor === '' && authority.status.code === 'ER_SUCCESS_MATCH') {
flavor = authority.values[0].value.id;
}
})
if (flavor === '') { // ER_SUCCESS_MATCHがない場合
flavor = h.requestEnvelope.request.intent.slots.flavor;
return h.responseBuilder
.speak('すいません、' + flavor.value + 'は、ありません。塩、味噌、醤油からお選び下さい')
.addElicitSlotDirective("flavor")
.getResponse();
}
return h.responseBuilder
.speak(flavor + "をご用意致します。")
.getResponse();
}
};
3 カスタムスロットの動的追加
期間限定ですが、「塩」、「味噌」、「醤油」に加えて「豚骨」を提供できるようになった場合、従来は、カスタムスロットに値を追加する必要がありましたが、DynamicEntitiesを使用すると、コードだけで対応可能になります。
下記のコードは、LaunchRequestを処理する際に、 Dialog.UpdateDynamicEntitiesを使用して、カスタムリストlist_of_flavorに「豚骨」を追加しました。
const LaunchRequestHandler = {
canHandle(h) {
return isMatch(h, 'LaunchRequest');
},
handle(h) {
let replaceEntityDirective = {
type: 'Dialog.UpdateDynamicEntities',
updateBehavior: 'REPLACE',
types: [
{
name: 'list_of_flavor',
values: [
{
id: '豚骨',
name: {
value: '豚骨',
synonyms: ['豚骨味']
}
}
]
}
]
};
const speechText = 'ようこそ、クラメソ亭へ。ご注文をどうぞ';
return h.responseBuilder
.speak(speechText)
.reprompt(speechText)
.addDirective(replaceEntityDirective)
.getResponse();
}
};
上記の追加によって動作が変わり、「豚骨」を受けつけるようになりました。
理由は、 xxxx.dynamic.amzn1.ask.skill.xxxx.list_of_flavorという動的なリストで「豚骨」がヒットし、ER_SUCCESS_MATCHになったためです。
"slots": {
"flavor": {
"name": "flavor",
"value": "豚骨",
"resolutions": {
"resolutionsPerAuthority": [
{
"authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.0990f979-17ce-4225-940d-f0cb03341e9f.list_of_flavor",
"status": {
"code": "ER_SUCCESS_NO_MATCH"
}
},
{
"authority": "amzn1.er-authority.echo-sdk.dynamic.amzn1.ask.skill.0990f979-17ce-4225-940d-f0cb03341e9f.list_of_flavor",
"status": {
"code": "ER_SUCCESS_MATCH"
},
"values": [
{
"value": {
"name": "豚骨",
"id": "豚骨"
}
}
]
}
]
},
"confirmationStatus": "NONE",
"source": "USER"
}
}
4 制限など
(1) リストの評価順序
予め設定されている値と、動的に追加した値がヒットする評価順序は、以下のとおりです。
- 動的エンティティのカスタムスロット
- 動的エンティティの拡張ビルトイン
- 静的エンティティのカスタムスロット
- 静的エンティティの拡張ビルトイン
(2) サンプル発話では使用できない
スキルを引き出すためのサンプル発話には、動的エンティティは使用できません。
(3) 追加の上限
スロットタイプごと値と同義語の組み合わせの合計は、100を超えると403エラーが発生し、動的な追加は失敗します。
(4) 上書き
Dynamic Entitiesは、いつでも更新(上書き)することができます。
(5) ワンショットでは利用できない
Dialog.UpdateDynamicEntitiesを返すためには、一度は、リクエストを処理しなければなりません。したがって、ワンショットでインテントに突入する場合などは、そのタイミングが無いため利用できません。
今回の例で行くと、「クラメソ亭でラーメンを下さい」というような使い方をすると、LaunchRequestが呼ばれないため、Dialog.UpdateDynamicEntitiesを返すことができません。
5 最後に
色々と制約はありますが、動的にカスタムリストを操作できることは、非常に強力だと思います。
今回試した全コードは、下記に置いてます。
https://github.com/furuya02/DynamicEntitiesSample
6 参考リンク
Use Dynamic Entities to Create Personalized Voice Experiences
Use Dynamic Entities for Customized Interactions
弊社ではAmazon Connectのキャンペーンを行なっております。
3月に引き続き、4月も「無料Amazon Connectハンズオンセミナー」を開催致します。導入を検討されておられる方は、是非、お申し込み下さい。
また音声を中心とした各種ソリューションの開発支援も行なっております。