Kekeの日記

エンジニア、読書なんでも

Google AssistantとDialogflowで使えるLINE家計簿Botを作ってみる!

f:id:bobchan1915:20190216234429p:plain

動機

アドラー心理学によれば、私たちは常に目的をもって行動しています。 そして、過去は一切関係ないと。これがアドラー心理学の目的論の主眼点であり、これが過去のフロイトとも大きく論点が異なるものです。

特に、私はお金の管理が面倒で、たまに後悔することがあります。1ヶ月で使いすぎてしまったり、、、 そして、なんでミスをしてしまったのかを考え込んでしまいます。

アドラー心理学の考えでは「私は後悔することを後悔するために後悔している」ということができます。 つまり、悲しみなどは私の目的を達成するための道具でしかないのです。

感情を使わず、私の心の問題解決をするには、根本的な解決策は後悔することをなくすことであり、それが私は音声インタフェース機能も家計簿に取り込むことが必要なのではないかなと思って今回の記事にしました。

LINE Botの副次的な用途についてはいくつか記事にしています。

www.1915keke.com

www.1915keke.com

www.1915keke.com

アジェンダ

本記事のアジェンダは以下の通りです。

使えるデバイス

  • Google Home
  • Google Assistant
  • Google Assistant対応ヘッドフォン

ユースケース

f:id:bobchan1915:20190219204030p:plain

自分は決済後に家計簿をつけるためにはどのようことをしたらいいのか考えました。

問題: 携帯を取り出したくない。

解決策: コンビニ帰りにヘッドフォンで家計簿をつけること

アーキテクチャ完成図

今回のアプリケーションの仕様を満たすアーキテクチャは以下の通りです。

f:id:bobchan1915:20190216234429p:plain

注意点としてCloud Functions for Firebaseを使う解説記事が多いですが、今回はCloud Firestoreなどは使う必要がないため、Cloud Functionsを選定しました。

またCloud SQL(MySQL)に接続することも簡単です。

用語の確認

いくつかサービスの名前やAPIの名前など、知っておくべき用語があるため、まとめておきます。

Googleサービスについて

  • Actions on Google: Googleアシスタントアプリケーションを作成するためのプラットフォーム
  • Dialogflow: 言語解析エンジンのこと。
  • Google Assistant: Google Homeなどに搭載されているAIアシスタント。Google Homeに限らない

Dialogflowについて

  • Action: Applictionの振る舞いのこと
  • Entity: ユーザーの会話での変数や単語のこと。例えば日付、色、量や購入、予約などの単語です。Entitesはそのまとまりのこと。
  • Fulfillment: 解析した結果をWebhookなどバックエンドに渡す処理のこと。任意。
  • Intent: ユーザーの会話内容とActionの対応関係を定義したもの

Google Home Applicationを作成する

1. Projectの作成

1つのApplication = 1つのProject です。

"Add/import project"を選択します。

f:id:bobchan1915:20190216145528p:plain

次にModalが表示されるので答えて"AGREE AND CONTINUE"とします。おおまかな訳はつけました。

f:id:bobchan1915:20190216145831p:plain

次にProjectの名前、言語のProjectの言語の選択、そして住まいの国を選択します。

f:id:bobchan1915:20190216150011p:plain

ここで注意点ですがGoogle Cloud Platform(GCP)のProjectと一緒です。

なので、別Projectに拘りがなければ、他のAPIも使うことを考えると同じProjectにするのが良いと思います。

f:id:bobchan1915:20190216150355p:plain

