Intelligent Technology's Technical Blog

株式会社インテリジェントテクノロジーの技術情報ブログです。

Alexa に、今日のうどん屋さんを決めてもらう

こんにちは。中山です。
我が家にも届きました。Amazon Echo Dot。
Amazon Echo Dot (Newモデル)、ブラック

この Amazon Echo、その機能を独自にいろいろと拡張できる「スキル」を、自分でも開発できるとのこと。
そこで今回は、
Alexa に「アレクサ、うどん屋さんを開いて。」とたずねると、「本日のおすすめは、***うどんです。」と教えてくれるスキル
というのを作ってみたいと思います。


目次:

Alexa Skills Kit(ASK)

Amazon Echo Dot で使える「スキル」は、スマートフォン向けに提供されている管理用アプリ( Alexa アプリ)から、いろいろ選んで、有効にしたり無効にしたりできるわけなのですが、それにしても、現状のラインナップはまだ数もそんなに多くなく、その内容も玉石混交といった感じ。
ちょうど、Android スマートフォンの黎明期のアプリストアによく似た様子だなと感じました。

この「スキル」の開発は、「Alexa Skills Kit(ASK)」を使います。

developer.amazon.com

「Alexa Skills Kit(ASK)」によく似たものとして、「Alexa Voice Service(AVS)」というのもあるようなのですが、こちらは、Alexa の機能自体を、Amazon Echo や、Echo Dot 以外のいろんな機器に組み込んで使う場合のサービスみたいです。

スキル開発のトレーニングコース

「スキル」開発に関しては、以下のようなトレーニングコースが用意されており、これにしたがって操作していくことで、誰でも簡単に「スキル」が作れるよ、ということのようです。

developer.amazon.com

スキルの種類

また、一言に「スキル」と言っても、以下のようにいくつか種類があるようです。

  • カスタムスキル : 汎用のスキル
  • スマートホームスキル : 家電製品などを制御するスキル
  • フラッシュブリーフィングスキル : ニュースなどを読み上げるスキル

今回は、いちばん基本的な「カスタムスキル」を作ってみたいと思います。

スキル実行のイメージ

「スキル」を実行する場合の処理フローのイメージは以下のような感じ。

https://m.media-amazon.com/images/G/01/mobile-apps/dex/alexa/alexa-skills-kit/jp/blog/alexa-skill-flow._CB492860132_.png

バックエンドには AWS の Lambda があり、ここで発話内容の解析と、それに応じたレスポンスの生成などを行うようです。

Amazon Developer アカウントの登録

「スキル」開発を始めるにあたって、まずは「Amazon Developer アカウント」の登録が必要となります。
Amazon 開発者ポータル」のページから「サインイン」をクリックして、アカウント登録を進めることになるのですが、ここでひとつ注意点が。

Alexa 開発者アカウント作成時のハマりどころ : Alexa Blogs

こちらのブログ記事にもあるとおり、そのまま新規にアカウント登録する場合、米国の Amazon にひもつけられたアカウントができてしまうことがある、とのこと。
基本的には、普段、amazon.co.jp のショッピングサイトで使っているアカウントを用いて、Developer アカウントも作るようにする、というのがよいようです。

そして「サインイン」クリック後、画面の指示にしたがってアカウントを作成します。(詳細な手順はこちらの「ステップ1. アカウントの作成」も参考に。)

AWS アカウントの登録

次に、AWS のアカウントをまだ持っていなければ、新しく登録します。具体的にはこちらの手順を参考に。
なお、AWS のアカウント作成の際、クレジットカード情報の登録が求められます。
しかし、今回「Alexa Skills Kit(ASK)」から利用することになる AWS Lambda については、あらかじめ用意されている無料枠などで、実質的にはほとんど費用は発生しないだろう、とのこと。

スキルの作成

