初めてのAlexaスキルができるまで

投稿者: | 2018年9月6日

今回、Alexaスキルアワード2018への応募を目標に、Alexa用スキルの開発を行い、ストアで公開されたので、経緯とかやったことを時系列で簡単にまとめておく。いろいろと試行錯誤を繰り返しながらも、開発着手から公開まで、約1か月でできた。

今回開発したスキルは「みんなの図書館」。地元の公立図書館の蔵書検索ができる。書名またはタイトルから検索できて、多すぎる場合はさらにタイトル/書名から絞り込みができる、Amazonの豊富な書籍データベースから検索できる、検索結果がスマホアプリに残るのであとで確認可能、という特徴を持っている。

1. スキル開発の勉強

スキル開発については、アマゾン公式のハンズオントレーニングへの参加と、オンライン講座「Alexa道場」で勉強した。ハンズオンは実機を使っての演習ができて質問もしやすいので、できれば参加したほうがいいと思う。とはいえ、Alexa道場だけでも十分理解できる。

2. 目標とテーマ選定

勉強も進んできたので、何かアウトプットをしたいと考えるようになった。具体的にはスキルを作るのだが、何かしら目標があったほうが真剣度が増すので、ちょっと時間が少ないながらもアワード参加を目標とすることにした。これが8月上旬。

テーマはスキルアワードのサイトに協賛スポンサーのAPIのリストがあったので、ここから自分の興味の持てるものとして株式会社カーリルの「図書館蔵書検索API」を使うこととした。その当時、公開されていたスキルに図書館関係はゼロ。となれば、ネタかぶりも少なそうと判断し、何かしらの蔵書検索機能をスキルで提供することをテーマとした。(が、同様の図書館ネタのスキルが、このあとガンガン公開され、大いに焦る)

3. アイデア検証(慣れないJSONとの格闘)

Alexa向けスキル開発はNode.js以外にもJavaなどSDKが公開されているが、初心者ということもあるので、一番事例が多そうなNode.jsを選択。サーバサイドJavaScriptは初めてだったが、それ自体はさほど問題にはならなかった。

最初に取り組んだのは、蔵書検索APIの応答であるJSONデータの読み取り。単純な配列の場合と、キー名がデータ毎に異なる「連想配列」の場合とで処理が異なる、ということを初めて知る。決め打ちのISBNコード(書籍毎に付与)と、決め打ちの図書館システムID(公立図書館の場合は市区町村毎に付与)といった最低限の体裁で、貸出可とか貸出中といった検索結果を得られるようになった。8/11~14のお盆休みをこれに費やした。

4. 提供機能の検討(ざっくりめ)

ここで初めて、スキルの提供機能や構成を考えた。近めのゴールとして、提供機能については、まずは書名や著者名から検索するというオーソドックスな機能提供を目指すこととし、対象図書館は地元の市に限定することとした。そのためには「音声で書名や著者名を入力する」「入力された書名・著者名から書籍を検索し、ISBNコードを取得する」という2つの機能を実現する必要がある。

1つ目はAlexaの音声サービスで対応するのだが、ちょうどいいことにビルトインスロットに「AMAZON.Book」「AMAZON.Author」という書名・著者名を認識し、漢字に置き換えてくれるものがあり、これを使うことで解決した。

2つ目は無料で使える書籍検索APIを探した。Amazon、Google、楽天ブックスとあるが、Googleはデータの信頼度が低いというブログの記載が多くて早々に却下。Amazonと楽天ブックスにはそれぞれ下記のような特徴がある。この段階ではAPI利用回数制限が緩く、API利用方法も簡単な楽天ブックス書籍検索APIを選択した。


