YAMAGUCHI::weblog

噛み付き地蔵に憧れて、この神の世界にやってきました。マドンナみたいな男の子、コッペです。

api.aiのdefault fallback intentをFirebase Functionsで受ける

はじめに

こんにちは、Slack Bot界のアラーキーです。今日はAlphaGoが柯潔との3局対決2勝目で中押し勝ちで2勝目を挙げましたね。Machine Learningの発展はすごいなあという素人の感想ですが、そんなMachine Learningの力をBot開発にも簡単にもたらしてくれるサービスの一つがapi.aiです。api.ai自体の説明は公式サイトや他のサイトに譲るとして、今日はapi.aiのdefault fallback intentをFirebase Functionsで実装したFulfillmentで受けるという簡単なデモを試したので、その作業ログを残します。

チャットボット AIとロボットの進化が変革する未来

チャットボット AIとロボットの進化が変革する未来

前提

まずは用語の説明から。

  • api.ai: 様々なチャットシステム用Bot(Actions on Google、Slack、LINE、Facebook Messanger)などに対応しているチャットボットミドルウェア
    • Agent: あるひとまとまりの応答をするNLU(Natural Language Understanding、自然言語理解)モジュール。複数のチャットアプリケーションと同時に連携が可能。
    • Intent: ユーザーからの特定のクエリに対する応答のマッピング。このintentをいかに多くの応答に対して作成できるかがapi.aiの肝。
    • Fulfillment: api.aiの先に用意する自前の応答システム。通常のbotシステムであればチャットシステムから直接メッセージデータを受け取るが、api.aiを利用する場合は前段となるapi.aiで捌けなかったものや複雑なトランザクションが発生するものをここで受ける。

api.ai自体を利用する場合は他にもEntityやContextといったものとapi.aiで内蔵している自然言語理解のトレーニング機構を使っていかに効率よくルールを作成していくかが肝心なのですが、今日は対応するIntentがなにもない場合のフォールバック先であるDefault Fallback Intentを自分で用意したFirebase Functionsのエンドポイントで受ける、ということをまずやってみます。

Firebase Functionsでのエンドポイントの作成

Firebaseプロジェクトの作成

Firebase FunctionsのGetting Startedのドキュメントを読めば簡単にできると思いますが、簡単にコマンドログだけ書くと

$ npm install -g firebase-tools
$ firebase login
$ firebase init functions
$ cd functions
$ npm install --save firebase-functions
$ npm install --save firebase-admin@4.2.1
$ tree -a -L 2 .
.
├── .firebaserc
├── firebase.json
└── functions
    ├── index.js
    ├── node_modules
    └── package.json

作成された firebase.json は空のオブジェクトが書いてあるだけですが、作成するFirebase Functionsのファイルを functions 以下に置くのであればそのままで大丈夫。functionsディレクトリの中のindex.jsに実際のエンドポイントの処理を書いていきます。

index.jsの作成

index.js をこんな感じで雑に作ります。Slackのみをつなげているため、dataの中にslackしかありませんが、つなげているアプリケーションが複数あればそれに応じてassistantfacebookなどのメッセージも追加することで対応できます。api.aiから飛んでくるリクエストと、そこに返すべきレスポンスのJSONスキーマに関しては api.ai のWebhookのドキュメントに書いてある。

const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp(functions.config().firebase);

const slack_message = {
    "text": "hello slack from firebase"
}

exports.sampleBotAgent = functions.https.onRequest((req, res) => {
    console.log(req);
    res.status(200).send({
        "speech": "hello from firebase",
        "displayText": "hello from firebase",
        "data": {"slack": slack_message},
        "source": "foo"
    })
});

デプロイ

これで完了です。デプロイします。プロジェクトルート直下で firebase deploy コマンドを実行します。

$ firebase deploy --only functions
=== Deploying to 'sample-bot-agent'...

i  deploying functions
i  functions: ensuring necessary APIs are enabled...
i  runtimeconfig: ensuring necessary APIs are enabled...
✔  functions: all necessary APIs are enabled
✔  runtimeconfig: all necessary APIs are enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (1.55 KB) for uploading
✔  functions: functions folder uploaded successfully
i  starting release process (may take several minutes)...
i  functions: updating function sampleBotAgent...
✔  functions[sampleBotAgent]: Successful update operation.
✔  functions: all functions deployed successfully!

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/samplebot-agent/overview
Function URL (sampleBotAgent): https://us-central1-samplebot-agent.cloudfunctions.net/sampleBotAgent

ログの最後のFunction URLというのが作成されたエンドポイントのURLなのでこれをコピーします。

api.aiの設定

Agentの作成

api.aiに初めてログインするとすぐにAgentの作成画面に飛ばされると思います。すでにAgentがあるけれど新規に作る場合には、左ペインのエージェント名の右側にあるメニューボタンを押すと “Create new agent” というメニューがでてくるのでそこで作成。適当にAgentの名前やdescriptionを書きます。Sample Dataは無いと思うので無視。言語は英語が一番ちゃんと動きますが、日本語もちょっとは使えます。目下改良中の模様。今回はどうせDefault Fallback Intentしか作らないのであまり関係ないです。Google Projectはデフォルトで作ってくれるものでいいと思うので無視。

f:id:ymotongpoo:20170526002606p:plain

Slackとの連携

Agentは複数のチャットアプリケーションと連携できますが、今回はSlackのみと連携します。左ペインのメニューのIntegrationsを押して、Slackのトグルスイッチをオンにします。 f:id:ymotongpoo:20170526004756p:plain

するとSlackの各種トークンを設定するダイアログが出てくるので各々設定します。Slack側でもBotの設定をする必要がありますが、そのあたりは次のドキュメントにスクリーンショット付きで書いてあるのでそちらに譲ります。 先のダイアログ内のOAuth URLとEvent Request URLはSlack側のBotの設定で必要となります。その設定手順も次のドキュメントに書いてあります。

Fulfillmentの設定

AgentができてIntegrationができたのでFulfillmentを設定します。左ペインのメニュー内のFulfillmentを選択して設定画面にいきます。 f:id:ymotongpoo:20170526003017p:plain

WebhookのEnabledをオンにするといくつかフォームが出てきますが、ここのURLに先ほどコピーしたFirebase FunctionsのURLを貼ります。あとは設定しなくてOKです。 f:id:ymotongpoo:20170526003156p:plain

default fallback intentの設定

Fulfillmentの設定が終わったのでいよいよdefault fallback intentの設定です。初期値ではDefault Fallback IntentとDefault Welcome Intentがあると思います。 f:id:ymotongpoo:20170526003813p:plain

このDefault Fallback Intentを開くといくつかText Responseが設定されていることと思います。 f:id:ymotongpoo:20170526003953p:plain

このText Responseをまず全部消します。全消しです。Actionはそのまま “input.unknown” にしておいてください。その後、画面下にある Fulfillment という文字を押します。ここがわかりにくいですがこの Fulfillment の文字を押すと “Use webhook” のチェックボックスが出てくるのでチェックします。 f:id:ymotongpoo:20170526004257p:plain

これで設定完了です。

Slackで試す

適当なチャンネルに先ほど Agent と連携させた Bot を招待して、適当に書き込んでみます。 f:id:ymotongpoo:20170526005711p:plain

無事に動作しました!あとはapi.ai側のIntentを拡充させて、Fallback側での動作を諸々と考えるだけですね!楽しくなってきました!

おわりに

チャットシステムが普及し、様々な場面で文字・音声チャットが使われることが増えてきました。自分用のBotもより柔軟なものにできるように自分もいろいろ試そうと思います。

参照