日本語のAlexaスキルの作り方(30分あればAmazon Echoがなくても試せるよ)

この記事を読んだらできるようになること

  • 簡単なAlexaスキルを作って、シミュレータ上で試せるようになります。

この記事で伝えたいこと

  • シミュレータをつかえば、Amazon Echo実機がなくてもスキルを試せるぞ。
  • VUI(Voice User Interface)を開発したいひとは、Alexa Skills Kitのドキュメントを読むと参考になるぞ。

今回作ったもの

youtu.be

「アレクサ、むすんでひらいててのなるほうへ」というと、
「またひらいて、てをうって、そのてをうえに」と返ってくるスキルを作りました。


このエントリーのターゲット

  • Amazon Echoを購入できていないけど、試しにAlexaスキルを作ってみたい人に向けて書いてます。

※ 僕自身、招待メールをリクエストしているものの、まだ購入できてません。。。
※ 当然、購入できた人も楽しめる内容になっております
※ すでにスキルを開発したことがある人には退屈な内容だと思います


はじめに

こんにちは。
Tech KAYAC Advent Calendar 2017の6日目の記事をお届けします。マットでマックスなフロントエンジニア、 @ki_230 です。

ついに日本でも、 Amazon Echo が発売されましたね。

Amazon Echo (Newモデル)、サンドストーン (ファブリック)

Amazon Echo (Newモデル)、サンドストーン (ファブリック)

僕も、Amazon Echo Dot を購入しようと思い、招待メールをリクエストしたのですが、
残念ながらまだ招待が届かず、購入できておりません。。。(上記ムービーは友達のものを借りて撮影しました)
きっと、まだまだそういう人も多いと思いんじゃないでしょうか。

Amazon Echo Dot (Newモデル)、ホワイト

Amazon Echo Dot (Newモデル)、ホワイト

そんなあなたに朗報です。

本日は、Amazon Echoが購入できていなくても、
日本語のAlexaスキルを作って試せる方法を紹介します。

実際にスキルを作ってみてから購入を検討したり、商品が届くまでにスキルを作ってみたりする際に活用頂ければ幸いです。


本格的にスキルを作ってみたい方は、
時間があるときに下記のリンクを読んだほうが参考になります。
なぜならば。本エントリーでは、本当に触りの部分だけを最速で試すことを目的としているからです。

developer.amazon.com
developer.amazon.com


