こんにちは、AIチームの友松です。
この記事は以下の記事の続編となります。先にそちらをご覧いただいてから読むことをおすすめします。
これまではDialogflowでの対話設計の方法について執筆しましたが、今回は作成したDialogflow Agentにリクエストをして、簡易なチャットボットを作成します。
Dialogflowを外部から呼び出すことができるようにするために権限設定を行います。
2. IAMと管理ページに移動
3. サービスアカウント作成ページよりサービスアカウントの作成を行う。
4. 作成したサービスアカウントの鍵を作成します。鍵を管理 -> 鍵を追加 -> 新しい鍵を追加 -> キーのタイプをJSONを選択 -> 作成 の手順で作成ができます。作成したjsonファイルを任意の場所に格納してください。
5. サービスアカウントへの権限設定
IAMのページに移動し、追加を選択します。
先程作成したサービスアカウントを入力し ロールとしてDialogflow APIクライアント
のロールを付与します。
前回の記事の対話をベースに拡張を行います。前回はユーザが予約希望として伝えた時間を営業時間判定をするところまで説明しましたが、一連の対話として対話が完結するまで対話シナリオを膨らませて、対話終了のIntentにend_conversationを設定し、対話の終了を区別できるように変更します。
「はい」を拾うためのEntityを設定します。はいの言い換えとして考慮しうるものをsynonymに追加すると色々なパターンで拾うことができます。
「いいえ」を拾うためのEntityを設定します。いいえの言い換えとして考慮しうるものをsynonymに追加すると色々なパターンで拾うことができます。
「時間」を拾うためのEntityを設定します。Regexp entityを選択肢、正規表現でパターンを記述します。
Welcome Intentは前回までのものとほぼ同じ設定なのですが、追加事項としてEventでwelcomeを設定しています。これによって、テキストで「こんにちは」を拾う以外にもeventでこちらのIntentに遷移することができます。
チャットボット作成時、最初のフックとしてイベントを使うことでBotの発話を引っ張ることができます。
Webhook Callを呼び出すIntentになります。設定は前記事を全く同じになっています。
こちらのIntentは前回の差分としてResponse文言を若干変更、そして新たにend_conversationの設定をオンにしています。end_conversationをonにすると、そのIntentにたどり着いたときに会話の終了地点かどうかを受け取ることができます。
こちらのIntentは前回の差分としてResponse文言を若干変更しています。こちらのIntentは後ろに対話が続くのでOutputContextを設定し、end_conversationはoffにします。
こちらのインテントは予約の実行有無を肯定した際に遷移するIntentです。end_conversationをonにします。
こちらのインテントは予約の実行有無を否定した際に遷移するIntentです。end_conversationをonにします。
Webhookサーバーの実装も前回と全く同じです。詳しい説明はそちらに譲ります。
import jsonimport redef main(request) -> str: body = request.get_json() # Request Body intent_name = body["queryResult"]["intent"]["displayName"] if intent_name == "Request Reservation Hour Intent": # Enable webhook call for this intent.を指定したintent名 return fulfillment_request_reservation_hour(body) else: raise Exceptiondef fulfillment_request_reservation_hour(body): session = body["session"] # sessionId hour = body["queryResult"]["parameters"]["hour"] # ユーザー発話から抽出したhourパラメータ hour_int = int(re.search(r'\d+', hour).group()) # ◯時の表現から数字部分を抜き出す if hour_int >= 24: raise Exception elif 10 <= hour_int <= 19: event_name = "during_business_hours" else: event_name = "after_business_hours" res = { "followupEventInput": { "name": event_name "parameters": { "hour_int": hour_int } } } return json.dumps(res)
$ pip install google-cloud-dialogflow
必要なライブラリのインストールを行います。
from google.cloud import dialogflow_v2 as dialogflowimport uuidimport os # 1. 初期化処理ブロックos.environ["GOOGLE_APPLICATION_CREDENTIALS"] = "{YOUR CREDENTIAL FILE PATH}"project = "{YOUR DIALOGFLOW PROJECT ID}"session = str(uuid.uuid4())session_client = dialogflow.SessionsClient()session_path = session_client.session_path(project=project, session=session)# Welcome発話処理ブロックprint("----チャット開始----")# 最初のbot発話はEventInputを発火することで取得。event = "welcome"event_input = dialogflow.types.EventInput( name=event, language_code="ja-JP")query_input = dialogflow.types.QueryInput(event=event_input)response = session_client.detect_intent( dialogflow.types.DetectIntentRequest( query_input=query_input, session=session_path ))# 対話ブロック# 会話終了フラグ(end_conversation)を検知するまでループする。while True: response_text = response.query_result\ .fulfillment_messages[0]\ .text.text[0] print(f"Bot: \n{response_text}\n") # 会話終了判定 end_conversation_flg = ( response.query_result.diagnostic_info is not None and "end_conversation" in response.query_result.diagnostic_info and response.query_result.diagnostic_info["end_conversation"] ) if end_conversation_flg: print("----チャット終了----") break print("User:") user_text = input() print("\n") # 2回目以降のbot発話はuserからのTextInputをもとに取得。 text_input = dialogflow.types.TextInput( text=user_text, language_code="ja-JP" ) query_input = dialogflow.types.QueryInput(text=text_input) response = session_client.detect_intent( dialogflow.types.DetectIntentRequest( query_input=query_input, session=session_path ) )
実際にBotを作成します。
初期化ブロックでは、Dialogflowクライアントの初期化を行います。また第1章で作成したサービスアカウントのJSONのパスをGOOGLE_APPLICATION_CREDENTIALSの環境変数に設定します。
Welcome発話処理ブロックでは、welcome Eventを発火することでWelcome IntentのResponseを引っ張ってきて会話を開始します。イベントの発火にはsession_client.detect_intentにEventInputを渡すことで実現できます。
対話ブロックではend_conversationが発火するまで対話を継続するようなループを行います。ユーザの入力を標準入力から受け取り、session_client.detect_intentにTextInputを渡すことで実現できます。
実際にチャットボットが動作する様子を動画で示します。
今回は作成したDialogflow Agentにリクエストをして、簡易なチャットボットを作成する方法について執筆しました。今回は非常にシンプルな実装で行いましたが、こちらを拡張することでDialogflowを組み込んだ様々なチャットボットを作ることができます。簡単にできるのでぜひお試しください。