この Codelab では、Vision API を Dialogflow と統合して、ユーザーが提供した画像入力に対してリッチで動的な機械学習ベースのレスポンスを提供します。画像を入力として受け取り、Vision API で処理して、特定されたランドマークをユーザーに返す chatbot アプリを作成します。たとえば、ユーザーがタージマハルの画像をアップロードすると、chatbot はタージマハルをレスポンスとして返します。
これは、画像内のアイテムを分析して、取得した情報に基づいてアクションを実行できるため、便利です。払い戻し処理システムを構築して、ユーザーが領収書をアップロードし、領収書から購入日を抽出し、その日付が適切であれば払い戻しを処理できるようにすることもできます。
次のサンプル ダイアログをご覧ください。
お客様: こんにちは
Chatbot: こんにちは。写真をアップロードしてランドマークを検索する
ユーザー: タージマハルが写っている画像をアップロードします。
Chatbot: ファイルを処理しています。結果は次のとおりです。タージマハル、タージマハル庭園、タージマハル。
前提条件
続行する前に、次の Codelab を完了する必要があります。
- Dialogflow を使用して予約スケジューラを構築する
- Dialogflow chatbot を Actions on Google と統合する
- Dialogflow のエンティティについて
- Dialogflow アプリのフロントエンド Django クライアントを構築する
また、Dialogflow の基本コンセプトと構成についても理解する必要があります。これについては、Dialogflow でチャットボットを構築するの次の動画で確認できます。
学習内容
- Dialogflow エージェントを作成する方法
- ファイルをアップロードするように Dialogflow エージェントを更新する方法
- Dialogflow フルフィルメントで Vision API 接続を設定する方法
- Dialogflow 用の Django フロントエンド アプリを設定して実行する方法
- Django フロントエンド アプリを App Engine の Google Cloud にデプロイする方法
- カスタム フロントエンドから Dialogflow アプリをテストする方法
作成するアプリの概要
- Dialogflow エージェントを作成する
- ファイルをアップロードする Django フロントエンドを実装する
- アップロードされた画像に対して Vision API を呼び出す Dialogflow フルフィルメントを実装する
必要なもの
- Python の基礎知識
- Dialogflow の基本的な知識
- Vision API に関する基礎知識
カスタム Django フロントエンドを使用して新しい会話型エクスペリエンスを作成し、Vision API と統合するように拡張します。Django フレームワークを使用してフロントエンドを構築し、ローカルで実行してテストしてから、App Engine にデプロイします。フロントエンドは次のようになります。
リクエスト フローは、次の図に示すように機能します。
- ユーザーはフロントエンド経由でリクエストを送信します。
- これにより、Dialogflow detectIntent API への呼び出しがトリガーされ、ユーザーの発言が適切なインテントにマッピングされます。
- ランドマーク探索インテントが検出されると、Dialogflow フルフィルメントは Vision API にリクエストを送信し、レスポンスを受信してユーザーに送信します。
全体的なアーキテクチャは次のようになります。
Vision API は、画像から分析情報を導き出す事前トレーニング済み ML モデルです。画像のラベル付け、顔とランドマークの検出、光学式文字認識、露骨な表現を含むコンテンツのタグ付けなど、複数の分析情報を取得できます。詳細については、Vision AI をご覧ください。
- Dialogflow コンソールに移動します。
- ログインします。(初めてご利用になる場合は、メールアドレスを使用して登録してください)。
- 利用規約に同意すると、コンソールが表示されます。
をクリックし、一番下までスクロールして [Create new agent] をクリックします。
5. [エージェント名] に「VisionAPI」と入力します。
- [作成] をクリックします。
Dialogflow では、エージェントの一部として次の 2 つのデフォルト インテントが作成されます。
- デフォルトのウェルカム インテントは、ユーザーに挨拶をします。
- デフォルトのフォールバック インテントは、ボットが理解できないすべての質問をキャッチします。
この時点で、ユーザーに挨拶する機能的なボットが完成していますが、ユーザーが画像をアップロードしてランドマークを探索できることを知らせるように更新する必要があります。
画像をアップロードするようユーザーに通知するよう、デフォルトのウェルカム インテントを更新
- [Default Welcome Intent] をクリックします。
- [Responses] > [Default] > [Text or SSML Response] に移動して、「Hi! 写真をアップロードしてランドマークを検索できます。」
エンティティを作成
- [Entities] をクリックします。
- [Create Entity] をクリックし、「filename」という名前を付けて、[Save] をクリックします。
新しいインテントを作成する
- [インテント] > [インテントを作成] をクリックします。
- [インテント名] に「Explore uploaded image」と入力します。
- [トレーニング フレーズ] > [トレーニング フレーズを追加] をクリックし、エンティティとして @filename を使用して、ユーザー式として「file is
demo.jpg
」と「file istaj.jpeg
」を入力します。
- [レスポンス] > [レスポンスを追加] > [デフォルト] > [テキストまたは SSML レスポンス] をクリックします。「Assessing file」と入力し、[Add Responses](レスポンスを追加)をクリックします。
- [Fulfillment] > [Enable fulfillment] をクリックし、[Enable webhook call for this intent] をオンにします。
- [Fulfillment](フルフィルメント)をクリックします。
- [Inline Editor] を有効にします。
- 次のコードで
index.js
を更新し、YOUR-BUCKET-NAME
を Cloud Storage バケットの名前に更新します。
'use strict';
const functions = require('firebase-functions');
const {google} = require('googleapis');
const {WebhookClient} = require('dialogflow-fulfillment');
const vision = require('@google-cloud/vision');
/**
* TODO(developer): Uncomment the following lines before running the sample.
*/
const bucketName = 'YOUR-BUCKET-NAME';
const timeZone = 'America/Los_Angeles';
const timeZoneOffset = '-07:00';
exports.dialogflowFirebaseFulfillment = functions.https.onRequest((request, response) => {
const agent = new WebhookClient({ request, response });
console.log("Parameters", agent.parameters);
function applyML(agent){
const filename = agent.parameters.filename;
console.log("filename is: ", filename);
// call vision API to detect text
return callVisionApi(agent, bucketName, filename).then(result => {
console.log(`result is ${result}`);
agent.add(`file is being processed, here are the results: ${result}`);
//agent.add(`file is being processed ${result}`);
}).catch((error)=> {
agent.add(`error occurred at apply ml function` + error);
});
}
let intentMap = new Map();
intentMap.set('Explore uploaded image', applyML);
agent.handleRequest(intentMap);
});
async function callVisionApi(agent, bucketName, fileName){
// [START vision_text_detection_gcs]
// Imports the Google Cloud client libraries
// Creates a client
const client = new vision.ImageAnnotatorClient();
try {
// Performs text detection on the gcs file
const [result] = await client.landmarkDetection(`gs://${bucketName}/${fileName}`);
const detections = result.landmarkAnnotations;
var detected = [];
detections.forEach(text => {
console.log(text.description);
detected.push(text.description);
});
return detected;
}
catch(error) {
console.log('fetch failed', error);
return [];
}
}
- 次の内容を
package.json
に貼り付けて、その内容を置き換えます。
{
"name": "dialogflowFirebaseFulfillment",
"description": "Dialogflow fulfillment for the bike shop sample",
"version": "0.0.1",
"private": true,
"license": "Apache Version 2.0",
"author": "Google Inc.",
"engines": {
"node": "6"
},
"scripts": {
"lint": "semistandard --fix \"**/*.js\"",
"start": "firebase deploy --only functions",
"deploy": "firebase deploy --only functions"
},
"dependencies": {
"firebase-functions": "2.0.2",
"firebase-admin": "^5.13.1",
"actions-on-google": "2.2.0",
"googleapis": "^27.0.0",
"dialogflow-fulfillment": "^0.6.1",
"@google-cloud/bigquery": "^1.3.0",
"@google-cloud/storage": "^2.0.0",
"@google-cloud/vision": "^0.25.0"
}
}
- [保存 ] をクリックします。
- ローカルマシンにこのリポジトリのクローンを作成します。
https://github.com/priyankavergadia/visionapi-dialogflow.git
- コードが含まれているディレクトリに移動します。または、zip ファイルとしてサンプルをダウンロードして展開することもできます。
cd visionapi-dialogflow
デプロイされたアプリは、App Engine スタンダード環境に組み込まれている Cloud SQL Proxy を使用して Cloud SQL インスタンスと通信します。ただし、アプリをローカルでテストするには、Cloud SQL Proxy のローカルコピーを開発環境にインストールして使用する必要があります。詳細については、Cloud SQL Proxy についてをご覧ください。
Cloud SQL インスタンスに対する基本的な管理タスクを行うには、Cloud SQL for MySQL クライアントを使用します。
Cloud SQL Proxy をインストールする
次のコマンドを使用して、Cloud SQL Proxy をダウンロードしてインストールします。Cloud SQL Proxy は、ローカルで実行中の Cloud SQL インスタンスに接続するために使用されます。
プロキシをダウンロードします。
curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64
プロキシを実行可能にします。
chmod +x cloud_sql_proxy
Cloud SQL インスタンスを作成する
- Cloud SQL for MySQL 第 2 世代のインスタンスを作成します。名前に「polls-instance」などの名前を入力します。インスタンスを使用できるようになるまで数分かかることがあります。準備が完了すると、インスタンス リストに表示されます。
- 次に、gcloud コマンドライン ツールを使用して次のコマンドを実行します。ここで、
[YOUR_INSTANCE_NAME]
は Cloud SQL インスタンスの名前を表します。次のステップで使用するために、connectionName
に示された値をメモしておきます。[PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]
の形式で表示されます。
gcloud sql instances describe [YOUR_INSTANCE_NAME]
または、コンソールでインスタンスをクリックして、[インスタンス接続名] を取得することもできます。
Cloud SQL インスタンスを初期化する
前のセクションの connectionName
を使用して、Cloud SQL Proxy を起動します。
./cloud_sql_proxy -instances="[YOUR_INSTANCE_CONNECTION_NAME]"=tcp:3306
[YOUR_INSTANCE_CONNECTION_NAME]
は、前のセクションで記録した値に置き換えます。これにより、ローカル コンピュータから Cloud SQL インスタンスへのローカルテスト用の接続が確立されます。ローカルでのアプリのテストが終了するまで、Cloud SQL Proxy を実行したままにしてください。
次に、新しい Cloud SQL ユーザーとデータベースを作成します。
- polls-instance という名前の Cloud SQL インスタンスに、Google Cloud コンソールを使用して新しいデータベースを作成します。たとえば、「polls」という名前を入力します。
- polls-instance という名前の Cloud SQL インスタンスに、Cloud コンソールを使用して新しいユーザーを作成します。
データベースの設定を行う
mysite/settings-changeme.py
を編集用に開きます。- ファイルの名前を
setting.py
に変更します。 - 2 か所で、
[YOUR-USERNAME]
と[YOUR-PASSWORD]
を、前のセクションで作成したデータベースのユーザー名とパスワードに置き換えます。これにより、App Engine のデプロイとローカルテストの両方でデータベースに接続できるようになります。 ‘HOST': ‘cloudsql/ [PROJECT_NAME]:[REGION_NAME]:[INSTANC
E_NAME]' 行の[PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]
は、前のセクションで取得したインスタンス名に置き換えます。- 次のコマンドを実行し、出力された
connectionName
の値をコピーして次のステップで使用します。
gcloud sql instances describe [YOUR_INSTANCE_NAME]
[YOUR-CONNECTION-NAME]
は、前のステップで記録した値に置き換えます。[YOUR-DATABASE]
は、前のセクションで選択した名前に置き換えます。
# [START db_setup] if os.getenv('GAE_APPLICATION', None): # Running on production App Engine, so connect to Google Cloud SQL using # the unix socket at /cloudsql/<your-cloudsql-connection string> DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '/cloudsql/[PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]', 'USER': '[YOUR-USERNAME]', 'PASSWORD': '[YOUR-PASSWORD]', 'NAME': '[YOUR-DATABASE]', } } else: # Running locally so connect to either a local MySQL instance or connect to # Cloud SQL via the proxy. To start the proxy via command line: # $ cloud_sql_proxy -instances=[INSTANCE_CONNECTION_NAME]=tcp:3306 # See https://cloud.google.com/sql/docs/mysql-connect-proxy DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'HOST': '127.0.0.1', 'PORT': '3306', 'NAME': '[YOUR-DATABASE]', 'USER': '[YOUR-USERNAME]', 'PASSWORD': '[YOUR-PASSWORD]' } } # [END db_setup]
settings.py
を閉じて保存します。
- Dialogflow のコンソールで、
をクリックします。[全般] タブで、[Google プロジェクト] > [プロジェクト ID] に移動し、[Google Cloud]
をクリックして Cloud コンソールを開きます。
- ナビゲーション メニュー アイコン ☰ > [IAM と管理] > [サービス アカウント] をクリックし、[Dialogflow インテグレーション] の横にある
をクリックして、[キーを作成] をクリックします。
- JSON ファイルがパソコンにダウンロードされます。このファイルは、次の設定セクションで必要になります。
- chat フォルダで、
key-sample.json
を認証情報の JSON ファイルに置き換え、名前をkey.json
にします。 - チャット フォルダの
views.py
で、GOOGLE_PROJECT_ID = "<YOUR_PROJECT_ID>"
をプロジェクト ID に変更します。
フロントエンドの静的オブジェクト用の Cloud Storage バケットを作成する
- Cloud コンソールで、ナビゲーション ナビゲーション メニュー ☰ > [ストレージ] をクリックします。
- [バケットを作成] をクリックします。
- グローバルに一意の名前を指定します。
- データの保存場所の選択[リージョン] を選択し、ニーズに最適な場所を選択します。
- デフォルトのストレージ クラスとして [Standard] を選択します。
- [権限をバケットレベルで一律に設定する(バケット ポリシーのみ)] を選択し、[続行] をクリックしてバケットを作成します。
- バケットが作成されたら、ナビゲーション メニュー ☰ > [Storage] > [ブラウザ] をクリックして、作成したバケットを見つけます。
- 対応するバケットの横にある
をクリックし、[バケットの権限を編集] をクリックします。
- [メンバーを追加] をクリックし、[新しいメンバー] をクリックして「allUsers」と入力し、[ロールを選択] > [ストレージ オブジェクト閲覧者] をクリックします。これにより、静的フロントエンド ファイルに対する閲覧権限が allUsers に付与されます。これはファイルにとって理想的なセキュリティ設定ではありませんが、この Codelab の目的には適しています。
ユーザーがアップロードした画像用の Cloud Storage バケットを作成する
同じ手順に沿って、ユーザー画像をアップロードするための別のバケットを作成します。権限を再度「allUsers」に設定しますが、ロールとして [Storage オブジェクト作成者] と [Storage オブジェクト閲覧者] を選択します。
settings.py で Cloud Storage バケットを構成する
mysite/setting.py
を開きます。GCS_BUCKET
変数を見つけて、‘<YOUR-GCS-BUCKET-NA
ME>' を Cloud Storage 静的バケットに置き換えます。GS_MEDIA_BUCKET_NAME
変数を見つけて、‘<YOUR-GCS-BUCKET-NAME-MED
IA>' をイメージの Cloud Storage バケット名に置き換えます。GS_STATIC_BUCKET_NAME
変数を見つけて、‘<YOUR-GCS-BUCKET-NAME-STAT
IC>' を静的ファイルの Cloud Storage バケット名に置き換えます。- ファイルを保存します。
GCS_BUCKET = '<YOUR-GCS-BUCKET-NAME>'
GS_MEDIA_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-MEDIA>'
GS_STATIC_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-STATIC>'
home.html で Cloud Storage バケットを構成する
- チャット フォルダを開き、
templates
を開いてhome-changeme.html
の名前をhome.html
に変更します。 <YOUR-GCS-BUCKET-NAME-MEDIA>
を探し、ユーザーがアップロードしたファイルの保存先となるバケット名に置き換えます。これにより、ユーザーがアップロードしたファイルをフロントエンドに保存し、静的アセットを Cloud Storage バケットに保持することができなくなります。Vision API は Cloud Storage バケットを呼び出してファイルを取得し、予測を行います。
ローカル コンピュータ上で Django アプリを実行するには、Python、pip、virtualenv を含む Python 開発環境をセットアップする必要があります。手順については、Python 開発環境のセットアップをご覧ください。
- 隔離された Python 環境を作成し、依存関係をインストールします。
virtualenv env source env/bin/activate pip install -r requirements.txt
- Django の移行を実行してモデルを設定します。
python3 manage.py makemigrations python3 manage.py makemigrations polls python3 manage.py migrate
- ローカルのウェブサーバーを起動します。
python3 manage.py runserver
- ウェブブラウザで http://localhost:8000/ に移動します。次のようなシンプルなウェブページが表示されます。
サンプルアプリのページは、コンピュータで実行されている Django ウェブサーバーから配信されます。次に進む準備ができたら、Control+C
(Macintosh の場合は Command+C
)キーを押してローカル ウェブサーバーを停止します。
Django 管理コンソールを使用する
- スーパーユーザーを作成します。
python3 manage.py createsuperuser
- ローカルのウェブサーバーを起動します。
python3 manage.py runserver
- ウェブブラウザで http://localhost:8000/admin/ に移動します。管理サイトにログインするには、
createsuperuser
の実行時に作成したユーザー名とパスワードを入力します。
次のコマンドを実行して、すべての静的コンテンツを 1 つのフォルダに集約します。このコマンドは、アプリのすべての静的ファイルを settings.py
の STATIC_ROOT
で指定されたフォルダに移動します。
python3 manage.py collectstatic
app.yaml
ファイルが置かれているアプリのディレクトリから次のコマンドを実行して、アプリをアップロードします。
gcloud app deploy
更新が完了したことを通知するメッセージが表示されるまで待ちます。
ウェブブラウザで https://<your_project_id>.appspot.com に移動します。
今回は、App Engine スタンダード環境で実行されているウェブサーバーによってリクエストが処理されます。
app deploy
コマンドは、app.yaml
で説明されているようにアプリをデプロイし、新しくデプロイされたバージョンをデフォルト バージョンとして設定します。これにより、すべての新しいトラフィックがこのバージョンによって処理されます。
本番環境でコンテンツを提供する準備が整ったら、mysite/settings.py
で DEBUG
変数を False
に変更します。
チャットボットはシミュレータでテストすることも、以前に作成したウェブまたは Google Home の統合を使用することもできます。
- ユーザー: 「hi」
- Chatbot: 「こんにちは。写真をアップロードしてランドマークを検索できます。」
- ユーザーが画像をアップロードします。
この画像をダウンロードして demo.jpg
という名前を付け、使用します。
- チャットボット: 「ファイルが処理されています。結果は次のとおりです。ゴールデン ゲート ブリッジ、ゴールデン ゲート国立レクリエーション エリア、ゴールデン ゲート ブリッジ、ゴールデン ゲート ブリッジ、ゴールデン ゲート ブリッジ。」
全体は次のようになります。
他の Dialogflow Codelab を完了する場合は、このセクションをスキップして後で戻ってください。
Dialogflow エージェントを削除する
- 既存のエージェントの横にある
をクリックします。
- [全般] タブで下にスクロールし、[Delete This Agent] をクリックします。
- 表示されたウィンドウに「Delete」と入力し、[削除] をクリックします。
Dialogflow で chatbot を作成し、Vision API と統合しました。これで chatbot の開発が可能になりました。
その他の情報
詳細については、Dialogflow の GitHub ページのコードサンプルをご覧ください。