私は今回、yamashita-bankというProjectにActionsを追加します。この場合は`IMPORT PROJECT'になります。

そして、無事に作成されると以下のような画面になるはずです。

f:id:bobchan1915:20190216150532p:plain

2. Dialogflowエージェントを作成する

再度、"Add/import projects"を選択する画面に戻って、先ほど作成したアプリケーションを選択します。

f:id:bobchan1915:20190216151325p:plain

するとOverview画面が開かれます。

f:id:bobchan1915:20190216151303p:plain

そしてBuild -> Actionを選択してADD YOUR FIRST ACTIONを選択します。

今回はBuild-in intentsを使わないので、Custom intentを選択し、BUILDを選びます。

f:id:bobchan1915:20190216151914p:plain

Dialogflowに権限を許可します。

f:id:bobchan1915:20190216152007p:plain

そして、今度はDialogflowの利用規約に同意します。

f:id:bobchan1915:20190216152057p:plain

すると以下のようにAgentの名前を選ぶことになります。Agentは直訳すると代理人なのでyamashita-bankのところのbankerとしましたが、実際のところ何でも良いです。

f:id:bobchan1915:20190216152340p:plain

3. AgentのEntitiesやIntentsを作成する

3.1 Entitiesを作成

用語の節でも定義したように

会話の中での変数の定義

です。

Dialogflow Agentが会話を解析して、Entityを抽出さます。その言葉を定義しなければなりません。

例えば「コーヒーを〇〇する」の〇〇が変数で、ユーザーのしたいことが変わります。

〇〇が「購入」や「予約」ということもありえ、また、「お渡し」という言葉もあり得ます。

それでは、それを定義していきましょう。左のサイドバーメニューから"Entities"を選択して、"CREATE ENTITY"でEntityを作成します。

f:id:bobchan1915:20190216153938p:plain

今回はRequest Entityをまず定義しました。

Request Entity = ユーザーの要求すること

を定義するEntitiesです。

3.1.1 System Entities

あらかじめシステムに組み込まれていて、自分で定義をすることなく使用できるEntityのことです。

使用言語によって異なります。

日本語での一部例を紹介すると

  • @sys.number: 数字を定義
  • @sys.date: 日付

などです。

もし仮に使いたいものがなければ、自分で定義をしなければならないことになります。

3.2 Intentsの作成

f:id:bobchan1915:20190216155607p:plain

図のようにIntentはユーザーの意図(=Intent)とActionを結びつけるものです。

まず設定項目を包括的にまとめます。

項目 概要
Contexts Intent間で渡せる変数
Events 会話以外にIntentを設定する方法
Training phrases Intentをトリガーするフレーズ
Action and parameters このIntentで使用するアクションや変数を定義する
Response ユーザーへの返答の定義
Fulfillment 解析した結果をWebhookなどバックエンドに渡す処理のこと

最初に必要最低限に定義をしなければならない項目について設定をしていきます。

3.2.1 Training phrases

どのようにこのIntentがトリガーされるかを記録するものです。

以下のように定義します。

f:id:bobchan1915:20190216175822p:plain

3.2.2 Action and parameters

例えば家計簿だと「支出をつけて」っといっても良いですし、「記録して」だけの使い方でもありえます。

ということは、Request EntityはRequiredであり、「支出」やのちに定義する「一覧」Operation Entityは任意であることがわかります。

f:id:bobchan1915:20190216180103p:plain

ここで$request$operationなどの変数は次のResponseに使用することができます。

注意して欲しいのは$[VALUE名]で参照できるわけではなくて$[PARAMETER NAME]で参照できます。

今回の簡単なParameter定義ではうまくいきますが、Contextsを使い始めるとハマってしまう人が多いと聞きました。

また"PROMPTS"では、必須項目がなかったときに聞く質問を定義できます。

f:id:bobchan1915:20190216204003p:plain

3.2.3 Response

レスポンスはユーザーへの返答を定義します。

以下のように定義しました。特に$から始まる変数を使う必要がなかったので使用していません。

f:id:bobchan1915:20190216180204p:plain

ここまでで一つのIntentを構築できました。

4. Dialogflow Console上でTestする

正しくIntentが構築できているかをTestします。

右にTestできる機能があります。

例えば、Training phrasesで定義したフレーズを使用してみます。

f:id:bobchan1915:20190216180636p:plain

すると以下のようにレスポンスが返ってきます。

f:id:bobchan1915:20190216180725p:plain

これによって、Google Homeアプリケーションそのものを作ることができました。

DialogflowをActions on Googleと連携する

f:id:bobchan1915:20190216181921p:plain

Dialogflowのシミュレータで作成しましたが、まだActions on Googleで使用することができません。

OverviewのBuildで"INTEGRATE ACTIONS FROM DIALOGFLOW"を選択してActionを取り込みます。

f:id:bobchan1915:20190216182029p:plain

1. Explicit invocation componentsを設定する

どのようにそのApplicationをGoogle Homeで使用するかを設定します。

以下のようなフレーズで、Invocation nameを指定して、意図を伝えます。

f:id:bobchan1915:20190216183754p:plain

またExplicit invocationは一つしか設定できませんが、Implicite invocationは複数設定できます。

Explicit invocation = デフォルトで呼び出されるIntentということができます。

f:id:bobchan1915:20190217073343p:plain

2. Simulatorでテストする

"Build" -> "Action"のところで"TEST"があるので押してSimulatorを起動します。

f:id:bobchan1915:20190216183411p:plain

以下のようにシミュレーションしてみます。

f:id:bobchan1915:20190216183845p:plain

正しく会話ができています。

Dialogflow consoleで変更するとどうなるでしょう。

すぐ反映されます。特にDialog上での変更で、何かしないといけないことはありません。

f:id:bobchan1915:20190216184027p:plain

また、実機でもテストをすることができます。

注意点としては同じGmailアカウントでセットアップされている実機でしかテストをすることができません

たとえば、Google Homeだと、管理者に紹介をされて管理者アカウントになった場合でも、セットアップしたアカウントと異なるので実機でもはできませんので注意してください。

3. 実機テストをする

またはAlpha, Beta版でテストユーザーを定義して作成することができ、公開する前にしっかりとテストができます。

f:id:bobchan1915:20190216202845p:plain

このあとにAlpha版やBeta版でEmailをテスター一覧に追加することによって、指定したEmailアドレスに紐づくGoogle Assistantで使用することができます。

f:id:bobchan1915:20190313144907p:plain

ホワイトリスト制なので、適宜追加する必要があります。

4. Deployする

サイドバーの"Deploy"を順序をおって設定していけばDeployすることができます。

ここではDeployしたくないためしません。

高度な会話

1. Follow-up Intentを使用する

Follow-up Intentを使用すると継続的な会話をすることができます。

Follow-up Intentとは

Follow up intentとは親のIntentのcontextを保持するintentである

作成方法は以下の箇所をボタンで押します。

f:id:bobchan1915:20190216192541p:plain

すると、以下のように選択肢が出てきます。

f:id:bobchan1915:20190216192444p:plain

大雑把に説明すると以下のように対応をしています。

  • Custumは自前で定義します
  • yes: はいと答えるものに対して
  • no: 断るときに使用
  • Fallbackはどれもトリガーされなかったときにトリガーします
  • Later : あとで などの言葉に対して使います
  • More: もっと結果をほしいなど
  • Repeat: なんていった?など聞き返してくるときに使う
  • Select.number: 数をせんたくするようなIntent

例えばcancelを見てみましょう。

「支出を記録して」などといったあとに「やめて」などというようなシチュエーションです。customを選択すると、すでに設定されているフレーズがたくさん用意されているのがわかります。

f:id:bobchan1915:20190216192759p:plain

また、キャンセルで会話を終わるのが自分のアプリケーションの要件なのでResponseの部分で以下のようにチェックを入れてContextを解放しています。

f:id:bobchan1915:20190216192901p:plain

Cancelに限らず、Follow-up IntentとParent IntentはContextを持ってやりとりをします。

Parent IntentにはOutput context

f:id:bobchan1915:20190216193029p:plain

Follow-up IntentにはInput context

f:id:bobchan1915:20190216193105p:plain

が設定されています。

Follow-up Intentのメリットとしては、継続的な会話を定義できることであり、それは逆にいうとContextを持たないときにFollow-up Intentを直接呼び出せません。

例えば最初に「記録」としてContextを生成します。

f:id:bobchan1915:20190216193251p:plain

すると、その継続的な会話に対応するユーザーの入力は受け付けてもらいます。

f:id:bobchan1915:20190216193327p:plain

しかし、いきなり2つ目のFollow-up Intentから入力しても、何も起きません。

f:id:bobchan1915:20190216193359p:plain

このように簡単に会話ができるようになります。いろんな会話を定義してみてください。

Contextsの使用

例えば前の前の会話から内容から値を取得したいときはどのようにしたらいいのでしょう。

例えば以下のようなuserrecord-custom-followup contextを参照しているものがあるとします。

f:id:bobchan1915:20190216205845p:plain

すると以下のように使用することができます。

f:id:bobchan1915:20190216205921p:plain

これによって会話内容の保持をすることができます。

2. Fulfillmentを使用して高度なオペレーションをする

Fulfillmentとは

Dialogflow agentのためにデプロイされるWebhookで、より高度なロジックなどを実現する機能

です。ここではGCPのCloud Functionsを使用します。

f:id:bobchan1915:20190216211001p:plain

デプロイしてURLを取得します。それをFulfillmentのURLに記述します。

f:id:bobchan1915:20190216214544p:plain

これだけではURLの設定ができただけで、何もすることはできません。

Intentごとに指定されたWebhookのURLに送信するかを定義します。

一番下の"Enable webhook call for this intent"にチェックを入れます。

f:id:bobchan1915:20190216223820p:plain

実際にやってみると、楽しかったです。

LINE Botと統合

LINE家計簿Botへのインテグレーションを同時に行いました。

実際に最後まで会話をしたあとにLINE Botから送信されるものはこちらです。

f:id:bobchan1915:20190216233132p:plain

スマホを開かなくても家計簿をつけることが可能になりました。

まとめ

やはりエンジニアとしての解決力は、学際的に、トレンドを用いる問題解決が必須なのではないかなと日々思います。

特に音声インタフェースは可能性が満ち溢れていて、いろんなアプリケーションが試行錯誤されている状況です。

もちろん、家計簿はこれまでは"書き物"でした。 しかし、日々の生活の中でのユースケースを捉え、自分としては満足いくアプリケーションになりました。

これから、どんどん開発を進めたいと思います。