Slide 1

Slide 1 text

VUI設計後の実装からリリースまでのポイント Yoichiro Tanaka, Google Developers Expert

Slide 2

Slide 2 text

Yoichiro Tanaka Software Engineer / IT Architect Google Developers Expert (Web) twitter.com/yoichiro google.com/+YoichiroTanaka

Slide 3

Slide 3 text

この資料は何か? Googleアシスタント向けアプリとして数当てゲーム「イートアンドバイト」を開発した際 に行った、 ● 設計時のポイント ● 実装時のポイント ● レビュー提出時のポイント をまとめたものです。

Slide 4

Slide 4 text

イートアンドバイトの動作風景

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

No content

Slide 7

Slide 7 text

No content

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

No content

Slide 12

Slide 12 text

設計時のポイント

Slide 13

Slide 13 text

設計ツール VUI向けの設計ツールは「皆無」な状況 ● 業界全体が模索状態、今度ツールがいろいろ出てくるはず。 ● とはいえ、何もなしでは、デザインは困難。 Actions on Googleでのオススメと自分なりのメソッドを見つける。

Slide 14

Slide 14 text

僕が考えたメソッド 1. 脚本を書きまくる。 2. コンテキストを洗い出す。 3. コンテキストの遷移を図示する。 4. インテントを洗い出して、コンテキストの遷移に挟める。 5. インテントの出入り口に対話を当てはめる。

Slide 15

Slide 15 text

1. 脚本を書きまくる

Slide 16

Slide 16 text

Google Spreadsheetで「交互の背景色」機能で行の色分けをしておくと便利

Slide 17

Slide 17 text

Happy Path から順にシナリオを書いていく Happy Path Scenario 2 Scenario 3

Slide 18

Slide 18 text

Happy Path

Slide 19

Slide 19 text

もう一度遊ぶ

Slide 20

Slide 20 text

ヘルプ

Slide 21

Slide 21 text

ヒント

Slide 22

Slide 22 text

3回間違えた

Slide 23

Slide 23 text

2. コンテキストを洗い出す

Slide 24

Slide 24 text

2. コンテキストを洗い出す 話の文脈が変化した場所を探して、変化前と変化後を「コンテキスト」として抽出して いく。 ● 「3桁の数字を聞いて、判定結果を答えている」という文脈 ● 「正解した後、もう一回遊ぶかどうかを尋ねている」という文脈 ● 「3回間違えた後、ヒントを聞きたいかどうか尋ねている」という文脈

Slide 25

Slide 25 text

Happy Path - 「ゲーム中」から「もう一度遊ぶか?」に話題が変化した → コンテキストが変わった

Slide 26

Slide 26 text

ヘルプ - 「ゲーム中」にヘルプを聞いたけれど、「ゲーム中」に変わりはないので、コンテキストは「ゲーム中」のまま

Slide 27

Slide 27 text

3回間違えた - 3回間違えたことで「ゲーム中」ではなく「ヒントを聞きたいか?」を尋ねるコンテキストに変化

Slide 28

Slide 28 text

3. コンテキストの遷移を図示する

Slide 29

Slide 29 text

「ゲーム中」 「もう一度遊ぶかどうか?聞い ている最中」 「ヒントが欲しいか?聞いてい る最中」 コンテキストの遷移を図示することで、会話の流れの概略を把握できる

Slide 30

Slide 30 text

4. インテントを洗い出す

Slide 31

Slide 31 text

4. インテントを洗い出す ユーザの「意図(= アプリへの意思表示、要望)」を抽出する。 ● 「コンテキスト」は、どちらかというと「アプリ都合」。 ● 「インテント」は、「ユーザ都合」で考えていく。

Slide 32

Slide 32 text

Happy Path - 「3桁の数字を言って当てる」= "input.numbers" 、「もう一度遊ばないと表明する」= "play_again.no"

Slide 33

Slide 33 text

Happy Path - "input.numbers" インテントは、コンテキストを変える(game から play_again に)

Slide 34

Slide 34 text

3回間違えた - "input.numbers" インテントは、hear_hint コンテキストにも変えることがある

Slide 35

Slide 35 text

ヒント - 「ヒントを聞く」= "help_hint" インテント

Slide 36

Slide 36 text

4. コンテキストの遷移にインテントを挟める

