Tích hợp Vision API với Dialogflow

Trong lớp học lập trình này, bạn sẽ tích hợp Vision API với Dialogflow để cung cấp các phản hồi phong phú và linh hoạt dựa trên học máy cho dữ liệu đầu vào là hình ảnh do người dùng cung cấp. Bạn sẽ tạo một ứng dụng chatbot nhận hình ảnh làm dữ liệu đầu vào, xử lý hình ảnh đó trong Vision API và trả về một địa danh đã xác định cho người dùng. Ví dụ: nếu người dùng tải lên hình ảnh về Taj Mahal, thì chatbot sẽ trả về Taj Mahal làm câu trả lời.

Điều này rất hữu ích vì bạn có thể phân tích các mục trong hình ảnh và hành động dựa trên thông tin thu được. Bạn cũng có thể xây dựng một hệ thống xử lý việc hoàn tiền để giúp người dùng tải biên nhận lên, trích xuất ngày mua trong biên nhận và xử lý việc hoàn tiền nếu ngày đó phù hợp.

Hãy xem hộp thoại mẫu sau:

Người dùng: Chào bạn

Chatbot: Xin chào! Bạn có thể tải ảnh lên để khám phá các địa danh

Người dùng: Tải một bức ảnh có Taj Mahal lên.

Chatbot: Tệp đang được xử lý, đây là kết quả: Taj Mahal, Vườn Taj Mahal, Taj Mahal.

Điều kiện tiên quyết

Trước khi tiếp tục, bạn cần hoàn tất các lớp học lập trình sau:

  1. Tạo một trình lập lịch hẹn bằng Dialogflow
  2. Tích hợp chatbot Dialogflow với Actions on Google
  3. Tìm hiểu về thực thể trong Dialogflow
  4. Tạo một ứng dụng Django phía trước cho ứng dụng Dialogflow

Bạn cũng cần nắm được các khái niệm và cấu trúc cơ bản của Dialogflow. Bạn có thể tìm hiểu thông qua các video sau trong lộ trình Xây dựng chatbot bằng Dialogflow:

Kiến thức bạn sẽ học được

  • Cách tạo một đặc vụ Dialogflow
  • Cách cập nhật một đặc vụ Dialogflow để tải tệp lên
  • Cách thiết lập mối kết nối Vision API với dịch vụ thực hiện của Dialogflow
  • Cách thiết lập và chạy ứng dụng giao diện người dùng Django cho Dialogflow
  • Cách triển khai ứng dụng giao diện người dùng Django lên Google Cloud trên App Engine
  • Cách kiểm thử ứng dụng Dialogflow từ giao diện người dùng tuỳ chỉnh

Sản phẩm bạn sẽ tạo ra

  • Tạo một nhân viên hỗ trợ Dialogflow
  • Triển khai giao diện người dùng Django để tải tệp lên
  • Triển khai phương thức thực hiện Dialogflow để gọi Vision API dựa trên hình ảnh đã tải lên

Bạn cần có

  • Kiến thức cơ bản về Python
  • Có kiến thức cơ bản về Dialogflow
  • Hiểu biết cơ bản về Vision API

Bạn sẽ tạo một trải nghiệm đàm thoại mới với giao diện người dùng Django tuỳ chỉnh và mở rộng giao diện đó để tích hợp với Vision API. Bạn sẽ tạo giao diện người dùng bằng khung Django, chạy và kiểm thử giao diện đó cục bộ, rồi triển khai giao diện đó lên App Engine. Giao diện người dùng sẽ có dạng như sau:

Luồng yêu cầu sẽ hoạt động như minh hoạ trong hình ảnh sau:

  1. Người dùng sẽ gửi yêu cầu thông qua giao diện người dùng.
  2. Thao tác này sẽ kích hoạt một lệnh gọi đến API detectIntent của Dialogflow để liên kết câu nói của người dùng với ý định phù hợp.
  3. Sau khi phát hiện thấy ý định khám phá địa danh, phương thức thực hiện của Dialogflow sẽ gửi một yêu cầu đến Vision API, nhận phản hồi và gửi phản hồi đó cho người dùng.

Sau đây là cấu trúc tổng thể.

