エンジニアHubproduced by エン

若手Webエンジニアのための情報メディア

Alexaスキルを開発してVUIを学ぼう! 手軽にAWS Lambdaで作る音声インターフェイスの基本

Amazon EchoやGoogle Homeといったスマートスピーカーが話題となっています。AIとの対話をインターフェイスとするVUIの基礎知識から、Alexaスキル製作の基本まで、スマートスピーカー向けのアプリケーションを数多く手がける君塚史高さんに教えてもらいました。

こんにちは。君塚史高@ki_230と申します。
普段は面白法人カヤックで、IoTデバイス向けのソフトウェアを開発しています。

最近ではAmazon EchoやGoogle Home、Clova WAVEといったスマートスピーカー向けのアプリケーションを制作する機会が増えました。そこで得られた知見をもとに、本稿ではAmazon Echo向けにシンプルな「時計」アプリケーションの作り方を解説します。

スマートスピーカーのユーザーインターフェイスは音声のみ(VUI)のため、一般のアプリ開発とは違った考え方が必要になります。そういったことから実際の開発手順まで取り上げるため、かなり駆け足になるかと思いますが、よろしくお願いいたします。

VUIはまだ黎明期であり、シンプルなコンテンツでもアイデア次第で勝負できる状況にあります。本稿で説明した内容を発展させることで、広く利用されるアプリケーションを作成できるかもしれません。

VUIとは何か? 電卓アプリを例に

まず、簡単にVUIについて説明します。VUIとは、Voice User Interfaceの略語です。

ざっくり説明すると、音声でコンピュータとやりとりをするインターフェイスです。CUI(Character User Interfac)やGUI(Graphical User Interface)と比較すると、より理解しやすいでしょう。ここでは、電卓アプリを例に比較してみます。

CUI(Character User Interface)
CUIは、文字入力によるコマンドでコンピュータとやりとりを行うインターフェイスで、いわゆる「黒い画面」(ターミナル、コマンドプロンプトなど)がその代表例です。
GUIより素早く操作でき、開発者には好んで使われますが、一般ユーザーには敬遠されがちです。
GUI(Graphical User Interface)
GUIは、コンピュータグラフィクスで構成された要素に対する操作で、コンピュータとやりとりを行うインターフェイスです。CUIよりも直感的に操作できるため、一般ユーザーによりフレンドリーです。
PCではマウスなどのポインティングデバイスを使ったGUIが採用され、スマートフォンなどではタッチディスプレイが使われますが、直感性において大きな差があります。
VUI(Voice User Interface)
VUIは、音声でコンピュータとやりとりするインターフェイスです。代表的な採用例としては「スマートスピーカー」のほか、スマートフォンやPCの「音声アシスタント」などが挙げられます。
ものすごくシンプルに考えるなら、CUIのコマンドを音声で入力でき、応答も音声で出力されるイメージです。

さて、いかがでしょう。VUIの特徴がお分かりいただけたでしょうか。

ただし、この説明ではVUIの魅力があまり伝わらなかったかもしれません。なぜなら、上記のようにCUIのコマンドを単純に音声化しただけでは、入力が容易になるかというとむしろ面倒になっているからです。

では、なぜいまVUIが注目されているのでしょう?

個人的には、昨今のAIブームの影響が強いのではないかと思っています。語弊を恐れずに言えば、VUIはAIとの対話という分野で大きく期待されたインターフェイスなのです。

AIとの対話をインターフェイスとしたアプリケーション

「AIとの対話をインターフェイスにする」ことを考えてみましょう。その魅力は、「手続き」ではなく「目的」を入力できることです。

例えば、税抜きで100円の商品があったときに、その税込み価格を知りたいとします。普通に電卓を使うのであれば「100 × 1.08」と入力して「108円」という出力を受け取るでしょう(消費税は8%と前提)

「そんなのあたりまえじゃないか」と思うかもしれませんが、この手続きは、ユーザーが「現在の消費税率」と「8%増しの計算方法」を知っていることを前提に成り立っています。そもそもユーザーが知りたかったことは「税抜き100円の商品の税込み価格」であり、「100 × 1.08」の答えではありません。