Slide 37

Slide 37 text

コンテキストの遷移を図示することで、会話の流れの概略を把握できる

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

No content

Slide 40

Slide 40 text

5. インテントの出入り口に対話を当てはめる

Slide 41

Slide 41 text

No content

Slide 42

Slide 42 text

例: 「ゲーム中」から「ヒントを聞くかどうか尋ねる」コンテキスト間にインテントを入れて対話を当てはめる

Slide 43

Slide 43 text

例: 「ゲーム中」から「ヒントを聞くかどうか尋ねる」コンテキスト間にインテントを入れて対話を当てはめる 789 1イート0バイトです。ヒントを聞き たいですか? はい 3桁の数字の合計は、16です。

Slide 44

Slide 44 text

例: 「ゲーム中」から「ヒントを聞くかどうか尋ねる」コンテキスト間にインテントを入れて対話を当てはめる 789 ヒント 1イート0バイトです。ヒントを聞きたいですか? はい 3桁の数字の合計は、 16です。 3桁の数字の合計は、 16です。 続けましょう。3桁の数字をどうぞ。 1イート0バイトです。 よくわかりませんでした。 3桁の数字をどうぞ。 いいえ 123 ???

Slide 45

Slide 45 text

脚本 ● Google SpreadSheet 脚本からのVUI設計 VUI設計 ● Google SpreadSheet ● UML: ステートチャート図 ● UML: アクティビティ図

Slide 46

Slide 46 text

実装時のポイント

Slide 47

Slide 47 text

実装時のポイント ● VUI設計からDialogflowへのマッピング ● インテントからアクションの抽出とその実装コードの作成 ● いつでも会話を終了できる

Slide 48

Slide 48 text

Dialogflowへのマッピング

Slide 49

Slide 49 text

789 1イート0バイトです。ヒントを聞きたいですか? 1イート0バイトです。 おめでとうございます! 3イートです。もう一度遊びますか?

Slide 50

Slide 50 text

789 1イート0バイトです。ヒントを聞きたいですか? 1イート0バイトです。 おめでとうございます! 3イートです。もう一度遊びますか? Training phrases Input context Output context Response Intent

Slide 51

Slide 51 text

Intent Input context Output context Training phrases Response

Slide 52

Slide 52 text

アクションとフルフィルメント

Slide 53

Slide 53 text

アクションの発見 インテントに対するレスポンスが 1つに決まることは 希なこと。ユーザの発言やコンテキスト、アプリの 状況に応じて動的に変わる。 → フルフィルメントが次を決定する。 ● Output contexts ● Response フルフィルメントに処理を指示するために、アクショ ンを定義して指定する。

Slide 54

Slide 54 text

Action name Use Fulfillment

Slide 55

Slide 55 text

フルフィルメント 開発者がコードを書く対象は、このフルフィルメントになる。 ● HTTPS+JSONを扱えれば、基本的に何でも良い。 ● Node.js向けの actions-on-google-nodejs を使うのが一般的。 ○ https://github.com/actions-on-google/actions-on-google-nodejs ● Cloud Functionsとの親和性がある。 ○ GCP/Firebase Cloud Functions (外部通信しなければ無料枠で Ok) ○ 似たような他のソリューションでも問題ないはず

Slide 56

Slide 56 text

Dialogflow Fulfillment ● Action name ● Arguments (= Parameters) ● ... HTTPS request

Slide 57

Slide 57 text

const DialogflowApp = require("actions-on-google").DialogflowApp; const ACTION_INPUT_WELCOME = "input.welcome"; exports.fulfillment = (req, res) => { const app = new DialogflowApp({request: req, response: res}); const inputWelcome = app => { app.ask("こんにちは。○○です。・・・"); }; const actionMap = new Map(); actionMap.set(ACTION_INPUT_WELCOME, inputWelcome); app.handleRequest(actionMap); }; フルフィルメントのテンプレートコード

Slide 58

Slide 58 text

Responseの決定に使用するコード // 会話を継続してユーザに次の意図を発言してもらう app.ask("正解です!おめでとうございます。もう一度遊びますか? "); // 相手が何も言わなかった際の再プロンプトを第 2引数に指定する app.ask( "正解です!おめでとうございます。もう一度遊びますか? ", ["よく聞こえませんでした。再度遊びますか? ", ...] ); // 会話を終わる app.tell("わかりました。また遊びましょう。 ");

