今回は、画面付きのAmazon Echoシリーズ(Echo Spot/Echo Showなど)向けのマルチモーダルなスキル開発を行うために必要となるデザイン言語「Alexa Presentation Language」について簡単な導入方法も含めて紹介していきます。

2017年に画面付きのAmazon Echo端末であるEcho Showがアメリカで発表され、2018年には日本でもEcho Spotが発売開始されました。このような画面付きスマートスピーカー(「スマートディスプレイ」とも呼びます)では、Voice User Interface(VUI)による操作や案内に加えて液晶ディスプレイによるグラフィカルな表現が取り入れられ、マルチモーダル(複数の形式の、複数の手段で、の意)なユーザー体験が可能です。

その後Google アシスタント、LINE Clova 搭載の画面付きデバイスも次々に発表され、音声と画面による入出力の両方を備えた端末は今後さらに普及していくことが予想されます。それに伴い音声アプリケーションも、画面付きスマートスピーカー向けに設計開発を行う必要がでてきます。

Alexa Presentation Language について

Alexa Presentation Language(APL)とは、Alexaを搭載した端末の画面レイアウトを実装するためにAmazonが開発した専用のデザイン言語のことです。JSON(JavaScript Object Notation:コンピュータにおいて扱うデータを記述するための言語の1つ)形式で構成され、HTML/CSSのような要素をセットすることで画面のレイアウトを構築することができます。APLでは、スマートスピーカー特有の音声操作はもちろん、スマートフォンのようなタッチ操作も実現可能です。最近では、オーディオデータやムービーデータをAPLの中に組み込めるようになり実装の幅がより広がりました。

APLを利用したスキル

この章では実際にAPLを導入して開発したヤフーのスキルについて紹介します。

1. Yahoo!路線スキル

Yahoo!路線スキルは、指定した路線の運行情報を案内するスキルです。APLを利用することで声による案内だけではなく、色やマークなど視覚的な情報も同時に提示できるようになりました。表示された画面を見るだけで運行情報がわかるため、声による案内を部分的に聞き逃してしまったときでもAlexaにもう一度聞き返す手間を省略できます。

  • Yahoo!路線スキル

    Yahoo!路線スキル

2. Yahoo!天気・災害スキル

Yahoo!天気・災害スキルは、指定された地域の天気災害情報を案内するスキルです。APLを利用することで指定した日の天気のみではなく1週間分の天気など、音声では冗長な情報でも画面を通してユーザーに提示しやすくなっています。

  • Yahoo!天気・災害スキル
  • Yahoo!天気・災害スキル
  • Yahoo!天気・災害スキル

3. Yahoo!ニューススキル

Yahoo!ニューススキルは、最新のニュースを5件お知らせします。ニュースの内容は1日に3回更新されます。Yahoo!ニューススキルではニュースの読み上げを音声合成ではなく、録音されたオーディオデータを再生します。

APLは最近、音声や動画の埋め込みが可能になり、Yahoo!ニューススキルもそれらの機能を用いてAPLを実装しました。読み上げるニュースに対応した記事が画面に表示され、その記事の読み上げが終わるとスライドショーのように自動でページが送られていきます。

  • Yahoo!ニューススキル
  • Yahoo!ニューススキル
  • Yahoo!ニューススキル

APLの導入手法

ここからはAPLを実際に導入するための簡単な手順について説明します。スキル開発の手法については第5回記事「Amazon Alexa / Google アシスタント両PFの横断開発テクニック」にて紹介しているため、すでに開発されたスキルをAPLで画面対応する方法について紹介します。

1. APLの有効化

まず、Alexaコンソールにログインし、APLを有効にしたいスキルの画面を開きます。次に「ビルド」タブ(下図①)の「インタフェース」(下図②)を選択します。利用可能なインタフェースの一覧が表示されるので、「Alexa Presentation Language」(下図③)と「Displayインタフェース」(下図④)を有効にして「インタフェースを保存」(下図⑤)をクリックします。最後に「モデルをビルド」(下図⑥)をクリックします。これでAPLを導入する下準備は完了です。

  • Alexa開発者コンソール

    Alexa開発者コンソール

2. APLドキュメントの作成

ここからはAPLのコーディングを行います。APLはJSON形式のドキュメントのため、直接ドキュメントを作成することはもちろん、プログラムで動的に生成することも可能です。APLの構造はRenderDocumentとExcuteCommandsの大きく2つに分けられます。それぞれの要素について説明します。

RenderDocument

RenderDocumentはAPLの骨格となる要素です。基本的な画面のレイアウトをここで定義します。RenderDocumentは大きく分けて以下のような4つの要素で構成されています。

type: 'Alexa.Presentation.APL.RenderDocument',
    token: ‘sampleToken’, //このドキュメントが保持するトークン
    document: {
        // 画面のレイアウト
    },
    datasources: {
       // 画面レイアウトに当て込むパラメータ
    }

この中でも開発者が最も手を加える必要がある要素はdocumentとdatasourcesです。それぞれの要素について見ていきましょう。documentは文字の大きさや画像の並び方といったレイアウトの枠組みを設定するための要素です。以下にサンプルコードを示します。文字サイズや幅、高さなど細かいレイアウトの設定は省略してあります。