あくまで「税抜き100円の商品の税込み価格」を知るという目的のため、「100 × 1.08」という計算式を手続きとして入力してしているのにすぎません。

AIとの対話では「目的」を入力する

このときVUIをインターフェイスにすると、「税抜き100円の商品の税込価格を教えて」というように、目的を入力に取ることが可能です。ユーザーは「現在の消費税率」や「8%増しの計算方法」を知らなくてもよいのです。

「手続き」ではなく「目的」を入力に取れるということは、非常に便利な体験を生み出す可能性があるのです。

マーケティングではよく「顧客が欲しがっているのはドリルではなく、穴である」などと言われますが、目的を入力に取ることは、これに近いのかもしれません。

なお、AIとの対話はVUIの専売特許ではありません。例えば、チャット風のインターフェイスを用いれば、テキスト入力でAIとの対話を行うこともできますし、実際にGoogleアシスタントではチャット型のインターフェイスも用意されています。

Google Allo で Google アシスタントとチャットする - Google Allo ヘルプ

とはいえ、対話という行為においては、音声による会話が最も自然な形です。このため、会話をインターフェイスとするVUIは、AIとの対話において期待されています。

VUIの弱点とその克服

VUIの弱点の1つに同音異義語の入力がありますが、「目的を入力に取る」という対話式のインターフェイスでは、それを打ち消すことができます。

例えば、ユーザーが「こうしょう」とのみ発声した際に、それが「交渉」なのか「公称」なのか「校章」なのかを判断することは困難です。したがって、短いコマンド入力にVUIを使用すると、上手く認識されないケースも出てきます。

一方で、AIは文脈を理解できます。例えば、より長く「らいきのねんぽうをこうしょうして」と発話すれば、この文脈における「こうしょう」は「交渉」だと評価され、AIが来季の年俸を交渉してくれるかもしれません。

つまり、VUIは短いコマンド入力よりも、ある程度の文脈を持った対話に向いています。こういったことも、VUIをAIとの対話という分野で活用する流れを後押ししているのではないでしょうか。

VUIの現在 ― アイデアで勝負できる黎明期

ここまでは、AIとの対話という分野でVUIが期待されているという話をしてきました。それでは、いま現在、VUIはどんな状況なのでしょうか?

昨今、これだけVUIという言葉がフューチャーされるようになった大きな要因は、間違いなくスマートスピーカーの登場でしょう。スマートスピーカーは「AIスピーカー」とも呼ばれるように、AIアシスタントを搭載している対話可能なスピーカーのことです。

Amazon Echo、Google Home、Clova WAVEなど、ほとんどのスマートスピーカーでアプリケーション開発用のSDKが公開されており、サードパーティがコンテンツを提供できます。つまり、AIとの音声対話をインターフェイスとしたアプリケーションを、誰でも制作できる時代が来ているのです。

しかし、いまはまだまだ黎明期、やがてはVUIの本質を捉えたアプリケーションが登場すると思うのですが、現段階ではプラットフォームを狙うような土壌が十分に整っているとは言えない状況です。

10年前のスマートフォンアプリに似た状況

思えば、iPhoneが発売されたばかりの頃のスマートフォンアプリもそうでした。

10年がたったいまでこそ、ソーシャルゲームやSNSといった利用時間の長いアプリが当たり前のようにヒットしてますが、当時は「スマホを傾けるとビールが飲める(ように見える)アプリ」や「マイクに息を吹きかけて、画面上のライターの火を消すアプリ」など、かなりシンプルなものがヒットしていたことを覚えているでしょうか。

思うに、そもそも黎明期とはそういう時期なのです。繰り返しになりますが、プラットフォームを狙うには、まだユーザーが少なすぎるのです。

一方で、黎明期のユーザーの多くは「アーリーアダプター」と呼ばれ、新しいもの好きです。アーリーアダプターのインサイトを考えると、「新しいデバイスを自慢したい」という気持ちが強く、その相手は「まだそのデバイスを持っていないユーザー」であることが多いでしょう。そのため、デバイスの新機能を披露できるシンプルな体験を提供するコンテンツが好まれるのだと思います。