トレーニングコースの「ステップ2. スキルの作成」の手順にしたがって、「Amazon 開発者コンソール」の画面から、新しく Alexa スキルの作成と設定を行います。

「スキル情報」の設定

「スキル情報」画面では、以下のように設定しました。
 f:id:IntelligentTechnology:20180210154541p:plain

「呼び出し名」の部分は、この文言を使ってスキルを呼び出すことになるので、ほかの既存のスキルと重複しない、かつ、発話・認識しやすいものにしないといけないため、けっこう重要になってくる部分です。
実際、最初ここに「今日のうどん」と設定しようとしていたのですが、これはなぜか認識精度が悪く、かわりに「うどん屋さん」に変えました。

「対話モデル」の設定

「対話モデル」画面では、「インテントスキーマ」欄に、以下のような値を設定します。

{ "intents": [
  { "intent": "GetNewUdonIntent" },
  { "intent": "AMAZON.HelpIntent" },
  { "intent": "AMAZON.StopIntent" },
  { "intent": "AMAZON.CancelIntent" }
]}

上記の「GetNewUdonIntent」は、後述の Lambda の関数内に、今回独自に定義する function。「うどん屋さん」という呼びかけがあったときに呼び出されるものです。
残りの「AMAZON.HelpIntent」「AMAZON.StopIntent」などは、もともと用意されているもので、それぞれ「ヘルプ」や「終了」に関する発話があったときに、自動的に呼び出される、というものです。

なお、この「対話モデル」画面に表示されている「スキルビルダー」という機能は、トレーニングコースの説明によると、現時点ではまだ使わないでくださいとのこと。(まだ動作が完全でない、とかだから?)
 f:id:IntelligentTechnology:20180208142921p:plain

同じく「対話モデル」画面で、「カスタムスロットタイプ」のところは空のままにしておいて、その下の「サンプル発話」欄に、以下のように設定します。

GetNewUdonIntent うどん屋さん
GetNewUdonIntent うどん屋
GetNewUdonIntent うどん

これは、「スキルと対話する際にユーザーが使いそうな発話例」となる、とのことです。
今回独自に定義する「GetNewUdonIntent 」function は、これらの「うどん屋さん」などの発話を検知したときに呼び出されるようになる、という設定です。
 f:id:IntelligentTechnology:20180210155347p:plain

この「開発者コンソール」画面側の設定は、まずはいったんここまで。

AWS Lambdaの構成

次に、AWS の Lambda 側のセットアップを行います。
トレーニングコースの「ステップ3. AWS Lambdaの構成」の手順にしたがって作業を進めます。

Lambda の「関数」に指定する情報は以下のとおり。
「ロール」は、「カスタムロール」を選択します。
トレーニングコースのページで説明されているものと、少し設定画面のレイアウトなどが異なっていますが、設定する内容自体は、ほとんど、このトレーニングコースで説明されているものと同じであるようです。
 f:id:IntelligentTechnology:20180208155120p:plain

1点だけ、「スキル ID」の設定の部分だけは、トレーニングコースの方に説明がありませんでした。
「Amazon 開発者コンソール」の画面のほうから、先ほど作成した「うどん屋さん」スキルの「スキル ID」を取得して、Lambda のほうの設定画面の「アプリケーションID」欄に設定します。

f:id:IntelligentTechnology:20180208162624p:plain

Lambda に登録する「関数」の内容の調整

Lambda に登録する「関数」は、もともとサンプルとして用意されているこちら( lambda.zip )を、少しカスタマイズして利用します。

この lambda.zip を展開した中の、「 index.js 」を以下のように修正して保存します。

'use strict';
var Alexa = require('alexa-sdk');

const APP_ID = "{ここにはスキルIDを指定}";

const SKILL_NAME = "うどん屋さん";
const GET_UDON_MESSAGE = "本日のおすすめは、";
const GET_UDON_MESSAGE_END = "です。";
const HELP_MESSAGE = "おすすめのうどんを知りたい時は「うどん屋さん」と、終わりたい時は「おしまい」と言ってください。どうしますか?";
const HELP_REPROMPT = "どうしますか?";
const STOP_MESSAGE = "さようなら";

