先月中旬(2019.3.16), Urban Data Challenge 2018のファイナルが行われ, CODE for YAMATOKORIYAMAが金魚愛(AI)育成プロジェクトとして取り組んでいる「Kingyo AI Navi」が, アイデア部門の金賞[1]を受賞した.
CODE for YAMATOKORIYAMAでは, 今年度このアイデアをアプリ化したいと考えており, LINEの枠組みを利用したアプリ化の検討を開始した.
関連記事:
・「Kingyo AI Navi」のアプリ化を考える (1)
・「Kingyo AI Navi」のアプリ化を考える (2)
・「Kingyo AI Navi」のアプリ化を考える (3)
・「Kingyo AI Navi」のアプリ化を考える (4)
・「Kingyo AI Navi」のアプリ化を考える (5)
・「Kingyo AI Navi」のアプリ化を考える (6)
1. 概要
「Kingyo AI Navi」をLINEのMessaging API + サービスで実現すべく, 今回はLINE Botから金魚や大和郡山に関する簡単な問い合わせを行い, 関連情報を返す部分の基本的な動作を試してみた.
サービス側は, これまでGCPの枠組みを活用して検討してきたので, 今回も問い合わせ部分の解析にはDialogflowを利用することにした.
Dialogflowは, 自然言語で会話できるボットを作るためのツールを提供するサービスである.
[構成図]
① LINEアプリからLINE Botサーバへ質問文を送信する.
② LINE Botサーバは, Messaging API経由で, Kingyo AI NaviサービスのWebhook URLをコールする.
③ Kingyo AI Naviサービスは, 質問文をDialogflowに送信し, 質問文の解析を行う.
④ Kingyo AI Naviサービスは, Dialogflowから質問タイプを受信する.
⑤ LINE Botサーバは, Messaging API経由で, Kingyo AI Naviサービスから質問タイプに応じた応答(関連情報等)を受信する.
⑥ LINE Botサーバは, 受信した応答をLINEアプリに送信する.
2. サービス開発
2.1 Dialogflow側設定
Dialogflowの利用手順については, ネット上に多くの記事[2][3]があるので, そちらを参照のこと.
2.2 質問文解析処理
「Kingyo AI Navi」に問い合わせできる内容については, 別途タスクを決めるとして, 今回は以下の4つの質問文で試してみる.
Dialogflowは, 質問文の揺らぎを吸収し, 質問タイプを特定することに利用し, 応答内容についてはGCEでMessaging APIの仕様に基づき生成することにした.
質問文 | 応答(タイプ) |
金魚の育て方 | BREEDING |
金魚スポット | SPOT |
金魚の病気について | DISEASE |
大和郡山のイベント | EVENT |
Dialogflowでは, どのように質問文の揺らぎを吸収しているのか?
Intentで基本的な質問文の型を定義しており, Entityでキーとなる言葉の揺らぎを定義する.
下記例では, 「金魚」×「飼い方」の組み合わせ, 及び, 例えば「を教えて」など余分な語彙がついても正しく質問文タイプを識別できる.
[Intentの例]
[Entityの例]
2.3 アプリ実装
LINE Messaging APIによるMessageEventがTextMessageの場合, 問い合わせとして処理する.
前回のコードをベースに, TextMessageイベントを処理する部分を変更する.
(1) dflow.send_text_request()関数でDialogflowに質問文を送信し, 解析し, 質問タイプを得る.
(2) 質問タイプに応じて, LINEへの応答内容をButtonsTemplateを使って作成する.
[コード]
# Handle text message @handler.add(MessageEvent, message=TextMessage) def handle_text_message(event): try: print('call dialogflow : ', datetime.datetime.today()) message, params = dflow.send_text_request(event.message.text) print('return dialogflow : ', datetime.datetime.today()) messages = make_buttons_template(message, params) reply_message(event, messages) except Exception as e: import traceback traceback.print_exc() reply_message(event, TextSendMessage(text='何か調子が悪いなー.'))
LINEとDialogflowを直接つなぐ場合, DialogflowのIntegrationsでLINEを有効にするだけでよいようだ.
しかし, 今回はLINEとDialogflowの間にGCEが入るので, GCEでLINEからのメッセージを受けて, APIを使ってDialogflowを呼び出す処理が必要となる.
(1) setup_dialogflow()関数で, Dialogflowを使うための準備を行う.
(2) send_text_request()関数で, 質問文をDialogflowに送信して質問文のタイプ及びパラメータを返す.
[コード]
import os import settings import uuid import json from google.oauth2 import service_account import dialogflow_v2 as dialogflow from google.protobuf.json_format import MessageToJson LANGUAGE_CODE = 'jp' # init Dialogflow def setup_dialogflow(): session_id = uuid.uuid4().hex credentials = service_account.Credentials.from_service_account_file(os.envi\ ron['DIALOGFLOW_CREDENTIALS']) session_client = dialogflow.SessionsClient(credentials=credentials) session = session_client.session_path(os.environ['PROJECT_ID'], session_id) return session_client, session session_client, session = setup_dialogflow() def send_request(query_input): response = session_client.detect_intent(session=session, query_input=query_\ input) parameters = response.query_result.parameters params_json = json.loads(MessageToJson(parameters)) return response.query_result.fulfillment_text, params_json def send_text_request(text): text_input = dialogflow.types.TextInput(text=text, language_code=LANGUAGE_C\ ODE) query_input = dialogflow.types.QueryInput(text=text_input) return send_request(query_input)
[動作例]
LINE画面から質問文を送信すると, 質問文に応じた応答が表示される.
課題:
今回は, 対話シナリオ(質問文やそれに対する応答内容)についてDialogflowとGCEの両方で設定しているが, ズレをなくすためには, 対話シナリオを記述したデータセットをベースに, GCEからAPIを使ってDialogflowにIntent及びEntityの設定を行うなどの仕組みが必要となってくる.
また, この質問文に対する情報をどう収集し, 更新していくかなども課題となってくる.
まっ, ぼちぼち考えていこう!!
----
参照URL:
[1] UDC2018審査結果 | アーバンデータチャレンジ
[2] Dialogflow入門 - Qiita
[3] Dialogflowでチャットボットを作ってみた - アトトックラボ
LINE BOTを作ろう! Messaging APIを使ったチャットボットの基礎と利用例
|
|