Vision API là một mô hình học máy được huấn luyện trước, có khả năng rút ra thông tin chi tiết từ hình ảnh. Bạn có thể nhận được nhiều thông tin chi tiết, bao gồm cả việc gắn nhãn hình ảnh, phát hiện khuôn mặt và điểm mốc, nhận dạng ký tự quang học và gắn thẻ nội dung phản cảm. Để tìm hiểu thêm, hãy xem bài viết về AI thị giác.

  1. Truy cập vào bảng điều khiển Dialogflow.
  2. Đăng nhập. (Nếu bạn là người dùng lần đầu, hãy sử dụng email để đăng ký.)
  3. Chấp nhận các điều khoản và điều kiện, bạn sẽ được chuyển đến bảng điều khiển.
  4. Nhấp vào biểu tượng , di chuyển xuống dưới cùng rồi nhấp vào Tạo tác nhân mới.

5. Nhập "VisionAPI" làm Tên tác nhân.

  1. Nhấp vào Tạo.

Dialogflow tạo 2 ý định mặc định sau đây trong vai trò là một phần của tác nhân:

  1. Ý định chào mừng mặc định sẽ chào người dùng.
  2. Ý định dự phòng mặc định sẽ nắm bắt tất cả những câu hỏi mà bot của bạn không hiểu.

Đến đây, bạn đã có một bot hoạt động được và chào người dùng, nhưng bạn cần cập nhật bot để cho người dùng biết rằng họ có thể tải hình ảnh lên để khám phá các địa danh.

Cập nhật ý định chào mừng mặc định để thông báo cho người dùng tải hình ảnh lên

  1. Nhấp vào Ý định chào mừng mặc định.
  2. Chuyển đến Responses (Phản hồi) > Default (Mặc định) > Text or SSML Response (Phản hồi bằng văn bản hoặc SSML) rồi nhập "Chào bạn! Bạn có thể tải ảnh lên để khám phá các địa danh."

Tạo thực thể

  1. Nhấp vào Thực thể.

  1. Nhấp vào Tạo thực thể, đặt tên là "filename" rồi nhấp vào Lưu.

Tạo ý định mới

  1. Nhấp vào Ý định > Tạo ý định.
  2. Nhập "Khám phá hình ảnh đã tải lên" làm Tên ý định.
  3. Nhấp vào Cụm từ huấn luyện > Thêm cụm từ huấn luyện rồi nhập "tệp là demo.jpg" và "tệp là taj.jpeg" làm biểu thức của người dùng với @filename làm thực thể.

  1. Nhấp vào Responses (Phản hồi) > Add Response (Thêm phản hồi) > Default (Mặc định) > Text or SSML Response (Phản hồi bằng văn bản hoặc SSML). Nhập "Đánh giá tệp" rồi nhấp vào Thêm phản hồi.
  1. Nhấp vào Thực hiện > Bật tính năng thực hiện rồi bật Bật lệnh gọi webhook cho ý định này.

  1. Nhấp vào Thực hiện đơn hàng.
  2. Bật Trình chỉnh sửa tại chỗ.

  1. Cập nhật index.js bằng mã sau và cập nhật YOUR-BUCKET-NAME bằng tên của bộ chứa 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 [];
    }
}
  1. Dán nội dung sau vào package.json để thay thế nội dung của tệp này.
{
  "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"
  }
}
  1. Nhấp vào Lưu.
  1. Sao chép kho lưu trữ này vào máy cục bộ:
https://github.com/priyankavergadia/visionapi-dialogflow.git
  1. Chuyển đến thư mục chứa mã. Ngoài ra, bạn có thể tải mẫu xuống dưới dạng tệp zip rồi giải nén.
cd visionapi-dialogflow

Khi được triển khai, ứng dụng của bạn sẽ sử dụng Cloud SQL Proxy được tích hợp trong môi trường chuẩn của App Engine để giao tiếp với phiên bản Cloud SQL. Tuy nhiên, để kiểm thử ứng dụng trên máy, bạn phải cài đặt và sử dụng bản sao cục bộ của Cloud SQL Proxy trong môi trường phát triển. Để tìm hiểu thêm, hãy xem bài viết Giới thiệu về Cloud SQL Proxy.

Để thực hiện các tác vụ quản trị cơ bản trên phiên bản Cloud SQL, bạn có thể dùng ứng dụng Cloud SQL cho MySQL.