Slide 59

Slide 59 text

Output Contextsの決定に使用するコード // Output Contextを設定する const CONTEXT_PLAY_AGAIN = "play_again"; app.setContext(CONTEXT_PLAY_AGAIN, 1); // 1 はLifespan // Input Contextを削除する const CONTEXT_GAME = "game"; app.setContext(GAME, 0); // 0 によって削除される

Slide 60

Slide 60 text

アクションを跨いだ情報保持に使用するコード // 会話セッションの範囲内で情報を保持する app.data.answer = "123"; // 会話セッションが終了しても次の会話向けに情報を保持しておく app.userStorage.answer = "123";

Slide 61

Slide 61 text

const inputNumber = app => { const number = app.getArgument("number"); const answer = app.data.answer; if (number === answer) { app.setContext("game", 0); app.setContext("play_again", 1); app.ask("正解です!もう一度遊びますか? "); } else { app.setContext("game", 1); app.ask("○イート○バイトです。"); } }; 実際のコードの例

Slide 62

Slide 62 text

5秒以内にレスポンスを返すこと。 レスポンスを複数返すことは現状できない。 フルフィルメント実装のポイント

Slide 63

Slide 63 text

いつでも会話を終了できる

Slide 64

Slide 64 text

コンテキストの遷移を図示することで、会話の流れの概略を把握できる

Slide 65

Slide 65 text

コンテキストの遷移を図示することで、会話の流れの概略を把握できる

Slide 66

Slide 66 text

どのコンテキストにいても、ユーザが会話を終了することができるようにしておかなけ ればならない。 → レビュー時には「終了」というフレーズでいつでも会話を終わらせることができるか どうか確認している模様。 → app.askForConfirmation() で「はい」「いいえ」のみを受け付ける場面でも指摘さ れてしまうことがあるので要注意。 いつでも会話を終了できる

Slide 67

Slide 67 text

レビュー提出時のポイント

Slide 68

Slide 68 text

アプリの情報登録 ● アプリ名、発音 ● アプリの説明文 ● 画像、アイコン ● 呼び出しフレーズ ● 開発者情報 ● プライバシーポリシー、利用規約 ● カテゴリ ● その他もろもろ 基本的には、右図のページに必要となる情報を登 録していくことになる。

Slide 69

Slide 69 text

アプリ名 Googleアシスタントが「アプリ名」を期待通りに認識 してくれるかどうかを早めに確認しておくことがオス スメ。 → Googleアシスタントでアプリ名を声で認識させ て、どのようなテキストになるかを試す。 → あと「早い者勝ち」なので。 ”さいたまけんこうつうとりしまりけいかく ” 期待してたテキスト: 埼玉県交通取締計画 認識結果のテキスト : 埼玉県交通取締り計画 → アプリ名「埼玉県交通取締り計画」

Slide 70

Slide 70 text

画像、アイコン 小さなアイコンは「丸型」アイコン。 → 四隅が描画されないことを見越したアイコンにし なければならない。

Slide 71

Slide 71 text

呼び出しフレーズ レビュアーは登録された全ての呼び出しフレーズを 試して、実際にアプリが起動するかをちゃんと確認 している。 → しかも、全てのデバイスで!起動しなければ、 Rejectされる。 特に Implicit Invocation は全てのデバイスで確認 することが大事。 上記の2つ目のImplicit InvocationはAndroidアシ スタントではOkだったのでレビュー提出するも、実 はGoogle HomeではNGであり、結果Rejectになっ てしまった。

Slide 72

Slide 72 text

プライバシーポリシー、利用規約 レビュー時に「内容そのもの」についてはさほどチェックされていない模様。 → 自分を守るために責任をもって内容を決めることが大事。 「正しいアプリ名」が書かれているかどうかはちゃんとチェックされる。

Slide 73

Slide 73 text

まとめ

Slide 74

Slide 74 text

まとめ Googleアシスタント向けアプリを設計、実装し、リリースするために、 ● 設計時のポイント ● 実装時のポイント ● レビュー提出時のポイント を事前に把握しておけば、スムーズにリリースに辿り着くことができます。

Slide 75

Slide 75 text

Fin.