const data = [
    "うどん <sub alias='いっぷく'>一福</sub>",
    "手打十段 うどんバカ一代",
    "本格手打うどん おか<sub alias='せん'>泉</sub>",
    "<sub alias='やまごえ'>山越</sub>うどん",
    "<sub alias='めんどころ'>麺処</sub> <sub alias='わたや'>綿谷</sub>",
    "もり<sub alias='や'>家</sub>",
    "釜あげうどん 長田in<sub alias='か'>香</sub>の<sub alias='か'>香</sub>",
    "さか枝",
    "谷川米穀店",
    "がもううどん"
];

exports.handler = function(event, context, callback) {
    let alexa = Alexa.handler(event, context);
    alexa.APP_ID = APP_ID;
    alexa.registerHandlers(handlers);
    alexa.execute();
};

let handlers = {
    'LaunchRequest': function () {
        this.emit('GetNewUdonIntent');
    },
    'GetNewUdonIntent': function () {
        let udonArr = data;
        // 一見、単純なランダム選択に見えるが、ここはスマートな人工知能が的確な判断を下しているつもりで
        let udonIndex = Math.floor(Math.random() * udonArr.length);
        let randomUdon = udonArr[udonIndex];
        let speechOutput = GET_UDON_MESSAGE + randomUdon + GET_UDON_MESSAGE_END;
        this.emit(':tellWithCard', speechOutput, SKILL_NAME, randomUdon)
    },
    'AMAZON.HelpIntent': function () {
        let speechOutput = HELP_MESSAGE;
        let reprompt = HELP_REPROMPT;
        this.emit(':ask', speechOutput, reprompt);
    },
    'AMAZON.CancelIntent': function () {
        this.emit(':tell', STOP_MESSAGE);
    },
    'AMAZON.StopIntent': function () {
        this.emit(':tell', STOP_MESSAGE);
    }
};

「うどん屋さん」スキルの呼び出しにより、高度な人工知能(を想定したもの)が、最適なうどん屋さんの名前を教えてくれる、という内容です。
この修正後のファイルを、再度 ZIP ファイルに固めます。( lambda ディレクトリの中身だけを ZIP 圧縮して固めるようにします。)

$ cd lambda
$ zip -r ../lambda.zip .

できあがった ZIP ファイルは、Lambda の設定画面にアップロードします。

Lambda の関数のテスト

トレーニングコースの「ステップ3. AWS Lambdaの構成」の手順にしたがって、Lambda の関数の単体での動作確認を行います。

以下のように、「イベントテンプレート」として「 Alexa Start Session 」を選択し、イベント名に適当な名前をつけます。下側に表示される JSON は、自動的に生成されるもので、こちらは編集の必要はありません。
 f:id:IntelligentTechnology:20180208180447p:plain

テストが成功すると、以下のような画面が表示されます。
 f:id:IntelligentTechnology:20180208180801p:plain

Lambda 関数の ARN を保存

Lambda 関数の設定画面右上に表示されている「ARN」の値を保存しておきます。
この値は、後述の手順で利用します。

f:id:IntelligentTechnology:20180208181635p:plain

Alexa スキルから、Lambda 関数を呼び出すための設定

Lambda 関数単体での動作は確認できたので、今度はこれを、Alexa スキルから呼び出してみます。
トレーニングコースの「ステップ4. スキルとLambdaの接続」の手順にしたがって、先ほど取得した Lambda 関数の「ARN」を、「Amazon 開発者コンソール」の、「設定」画面に登録します。

「サービスシミュレーター」で Alexa スキルを試す