前述の「ビールを飲む」アプリや「ライターの火を吹き消す」アプリも、ガラケーのユーザーに対して「スマホならこんなことができるんだぜ」と、既存製品との違いを簡単に自慢できることがヒットの要因だったのではないでしょうか。

シンプルなアイデアで勝負できる黎明期はチャンス

それに倣って考えると、いまVUIコンテンツを作るのであれば、一言で表すなら「自慢しやすい」体験を提供するのが良いでしょう。要素を分解して考えるなら、

  • 分かりやすさ
  • 一度は起動してみたくなるキャッチーさ
  • 使った後で人に見せたくなる面白さ

を持ったコンテンツが良いと思います。

シンプルなアイデアで勝負できる黎明期はチャンスです。いまのうちにVUIコンテンツ制作の基本を身に着け、思いついたアプリケーションを急いで作ってリリースしてみましょう。そして、来るべきVUI時代に備えてください。

次章から、非常にシンプルなAlexaスキルを例に取り、VUIコンテンツの作り方を紹介していきます。

Amazon Echoで利用できるAlexaスキルの作り方と考え方

ここからは、Amazon Echoで利用できる「時計」の作り方を説明します。

Alexa | アレクサ| Amazon開発者ポータル

Amazon Echoで利用できる追加機能のことを「Alexaスキル」と言いますが、まずはこういった基本的な用語を簡単に解説します。

Alexaとスキルについての基本的な用語

Alexa
Amazon Echo端末の頭脳となるクラウドベースの音声サービスです。「アレクサ」と話しかけるだけで、いろいろな操作が簡単にできます。
iPhoneでのSiri、WindowsのCortana、Google HomeにおけるGoogleアシスタント、Clova WAVEでいうところのClovaに相当します。
Amazon Echo
Alexaが搭載されたAmazon製のスマートスピーカーです。音声だけでリモート操作が可能です。
コンパクトなサイズのEcho Dot、ディスプレイ付きのEcho Showなどさまざまな種類があります。
Alexaスキル
Alexaに対応した端末で動作するアプリケーションです。SDKが公開されているので、誰でも開発ができます。スマートフォンでいう「アプリ」に相当します。
Alexaアプリ
Amazon Echoの設定で使うスマートフォン用のアプリや、Webサイトを指します。Alexaスキルとは別物です。
Alexa Skills Kit(ASK)
誰でもAlexaスキルを簡単に作れるように、一連のAPI・ツール・ドキュメント・コードサンプルをまとめたものです。
ASK SDK for Node.js
Node.js用のAlexa Skills Kit SDK(npmモジュール)です。バージョン1と2で大きく記法が変わっており、理由は後述しますが、今回はバージョン1を使用します。

開発のために必要な用語

スキル名
ストアに表示されるカスタムスキルの名前です。
呼び出し名
スキルを呼び出すときの名前です。スキル名と同一でなくてもかまいません。
「アレクサ、(呼び出し名)を起動して」でスキルを呼び出すことができるので、なるべく簡単な呼び出し名にしたいところですが、「呼び出し名がブランド」「知的財産独自のもの」以外については、2つ以上の名詞を使用する必要があります。例えば「時計」はNGですが、「伝説の時計」ならOKです。
インテント
ユーザーからの要求に対して発生するイベント名のことです。
サンプル発話
インテントに結びつく発話です。 例えば、ユーザーが「おはよう」という発話に対してGoodMorningIntentを実行したいなら、GoodMorningIntentのサンプル発話に「おはよう」を追加します。
ビルトインインテント
Amazon側で用意しているインテントで、ユーザーがサンプル発話を設定しなくても使用できます。Amazon.XXIntentという名前になっています。
例えば、ヘルプを返すことを期待されているAmazon.HelpIntentや、キャンセルを受け取るために使われるAmazon.CanselIntent、はい・いいえの選択を受け取るAmazon.YesIntentおよびAmazon.NoIntentなどが用意されています。Amazon.HelpIntentなどいくつかは、スキルを公開のために実装が必須となっています。
スロット
発話に含まれる変数のようなものです。
今回の記事では登場しませんが、例えば、羊を100匹まで数えることができるスキルを作る際に、サンプルとして「羊を1匹数えて」から「羊を100匹数えて」まで100個のフレーズを用意しておかなくても、スロットを使った「羊を{number}匹数えて」という1つだけで済むといった使い方をします。
スロットタイプ
スロットの型です。
「羊を{number}匹数えて」の例で言えば、numberAmazon.NUMBERに設定しておくと、数字を受け取ることができます。今回は登場しません。