Cài đặt Cloud SQL Proxy

Tải xuống và cài đặt Cloud SQL Proxy bằng lệnh sau. Cloud SQL Proxy được dùng để kết nối với thực thể Cloud SQL khi chạy cục bộ.

Tải proxy xuống:

curl -o cloud_sql_proxy https://dl.google.com/cloudsql/cloud_sql_proxy.darwin.amd64

Tạo tệp thực thi proxy.

chmod +x cloud_sql_proxy

Tạo một phiên bản Cloud SQL

  1. Tạo một phiên bản Cloud SQL for MySQL thế hệ thứ hai. Nhập "polls-instance" hoặc một tên tương tự. Có thể mất vài phút thì phiên bản mới sẵn sàng. Sau khi sẵn sàng, phiên bản này sẽ xuất hiện trong danh sách phiên bản.
  2. Bây giờ, hãy sử dụng công cụ dòng lệnh gcloud để chạy lệnh sau, trong đó [YOUR_INSTANCE_NAME] là tên của phiên bản Cloud SQL. Ghi lại giá trị xuất hiện cho connectionName để thực hiện bước tiếp theo. Nội dung này hiển thị ở định dạng [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME].
gcloud sql instances describe [YOUR_INSTANCE_NAME]

Ngoài ra, bạn có thể nhấp vào phiên bản trong bảng điều khiển để lấy Tên kết nối phiên bản.

Khởi chạy phiên bản Cloud SQL

Khởi động Cloud SQL Proxy bằng cách sử dụng connectionName ở phần trước.

./cloud_sql_proxy -instances="[YOUR_INSTANCE_CONNECTION_NAME]"=tcp:3306

Thay thế [YOUR_INSTANCE_CONNECTION_NAME] bằng giá trị mà bạn đã ghi lại trong phần trước. Thao tác này sẽ thiết lập một kết nối từ máy tính cục bộ đến phiên bản Cloud SQL của bạn cho mục đích kiểm thử cục bộ. Luôn chạy Cloud SQL Proxy trong suốt thời gian bạn kiểm thử ứng dụng cục bộ.

Tiếp theo, hãy tạo một người dùng và cơ sở dữ liệu Cloud SQL mới.

  1. Tạo một cơ sở dữ liệu mới bằng Google Cloud Console cho phiên bản Cloud SQL có tên là polls-instance. Ví dụ: bạn có thể nhập "cuộc thăm dò" làm tên.
  2. Tạo một người dùng mới bằng Cloud Console cho phiên bản Cloud SQL có tên là polls-instance.

Định cấu hình chế độ cài đặt cơ sở dữ liệu

  1. Mở mysite/settings-changeme.py để chỉnh sửa.
  2. Đổi tên tệp thành setting.py.
  3. Ở hai vị trí, hãy thay thế [YOUR-USERNAME][YOUR-PASSWORD] bằng tên người dùng và mật khẩu cơ sở dữ liệu mà bạn đã tạo trong phần trước. Điều này giúp thiết lập kết nối với cơ sở dữ liệu để triển khai App Engine và kiểm thử cục bộ.
  4. Trong dòng ‘HOST': ‘cloudsql/ [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]', hãy thay thế [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME] bằng tên phiên bản mà bạn đã có được trong phần trước.
  5. Chạy lệnh sau và sao chép giá trị connectionName được xuất ra cho bước tiếp theo.
gcloud sql instances describe [YOUR_INSTANCE_NAME]
  1. Thay thế [YOUR-CONNECTION-NAME] bằng giá trị mà bạn đã ghi lại ở bước trước
  2. Thay thế [YOUR-DATABASE] bằng tên mà bạn đã chọn trong phần trước.
# [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]
  1. Đóng và lưu settings.py.
  1. Trong bảng điều khiển của Dialogflow, hãy nhấp vào . Trong thẻ Chung, hãy chuyển đến Dự án trên Google > Mã dự án rồi nhấp vào Google Cloud để mở Cloud Console.
  2. Nhấp vào Trình đơn điều hướng ☰ > IAM và Quản trị > Tài khoản dịch vụ, sau đó nhấp vào bên cạnh Các dịch vụ tích hợp Dialogflow rồi nhấp vào Tạo khoá.

  1. Một tệp JSON sẽ được tải xuống máy tính của bạn. Bạn sẽ cần tệp này trong các phần thiết lập sau đây.
  1. Trong thư mục trò chuyện, hãy thay thế key-sample.json bằng tệp JSON thông tin đăng nhập của bạn và đặt tên là key.json.
  2. Trong views.py trong thư mục trò chuyện, hãy thay đổi GOOGLE_PROJECT_ID = "<YOUR_PROJECT_ID>" thành mã dự án của bạn.