{
  "document": {
    "type": "APL",
    "version": "1.0",
    "theme": "dark",
    "import": [
      {
        "name": "alexa-layouts",
        "version": "1.0.0"
      }
    ],
    "resources": [],
    "styles": [],
    "mainTemplate": {
      "parameters": [
        "payload"
      ],
      "item": [
        {
          "type": "Container",
          "width": "100vw",
          "height": "100vh",
          "items": [
            {
              "type": "Pager",
              "id": "${payload.pagerData.properties.pagerId}", // Pagerのid
              "data": "${payload.pagerData.properties.list}", // datasourcesのパス
              "width": "100vw",
              "height": "100vh",
              "numbered": true,
              "item": [
                {
                  "type": "Container",
                  "width": "100vm",
                  "alignItems": "center",
                  "item": [
                    {
                      "type": "Container",
                      "justifyContent": "center",
                      "alignItems": "center",
                      "paddingBottom": "10px",
                      "items": [
                        {
                          "type": "Image", // 画像を挿入
                          "source": "${data.icon}" // 画像のURL
                        },
                        {
                          "type": "Text", // テキストを挿入
                          "text": "${data.text}" // 表示するテキスト
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ]
        }
      ]
    }
  }
}  

テキストデータなどを直接埋め込んで使用することもできますが、データを変数として定義し、それを呼び出して表示することもできます。その変数を格納するための要素がdatasourcesです。datasourcesはdocumentで構成した画面レイアウトの中に実際に当て込んで行くパラメータを定義する要素です。具体的には、テキストや画像のURLなどをここで定義します。以下にサンプルコードを示します。

datasources.json

{
  "datasources": {
    pagerData: {
      type: 'object',
      properties: {
        pagerId: 'samplePager', 
        list: [
          {
            icon: '',
            text: '1ページ目です',
            textId: 'textOne'
          },
          {
            icon: '',
            text: '2ページ目です',
            textId: 'textTwo'
          }
        ]
      }
    }
  }
}

datasourcesで定義されたパラメータは、Javascriptのテンプレートリテラルを用いて取得可能です。そのため、同じレイアウトであれば新しいコンポーネントを用意しなくても複数のページやオブジェクトを作成できます。なお、APLでテンプレートリテラルを扱う場合は``(バッククオーテーション)ではなく””(ダブルクオーテーション)で変数を囲むようにしてください。

ExcuteCommands

ExcuteCommandsは表示された画面の動作を管理する要素です。ページ送りや、タッチイベント、APLで埋め込んだビデオの再生停止などのコマンドをここで定義します。以下にサンプルコードを示します。

commands.json

// 5秒後に1ページめくるコマンドのサンプル
{
    "type": "Alexa.Presentation.APL.ExecuteCommands",
    "token": "sampleToken", //RenderDocumentと同じトークンを指定
    "commands": [
        {
            "type": "SetPage",
            "componentId": "samplePager", // 操作したいPagerコンポーネントのid
            "position": "relative",
            "delay": 5000, // 5000ミリ秒
            "value": 1
        }
    ]
}

上記のサンプルは「5秒後に次のページを表示する」という動作を実行するコマンドです。このコマンドを複数用いることでスライドショーのように自動で画面を遷移させるスキルを作れます。ExcuteCommandsのtokenは、操作したいRenderDocumentのtokenと同一の文字列を指定してください。

なお、単一ページなどでAPLの要素を操作しない場合やタッチイベントなどユーザー入力を必要としない場合はExcuteCommandsを使用する必要はありません。反対に、すでに表示されているAPLの画面に対して、ページ送りなどのコマンドを送る場合はExcuteCommandsのみをレスポンスに挿入してください。

3. directive要素に作成したAPLドキュメントを挿入

ここまでで、画面付きEcho端末に対してAPLでデザインされた画面レイアウトを表示する準備は整いました。最後に、Echo端末へのレスポンス情報としてdirective要素に作成したAPLドキュメントを挿入してください。注意しなければならないことは、Echo Dotなどディスプレイ未搭載端末に対してAPLが挿入されたレスポンスを返すとエラーが発生してしまうことです。

そのため、リクエストを送信するデバイスに画面があるかないかを判定して、画面がある場合のみAPLを挿入するように実装してください。あとはLambdaにソースコードをアップロードしてEcho端末からリクエストを送れば画面対応したAlexaスキルが起動します。最終的なレスポンスのJSONデータは以下のようになります。

スキルI/O JSON出力

{
  "body": {
    "version": "1.0",
    "response": {
      "outputSpeech": {
        "type": "SSML",
        "ssml": "Alexaが発話する内容"
      },
      "directives": [
       //** 以下、addDirectiveメソッドで挿入されたAPLドキュメント **//
        {
          "type": "Alexa.Presentation.APL.RenderDocument",
          "document": {
           // 画面のレイアウト
          },
          "datasources": {
            // レイアウトに当て込むパラメータ
          }
        },
        {
          "type": "Alexa.Presentation.APL.ExecuteCommands",
          "commands": [
            // 画面の動作をコントロールするコマンド
          ]
        }
        //** ここまで **//
      ],
      "shouldEndSession": true // 会話を終了するか否か
    },
    "sessionAttributes": {} // 会話の中で引き継ぐパラメータ
  }
}  

今回紹介した機能以外にもAPLでできることはまだたくさんあります。詳しくはAmazonの公式ドキュメントを参照してください。

まとめ

今回はAPLについて簡単な導入方法を含めて紹介しました。次回は「GUI以外のインタフェースについて」について紹介する予定です。

著者紹介

Yahoo! JAPAN スキルプロジェクトチーム
データ&サイエンスソリューション統括本部のスマートデバイス本部に所属するプロジェクトチーム。スマートデバイス本部は、IoTや今回のテーマである音声アプリケーション開発など、ちょっとだけ未来の技術に挑戦する部署。

今回の執筆者:板橋孝典(いたばしたかのり)/エンジニア
スキルプロジェクト エンジニア。ヤフーでは、スマートスピーカー向け音声アプリケーションVUI設計、フロントエンド、バックエンド開発等を担当。