最初は、「Amazon 開発者コンソール」に用意されている、「サービスシミュレーター」というスキルのシミュレータで動作を確認します。
トレーニングコースの「ステップ5. サービスシミュレーターによる動作確認」の手順にしたがって、動作確認を行います。

この「サービスシミュレーター」、残念ながら音声での操作はできないようなのですが、発話音声をテキスト化した、という想定の文字列をリクエストして、その結果をテキストデータとして受け取ることができる、というツールのようです。

今回の検証では
アレクサ、うどん屋さんを開いて。
という発話があったときに、どのような結果が返ってくるか、というのを試してみます。
 f:id:IntelligentTechnology:20180210163852p:plain

結果は上記のとおり。ひとまず成功のようです。
Alexa は、知る人ぞ知るうどん屋、「谷川米穀店」をチョイスしてくれました。
なお、右下の音声再生ボタンをクリックして、レスポンス内容を音声として聴くこともできます。

Amazon Echo Dot 実機でスキルを試す

開発したスキルは、正式に公開しなくても、Amazon Echo(または Amazon Echo Dot など)の実機で動作を試すことができます。
Alexa アプリ(Alexa の管理用アプリ)に、Amazon Developer アカウントと同じアカウントでログインすると、ここで作成したスキルが、「有効なスキル」の一覧に、自動的に登録されますので、これですぐに利用可能な状態になります。

ただ、実機でスキルを操作できるようにするために、あと少しだけ、準備の作業が必要となります。

「公開情報」の設定

「Amazon 開発者コンソール」の、「公開情報」画面に、このスキルに関する情報を埋めます。
今回は、正式に公開するわけではないので、仮の情報で埋めていくわけなのですが、だいたい、それっぽい情報を設定するようにします。
 f:id:IntelligentTechnology:20180210165504p:plain

「プライバシーとコンプライアンス」の設定

「Amazon 開発者コンソール」の、「プライバシーとコンプライアンス」画面も、それっぽく情報を設定します。
 f:id:IntelligentTechnology:20180210165755p:plain

ここまで設定を行い、「Amazon 開発者コンソール」画面の設定項目のすべてにチェックがつきましたら、実機での動作確認準備完了です。
 f:id:IntelligentTechnology:20180210170024p:plain

Alexa アプリでのスキルの確認

スキルの各設定が完了しますと、Alexa アプリの「有効なスキル」の「 DEV スキル」の部分に、開発したスキルが表示されます。
 f:id:IntelligentTechnology:20180210170247p:plain

すでにスキルが有効な状態で登録されています。
 f:id:IntelligentTechnology:20180210170353p:plain

Amazon Echo Dot での動作確認

実機での動作確認結果はこちら。


Alexa カスタムスキル 動作確認

実機では、Alexa は「釜バターうどん」でおなじみ、「手打十段 うどんバカ一代」をお勧めしてくれました。

まとめ

今回、シンプルなレスポンスを返すだけの「スキル」ということもあり、一度、設定が終わってしまえば、あとはソースコーディングの部分もそんなに複雑なものではないので、開発のハードルとしてはそんなに高くなさそうです。
重要になってくるのは、いかにユーザにストレスなく音声操作させるのか、かつ、ユーザが望む、的確なレスポンスを返せるか、といったところの細かな調整、といった部分になってくるのでしょう。

普段、Amazon Echo Dot を使っていますと、現在の天気の状況を聞いたり、タイマーやアラームをセットしたり、といった、ちょっとした作業が、音声だけで完結するのは、思った以上にメリットがあるのかなと感じました。
同じことをスマートフォンでやろうとすると、ロックを解除して、対象のアプリをタップして、アプリのボタンをタップして、みたいに、何ステップかの作業が発生するのですが、これがなくなるだけで、想像以上の利便性を感じることができます。
一方で音声だけではわかりにくい、という場面もありますので、今後、適材適所で、こういった「スマートスピーカー」と従来のスマートフォンとの住み分けが行われていくのかなと思いました。