Tạo một bộ chứa Cloud Storage cho các đối tượng tĩnh ở giao diện người dùng

  1. Trong Cloud Console, hãy nhấp vào biểu tượng Điều hướng Trình đơn điều hướng ☰ > Bộ nhớ.

  1. Nhấp vào Tạo vùng lưu trữ.
  2. Đặt một tên riêng biệt trên toàn cầu.

  1. Chọn nơi lưu trữ dữ liệu của bạn. Chọn Khu vực rồi chọn vị trí phù hợp nhất với nhu cầu của bạn.
  2. Chọn Chuẩn làm lớp lưu trữ mặc định.

  1. Chọn Đặt quyền một cách đồng nhất ở cấp độ nhóm (Chỉ chính sách nhóm), rồi nhấp vào Tiếp tục để tạo nhóm.

  1. Sau khi tạo vùng chứa, hãy nhấp vào Trình đơn điều hướng ☰ > Bộ nhớ > Trình duyệt rồi tìm vùng chứa mà bạn đã tạo.

  1. Nhấp vào biểu tượng bên cạnh nhóm tương ứng rồi nhấp vào Chỉnh sửa quyền đối với nhóm.

  1. Nhấp vào Thêm thành viên,nhấp vào Thành viên mới, nhập "allUsers", rồi nhấp vào Chọn vai trò > Người xem đối tượng lưu trữ. Thao tác này cấp quyền xem các tệp giao diện người dùng tĩnh cho allUsers. Đó không phải là chế độ cài đặt bảo mật lý tưởng cho các tệp, nhưng phù hợp với mục đích của lớp học lập trình cụ thể này.

Tạo một bộ chứa Cloud Storage cho hình ảnh do người dùng tải lên

Làm theo hướng dẫn tương tự để tạo một nhóm riêng biệt nhằm tải hình ảnh người dùng lên. Đặt lại quyền thành "allUsers", nhưng chọn Storage Object Creator (Người tạo đối tượng lưu trữ) và Storage Object Viewer (Người xem đối tượng lưu trữ) làm vai trò.

Định cấu hình bộ chứa Cloud Storage trong settings.py

  1. Mở mysite/setting.py.
  2. Tìm biến GCS_BUCKET rồi thay thế ‘<YOUR-GCS-BUCKET-NAME>' bằng nhóm tĩnh Cloud Storage của bạn.
  3. Xác định vị trí biến GS_MEDIA_BUCKET_NAME rồi thay thế ‘<YOUR-GCS-BUCKET-NAME-MEDIA>' bằng tên vùng lưu trữ trên Cloud Storage cho hình ảnh.
  4. Xác định vị trí biến GS_STATIC_BUCKET_NAME rồi thay thế ‘<YOUR-GCS-BUCKET-NAME-STATIC>' bằng tên nhóm Cloud Storage cho các tệp tĩnh.
  5. Lưu tệp.
GCS_BUCKET = '<YOUR-GCS-BUCKET-NAME>'
GS_MEDIA_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-MEDIA>'
GS_STATIC_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-STATIC>'

Định cấu hình bộ chứa Cloud Storage trong home.html

  • Mở thư mục trò chuyện, sau đó mở templates và đổi tên home-changeme.html thành home.html.
  • Tìm <YOUR-GCS-BUCKET-NAME-MEDIA> rồi thay thế bằng tên nhóm lưu trữ mà bạn muốn lưu tệp do người dùng tải lên. Điều đó ngăn bạn lưu trữ tệp do người dùng tải lên ở giao diện người dùng và giữ các tài sản tĩnh trong bộ chứa Cloud Storage. Vision API gọi bộ chứa Cloud Storage để chọn tệp và đưa ra dự đoán.