事前に準備するもの

  1. Amazon開発者ポータルのアカウント( https://developer.amazon.com
  2. AWSのアカウント ( https://aws.amazon.com

Amazon Echoの実機がなくとも、シミュレータで挙動の確認ができるので実機は必須でありません。
本当はAWSも必須ではないのですが、開発の手間が変わってくるので、本エントリーではAWSをつかった開発方法を紹介します。


事前に覚えておいたほうが良い用語

まずは、認識を合わせるために基本的な用語を説明します。

  • Amazon Echo

Amazonが作ったスマートスピーカー。
2017年通年で世界で2,400万台売れると予想されているすごいやつ。
執筆時では、選ばれし者のみが購入できる状況。(招待メールが来ないと買えない)

  • Alexa

AIアシスタントの名前。Amazon Echoに搭載されている。
iPhoneでいうところのSiriと思って頂ければ。

  • Alexaスキル

iPhoneでいうところのiPhoneアプリ。
Amazon Echoで動くプログラムのようなもの。
Alexaアプリと表現すると、違うもの(AmazonEchoのAlexaを設定するためのアプリ)になるので注意。


事前に覚えて置いたほうが良いスキル用の用語

次に、スキル開発にでてくる基本的な用語を説明します。

  • 起動ワード

Alexaに指令を出す前に必要な呼びかけ。Siriでいうところの「Hey Siri」。
シミュレータで試すときには不必要。
選ばれし者(実機を買えた人)は本体設定で、「アレクサ」「アマゾン」「コンピュータ」「エコー」から選択可能。
※ 「エコー」も選択可能ということを選ばれし者に教えていただきました。 [12月7日12:00 追記]

  • スキルの呼び出し名

スキルを呼び出すときの呼び方。スキル名と異なっていてもOK。

  • インテント

ユーザーの音声によるリクエストを満たすアクション。
メソッドのようなものだと思って頂ければ。

  • スロット

インテントに渡す引数。(今回は登場せず)

  • サンプル発話

インテントを呼び出すためのフレーズ。
1つのインテントに複数のサンプル発話を登録可能。
僕の頭の中では、「発話」の部分に「フレーズ」とルビを振って、「さんぷるふれーず」と音にしています。

  • SSML

音声合成マークアップ言語。
今回はSDKをつかってサンプルを作るので、特に意識しなくてもOK。
今後、もっと難しいことをやりたくなった場合はSSMLの書き方を調べてみると良いです。



本エントリーを読む際には、
上記のようなイメージを持っていれば問題ないのですが、
もっと正確な情報を知りたい方はこちらのページをご確認ください。

developer.amazon.com

そして、なんとなく図にすると、こんな感じです。
f:id:kimizuka:20171204144546p:plain

Alexaは起動ワードからサンプル発話までを一気に言えるところがすごいですね。
Siriだと、

😃 「Hey Siri」

📱(ピコン) 

😃 「今日の天気をおしえて」

📱「ハイ、今日ノ天気予報デス」

と、「起動ワード」と「質問」をわける必要がありますが、
流石はスマートスピーカーに特化したAIといったところでしょうか。

当然、一度スキルを立ち上げた後であれば、
起動ワードを言わずに「サンプル発話」だけで処理を実行するようにすることもできます。
(今回作成するサンプルでは対応してません)


今回作るもの

上記のおみくじを作ってみても良いんですが、
ちょっと変化球で、

f:id:kimizuka:20171204145440p:plain

という感じで起動できるスキルを作ってみたいと思います。

スキルの呼び出し方が、

<呼び出し名> を起動して <アクション>
<呼び出し名> を実行して <アクション>
<呼び出し名> をスタートして <アクション>
<呼び出し名> を呼び出して <アクション>
<呼び出し名> 開いて <アクション>
<呼び出し名> 起動して <アクション>
<呼び出し名> 実行して <アクション>
<呼び出し名> スタートして <アクション>
<呼び出し名> 呼び出して <アクション>

https://developer.amazon.com/ja/docs/custom-skills/understanding-how-users-invoke-custom-skills.html

と、色々あるのですが、「開いて」という呼び出し方を最大限に活かしたスキルと言えるでしょう。
何の役にもたちませんが、まあサンプルなので良いでしょう。

イメージ図にすると、こんな感じです。

f:id:kimizuka:20171205142032p:plain
※ 本体が音声をJSONにしているのかは定かではないですが、Lambdaには音声をテキストにしたJSONが送られてきます。
※ 後の調査で音声をサーバに送り、サーバからLambdaにJSONを送っているらしいということがわかりました。 [12月13日12:00 追記]

Amazon EchoはただのI/Oで、処理自体はすべてLambdaファンクションで行います。

なので、今回作るものは主に、 Lambdaファンクション です。
あとは、 Amazon開発者ポータル にて サンプル発話インテント の紐付け、AlexaスキルLambdaファンクション の紐付けを行えば、Amazon Echoから動作させることができますし、実機がなくともシミュレータで動作させることができるようになります。


作る

では、いよいよここからは実際に手を動かしていきましょう。
僕は、マットでマックスなフロントエンドエンジニアなのでAWSのアカウントすら持っていなかったのですが、
AWS自体の契約も簡単にできましたし、開発も言語がNode.jsだったこともあり、驚くほどあっという間に作ることができました。

Lambda側でのもろもろ

1. 新規Lambdaファンクションを作る

f:id:kimizuka:20171204171043p:plain

AWS( https://aws.amazon.com )にアクセスして、左上の「サービス」からLambdaを選択し、「関数を作成」をクリックしましょう。
僕は、記念すべきはじめてのLambdaファンクションでした。(AWSもこのためにつかいはじめました)
以前はリージョンを「バージニア北部」にしないといけなかったようなの記憶がありますが、いまは普通に「東京リージョン」で開発しても問題ありませんでした。


2. 設計図を選ぶ

f:id:kimizuka:20171204172244p:plain

関数を作るとき、「一から作成」と「設計図」を選ぶことができるのですが、
今回は「alexa-skill-kit-sdk-factskill」の「設計図」をつかってさくっと作りましょう。
設計図一覧に「alexa」とかでフィルターを掛けると簡単に見つかります。


3. 名前をつけたり、ロールを選んだりする

f:id:kimizuka:20171204172744p:plain

名前をつけたり、ロールを選んだりして、一旦関数を作成します。
この時点ではコードは設計図通りのものでOKです。


4. トリガーを選択する

f:id:kimizuka:20171204174151p:plain

トリガーを、

f:id:kimizuka:20171204174648p:plain

「Alexa Skills Kit」に設定します。


5. コードを編集する

f:id:kimizuka:20171204175043p:plain

Lambdaは、この画面上でコードを編集することもできますし、コードを圧縮し、Zip形式でアップロードすることもできます。
今回はそんなに長くないコードなので、このままインラインで書いてしまいましょう。
内容も、Node.jsが読める人であれば全然難しいことは無いと思います。

index.js

"use strict";

const Alexa = require("alexa-sdk"); // 設計図を使うと npm install なしで require できます

const languageStrings = { // ゆくゆくの多言語対応に備えて
    "ja": {  // 今回は日本語のみ対応します。
        translation: {
            ANSER_MESSAGE: "またひらいて、てをうって、そのてをうえに。",
            HELP_MESSAGE: "このスキルは、むすんでひらくスキルです。",
            STOP_MESSAGE: "スキルを終了します。",
        },
    },
};

const handlers = {
    // 起動時の処理
    "LaunchRequest": function () {
        this.emit("AMAZON.HelpIntent");
    },
    // 「ヘルプ」とか言ったときの処理
    "AMAZON.HelpIntent": function () {
        const speechOutput = this.t("HELP_MESSAGE");

        this.emit(":tell", speechOutput);
    },
    // 「キャンセル」とか言ったときの処理
    "AMAZON.CancelIntent": function () {
        this.emit("AMAZON.StopIntent");
    },
    // 「ストップ」とか言ったときの処理
    "AMAZON.StopIntent": function () {
        const speechOutput = this.t("STOP_MESSAGE");

        this.emit(":tell", speechOutput);
    },
    // 「てをうってむすんで」とか言ったときの処理(Amazon開発者ポータル側で設定予定)
    "HandClapIntent": function() {
        const speechOutput = this.t("ANSER_MESSAGE");

        this.emit(":tell", speechOutput);
    }
};

exports.handler = function (event, context) {
    const alexa = Alexa.handler(event, context);

    alexa.resources = languageStrings; // 言語を設定
    alexa.registerHandlers(handlers); // ハンドラの登録
    alexa.execute(); // 実行
};

ちょっとだけ、コードを解説します。
基本的にはexports.handlerで関数をひとつエクスポートしているだけです。

alexa.registerHandlers(handlers);

の部分でhandlersをいう名前のオブジェクトを登録しているのですが、
LaunchRequest は起動した時、今回で言うと、「アレクサ、むすんでを起動して」とかで実行される予定の内容。(Amazon開発者ポータル側で設定予定)

AMAZON.HelpIntentは「ヘルプ」とかで実行される内容。
AMAZON.CancelIntentは「キャンセル」とかで実行される内容。
AMAZON.StopIntentは「ストップ」とかで実行される内容。

その中でも、Amazon.XXXという3つインテントに関しては、「標準ビルトインインテント」と呼ばれ、
「サンプル発話」を登録すること無く使用することができます。
今回はデモ用なので問題ありませんが、スキルを公開しようとすると、AMAZON.HelpIntentAMAZON.CancelIntentAMAZON.StopIntentの3つは必須なようです。

標準ビルトインインテントの一覧は こちら にまとまっているので、本格的な開発を考えている人は時間があるときに一度目を通してみることをおすすめします。

developer.amazon.com

また、HandClapIntentを例に、読み上げの部分を説明します。

"HandClapIntent": function() {
    const speechOutput = this.t("ANSER_MESSAGE"); // => 本体の言語のANSER_MESSAGEが入るので、日本語環境下では、speechOutputに、またひらいて、てをうって、そのてをうえに。"が入ります。

    this.emit(":tell", speechOutput); // => ":tell"だと応答後終了、":ask"だと応答後待受状態になります
}

という感じです。
機会音声での読み上げであればSSMLを意識しなくとも、読み上げたい内容をStringで渡せばOKです。


6. LambdaのARN(Amazonリソースネーム)を覚えておく

f:id:kimizuka:20171204174648p:plain

スクリーンショット上では消していますが、右上に表示されているarnから始まる文字列は、Lambdaとスキルを紐付ける際に必要となるのでメモしておきましょう。

Amazon開発者ポータル側でのもろもろ

1. Amazon開発者ポータルにアクセス

f:id:kimizuka:20171205150155p:plain

https://developer.amazon.com にアクセスして、
上部メニューから「Alexa」タブを選択し、

f:id:kimizuka:20171205174336p:plain

「Alexa Skills Kit」の方の「始める >」ボタンを押しましょう。


2. 新しいスキルを作る

f:id:kimizuka:20171205150710p:plain

右上の「新しいスキルを追加する」ボタンを押します。


3. スキルの情報を入力

f:id:kimizuka:20171205150822p:plain
f:id:kimizuka:20171205150843p:plain

スキルの種類 👉 カスタム対話モデル
言語 👉 Japanese
スキル名 👉 むすんでひらいで
呼び出し名 👉 むすんで

で、グローバフィールドはすべて「いいえ」と回答しました。
スキルの呼び出し名」はここで設定します。

4. 対話モデルを入力

f:id:kimizuka:20171205151342p:plain
f:id:kimizuka:20171205151353p:plain

ここで、インテントとサンプル発話を結びつけます。

インテントスキーマには、

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

と、標準ビルトインインテントを含めて、使用するインテントの一覧を記載しています。
今回はスロットをつかっていないので、単純にインテント名を記載しただけです。

サンプル発話には、

HandClapIntent てをうってむすんで
HandClapIntent てを打ってむすんで
HandClapIntent てを打って結んで
HandClapIntent てをうって結んで
HandClapIntent 手をうってむすんで
HandClapIntent 手を打ってむすんで
HandClapIntent 手をうって結んで
HandClapIntent 手を打って結んで

という感じで、HandClapIntentに対するサンプル発話を記載しました。


4. Lambdaファンクションと紐付ける

f:id:kimizuka:20171205152700p:plain
f:id:kimizuka:20171205152712p:plain

「サービスエンドポイントのタイプ」を「AWS Lambdaのarn(Amazonリソースネーム)」にして、
「デフォルト」の部分に、先程メモしていた、Lambdaのarn(Amazonリソースネーム)の文字列を入力します。


5. シミュレータで試す

f:id:kimizuka:20171205153413p:plain

ここまで終われば、シミュレータ上で実行できます。
手を動かす如何としては30分あればお釣りが来るのですが、文章にするととても長くなってしまいました。。。

それでは、テキストのタブで発話を入力し、
登録しているサンプル発話を入力して、
「むすんでひらいてを呼び出す」ボタンを押してみましょう。

すると、、、

f:id:kimizuka:20171205160314p:plain

やったー。

エラーなく、JSONが返ってくることが確認できました。
右下の「聞く」ボタンを押すと、音声を再生することもできます。

これが、実機において「アレクサ、むすんでひらいててをうってむすんで」と呼びかけたときと、
だいたい同じ挙動となります。

JSONを確認すると、
サービスリクエストはこんな感じで、

{
  "session": {
    "new": true,
    "sessionId": "HOGEHOGE",
    "application": {
      "applicationId": "HOGEHOGE"
    },
    "attributes": {},
    "user": {
      "userId": "HOGEHOGE"
    }
  },
  "request": {
    "type": "IntentRequest",
    "requestId": "HOGEHOGE",
    "intent": {
      "name": "HandClapIntent",
      "slots": {}
    },
    "locale": "ja-JP",
    "timestamp": "2017-12-05T06:48:23Z"
  },
  "context": {
    "AudioPlayer": {
      "playerActivity": "IDLE"
    },
    "System": {
      "application": {
        "applicationId": "HOGEHOGE"
      },
      "user": {
        "userId": "HOGEHOGE"
      },
      "device": {
        "supportedInterfaces": {}
      }
    }
  },
  "version": "1.0"
}

サービスレスポンスはこんな感じです。

{
  "version": "1.0",
  "response": {
    "outputSpeech": {
      "ssml": "<speak> またひらいて、てをうって、そのてをうえに。 </speak>",
      "type": "SSML"
    },
    "speechletResponse": {
      "outputSpeech": {
        "ssml": "<speak> またひらいて、てをうって、そのてをうえに。 </speak>"
      },
      "shouldEndSession": true
    }
  },
  "sessionAttributes": {}
}

もしもうまくいかない場合は、AWSのCloud WatchからLambdaのログを確認してみましょう。
ちなみに、サンプル発話に登録していなくても、「ヘルプ」「キャンセル」「ストップ」も認識できます。


EX. 実機で試す

折角、「アレクサ、むすんでひらいててをうってむすんで」というセリフを設計したにも関わらず、
シミュレータでは「てをうってむすんで」のレスポンスとしての結果としてしか表示できません。

この後、実機で確認するためには、まだ若干やらなければならないことが残っていまして、
長くなるので本エントリーでは詳細を割愛しちゃいますが、
僕は、「公開情報」「プライバシーとコンプライアンス」の項目を埋めて、
Skills Beta Testingから自分自身をテスターとして登録することで実機に反映しています。


おもったこと

iPhoneアプリが作れるようになったときに、Appleが公開した、iOSヒューマンインターフェイスガイドラインは非常に完成度が高く、iOSディベロッパーに限らずタッチディスプレイでのコンテンツを制作する為の指南書としてつかわれたりしていました。

[参考リンク]
ユーザインターフェイスのデザインのヒント - Apple Developer


Alexa Skills KitのドキュメントはVUI(Voice User Interface)の指南書としてつかえる内容だと思うので、VUIを作りたいと思っている人は、是非とも読んでみてほしいです。
特に、デザインプロセスの部分は大変参考になります。

[参考リンク]
デザインプロセス | Amazon Alexa Voice Design Guide


おわりに

いかがだったでしょうか。
今回は実機がなくてもさくっと試すことを目的に書いたエントリーだったので、内容は深くはありませんが、
実際に試してみて、面白そうだったらドキュメントを読むという流れの第一歩として活用頂けるとうれしいです。

そして、現在カヤックではスマートスピーカー(AIスピーカー)に力を入れています!
スマートスピーカーアプリを作ってみたいエンジニアの方、
是非とも一緒にスマートスピーカーを盛り上げていきましょう!

smartspeaker.kayac.com
www.kayac.com

現場からは以上です。

明日は、hashtさんによる「経済のなりたちやイノベーションの根源のおはなし」です。楽しみですね。^ ^