Integracja interfejsu Vision API z Dialogflow

W tym ćwiczeniu z programowania zintegrujesz interfejs Vision API z Dialogflow, aby dostarczać bogate i dynamiczne odpowiedzi oparte na uczeniu maszynowym na dane wejściowe w postaci obrazów dostarczane przez użytkowników. Utworzysz aplikację chatbota, która przyjmuje obraz jako dane wejściowe, przetwarza go w interfejsie Vision API i zwraca użytkownikowi zidentyfikowany punkt orientacyjny. Jeśli na przykład użytkownik prześle zdjęcie Tadż Mahal, czatbot zwróci odpowiedź „Tadż Mahal”.

Jest to przydatne, ponieważ możesz przeprowadzić analizę elementów na obrazie i podjąć działania na podstawie uzyskanych informacji. Możesz też utworzyć system przetwarzania zwrotów środków, który pomoże użytkownikom przesyłać potwierdzenia zakupu, wyodrębniać z nich datę zakupu i przetwarzać zwroty środków, jeśli data jest odpowiednia.

Zapoznaj się z tym przykładowym dialogiem:

Użytkownik: Cześć

Czatbot: Cześć! Możesz przesłać zdjęcie, aby odkrywać zabytki

Użytkownik: prześlij obraz z Tadż Mahalem.

Chatbot: Plik jest przetwarzany. Oto wyniki: Tadż Mahal, ogród Tadż Mahal, Tadż Mahal.

Wymagania wstępne

Zanim przejdziesz dalej, musisz ukończyć te ćwiczenia:

  1. Tworzenie harmonogramu spotkań za pomocą Dialogflow
  2. Integrowanie czatbota Dialogflow z Actions on Google
  3. Informacje o encjach w Dialogflow
  4. Tworzenie klienta Django frontendu dla aplikacji Dialogflow

Musisz też znać podstawowe pojęcia i konstrukcje Dialogflow. Możesz je poznać, oglądając te filmy z ścieżki Tworzenie chatbota za pomocą Dialogflow:

Czego się nauczysz

  • Jak utworzyć agenta Dialogflow
  • Jak zaktualizować agenta Dialogflow, aby przesyłać pliki
  • Jak skonfigurować połączenie z interfejsem Vision API w ramach realizacji Dialogflow
  • Konfigurowanie i uruchamianie aplikacji frontendowej Django na potrzeby Dialogflow
  • Jak wdrożyć aplikację front-end Django w Google Cloud w App Engine
  • Testowanie aplikacji Dialogflow z niestandardowego interfejsu

Co utworzysz

  • Tworzenie agenta Dialogflow
  • Implementowanie interfejsu Django do przesyłania pliku
  • Wdrożenie realizacji Dialogflow w celu wywołania interfejsu Vision API na przesłanym obrazie

Czego potrzebujesz

  • podstawową wiedzę o Pythonie,
  • Podstawowa znajomość Dialogflow
  • Podstawowa wiedza o interfejsie Vision API

Utworzysz nowy tryb konwersacyjny z niestandardowym interfejsem Django i rozszerzysz go, aby zintegrować go z interfejsem Vision API. Frontend utworzysz za pomocą platformy Django, uruchomisz i przetestujesz go lokalnie, a następnie wdrożysz w App Engine. Interfejs będzie wyglądać tak:

Proces żądania będzie wyglądać tak, jak pokazano na tym obrazie:

  1. Użytkownik wyśle żądanie za pomocą frontendu.
  2. Spowoduje to wywołanie interfejsu Dialogflow detectIntent API, aby zmapować wypowiedź użytkownika na odpowiednią intencję.
  3. Gdy zostanie wykryty zamiar eksplorowania punktu orientacyjnego, realizacja Dialogflow wyśle żądanie do interfejsu Vision API, otrzyma odpowiedź i prześle ją użytkownikowi.

Oto jak będzie wyglądać ogólna architektura.

Vision API to wstępnie wytrenowany model uczenia maszynowego, który wyodrębnia informacje z obrazów. Może dostarczać wielu informacji, w tym oznaczanie obrazów etykietami, rozpoznawanie twarzy i punktów orientacyjnych, optyczne rozpoznawanie znaków oraz tagowanie treści dla dorosłych. Więcej informacji znajdziesz w artykule Vision AI.

  1. Otwórz konsolę Dialogflow.
  2. Zaloguj się. (Jeśli używasz tej usługi po raz pierwszy, zarejestruj się za pomocą adresu e-mail).
  3. Zaakceptuj warunki korzystania z usługi, a następnie przejdź do konsoli.
  4. Kliknij , przewiń w dół i kliknij Utwórz nowego agenta.

5. Wpisz „VisionAPI” jako nazwę agenta.

  1. Kliknij Utwórz.