Để chạy ứng dụng Django trên máy tính cục bộ, bạn cần thiết lập một môi trường phát triển Python, bao gồm Python, pip và virtualenv. Để biết hướng dẫn, hãy tham khảo bài viết Thiết lập môi trường phát triển Python.

  1. Tạo một môi trường Python riêng biệt và cài đặt các phần phụ thuộc.
virtualenv env
source env/bin/activate
pip install -r requirements.txt
  1. Chạy các lệnh di chuyển Django để thiết lập mô hình.
python3 manage.py makemigrations
python3 manage.py makemigrations polls
python3 manage.py migrate
  1. Khởi động một máy chủ web cục bộ.
python3 manage.py runserver
  1. Trong trình duyệt web, hãy chuyển đến http://localhost:8000/. Bạn sẽ thấy một trang web đơn giản trông như sau:

Các trang ứng dụng mẫu được phân phối bởi máy chủ web Django chạy trên máy tính của bạn. Khi bạn đã sẵn sàng chuyển sang bước tiếp theo, hãy nhấn Control+C (Command+C trên Macintosh) để dừng máy chủ web cục bộ.

Sử dụng bảng điều khiển quản trị Django

  1. Tạo một siêu người dùng.
python3 manage.py createsuperuser
  1. Khởi động một máy chủ web cục bộ.
python3 manage.py runserver
  1. Chuyển đến http://localhost:8000/admin/ trong trình duyệt web. Để đăng nhập vào trang web quản trị, hãy nhập tên người dùng và mật khẩu mà bạn đã tạo khi chạy createsuperuser.

Tập hợp tất cả nội dung tĩnh vào một thư mục bằng cách chạy lệnh sau. Lệnh này sẽ di chuyển tất cả các tệp tĩnh của ứng dụng vào thư mục do STATIC_ROOT chỉ định trong settings.py:

python3 manage.py collectstatic

Tải ứng dụng lên bằng cách chạy lệnh sau trong thư mục của ứng dụng có chứa tệp app.yaml:

gcloud app deploy

Đợi thông báo cho biết quá trình cập nhật đã hoàn tất.

Trong trình duyệt web, hãy truy cập vào https://<your_project_id>.appspot.com

Lần này, yêu cầu của bạn sẽ được một máy chủ web chạy trong môi trường tiêu chuẩn của App Engine xử lý.

Lệnh app deploy triển khai ứng dụng như mô tả trong app.yaml và đặt phiên bản mới triển khai làm phiên bản mặc định, khiến phiên bản này phân phát tất cả lưu lượng truy cập mới.

Khi bạn đã sẵn sàng phân phát nội dung trong bản phát hành chính thức, hãy thay đổi biến DEBUG thành False trong mysite/settings.py.

Bạn có thể kiểm thử chatbot trong trình mô phỏng hoặc sử dụng tính năng tích hợp web hoặc Google Home mà bạn đã tạo trước đó.

  1. Người dùng: "hi"
  2. Chatbot: "Chào bạn! Bạn có thể tải ảnh lên để khám phá các địa danh."
  3. Người dùng tải một hình ảnh lên.

Tải hình ảnh này xuống, đặt tên là demo.jpg rồi sử dụng.

  1. Chatbot: "Tệp đang được xử lý, đây là kết quả: Cầu Cổng Vàng,Khu giải trí quốc gia Cổng Vàng,Cầu Cổng Vàng,Cầu Cổng Vàng,Cầu Cổng Vàng."

Nhìn chung, ứng dụng sẽ có dạng như sau:

Nếu muốn hoàn thành các lớp học lập trình khác về Dialogflow, hãy bỏ qua phần này và quay lại sau.

Xoá nhân viên hỗ trợ Dialogflow

  1. Nhấp vào biểu tượng bên cạnh tác nhân hiện có.

  1. Trong thẻ Chung, hãy di chuyển xuống rồi nhấp vào Xoá nhân viên này.
  2. Nhập Xoá vào cửa sổ xuất hiện rồi nhấp vào Xoá.

Bạn đã tạo một chatbot trong Dialogflow và tích hợp chatbot đó với Vision API. Bạn hiện là nhà phát triển chatbot!

Tìm hiểu thêm

Để tìm hiểu thêm, hãy xem các mã mẫu trên trang Dialogflow Github.