Alexaスキルの開発環境を確認する

それでは早速、Alexa Skills Kitを使って、簡単なVUIコンテンツとして「時計」スキルを作ってみましょう。先ほど説明したように呼び出し名としてただの「時計」は使えないので「伝説の時計」とします。

開発のため、次の2つのアカウントが必要です。

  • Amazon開発者アカウント
  • AWSアカウント

Amazon開発者アカウントは、Alexaスキルを作成して公開するために必要です。開発者ポータルから作成すると「必ずハマる」らしいので、次の記事を参考に作成すると良いでしょう。

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

AWS(Amazon Web Services)は必須ではありませんが、Amazon Lambdaで開発するのが一番手っ取り早いので、今回はこれを使用します。アカウントの作り方は、次のURLが参考になります。

AWS アカウント作成の流れ | AWS

AWSは無料のサービスではありませんが、アカウントを作ると1年間無料枠がついてきますし、執筆時点(2018年9月)ではスキルを公開するとAlexa AWSプロモーションクレジットで毎月100ドル分の無料枠がもらえるので、当分の間は無料で運用できるでしょう。

作成する「時計」スキルのイメージを考える

バックエンドにAWS Lambdaを使用したAlexaスキルにおいて、一般的にユーザーの発話から端末の返答までのフローは、ざっくり言うと次のような流れで処理されます。

  1. ユーザーが端末に話しかける
  2. 端末が音声データがAlexaサービスに送信
  3. Alexaサービスが音声を解析しJSON化
  4. JSONをLambdaに送信
  5. JSONに基づいて、Lambdaが処理を実行、実行結果をJSONでAlexaサービスに返す
  6. 受け取ったJSONに基づいてAlexaサービスが音声を生成し、端末に送信
  7. 端末が喋る

これから作成する「時計」スキルの動作イメージを考えると、次の図のようになります。

これを実現するには、次の開発作業を行います。

  • 3.の部分(音声をJSONにするスキル)の設定
  • 5.の部分(JSONを処理するLambdaファンクション)の作成

バックエンドの環境については悩みましたが、今回は最速で作ることを目標に、ASK SDK for Node.jsバージョン1を使います。2018年4月にリリースされた最新版(バージョン2)とは記法がかなり異なりますが、ローカルのセットアップを必要とせず、Lambdaのインラインエディタでさくっと作ることができます。

具体的な作り方は、Lambdaファンクションのパートと、Alexaスキルのパートに分けて説明します。

時計の機能を実行するLambdaファンクションを作成する

バックエンドとなるAWS Lambdaで、受け取ったJSONを入力に取り、実行結果を返すファンクションを作成します。

今回では、次の2つの機能を実装します。

  • スキルを起動したときに、起動メッセージを返す。
  • 時間を尋ねられたときに、現在時刻を返す。

1. AWSにログインしてLambdaにアクセス

「Lambda」で検索すると簡単にアクセスできます。

2. alexa-skill-kit-factskillを設計図にLambdaファンクションを作成

「alexa」で検索すると設計図が見つかりやすいです。

関数名は何でも良いのですが、今回は「伝説の時計」スキルを作るので「LegendClock」にします。

3. トリガーにAlexa Skills Kitを選択

スキルの検証を有効にすると、指定したスキルからしか呼び出せなくなるので、そちらがベストプラクティスなのですが、今回はスピード重視でスキル検証を無効にします(②)。