Dialogflow tworzy w ramach agenta te 2 domyślne intencje:

  1. Domyślna intencja powitalna wita użytkowników.
  2. Domyślny zamiar rezerwowy przechwytuje wszystkie pytania, których bot nie rozumie.

W tym momencie masz już działającego bota, który wita użytkowników, ale musisz go zaktualizować, aby poinformować użytkowników, że mogą przesłać obraz, aby odkrywać zabytki.

Aktualizowanie domyślnego zamiaru powitania, aby powiadomić użytkownika o konieczności przesłania obrazu

  1. Kliknij Default Welcome Intent (Domyślna intencja powitalna).
  2. Kliknij Odpowiedzi > Domyślne > Odpowiedź tekstowa lub SSML i wpisz „Cześć! Możesz przesłać zdjęcie, aby odkrywać zabytki”.

Utwórz encję

  1. Kliknij Jednostki.

  1. Kliknij Utwórz jednostkę, nadaj jej nazwę „filename” i kliknij Zapisz.

Utwórz nowy zamiar

  1. Kliknij Intencje> Utwórz intencję.
  2. W polu Nazwa intencji wpisz „Explore uploaded image”.
  3. Kliknij Wyrażenia na potrzeby trenowania > Dodaj wyrażenia na potrzeby trenowania i wpisz „plik to demo.jpg” oraz „plik to taj.jpeg” jako wyrażenia użytkownika z encją @filename.

  1. Kliknij Odpowiedzi > Dodaj odpowiedź > Domyślna> Odpowiedź tekstowa lub SSML. Wpisz „Sprawdzanie pliku” i kliknij Dodaj odpowiedzi.
  1. Kliknij Realizacja > Włącz realizację i włącz Aktywuj wywołanie webhooka dla tej intencji.

  1. Kliknij Realizacja.
  2. Włącz Edytor wbudowany.

  1. Zastąp index.js tym kodem i zmień YOUR-BUCKET-NAME na nazwę swojego zasobnika 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. Wklej do pliku package.json ten fragment kodu, aby zastąpić jego zawartość.
{
  "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. Kliknij Zapisz .
  1. Sklonuj to repozytorium na komputer lokalny:
https://github.com/priyankavergadia/visionapi-dialogflow.git
  1. Przejdź do katalogu zawierającego kod. Możesz też pobrać próbkę jako plik ZIP i ją rozpakować.
cd visionapi-dialogflow

Po wdrożeniu aplikacja używa serwera proxy Cloud SQL wbudowanego w środowisko standardowe App Engine do komunikacji z instancją Cloud SQL. Aby jednak przetestować aplikację lokalnie, musisz zainstalować i użyć lokalnej kopii serwera proxy Cloud SQL w środowisku programistycznym. Więcej informacji znajdziesz w artykule Informacje o Cloud SQL Proxy.

Aby wykonywać podstawowe zadania administracyjne na instancji Cloud SQL, możesz użyć klienta Cloud SQL for MySQL.

Instalowanie Cloud SQL Proxy

Pobierz i zainstaluj serwer proxy Cloud SQL za pomocą tego polecenia. Serwer proxy Cloud SQL służy do łączenia się z instancją Cloud SQL podczas uruchamiania lokalnego.

Pobierz serwer proxy:

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

Ustaw plik serwera proxy jako wykonywalny.

chmod +x cloud_sql_proxy

Tworzenie instancji Cloud SQL

  1. Utwórz instancję Cloud SQL for MySQL drugiej generacji. Wpisz nazwę, np. "polls-instance". Przygotowanie instancji może potrwać kilka minut. Gdy będzie gotowa, powinna być widoczna na liście instancji.
  2. Teraz użyj narzędzia wiersza poleceń gcloud, aby uruchomić to polecenie. Zastąp symbol [YOUR_INSTANCE_NAME] nazwą instancji Cloud SQL. Zanotuj wartość elementu connectionName, która będzie Ci potrzebna w następnym kroku. Wyświetla się w formacie [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME].
gcloud sql instances describe [YOUR_INSTANCE_NAME]

Możesz też kliknąć instancję w konsoli, aby uzyskać nazwę połączenia instancji.

Inicjowanie instancji Cloud SQL

Uruchom serwer proxy Cloud SQL za pomocą polecenia connectionName z poprzedniej sekcji.

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

Zastąp [YOUR_INSTANCE_CONNECTION_NAME] wartością zapisaną w poprzedniej sekcji. Ustanawia to połączenie z komputera lokalnego z instancją Cloud SQL na potrzeby testów lokalnych. Podczas testowania aplikacji lokalnie serwer proxy Cloud SQL musi być cały czas uruchomiony.

Następnie utwórz nowego użytkownika i bazę danych Cloud SQL.

  1. Utwórz nową bazę danych za pomocą konsoli Google Cloud dla instancji Cloud SQL o nazwie polls-instance. Możesz na przykład wpisać „ankiety”.
  2. Utwórz nowego użytkownika za pomocą konsoli Google Cloud dla instancji Cloud SQL o nazwie polls-instance.

Konfigurowanie ustawień bazy danych

  1. Otwórz plik mysite/settings-changeme.py do edycji.
  2. Zmień nazwę pliku na setting.py.
  3. W 2 miejscach zastąp [YOUR-USERNAME][YOUR-PASSWORD] nazwą użytkownika i hasłem bazy danych utworzonymi w poprzedniej sekcji. Pomaga to skonfigurować połączenie z bazą danych na potrzeby wdrożenia w App Engine i testowania lokalnego.
  4. W wierszu ‘HOST': ‘cloudsql/ [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]' zastąp [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME] nazwą instancji uzyskaną w poprzedniej sekcji.
  5. Uruchom to polecenie i skopiuj wartość connectionName, która pojawi się w wyniku, aby użyć jej w następnym kroku.
gcloud sql instances describe [YOUR_INSTANCE_NAME]
  1. Zastąp [YOUR-CONNECTION-NAME] wartością zarejestrowaną w poprzednim kroku.
  2. Zastąp [YOUR-DATABASE] nazwą wybraną w poprzedniej sekcji.
# [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. Zamknij i zapisz settings.py.
  1. W konsoli Dialogflow kliknij . Na karcie Ogólne otwórz Projekt Google> Identyfikator projektu i kliknij Google Cloud, aby otworzyć Cloud Console.
  2. Kliknij Menu nawigacyjne ☰ > Administracja > Konta usługi, a następnie kliknij  obok Integracje DialogflowUtwórz klucz.

  1. Na komputer zostanie pobrany plik JSON, który będzie potrzebny w kolejnych sekcjach konfiguracji.
  1. W folderze czatu zastąp key-sample.json plikiem JSON z danymi logowania i nadaj mu nazwę key.json.
  2. W pliku views.py w folderze czatu zmień GOOGLE_PROJECT_ID = "<YOUR_PROJECT_ID>" na identyfikator projektu.

Tworzenie zasobnika Cloud Storage na potrzeby statycznych obiektów frontendu

  1. W konsoli Cloud kliknij Menu nawigacyjne > Przechowywanie.

  1. Kliknij Utwórz zasobnik.
  2. Podaj globalnie niepowtarzalną nazwę.

  1. Wybierz, gdzie chcesz przechowywać dane. Kliknij Region i wybierz lokalizację, która najlepiej odpowiada Twoim potrzebom.
  2. Jako domyślną klasę pamięci wybierz Standardowa.

  1. Wybierz Jednolite ustawienie uprawnień na poziomie zasobnika (Tylko zasady zasobnika), a potem kliknij Dalej, aby utworzyć zasobnik.

  1. Po utworzeniu zasobnika kliknij Menu nawigacyjne ☰> Przechowywanie danych> Przeglądarka i znajdź utworzony zasobnik.

  1. Kliknij  obok odpowiedniego zasobnika i wybierz Edytuj uprawnienia do zasobnika.

  1. Kliknij Dodaj członków, a następnie Nowi członkowie. Wpisz „allUsers” i kliknij Wybierz rolę > Wyświetlający obiekty Cloud Storage. Dzięki temu allUsers będą mogli wyświetlać statyczne pliki interfejsu. Nie jest to idealne ustawienie zabezpieczeń plików, ale w tym przypadku wystarczy.

Tworzenie zasobnika Cloud Storage na obrazy przesłane przez użytkowników

Postępuj zgodnie z tymi samymi instrukcjami, aby utworzyć osobny zasobnik do przesyłania zdjęć użytkowników. Ponownie ustaw uprawnienia na „allUsers”, ale jako role wybierz Twórca obiektów Cloud Storage i Wyświetlający obiekty Cloud Storage.

Konfigurowanie zasobnika Cloud Storage w pliku settings.py

  1. Otwórz pokój mysite/setting.py.
  2. Znajdź zmienną GCS_BUCKET i zastąp ‘<YOUR-GCS-BUCKET-NAME>' statycznym zasobnikiem Cloud Storage.
  3. Znajdź zmienną GS_MEDIA_BUCKET_NAME i zastąp ‘<YOUR-GCS-BUCKET-NAME-MEDIA>' nazwą zasobnika Cloud Storage, w którym znajdują się obrazy.
  4. Znajdź zmienną GS_STATIC_BUCKET_NAME i zastąp ‘<YOUR-GCS-BUCKET-NAME-STATIC>' nazwą zasobnika Cloud Storage dla plików statycznych.
  5. Zapisz plik.
GCS_BUCKET = '<YOUR-GCS-BUCKET-NAME>'
GS_MEDIA_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-MEDIA>'
GS_STATIC_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-STATIC>'

Konfigurowanie zasobnika Cloud Storage w pliku home.html

  • Otwórz folder czatu, a potem otwórz plik templates i zmień nazwę pliku home-changeme.html na home.html.
  • Znajdź symbol <YOUR-GCS-BUCKET-NAME-MEDIA> i zastąp go nazwą zasobnika, w którym chcesz zapisać plik przesłany przez użytkownika. Uniemożliwia to przechowywanie przesłanego przez użytkownika pliku w interfejsie i zachowywanie zasobów statycznych w zasobniku Cloud Storage. Interfejs Vision API wywołuje zasobnik Cloud Storage, aby pobrać plik i dokonać prognozy.

Aby uruchomić aplikację Django na komputerze lokalnym, musisz skonfigurować środowisko programistyczne Pythona, w tym Python, pip i virtualenv. Instrukcje znajdziesz w artykule Konfigurowanie środowiska programistycznego w Pythonie.

  1. Utwórz izolowane środowisko Pythona i zainstaluj zależności.
virtualenv env
source env/bin/activate
pip install -r requirements.txt
  1. Uruchom migracje Django, aby skonfigurować modele.
python3 manage.py makemigrations
python3 manage.py makemigrations polls
python3 manage.py migrate
  1. Uruchom lokalny serwer WWW.
python3 manage.py runserver
  1. W przeglądarce otwórz adres http://localhost:8000/. Powinna pojawić się prosta strona internetowa podobna do tej:

Strony aplikacji przykładowej są dostarczane przez serwer WWW Django działający na Twoim komputerze. Gdy wszystko będzie gotowe, naciśnij Control+C (Command+C na komputerze Macintosh), aby zatrzymać lokalny serwer WWW.

Korzystanie z konsoli administracyjnej Django

  1. Utwórz superużytkownika.
python3 manage.py createsuperuser
  1. Uruchom lokalny serwer WWW.
python3 manage.py runserver
  1. W przeglądarce otwórz adres http://localhost:8000/admin/. Aby zalogować się w witrynie administracyjnej, wpisz nazwę użytkownika i hasło utworzone podczas uruchamiania polecenia createsuperuser.

Zbierz całą zawartość statyczną w jednym folderze, uruchamiając to polecenie, które przenosi wszystkie statyczne pliki aplikacji do folderu określonego przez STATIC_ROOTsettings.py:

python3 manage.py collectstatic

Prześlij aplikację, uruchamiając to polecenie w katalogu aplikacji, w którym znajduje się plik app.yaml:

gcloud app deploy

Poczekaj na komunikat z informacją o zakończeniu aktualizacji.

W przeglądarce otwórz stronę https://<your_project_id>.appspot.com

Tym razem Twoje żądanie jest obsługiwane przez serwer WWW działający w standardowym środowisku App Engine.

Polecenie app deploy wdraża aplikację zgodnie z opisem w app.yaml i ustawia nowo wdrożoną wersję jako domyślną, co powoduje, że obsługuje ona cały nowy ruch.

Gdy wszystko będzie gotowe do wyświetlania treści w środowisku produkcyjnym, zmień zmienną DEBUG na False w pliku mysite/settings.py.

Możesz przetestować chatbota w symulatorze lub użyć utworzonej wcześniej integracji z internetem lub Google Home.

  1. Użytkownik: „hi”
  2. Czatbot: „Cześć! Możesz przesłać zdjęcie, aby odkrywać zabytki”.
  3. Użytkownik przesyła obraz.

Pobierz ten obraz, nadaj mu nazwę demo.jpg i użyj go.

  1. Chatbot: „Przetwarzamy plik. Oto wyniki: Golden Gate Bridge, Golden Gate National Recreation Area, Golden Gate Bridge, Golden Gate Bridge, Golden Gate Bridge”.

Powinien on wyglądać mniej więcej tak:

Jeśli chcesz wykonać inne ćwiczenia z Dialogflow, pomiń tę sekcję i wróć do niej później.

Usuwanie agenta Dialogflow

  1. Kliknij  obok istniejącego agenta.

  1. Na karcie Ogólne przewiń w dół i kliknij Usuń tego agenta.
  2. W wyświetlonym oknie wpisz Usuń i kliknij Usuń.

Utworzyliśmy czatbota w Dialogflow i zintegrowaliśmy go z interfejsem Vision API. Jesteś teraz deweloperem chatbotów.

Więcej informacji

Więcej informacji znajdziesz w przykładowych kodach na stronie Dialogflow na GitHubie.