スロットを使って任意の入力を受け付けよう
こんにちは。
スキルの開発の手順にはもう慣れましたか?
前回は開発の流れと、基本的なカスタムスキルの作り方について学びました。ユーザーがスキルとどのように対話をするかを決める「対話モデル」の設計方法についても学びましたね。
前回行った対話モデルの設計では、Alexaスキルが備える機能を表す「インテント」と、インテントをどのような言葉で呼び出すかを決める「サンプル発話」を扱いました。今回はさらに「スロット」と呼ばれる機能を使って、既定の発話サンプルにない情報を受け取る方法について学んでいきましょう。
連載2回目は、以下のテーマについて学びます。
- スロットを加えた設計
- スロットタイプ(組み込みスロットタイプ)を割り当てる
- カスタムスロットタイプを定義する
- Alexaとの複数回に渡るやりとり(ダイアログ)
それではさっそく始めましょう。
スロットを加えた設計
スロットとは簡単に言うと、「プログラミング言語における関数の引数のようなもの」です。次の対話例を見てください。
ユーザー:アレクサ、明日の東京都の天気を教えて
Alexa:○月○日の東京都の天気は概ね晴れ……
Alexaに天気を尋ねる際に、日付や場所の情報を指定することができます。上記の例では「明日」や「東京都」の部分ですが、これを受け取る引数に相当するのがスロットの役割です。
皆さんが開発するカスタムスキルではどうでしょうか。前回作成したスキルの例を見てみましょう。
ユーザー:アレクサ、来場者カウントで来場者数を教えて
Alexa:今日の来場者数は156人です
この対話では何のイベントであるか、いつの情報が欲しいかということを伝えていません。これらを追加すると、例えば次のような対話になるでしょう。
ユーザー:アレクサ、来場者カウントでAIフェスタの昨日の来場者数を教えて
Alexa: AIフェスタの○月○日の来場者数は208人でした
AIフェスタという(架空の)イベントが複数の日程で行われていて、そのうち昨日の来場者数が何人だったかを尋ねています。この問い合わせのサンプル発話を表現すると、次のようになります。
{eventName}の{eventDate}の来場者数を教えて
プログラミング言語のように、引数に当たる部分を{ }で囲んだ文字列に置き換えました。{eventName}の部分にユーザーが発した任意のイベント名、{eventDate}の部分に日付の情報が入ることを表しています。インテントのサンプル発話を表現する際にはこの記法を使います。さらにサンプルを追加しましょう。
{eventName}の来場者数を教えて
{eventName}の{eventDate}の来場者数を教えて
{eventCity}で開催の{eventName}の来場者数を教えて
{eventCity}で開催の{eventName}の{eventDate}来場者数を教えて
2行目は先ほどの例と同じですが、様々な問い合わせパターンに対応できるようにしています。省略した情報については既定の値({eventDate}であれば今日の日付など)を用いることにし、イベント名{eventName}は必須としましょう。ここまでの例で、次の3つのスロットが必要なことがわかりました。
- eventCity
- eventName
- eventDate
次は、これらのスロットにスロットタイプを割り当てます。
スロットタイプ(組み込みスロットタイプ)を割り当てる
多くのプログラミング言語の変数に「型」があるように、Alexaのスロットにも型が存在します。それを「スロットタイプ」と呼びます。Alexa Skills Kitには予めいくつかのスロットタイプが用意されており(組み込みのスロットタイプ)、日付や数値など、ほとんどのスキルに共通して使われそうなものはここから選択できます。以下にスロットタイプの一例を示します。
スロットタイプ | 説明 |
---|---|
AMAZON.DATE | 日付を表します。「今日」「明日」のように言葉で表現された場合には、内部で自動的に「2018-04-03」のような日付形式に変換されます |
AMAZON.TIME | 時刻を表します。「午後三時」などの言葉で表現された場合には、内部で自動的に「15:00」のような時刻形式に変換されます |
AMAZON.NUMBER | 数値を表します。 |
AMAZON.City | 都市の名前を表します。「東京都中央区」「京都市」などの都市の名前を表します。開発者が拡張することもできます。 |
より詳しい説明は、スロットタイプリファレンスのページをご覧ください。
組み込みのスロットタイプは、上記のように「AMAZON.」で始まる文字列で識別できるようになっています。
では、Alexa Skills Kit開発者コンソール(以降、開発者コンソール)でスロットの設定をしてみましょう。
前回作成した「来場者カウント」スキルの「VisitorCountIntent」編集画面を開きます。「インテントスロット」セクションにある「新しいスロットを作成」と書かれた入力欄に「eventCity」と入力して、その横の「+」をクリックします。
すると「スロットタイプを選択」と書かれた選択欄が有効になるので、「AMAZON.City」を選択します。色は自動的に割り当てられるようで、下記の画面とは異なるかもしれませんが、問題ありません。
同じようにして「eventDate」スロットを作成し、「AMAZON.DATE」を割り当てます。
さて、都市の名前でも日付でも数値でもない、{eventName}の場合はどのようにすればよいのでしょうか。イベント名としては任意の名称を受け付ける必要があります。このような場合には、組み込みのスロットタイプを使うのではなく、専用のスロットタイプタイプを新たに定義することができます。それが「カスタムスロットタイプ」です。
カスタムスロットタイプを定義する
それでは、イベント名を扱うためのカスタムスロットタイプを開発者コンソールで定義してみましょう。
まず左メニューから「スロット値(2)」と書かれた項目をクリックしてみてください。( )内の数値には現在使われているスロットタイプの数が入ります。「スロットのタイプ」ページが表示されたら「+スロットタイプ」をクリックして、新しいスロットタイプを作成します。
「スロットタイプ」欄に、これから作成するスロットタイプの名称を入力します。使用できるのは、アルファベットとアンダースコア(_)のみです。組み込みのスロットタイプで使われているピリオド(.)はここでは使用できません。今回は「EVENT_NAME」と入力して「カスタムスロットタイプを作成」をクリックします。
「スロットのタイプ」ページが表示されたら、このスロットが取り得る値、つまりここでは想定されるイベント名を入力していきます。「このスロットタイプの新しい値を入力」欄に文字列を入力し、[Enter]を押すことで値を登録できます。ここでは次の3つを登録しています。英数文字列と日本語文字列の間には、スペースを入れておきましょう。
- AI フェスタ
- ASK ユーザー会
- ジャパンアレクサデイズ
スロットタイプができたので、左メニューからVisitorCountIntentの編集ページに戻り、「eventName」スロットを追加します。スロットタイプには今作成した「EVENT_NAME」を選びます。
スロットの準備が整ったたら、サンプル発話を追加しておきましょう。
元々あったサンプル発話に加え、設計の項で挙げた4つのサンプルを新たに登録しています。スロットの部分は自動的に色分け表示されます。下記の画面の例と色が異なっていても問題ありません。完了したら、「モデルを保存」「モデルをビルド」の両方を実行しておきます。
ここまでの設定ができたら、スロットのデータを扱えるようにスキル・サービスにも変更を加えます。前回作成したAWS Lambdaの関数の中身を、以下のコード例1のように書き換えてください。APP_IDはスキルのエンドポイントのページで取得したスキルIDです。
'use strict'; const Alexa = require('alexa-sdk'); //============================================================================= //TODO: The items below this comment need your attention. //============================================================================= //Replace with your app ID (OPTIONAL). You can find this value at the top of your skill's page on http://developer.amazon.com. //Make sure to enclose your value in quotes, like this: const APP_ID = 'amzn1 .ask.skill.bb4045e6-b3e8-4133-b650-72923c5980f1'; const APP_ID = 'amzn1.ask.skill.b6030ab0-d878-4bd3-bff0-790750d638d2'; const SKILL_NAME = '来場者カウント'; const HELP_MESSAGE = '来場者数を教えて、で今日の来場者数をお知らせします'; const HELP_REPROMPT = '何をお調べしますか'; const STOP_MESSAGE = '終了します'; const visitorCount = 156; //============================================================================= //Editing anything below this line might break your skill. //============================================================================= const handlers = { 'LaunchRequest': function () { // このスキルを「開いて」とリクエストした場合に呼び出される // 今回は既定では何もしない this.emit(':responseReady'); }, 'VisitorCountIntent': function () { // VisitorCountIntent に対応して呼び出される // インテントObjectを取得する let intent = this.event.request.intent; // スロットの値を取得する var eventCity = intent.slots.eventCity.value; var eventName = intent.slots.eventName.value; var eventDate = intent.slots.eventDate.value; // 結果を生成する const speechOutput = eventCity + 'の' + eventName + 'の' + eventDate + 'の来場者数は' + visitorCount + '人です'; // Alexa アプリで参照できる情報 (カード) を返す this.response.cardRenderer(SKILL_NAME, speechOutput); // 音声で返答する this.response.speak(speechOutput); this.emit(':responseReady'); }, 'AMAZON.HelpIntent': function () { const speechOutput = HELP_MESSAGE; const reprompt = HELP_REPROMPT; this.response.speak(speechOutput).listen(reprompt); this.emit(':responseReady'); }, 'AMAZON.CancelIntent': function () { this.response.speak(STOP_MESSAGE); this.emit(':responseReady'); }, 'AMAZON.StopIntent': function () { this.response.speak(STOP_MESSAGE); this.emit(':responseReady'); }, }; exports.handler = function (event, context, callback) { const alexa = Alexa.handler(event, context, callback); alexa.APP_ID = APP_ID; alexa.registerHandlers(handlers); alexa.execute(); };
VisitorContentIntentのハンドラーで、インテントのObjectからスロットの値を取得しています。
//インテントObjectを取得する let intent = this.event.request.intent; //スロットの値を取得する var eventCity = intent.slots.eventCity.value; var eventName = intent.slots.eventName.value; var eventDate = intent.slots.eventDate.value;
eventCity、eventName、eventDateの3つのスロット値を取得し、それをそのまま返答内容に含めています。まずはこの状態でテストしてみましょう。
期待した結果になりましたでしょうか。サンプル発話が長く、一息で間違えずに言うのはなかなか難しいかもしれません。
次に、日付を省略すると今日の情報を返すというように、より簡単な言葉でもリクエストできるようにしたいと思います。Alexa Skills Kitに用意されている「ダイアログ」という機能を使うと、これらを簡単に実現できます。
連載バックナンバー
Think ITメルマガ会員登録受付中
全文検索エンジンによるおすすめ記事
- Alexaのスキルを作ってみよう
- Alexa Skills Kit SDK for Node.jsについて知る
- Androidの重要な機能、インテント
- LINE、開発者向けカンファレンスでスマートスピーカーWAVEを実現するAI、Clovaの概要などを解説
- ECMAScript
- 「Ace」を使って「TAURI」で「テキストエディタ」アプリを作ろう
- IBMとAmazonのAIプラットフォーム
- Socket.IOを使ってNode.jsでリアルタイムWebアプリを開発する
- Amazonの今後の展開は? 音声アシスタント『Alexa』がより使いやすくアップデート
- ES2015で導入された、より洗練された構文 Part 1