4. インラインエディタでソースを編集

下記のソースをコピペして、保存します(②)。

const Alexa = require('alexa-sdk');

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

    alexa.registerHandlers({
        // 起動時の処理
        'LaunchRequest': function () {
            this.emit(':tell', '伝説が始まりました。');
        },
        // 時間を聞かれたときの処理
        'WhatTimeIntent': function () {
            const currentTime = new Date(); // UTCを取得

            this.emit(':tell', `現在の協定世界時は${currentTime.getHours()}時${currentTime.getMinutes()}分です。`);
        }
    });

    alexa.execute();
};

このソースを簡単に説明すると、起動したときの処理(LaunchRequest)と、時間を聞かれたときの処理(WhatTimeIntent)を記述しています。

基本的には、次のメソッドの「読み上げたいテキスト」を、ユーザーの発話に応じて差し替えればスキルの出来上がりです。

this.emit(':tell', 読み上げたいテキスト);

起動時と、時間を聞かれたときに、それぞれ読み上げるテキストを設定しています。ここでは日本時間ではなく、協定世界時(UTC)をそのまま回答します。

画面右上にある「arn:」から始まる文字列は、後にスキルとLambdaの紐付けに必要になるので、コピーしておきましょう(④) 。

Alexaスキルで「伝説の時計」を設定する

Alexa Skills Kit開発者コンソールで、スキルとLambda、呼び出し名とスキル、ユーザー発話とインテントをそれぞれ紐付けるよう設定します。

まず、Amazon開発者アカウントで、開発者コンソールにログインします。

1. Alexa Skills Kit開発者コンソールを開く

ダッシュボードから「ALEXA SKILLS KIT」を選択します。

2. 新しいスキルを作成

スキルの作成ボタンを押し(①)、必要な情報を設定して[スキルを作成]ボタンを押します。今回は、次のように入力・選択しています。

設定欄 内容
スキル名 伝説の時計
デフォルトの言語 日本語(日本)
スキルに追加するモデル カスタム

3. エンドポイントの設定

エンドポイントの「デフォルトの地域」に、先程コピーしておいたLambdaファンクションの「arn:」から始まる文字列を入力し、スキルとLambdaを紐付けます。

4. 対話モデルの設定

GUIも用意されているのですが、今回はJSONエディタに下記のJSONをペーストして(②)、モデルをビルドします。

{
    "interactionModel": {
        "languageModel": {
            "invocationName": "伝説の時計",
            "intents": [
                {
                    "name": "WhatTimeIntent",
                    "slots": [],
                    "samples": [
                        "ユーティーシーを教えて",
                        "協定世界時を教えて",
                        "今何時か教えて",
                        "現在時刻を教えて",
                        "時間を教えて",
                        "今何時ですか",
                        "今何時"
                    ]
                }
            ],
            "types": []
        }
    }
}

interactionModel.languageModel.invocationNameが、呼び出し名です。

今回はinvocationNameを「伝説の時計」に設定しているので、「アレクサ、伝説の時計を起動して」でLaunchRequestが実行されるようになります。

interactionModel.languageModel.intentsには、インテント名(name)とサンプルフレーズの配列(samples)をオブジェクトにして収納します。今回は、「WhatTimeIntentsamples」のサンプルフレーズを「今何時」「今何時ですか」「時間を教えて」「現在時刻を教えて」「今何時か教えて」「協定世界時を教えて」「ユーティーシーを教えて」に設定しているので、「アレクサ、伝説の時計で現在時刻を教えて」で「WhatTimeIntent」が実行されるようになります。

ただし、これだけでは必須のインテントが実装されていなかったり、公開設定が設定されていなかったりするので、実際に公開することはできませんが、AIとの対話を試すだけであれば、Lambdaとスキルの設定はこれだけでOKです。非常に簡単ですね。

Webのシミュレーターでスキルを試してみる

続いて、そのまま動作を確認してみましょう。Alexa Skills Kit開発者コンソールに、Webシミュレーターがあるので、Echoの実機がなくてもスキルを試すことができます。

