Integracja interfejsu Vision API z Dialogflow

1. Zanim zaczniesz

W tym ćwiczeniu w Codelabs 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 przeanalizować elementy 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ć rachunki, 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.

15a4243e453415ca.png

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ż poznać podstawowe pojęcia i konstrukcje Dialogflow. Możesz to zrobić, oglądając te filmy z ścieżki Tworzenie czatbota 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
  • Jak skonfigurować i uruchomić aplikację frontendową Django dla 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ą znajomość Pythona,
  • Podstawowa znajomość Dialogflow
  • podstawową wiedzę o interfejsie Vision API;

2. Omówienie architektury

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:

5b07e09dc4b84646.png

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 przypisać wypowiedź użytkownika do odpowiedniej intencji.
  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.

153725eb50e008d4.png

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

a2fcea32222a9cb4.png

3. Czym jest interfejs Vision API?

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.

4. Tworzenie agenta Dialogflow

  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 d9e90c93fc779808.png, przewiń w dół i kliknij Utwórz nowego agenta. 3b3f9677e2a26d93.png
  5. W polu Nazwa agenta wpisz „VisionAPI”.
  6. 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ć ich, że mogą przesyłać obrazy, aby odkrywać zabytki.

Aktualizowanie domyślnego zamiaru powitalnego, aby powiadamiać 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”.

f9cd9ba6917a7aa9.png

Utwórz encję

  1. Kliknij Jednostki.

432fff294b666c93.png

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

602d001d684485de.png

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.

dd54ebda59c6b896.png

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

b32b7ac054fcc938.png

5. Konfigurowanie realizacji zamówień na potrzeby integracji z interfejsem Vision API

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

c8574c6ef899393f.png

  1. Zastąp index.js tym kodem i zastąp YOUR-BUCKET-NAME 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.

6. Pobieranie i uruchamianie aplikacji frontendowej

  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ę w formacie ZIP i ją rozpakować.
cd visionapi-dialogflow

7. Konfigurowanie środowiska lokalnego

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, gdzie [YOUR_INSTANCE_NAME] to nazwa instancji Cloud SQL. Zanotuj wartość wyświetlaną w przypadku elementu connectionName, aby użyć jej 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.

c11e94464bf4fcf8.png

Inicjowanie instancji Cloud SQL

Uruchom serwer proxy Cloud SQL, używając 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”. a3707ec9bc38d412.png
  2. Utwórz nowego użytkownika za pomocą konsoli Google Cloud dla instancji Cloud SQL o nazwie polls-instance. f4d098fca49cccff.png

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ą zapisaną 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.

8. Skonfiguruj konto usługi

  1. W konsoli Dialogflow kliknij 21a21c1104f5fdf3.png. Na karcie Ogólne otwórz Projekt Google > Identyfikator projektu i kliknij Google Cloud7b2236f5627c37a0.png, aby otworzyć Cloud Console. a4cfb880b3c8e789.png
  2. Kliknij Menu nawigacyjne ☰ > Uprawnienia i administracja > Konta usługi, a następnie kliknij 796e7c9e65ae751f.png obok opcji Integracje DialogflowUtwórz klucz.

3d72abc0c184d281.png

  1. Na komputer zostanie pobrany plik JSON, który będzie potrzebny w kolejnych sekcjach konfiguracji.

9. Skonfiguruj punkt końcowy detectIntent Dialogflow, aby można go było wywoływać z aplikacji.

  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.

10. Tworzenie zasobników Cloud Storage

Tworzenie zasobnika Cloud Storage na potrzeby statycznych obiektów frontendu

  1. W konsoli Cloud kliknij Menu nawigacyjne  > Przechowywanie.

87ff9469db4eb77f.png

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

a15a6612e92a39d3.png

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

9c56abe632cf61db.png

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

f175ac794049df04.png

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

9500ee19b427158c.png

  1. Kliknij 796e7c9e65ae751f.png obok odpowiedniego zasobnika i wybierz Edytuj uprawnienia do zasobnika.

fd0a310bc3656edd.png

  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.

7519116abd56d5a3.png

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.

11. Konfigurowanie zasobników Cloud Storage w aplikacji frontendowej

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ń jego nazwę z home-changeme.html na home.html.
  • Znajdź znak <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 zachowanie zasobów statycznych w zasobniku Cloud Storage. Interfejs Vision API wywołuje zasobnik Cloud Storage, aby pobrać plik i dokonać prognozy.

12. Kompilowanie i uruchamianie aplikacji lokalnie

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:

8f986b8981f80f7b.png

Strony przykładowej aplikacji 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.

13. Wdrażanie aplikacji w standardowym środowisku App Engine

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.

14. Testowanie aplikacji frontendowej

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.

15. Produkcja

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

16. Testowanie czatbota

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.

c3aff843c9f132e4.jpeg

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

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

228df9993bfc001d.png

17. Czyszczenie danych

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

Usuwanie agenta Dialogflow

  1. Kliknij ca4337eeb5565bcb.png obok istniejącego agenta.

520c1c6bb9f46ea6.png

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

18. Gratulacje

Utworzyliśmy czatbota w Dialogflow i zintegrowaliśmy go z interfejsem Vision API. Jesteś teraz programistą czatbota.

Więcej informacji

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