[Alexa] スロット値にシノニム(同義語)を設定してみる
1 はじめに
スロットには、シノニム(同義語)設定が可能です。
スロットには、組み込みスロットと、独自に定義するカスタムスロットがありますが、シノニムは、どちらのスロットでも設定可能です。(組み込みスロットの場合、追加した値でのみ利用可能)
一例ですが、あるインテントで、「"song" というスロットを受け取りたい」とした場合、カスタムスロット(仮に、MEDIA_TYPEとする)を作成し、その値として "song" を定義することになります。 そして、“track”や、“single”といった発話も、同じ意味で許容したい場合、これらも、カスタムスロットに追加することになります。
しかし、シノニムを使用すると、カスタムスロットに値を増やすのではなく、"song"の同義語として追加する事ができます。 シノニムを使用しない場合、複数のスロット値をスキル側で同じものとして扱う処理が必要になりますが、シノニムでは、それを開発者コンソールのInteraction Modelに押し込む事が可能になります。
今回は、このシノニムの利用方法について確認してみました。
2 シノニムの設定
シノニムを設定するには、Skill-builder(beta) を使用する必要があります。
Skill Builder(bata) では、スロットタイプに値を追加する時、各スロットの値(VALUE)に併せて、IDとシノニム(SYNONYMS)が定義できます。
また、Code Editorで、JSONを直接編集することもできます。
3 Custom Slot Type
Custom Slot Typs のJSON形式では、typesプロパティをオブジェクトの配列として指定しています。各オブジェクトは、一つのCustom Slot typeを表現し、名前とIDの配列を含みます。
{ "types": [ { "name": "MEDIA_TYPE", "values": [ { "id": "SONG", "name": { "value": "song", "synonyms": [ "single", "track" ] } } ] } ] }
各オブジェクトは、次のとおりです。
key | description |
---|---|
name | スロットの名前(アンダースコアと英字のみ) |
values | スロット値を定義するオブジェクトの配列 |
values[].id | スロット値の識別子(検出するとIntentRequestに含まれる。スペースは使用できない) |
values[].name | エンティティ(スロットの文字列と同義語を含む) |
values[].name.value | スロット値の標準的な文字列 |
values[].name.synonyms | スロット値の同義語の配列 |
4 スロット解決
Alexa からスキルに送信されるrequestには、スロット値に関する追加情報が含まれています。 次のJSONは、ユーザが"song"と発話し、スロットにヒットした時の例です。
nameがスロット値で、valueが、ユーザーの発話です。
後ろに、resolutionsPerAuthorityというKeyがあり、その中の、status.codeを見ると、ER_SUCCESS_MATCHとなており、標準値もしくは、同義語にマッチした事が分かります。
"song"と発話した場合
"request": { "type": "IntentRequest", "requestId": "amzn1.echo-api.request.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", "timestamp": "2017-07-19T10:14:34Z", "locale": "en-US", "intent": { "name": "PlaySongIntent", "confirmationStatus": "NONE", "slots": { "song": { "name": "song", "value": "song", "resolutions": { "resolutionsPerAuthority": [ { "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.MEDIA_TYPE", "status": { "code": "ER_SUCCESS_MATCH" }, "values": [ { "value": { "name": "song", "id": "SONG" } } ] } ] }, "confirmationStatus": "NONE" } } } }
続いて、同義語として定義した"single"と発話した場合です。こちらも、ER_SUCCESS_MATCHが確認できます。
"single"と発話した場合
"slots": { "song": { "name": "song", "value": "single", "resolutions": { "resolutionsPerAuthority": [ { "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.MEDIA_TYPE", "status": { "code": "ER_SUCCESS_MATCH" }, "values": [ { "value": { "name": "song", "id": "SONG" } } ] } ] },
マッチしない場合は、下記のようになりました。 ユーザーは、"sample"と発話しており、status.codeは、ER_SUCCESS_NO_MATCH
"sample"と発話した場合
"slots": { "song": { "name": "song", "value": "sample", "resolutions": { "resolutionsPerAuthority": [ { "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.MEDIA_TYPE", "status": { "code": "ER_SUCCESS_NO_MATCH" } } ] },
5 開発者ポータルのテスト
先の例のように、定義したスロット値にマッチしているかどうかは、status.codeを見ないと分かりませんが、開発者ポータルのTestからでは、resolutionsPerAuthorityが自体が含まれていないので注意が必要です。
"song"と発話した場合
"slots": { "song": { "name": "song", "value": "song" }
"sample"と発話した場合
"slots": { "song": { "name": "song", "value": "sample" }
6 シノニムを使用しない場合のスロット解決
シノニムを使用していない場合でも、resolutionsPerAuthorityは同じで、status.codeでマッチしたかどうかを確認できます。そして、マッチした際には、idが自動的に割り振られているようです。
ヒットした場合
"slots": { "song": { "name": "song", "value": "song", "resolutions": { "resolutionsPerAuthority": [ { "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.8d681e39-b94e-4110-badc-436be24c9aef.MEDIA_TYPE", "status": { "code": "ER_SUCCESS_MATCH" }, "values": [ { "value": { "name": "song", "id": "683eb609607a439b0561dcbb4c8329e8" } } ] } ] }, "confirmationStatus": "NONE" } }
ヒットしない場合
"slots": { "song": { "name": "song", "value": "sample", "resolutions": { "resolutionsPerAuthority": [ { "authority": "amzn1.er-authority.echo-sdk.amzn1.ask.skill.8d681e39-b94e-4110-badc-436be24c9aef.MEDIA_TYPE", "status": { "code": "ER_SUCCESS_NO_MATCH" } } ] }, "confirmationStatus": "NONE" } }
7 最後に
今回、シノニムの利用方法について確認して見ました。
発話の集約を、スキル側と、Interaction Model側の、どちら行う方が有利なのかという判断は、その要件によって変わってくると思います。
しかし、煩雑な処理をスキル側から排除して、よりロジックに集中できるいう意味では、シノニムは有効でしょう。
なお、今回、スロット値の解決を確認していて気がついたのですが、下記のようなコードは、スロット値として定義していないものが入っている可能性があることに留意が必要です。
var song = this.event.request.intent.slots.song.value;
そして、マッチしているかどうかの判断するための、ER_SUCCESS_MATCHが、検索してもほとんど出てこないことに、ちょっとモヤッとしてます。
定義した語にマッチしているかどうかは、あまり意味がなく、「AlexaがSlotsに入れた」という事実が重要ということでしょうか・・・・
8 参考リンク
Define Synonyms and IDs for Slot Type Values (Entity Resolution)
Use the Skill Builder (Beta) to Define Intents, Slots, and Dialogs
Entity Resolution in Skill Builder