Amazon楽天ブックス
書籍データ数◎:絶版書を含む(中古扱いがあるため)△:新刊中心(少ない)
応答データ形式XMLJSON
API利用回数制限△:1~0.1回/秒○:1回/秒
1検索で取得できる書籍数○:10件◎:30件
書籍以外(CD等)の除外○:カテゴリノーズ指定で書籍のみ検索可(実際にはKindle本を除外する指定が別途必要)△:検索対象の指定が1検索で1種類しかできないため、複数回検索した結果をマージする
API利用方法△:複雑(署名認証としてリクエストクエリに対しHMAC-SHA256アルゴリズムで算出したハッシュ値が必要)◎:容易

5. 実装

とりあえずのゴールが決まったので、ひたすら実装。WebAPIは非同期処理で呼ぶ必要があるが、Node.jsではV8.1以降でasync/awaitの記法が導入されていた。これはC#でもお馴染みの書き方なので、大変助かった。また、図書館蔵書検索APIは一回の呼び出しで検索が終了しない場合があり、一定時間を空けて再度呼び出す「ポーリング」の処理が必要な一方、Alexaには端末からサーバサイドの関数を呼び出した後、8秒以内にリクエストを返却しないといけない「8秒ルール」があり、検索終了前に何らかのレスポンスを返す必要がある。そのため、「検索に時間がかかっています。検索を続けますか?」といった形で処理を継続できるようにした。

6. フローの整理(しっかりめ)

8/19に、地元の図書館の蔵書確認ができるバージョンが完成した。想定したやりとり(処理フロー)通りに処理が進むかをチェックするため、フローの位置(state)と音声リクエスト(intent)ごとに、処理概要とstateの変更先を表にまとめてみたところで、ふと気づいた。

「どんなstateでも、すべての音声リクエストが飛んでくる可能性がある」=「想定外の音声リクエストが来た時の処理がまるで書けてない!」

Alexa(SDK V1)では、stateごとに音声リクエストの処理を書く必要があるが、この段階では想定フロー以外のリクエスト(intent)に対する処理がまるまる抜けていた。幸いリクエスト処理の記述がないintentをまとめてunhandledとして例外処理できる仕組みがあり、それを各stateに実装することでクリアした。これが8/20頃。

7. 拡張その1(全国対応)

ここからは機能拡張。まずは多くの利用者が使えるよう、対象を全国に拡大することにした。Alexa端末には所在地情報として国と郵便番号を登録でき、SDK経由でスキルから取得できるようになっている。また個人情報を取得する場合、スキル毎にユーザによる許可が必要になっており、そのあたりの実装も必要だった。注意点としては、公開申請時にスキルの公開国を「日本のみ」としても、スキル内では国コードをチェックし、日本以外は受け付けないようにすること(これをやらないで公開申請に出したらリジェクトされた)。

郵便番号を取得できたら、郵便番号から都道府県名・市区町村名を取得し、さらに図書館システムIDを取得することを考えた。郵便番号から都道府県名・市区町村名を取得するために、株式会社アイビスが公開する郵便番号検索APIを利用した。また、都道府県名・市区町村名から図書館システムIDを取得するために、株式会社カーリルの図書館検索APIを利用した。

図書館検索APIで得られる図書館システムIDは公立図書館以外に大学や特殊法人の図書館のIDも含まれており、これを公立図書館に絞り込む処理(システムIDの頭に付く都道府県名で判断)も追加した。これは複数システムIDを指定しての蔵書検索が重い(処理時間的にも、APIの利用制限的にも)ことの回避策として実装した。実装完了は8/22。

8. スキルアワードへの応募

応募期限(8/27)に向けての実装はここで時間切れとなった。応募に必要なデモ動画は、Amazon本社で開催の「駆け込み相談会」(8/23)にてエヴァンジェリストの畠中さんのご厚意によりEcho spotの実機を使って撮影させて頂いた。アイコンをあわてて作ったのもこの時。動画編集は8/25のもくもく会で実施し、その場で応募完了となった。応募時のスキル名は「図書館へ行こう!」、デモ動画はこちら

9. 拡張その2(書籍検索のAmazonへの変更)

