de:code 2018 [AD01] 試作で止まらないための チャット Bot 開発

[de:code 2018](https://www.microsoft.com/ja-jp/events/decode/2018/)に参加してきましたのでその結果をまとめています。

内容の間違い、誤字脱字等はご了承ください。正確なところは、本家のサイトを参照いただければと思います。

# タイトル等

## タイトル
de:code 2018 [AD01] 試作で止まらないための チャット Bot 開発

## 演者
* 大田 昌幸さん　日本マイクロソフト株式会社　コマーシャル ソフトウェアエンジニアリング本部　テクニカル エバンジェリスト
* 高木 充弘さん　日本マイクロソフト株式会社　デジタルトランスフォーメーション事業本部　クラウドソリューションアーキテクト
* 澤田 浩幸さん　株式会社JTB 経営戦略本部　IT企画担当マネージャー
* 田辺 晋一さん　株式会社ナビタイムジャパン　開発部 シニアエンジニア　cogbotプロジェクトプロジェクトマネージャー

## 日時
2018/05/23 15:00-15:50

# 概要、感じたこと

PoCをやる上の実際の開発方法（ユーザーストーリーマッピング）も参考になりましたが、成功するためには、心構えが大事だということが参考になりました。

特に、顧客も含めて提案受け姿勢から共同開発の姿勢へ巻き込んでいかなければ、というところは、受け身になりがちな姿勢では、それこそ互いにリソースを無駄遣いするだけだと感じます。

まとめると、Pocの段階では以下のことが大事ではないかと思います。

* 素早くリリース改善するためには100%を求めない
    * 100%を求めていたらいつまでたっても出せなくなる
* でもその認識を共有するためにユーザーストーリーマッピングを有効活用しよう。
なかなか進まない状況があるならなおさら
* 短いサイクルで失敗してもいいけど、必ず次の糧にしよう！
* 短期集中できるような体制を構築しよう！

# PoCを超える

![POC](https://locp9g.bl.files.1drv.com/y4mY1ODUkPDW5jsmPO9IdnJVFwxfIWEtW86j7sKCvS30K2BDAvH42_kw59btgk5M5cqN59nZ2QfAM0msCdMR1GckrVIxHCa9ZG58xDh9wB4iS_2lYNdNGWHQQgC0hRBWWmzLgo5Mc0h2S26_4TqMLL8kC-6k6D92T0MucW7vVBspRuF8PRAbkttYACIBEBFJRTGCuYgO-1MMokbKIxC7tkQOg?width=4032&height=2268&cropmode=none)

サービスを構築するには、

* フェーズ1：PoCを超える
	
	PoC（Proof of Concept（概念実証） の略であり、新しいプロジェクト全体を作り上げる前に実施する戦略仮説・コンセプトの実効性検証を指す。）を超える
	
	
* フェーズ2：利用率UP

	サービスをリリースし、バージョンアップを行い利用率UPを目指す
	
という手順を踏んでいくが、このPoCを超えるというところでつまづく会社が結構多い。

今回は、このPoCを超える（実証段階を超える）というところをどのように実現していくか？について説明していく。


# 今回開発するアプリケーション

## アプリケーション概要

![アプリ](https://k4beaw.bl.files.1drv.com/y4mmJyPlKTN4zZ7I1if-TEDsaXY5mihgKQdU_Ln-UIPz1pi_xjsSEAg2adUxQxAeIK55t83fCkOcTvV_jcXSzqB6FBquh-doSgvK9P7KddYa6amZ7IZe4N8OtdJpS553k9XdpqEHj79Prv8MA7HdnqSK5j-rG8Y2ValorMEF4R0I69xs16m4l0EBFaGAZ4PlJ8f_iXunf9V6S_1t_9HEmXXAw?width=3536&height=1989&cropmode=none)

旅は、旅をする前（計画段階）、旅している途中、旅が終わった後、と区分けをすることができるが、今回の開発対象としては、旅マエ、旅ナカを対象としている。

つまり、気軽に常に旅行をサポートすることができるサービスを提供したいということで始めた。

京都には4000万人が来るので、チャットボットで外国人の方に利用していただきたい。例えばちょっとした困りごととか調べものについて調べていただき、サポートしていただくことを目標としている。


## 参加会社

* 企画：JTB
* 開発：Navitime

旅行に強いJTBと、経路検索に強いNavitimeということになる。JTBが企画会社ということになるが、開発に関する本セッションで、企画会社であるJTBにも登壇してもらうのには意味がある。


## Demo

![イメージ](https://kocp9g.bl.files.1drv.com/y4mchv4_uYsYHAXOhefNaA4M5uueE9F31OdCcwLUD86j1SH-WNLIxdF7aySrcZOm1opUOTXCvPcQMgIfu_wSBWmeqE-sC2SAWTdQth24UqJeT-a6qXXcqj0lxuYApcJe8rApzZRwGLPl6hll404eZa34hNbBXihEW3juFoEckCxCwV5x8hjncM4RJFyWP9hiPaAVoD1pL0wYnFu8WMCj4GoGw?width=4032&height=2268&cropmode=none)

アプリ、キャラクターが常にしゃべりかけてくれる形。フリーソフト。AppStore Google Playからダウンロードできる。

例えば、フグのおいしい料理を福岡県で、というと検索してくれたり、もっとリーズナブルなフグを、というともっと値段が安いフグを検索してくれる。

英語でしゃべりかけたら、英語で答えてくれるということもできる。


# フェーズ1：Pocを超える

## 通常の開発の手順を適用するとうまくいかない

![PoC](https://iyaogg.bl.files.1drv.com/y4mEhK3jidtJ0DGKkXwXvohulIezxhsXyqhWh8i-3FLtmTh-SZP4nJ4dTEHXQRQdG4Qo_lxgMN1ybaJ_BXNdk6hGarbya2RRF9EtcLCq5F0kK3nZKkpJARekPDlbjZ6WQc89VwXleGn4RYOAFtTQCLeYk-MPoBfmZ53JSjKltDuuJ7T_rfo26UlVzVWt7rSB3HJQo4wSMXvP1gf_yi74oAmGg?width=3974&height=2235&cropmode=none)

PoC（技術検証）の失敗点としては、Pocではなくて開発になってしまったことが問題となる。

つまり、通常の開発と同じように、

* 要求事項を分析し、
* 提案を依頼し
* 成功することを前提とする

というように作業を進めてしまうと、本来のPoCではなくなってしまうので、技術的検証が上手く行かない。

PoCであれば、実験から遠ざからないように気をつけることが大事だが、開発の手法を適用し、実験ではなくなってしまったのが問題である。

## 短期集中がポイント

![短期集中](https://kobeaw.bl.files.1drv.com/y4mq8Gx64Myty-V0LxdY9JfHDFA36Nsj325D3DAQu-2GMC8nEauP9MP3lCK6QcKk8BhJPw8zALVx1HxO-Tcc6WKLGg41gqJtdTphbwVbi0KgShTxiN6UoYpzmKd-vbDnR3opzYW6x6Re797cQCJ7bZYf87fCxO3gs_3Wq80CIG7jRMmfRRRHCM7ah5e9urckcwtdh3twiN_OSJ0ia_Mb-D1jw?width=4032&height=2268&cropmode=none)

Microsoftの協力を得て、Hackfestというものを行った。

これは、1週間という短期間で、集中的に開発を行うものである。また、朝企画を立てて、昼開発し、夜フィードバックするというように1日単位でPDCAを回すのがポイントである。

またこのHackfestには、規格も開発も参加する。それこそ営業職から、実際にプログラムを行うプログラマーまで参加する。実際に参加した企画の方からは、実際に開発するメンバーを見ることができてよかったといういう意見も得られている。

## ユーザーストリーマッピング

![ユーザーストーリー](https://liaogg.bl.files.1drv.com/y4mEupppFrsQJSVF8-KOYAYBrBEXDhPJnI4TQkfD6hiKkJwLpH34N0E5EuZ6zcdZGmlHkmiNPEN6LS7Gxz3tJIl6fNZxg-zaRUiiIVMphXmRaV3hwqqjA7xZOayc3hIJezBlfCxzpVriyAOHJVNySxZb_UwMJIrNlZ9dJ2qt6Cuk3KxhIJlj1ND4tDqC3iodOIv5gD165mLeoZuNXBB-EcqnA?width=3817&height=2147&cropmode=none)

通常の開発でも使える手法としてユーザーストーリーマッピング(USM)というものがある。

（筆者補足）ユーザーストーリーマッピングとはJeff Patton氏(@jeffpatton)が開発した、製品の設計、ユーザーワークフロー、リリース計画を同時に見える化する手法です。

アプリケーション企画時点でエンジニアも参加し、USMをベースにミーティングすることで、アプリケーションで実装する機能、リリースするタイミングについて関係者で共有し、チームを１つにすることができる。

USMでは、まず実際にアプリケーションが使われるシーン（フロー）を決めて、そこから実際に実装する機能を決めていく。

## 進め方

一般的なアプリ開発の進め方とチャットボットの開発の進め方は変えなければいけない。

### 一般的なアプリ開発の進め方

![一般](https://kidf3w.bl.files.1drv.com/y4mXbD4vkJu0PF9Y_m2gg6VXbQsypnBbm9EcyM3US6DRHgzjVdpFjUi4vXIJXvGQqacOeRJKwAE-tT4NuZI3ui9Rk_h61pBJ4dSnn2JIcNpKI4MqnepJZlnIwkKDKgTTRu_krNC6OxYKXNXXMdofL3R3Q3q7qzzF06gls38ts7I7T-fs7ef55MdwdV9qWRgTI4_VzAKxrtg_B4Z9C3I2bHSOw?width=3971&height=2233&cropmode=none)

一般的なアプリケーションの開発では、大まかにいえば(2)開発/テストを複数回進めるだけでよかった。

### チャットボット開発の進め方

![チャット](https://k4df3w.bl.files.1drv.com/y4mc59OZn-2pAfOfDoaFI_vie_n-GQQ5159vb34D18ATMLbnH2G_6XWpuXH_s1N6iAzCPIpnplmQ3tK8Llw6e1InXMC06o1XkfAZngG73VkmMq743Br44z9XRicYmSciP0o1vAnigbsVtqHX7RYlMQnJojwC1An6GU_3K0rHZ8b3SAOVTXhvH3lAYdo6UlcCxd8mAImXPnfyVGu3zyTCyDaSg?width=3975&height=2235&cropmode=none)

チャットボット開発では、(2)〜(4)の手順が3つ増えている。

つまり、開発/テスト以外にやることが増えているため、開発とテストをスピーディに行わないと、(2)〜(5)の手順を回すことができない。

## 作業の絞り込み

どうすればいいのか？というと作業の絞り込みを行う。

* 業務ロジックを組み込まない
* 会話フローは実装しない
* AIモデルや学習に注力する

### 業務ロジックを組み込まない

![よくある](https://iiaogg.bl.files.1drv.com/y4mvSyEQYAN0P4CuyaQwRQ1RuOwolw6dzRdi8diQY-9XpnVtcUzQEZ2HbgSB9Zpm6XcAS4B9L2fO6A4SFIr-MY10bIMbtSYDs3c8u4wnRmuHGIQktKMM523IaFUkX50qJXqvmIMPuR71jNnoghRy34jbPZsZWHtl59efNpcYPrxJ0mSFlPrdo_ANjG6VfcQOJxtW5mYE7cAjaiG3oZC-WBbHw?width=4032&height=2268&cropmode=none)

よくあるチャットボットアプリでは、上手のような構造となっているが、これでは変更があった時に影響範囲が大きく、変更に弱いシステムとなる。

![排除する](https://kiaogg.bl.files.1drv.com/y4mj5uJPkTpxdNYE9wK7aLwKUgLmVpbY40O0AOEz5Px9K3uTdeP1ZeETW53Co7nPK2VhgaEPrvxz0FlVwQyMCg3MIycfzCvahmUtA7bDHWTxxsv3rlr2wUbEkLIHznUEQMJOSjvwwHDigh9ChujSIovu7bhWda5QlYokA85WvIpFVTTufhnQhvrMULwbo2lxHDW61aRGYmU2uV3UeH0XA-A2w?width=4032&height=2268&cropmode=none)

そこで、BOTアプリから、業務ロジックを排除した作りにすることが重要となる。

![実装](https://k4aogg.bl.files.1drv.com/y4mTSrNK0Qi00VK8nOx73NGhqInzPM5kHAP8sUC1ESdESQi7Wd0cDWpd1anCEUI_CBzMKU_jgyWs5dw1oRvzEVKwLJLs3IQAmJ5VCLFAKpWe52XK3xlZ5OhQhoSZfvgWzBpjMO0pXHRzfqGwFn8Ktg7QvtqXjotTIQt0Tw3fbIWCWwWLEWgHNuDuMomyfh3lqF9utTFXHgJeuHf8800LkXqtA?width=4032&height=2268&cropmode=none)

実際の実装としては、業務ロジックとデータはAzureの中に放り込むことで分割し、業務ロジックとビジネスロジックは、Azure Functionで実装している。

### 会話フローは実装しない

会話フローは実装しない、ということを実現するために3ステップだけを実装した。

つまり、意図を判断し（何かを食べたいのか？どこかに行きたいのか？）、意図でAPIの種別を判断して、エンティティを抽出している。

![画像](https://loaogg.bl.files.1drv.com/y4mk0L2DwCNltMrJsuwX1Wfo3LyJzONtEu2fctklQBW3zqomxsRJ78YUNmav_e-huHa36r0ZNVbzJliyXeg8aN21mFGF54qi47rXf_lnPAox_FG7pTXT6s6mxJvAGc542lsrN19xvFJT7iU8IYPzfQ6FqMiLob7NpAKU3GkVjyyeDm4uw2qIJ5p3gJ_8RwOrl_wgjFXvgi9MMMnLdVF0rprOg?width=4032&height=2268&cropmode=none)

この中で、例えば単純な会話についてAIで実装することもできる。しかし、こんにちはに対する回答を行うためのAIの実装まで行うと、時間がかかってしまうし、ユーザーは雑談をし始める。

#### 普遍的トピックチェーンフロー

そこで今回は、普遍的トピックチェーンフローで整理し、既存の機能で補えるところは既存の機能で実装し、残りをAIで開発することにした。

![画像](https://lidf3w.bl.files.1drv.com/y4m8JXVG2s-OZKK-SAYUdZOXk-JIM69gKT5drk8neC7L8GiePVo-qxAnymjojaXki2PFo4NT15YQ05IvYO3rHFmpuJffzqTqXLhwA4qm0xWNlCXJkT0yAWztxIGIsCEd6TsqklunSSuzvAgkLi380T3LNYM6E4VLCobrTNT-0D5Yej_noM9pBs74ECHz1segXzkFs5opvjVpsNxKzghldjt_w?width=3948&height=2220&cropmode=none)

1. ChitChat 雑談する
2. FAQ 普遍的なQAにこたえる
3. Finder　プラン／スポットを探す
4. Feedback　フィードバックをもらう

#### 具体的な実装

![実装](https://kodf3w.bl.files.1drv.com/y4m3o1UUwHnGRRXYZ0ki6LBE2YQjuMs5CmZ3fmH-0dxlNTlWvjv0p_EUEgEcJIgDoBK19v7cg5p5Y2vQCwRnhRFBAEmpJQS6AgGIvYN87aLSkNkn5A0wtqkGdk6nTXujt9cr9WEX6BVL06Du6kn1afrtX-9rCBCVzxcufFKWbu6qQLFYzLl3miahTMAkOUXeZsZMPXTBbEijEBgQgJIymZoWw?width=3943&height=2218&cropmode=none)

具体的な実装としては、

* (1)ChitChatと(2)FAQはAzureのQnA Maker（質問に対する回答を登録できる機能）で実装する
* (3)Finderと(4)FeedbackはLUISで実装した。

Luisからは、意図とEnthityが返ってくるので、それに応じたAPIを呼び出すという形となる。

Feedbackでは、はい、またはいいえを選択する画面の実装を行うチャットボットもあるが今回はしていない。これは、値段がもうちょっと安かったのになあ、という発言が判断されない場合もあるので、単純な画面を出さず、独自の判断をするようにした。

この実装で大事なのは、右側のAI学習モデル部分である。フローをちゃんと作った上で、学習モデルの作成にだけ注力すればよいような構成とし、**本当に重要な学習の部分に注力する**、ということが大事である。

## まとめ

### 開発

* 業務ロジックは排除
* 普遍的トピックチェーンフローの実装
* 本当に重要なファクターに注力

### 発注側も含めて

* 提案受け姿勢から、共同開発の姿勢へ
* PoCは時間をかけない、短期集中開発で素早く軌道修正する
* その結果成功を求めない、失敗を糧にする
* 最初から100％を求めると、すべてが失敗になる


# フェーズ2：利用率UP

ユーザーの声を反映し、本当に使ってもらえるアプリにしたい

そのためには、実際にどのような使われ方をしているかを分析することが大事になってくる。そこで実際の会話ログをもとに、ユーザーの声を知り、データ・ドリブンな開発の意思決定を行っていくことになる。

![実際](https://lobeaw.bl.files.1drv.com/y4m0jbWIYu4_P4S7Zy6bWiBOp-_klqs9lQV0_LEbs3f4KMU-uYJiSltd_N36Z6HOm4VeL2debS_wxCAMFEIM0ljcqQY8hJWoHDK_10n-eiuYCknAoqKSs7vGHAhyM0T2HD5F5SnpwEaHsfrVxVibFei9-QQ7HmYQnbf5bBwFvnX6-N6alA-4zAAk7B97bWEiopjEaxtYRhXYhztqIwhA8BkGg?width=4032&height=2268&cropmode=none)

* どんな意図の会話があるかを知りたい
* 出した情報へのポジネガを知りたい
* どんなデータを欲しがっているのか

## 分析のポイント

### データの流し方

Cosmos DBを使用しているが、ここからPowerBIにデータを流し込む形としたい、しかし直接Cosmos DBからPowerBIに流し込むと、レイテンシが下がる、位置情報が少なくなるなどの問題がある。

そこで、実際に使われているモバイルアプリから Azure Functionsを挟んでCosmosDBにデータを送る実装とした。Azure Functionsならスケーラビリティーも行うことができる

### 分析のポイント

LUISを使用することでデータの分析を行うことができる。

しかし、LUISは昨日のLUISと今日のLUISは異なるので学習モデルが異なってきてしまう。これはLUISが日々モデルが更新されることに伴う問題となってくる課題となる。

![分類](https://loci4g.bl.files.1drv.com/y4m19ss7H6EB_M2YZcFnyuKs_koiCKoWKhx3dMneFyEZ-wQfLIw71OC7INIEzlCyhtRQRNiuVcwBEj7K0iPr9MtQJezpxI2aOlk_ySNafD68rojLnTdEe0XTI1LtCOgC4tSePIIv4qv7NAZs_jfQcs0R-eJe760j4UJrc4rXcXZF-K2_pNrzbGaU6g69e06-lGk6QQv50hlpr99AlJqEugZlg?width=3968&height=2231&cropmode=none)

具体的に何が困るのかというと、昨日作ったモデルと今日作ったモデルで出す答えが変わってくるので、同じデータに対して結果を集積する分類結果が変わり、**統計がぶれる
**。

![解決](https://iici4g.bl.files.1drv.com/y4mx-8LeZUK2B1wLtqKsHu6dq3xjlWaKnS-kbyr4Tbzxm6rNpOPnBtfXxPLDnrMX5BxfjtLWqNAOh2FXlREH77JzVIllmgAz2bwMKHJ5qV-AwCEZoPgNWDab3hTyOD480HSn5LRZoO-BzbLFMBSLs6PIbhsEFiJI7O1H7VSbYIrFeQPKp5vuledkh4NWh5E0zsbDFNb2QelcarVqFA1sJBi3g?width=3988&height=2243&cropmode=none)

では、これに対してどう言った解決を行ったかというと、バージョンが変わることにPowerBI側でどこのコレクションを見るかとうことを固定するために、解析をかけた状態もCosmosDBに保存することで、分類結果のブレがない状態の分析を行えるようにした。

つまり、出来上がったPowerBIを使用して解析することになる。（この方法はボイスアーキテクチャでも応用できる方法である）


## PowerBIでの分析

Power BIではいつどこで入力したかを図ることができる。例えば、会話のなかから、ネガティブな情報が取れたとする。その結果、大阪で子どもの遊び場が見つからなかった、ということから、次のアクションの決定（大阪でもう少し子供の遊び場所に関する情報を登録しよう）を行うことができる。

![決定](https://l4beaw.bl.files.1drv.com/y4m2MqCoIxmao6CoeoC3D6kEuVSWzut81X6MMOY0MUr87kpXzUIC0G9l1rmdCIp-xL4i8mhzkti0-6TrrucJCxANDphhbCtBlb8lKI7pWWcXzAW5Cn4xm6NnHfSpM4LM_MOyuBEt1Ab3Nxwa0OUkJZpluTeybyyGttunIpV6CB-TQiy1xaSgMloKePKh9Tld-bCCYfiItDOphlvXbpxta75wg?width=4032&height=3024&cropmode=none)

# まとめ

## 複数の提案ミーティングより、一度のユーザーストーリーマッピングで一丸となったほうが良い。

提案してもうまくいかないなら、一度USMということをやりませんかということをすればPocから先に進むのではないか。

## 提案待ちでPocを行なっても報われないの

お互いに意見を出すことで、有用な情報を引き出すことができる。例えば、今回プログラマーの方と意見を出し合うことでやりやすかった、という意見もいただいている。

## 月・年単位ではなく、週単位の実験を糧にすることが大事。

今回関わったJTBの方は、1ヶ月単位の提案を持ってこないでほしい、と他の会社の方にもいっているらしい。