1. シミュレータで起動をテスト

テストタブを選択して、テストを有効にし、「伝説の時計を起動して」と入力してみましょう。

LambdaにJSONが送信され、LaunchRequestが実行された結果が返ってきます。

意図通り、「伝説が始まりました」という音声が返ってきたら成功です。

2. シミュレータで現在時刻を確認

続いて「伝説の時計で現在時刻教えて」と入力してみましょう。

WhatTimeIntentが実行されていることが確認できます。

おわりに

今回作ったサンプルは、ただ協定世界時を確認するものです。これだけでは、まだまだVUIの特徴を生かしたアプリケーションにはなってません。ここからがスタートです。

日常の中にある「時刻を確認する」行動をアプリケーションに落とし込んでみれば、さまざまな応用例を考えることができます。例えば、最寄り駅で電車に乗ろうとするときには、次のような手続きで行動するでしょう。

  1. 現在の時刻を時計で確認する
  2. 乗れそうな電車を、時刻表で確認する

AIと対話するVUIであれば、「最寄り駅に次の電車が来る時間を教えて」というように、行動の目的そのものを入力に取ることができます。

スキルを作成する際には、このように時刻を確認するシーンを手続きとしてまず思い出し、それがなるべく「分かりやすく」「キャッチーで」「面白い」スキルになるようにアイデアを追加すると良いでしょう。

今後の勉強のための参考リンク

今回のサンプルでは実装していませんが、Alexaスキルとしてユーザーに公開するには、使い方を聞かれたときのAmazon.HelpIntentや、スキルを停止させる際のAmazon.CancelIntentおよびAmazon.StopIntentといった処理の実装が必須となります。

実際に公開のためのスキル認証をAlexaストアに申請するには、下記のリンクが参考になります。

Alexaスキル開発トレーニングシリーズ 第6回 スキルの審査と公開 : Alexa Blogs

今回のサンプルではAlexa Skills Kit SDK for Node.jsバージョン1を使用しましたが、バージョン2の記法を知りたい方は、下記のリンクが参考になります。

[日本語Alexa] Alexa SDK for Node.js Ver2入門(その1)はじめの一歩 | DevelopersIO

また、VUIのデザインガイドにも、一度目を通しておくと良いでしょう。

Amazon Alexa Voice Design Guide

付録・現在時刻をベースとするスキルの参考例

最後に、わたしが個人的に作った「現在時刻をベースとするスキル」を、参考までにいくつか紹介します。

タイマーの逆襲
人間からタイマーに問いかけるのではなく、逆に、タイマー側から「ねえ、人間5秒たったら教えて」とリクエストがくるスキルです。AIと人間の主従関係に着目し、立場を逆転させてみました。スキルの起動時刻と回答するときの時刻を取得し、時間を測っています。
タイマーの逆襲
コンタクトカウント
2週間の使い捨てコンタクトレンズが何日目なのかを教えてくれるスキルです。初めてスキルを起動した時刻を初日として、「何日目か教えて」と質問するとに現在時刻を取得し、日数を割り出します。
コンタクトカウント
丁寧すぎる時計
読み上げによる返答は目視よりも理解に時間がかかるというVUIのデメリットを、逆に全面に押し出したスキルです。現在時刻を確認するだけなのに、やたら時間がかかります。
丁寧すぎる時計
時計の読み方
現在時刻を取得し、アナログ時計の読み方を返します。「時計の読み方を起動して」に対して、「短い針が1と2の間なので1時。長い針が6なので30分。合わせて1時30分です」というようなレスポンスを返します。
時計の読み方

君塚 史高(きみづか・ふみたか)ki_230 kimizuka

kimizuka
面白法人カヤックのフロントエンドエンジニア。JavaScriptを使って、IoTデバイス向けのソフトウェア、Web、iPhoneアプリなどを開発している。最近の趣味は、毎月Alexaスキルを開発・公開してAlexaTシャツをもらい続けること。
kimizuka.fm