図書館は書店で売っていない本が多くあるため、書籍検索エンジンとしては楽天ブックスよりAmazonのほうが向いているのは自明。ということで、実装再開。Amazon Product Advertising API(PA-API)は応答データがXMLのため、外部ライブラリを使ってパースする必要があった。ライブラリの追加はLambdaのインラインエディタではできず、ZIPファイルでアップロードする必要があった

実装を始めてから分かったのが、PA-APIで取得できる書籍情報は100件という制限(AmazonのAPI開発者ガイドには記述無し)。実際には、100件もの検索結果を音声で聞くのは厳しく、絞り込みを使うだろうから、良しとした。他にも「会話文のデータに半角の『&』が含まれていると例外発生する」ので、検索結果を置き換えて渡すとか、この段階になっても想定外のエラーが発生した。

いろいろと引っかかりつつも、Amazon検索を組み込むことができた。9/1に実装完了。

10. 公開申請

8/28にAmazon検索導入前の状態で一度申請し、リジェクトされた。リジェクトで指摘された点を直し、スキル名も「みんなの図書館」に変更、機能面ではAmazon検索を導入して2回目の申請を9/1に実施し、9/3の17:24に公開の通知メールを着信、9/4の午前0時過ぎにストア掲載を確認。全体的にスピーディー。

11. 今後の課題

11.1. Amazon PA-APIの検索回数制限問題

Amazon PA-APIは元々AmazonアフィリエイトのためのAPIであるため、アフィリエイトでの売上がない場合にはAPIの使用回数の制限が厳しくなる仕組みになっている。具体的には「APIから取得したURLからの売上が無い場合、30日毎に秒間1回の制限が0.1回ずつ減らされ、最大で秒間0.1回まで減らされる」というこの仕組み、つい最近(2018/7/30)に導入されたばかり。ぐぬぬ。

で、とりあえずは自分のブログの右メニューにAmazon検索窓を置いてみた。といってもAPIで生成したURLではないので無駄かもしれない(詳しく検証してない)。自分で何か買ってもアフィリエイトからは対象外として弾かれるので完全に他人任せになってしまうのが厳しいところ。逆に、売上が大きければAPI使用回数の上限が増える仕組みもあるが、月46万円以上売り上げてやっと秒間2回になるという厳しさ。つらい。

回避策として考えられるのは「Amazon以外の書籍データベースを探す」「アフィリエイト売上を増やす」の2つ。

案1:Amazon以外の書籍データベース

候補として考えられるのがOpenBD。これは、図書館APIを提供する株式会社カーリルと版元ドットコムが共同運営するプロジェクトで、書誌情報と書影(画像)がAPI経由で取得できるというオープンなプロジェクト。但し、APIはデータの一括取得に特化しており、書名や著者名での検索はできない。API経由で全データをDBへコピーし、検索も自前で用意するしかない。実現にはかなり手数が必要。

また、Google Books APIなど、他のAPIについても検証も必要かと思われる。

案2:アフィリエイト売上を増やす

このスキルを使って検索した書名、著者名をサーバに蓄積し、Webサイトで提供するなどのポータルサイトを開設し、そこにアフィリエイト売上に結びつくようなリンクを設置するといった、割と野心的な案。ただ「図書館へ人を誘導する」ためのスキルを入口に「Amazonの売上を増やす」という若干矛盾したところもあり、果たしてこれで良いのか…悩ましい所。

11.2. 画面表示がある端末への対応

Echo SpotやFireタブレットではAlexaスキルからの画面表示が可能となっている。画像表示も可能であるので、書影の表示など使い心地を向上させる余地があると考えている。幸い、Amazon PA-APIでは書影も取得可能。一応、開発者ポータルでも画面表示は確認できるので、取り組んでみたい。動作確認用に実機が欲しい所だけど、14,800円(Echo spot)とお高いのがなあ…

最後に

メジャープラットフォームへの公開ということで、反応があることを期待しつつ、機能追加の検討に入りたい。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください