שילוב ה-Vision API עם Dialogflow

במעבדה הזו, תשלבו את ה-API של Vision עם Dialogflow כדי לספק תשובות דינמיות עשירות ומבוססות על למידה חישובית. עליך ליצור אפליקציית צ'אט בוט שמצלם תמונה כקלט, מעבד אותה ב-Vision API ומחזיר למשתמש ציון דרך מזוהה. לדוגמה, אם המשתמש מעלה תמונה של טאג' מהאל, הצ'אט יחזור כטאג' מהאל כתגובה.

זה שימושי כי אפשר לנתח את הפריטים שמופיעים בתמונה ולבצע פעולות על המידע שנאסף. אפשר גם ליצור מערכת לעיבוד החזרים כספיים כדי לעזור למשתמשים להעלות קבלות, לחלץ את תאריך הרכישה בקבלה ולעבד את ההחזר הכספי אם התאריך הזה מתאים.

בתיבת הדו-שיח לדוגמה:

משתמש: היי

Chatbot: היי! אפשר להעלות תמונה כדי לגלות את ציוני הדרך

משתמש: העלאת תמונה שמופיעה בה טאג' מהאל.

צ'אט בוט: אנחנו מעבדים את הקובץ, אלו התוצאות: טאג' מהאל, גן טאג' מהאל, טאג' מהאל.

דרישות מוקדמות

לפני שממשיכים, צריך להשלים את ה-Labs הבאות:

  1. בניית מתזמן פגישות באמצעות Dialogflow
  2. שילוב של צ'אט בוט של Dialogflow עם פעולות ב-Google
  3. הסבר על ישויות ב-Dialogflow
  4. בניית לקוח Djago קדמי עבור אפליקציה של Dialogflow

חשוב גם להבין את הקונספטים ואת המבנים הבסיסיים של Dialogflow. אפשר להיעזר בסרטונים הבאים במסלול בניית צ'אט בוט עם Dialogflow:

מה תלמדו

  • איך יוצרים סוכן ב-Dialogflow
  • איך מעדכנים קובץ של Dialogflow כדי להעלות קבצים?
  • איך להגדיר את החיבור של Vision API עם מילוי הזמנות ב-Dialogflow
  • איך להגדיר ולהפעיל אפליקציה קדמית של Django עבור Dialogflow
  • איך לפרוס את אפליקציית Django Frontend ב-Google Cloud ב-App Engine
  • איך בודקים את אפליקציית Dialogflow בממשק קצה מותאם אישית?

מה תפתחו

  • יצירת סוכן של Dialogflow
  • יישום ממשק קצה של Django כדי להעלות קובץ
  • הטמעת אספקת הנתונים ב-Dialogflow כדי להפעיל את Vision API בתמונה שהועלתה

מה תצטרך להכין

  • ידע בסיסי ב-Python
  • הבנה בסיסית של Dialogflow
  • הבנה בסיסית של ה-Vision API

ניתן ליצור חוויית שיחה חדשה עם ממשק קצה של Django בהתאמה אישית ולהרחיב אותה לשילוב עם ה-Vision API. תוכלו לבנות את הקצה הקדמי של מסגרת Django, להריץ ולבדוק אותו באופן מקומי, ולאחר מכן לפרוס אותו ב-App Engine. ממשק הקצה ייראה כך:

תהליך הבקשה יפעל באופן הבא:

  1. המשתמש ישלח בקשה באמצעות ממשק הקצה.
  2. פעולה זו תפעיל קריאה ל-Dialogflow APIsIntent כדי למפות את הדיבור של המשתמש לכוונה הנכונה
  3. לאחר זיהוי כוונת הרכישה בדף הגילוי הנאות, באמצעות Dialogflow היא תשלח בקשה ל-Vision API, תקבל תגובה ותשלח אותה למשתמש.

כך תיראה הארכיטקטורה הכוללת.

ה-Vision API הוא מודל למידה חישובית מלמדת שמבוססת על תובנות מתמונות. הוא יכול לקבל מספר תובנות, כולל תיוג תמונות, זיהוי פנים וציוני דרך, זיהוי תווים אופטי ותיוג של תוכן בוטה. מידע נוסף זמין במאמר Vision AI.

  1. נכנסים למסוף Dialogflow.
  2. נכנסים לחשבון. (אם אתה משתמש חדש, השתמש בכתובת האימייל שלך כדי להירשם).
  3. מאשרים את התנאים וההגבלות, ואתם נמצאים במסוף.
  4. לוחצים על , גוללים למטה ולוחצים על יצירת סוכן חדש.

5. מזינים "VisionAPI" בתור שם הנציג.

  1. לוחצים על Create.

Dialogflow יוצר את שתי כוונות ברירת המחדל הבאות כחלק מהסוכן:

  1. ברירת המחדל של ברכת הפתיחה היא המשתמשים שלך.
  2. ברירת המחדל של פונקציית הגיבוי עונים על כל השאלות שהבוט לא מבין.

בשלב זה יש לכם בוט פונקציונלי שמקבל את פני המשתמשים, אבל עליכם לעדכן אותו כדי להודיע למשתמשים שהם יכולים להעלות תמונה כדי לחקור ציוני דרך.

עדכון ברירת המחדל של הודעת הפתיחה כדי להודיע למשתמש על העלאת תמונה

  1. לוחצים על ברירת מחדל של כוונת רכישה.
  2. עוברים אל Response > Default > Text or SSML Response ומזינים "שלום! אפשר להעלות תמונה כדי לחקור את ציוני הדרך

יצירת ישות

  1. לוחצים על ישויות.

  1. לוחצים על יצירת ישות, נותנים שם ל-"שם קובץ," ולוחצים על שמירה.

יצירת כוונה חדשה

  1. לוחצים על Intents> Create Intent.
  2. כותבים "ניתוח של תמונה שהועלתה&&; כשם ה-Intent.
  3. לוחצים על ביטויי אימון > מוסיפים ביטויי אימון ומזינים "הקובץ הוא demo.jpg " ו-"קובץ הוא taj.jpeg " כביטויים של משתמש עם @filename כישות.

  1. לוחצים על תגובות > הוספת תגובה > ברירת מחדל > טקסט או תגובת SSML. מזינים "הערכת קובץ" ולוחצים על הוספת תגובות.
  1. לוחצים על אספקת הזמנות > הפעלת מילוי הזמנות ומפעילים את האפשרות הפעלה של שיחת webhook למטרה הזו.

  1. לוחצים על מימוש.
  2. מפעילים את Inline Editor.

  1. מעדכנים את 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 [];
    }
}
  1. צריך להדביק את הטקסט הבא בשדה 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"
  }
}
  1. לוחצים על שמירה.
  1. שכפול המאגר הזה למכשיר המקומי:
https://github.com/priyankavergadia/visionapi-dialogflow.git
  1. צריך לעבור לספרייה שמכילה את הקוד. לחלופין, אפשר להוריד את הדגימה כקובץ ZIP ולחלץ אותה.
cd visionapi-dialogflow

לאחר הפריסה, האפליקציה משתמשת בשרת ה-proxy של Cloud SQL המובנה בסביבה הרגילה של App Engine כדי לתקשר עם המופע של Cloud SQL. עם זאת, כדי לבדוק את האפליקציה באופן מקומי, עליך להתקין עותק מקומי של שרת ה-proxy של Cloud SQL ולהשתמש בו בסביבת הפיתוח שלך. מידע נוסף זמין במאמר מידע על שרת ה-proxy של Cloud SQL.

כדי לבצע משימות בסיסיות של מנהל מערכת במופע של Cloud SQL, אפשר להשתמש ב-Cloud SQL ל-MySQL.

התקנה של שרת proxy ל-Cloud SQL

מורידים ומתקינים את שרת ה-proxy של Cloud SQL באמצעות הפקודה הבאה. שרת ה-proxy של Cloud SQL משמש לחיבור למופע של Cloud SQL בזמן הפעלה מקומית.

מורידים את שרת ה-proxy:

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

יש להפעיל את שרת ה-proxy.

chmod +x cloud_sql_proxy

יצירת מופע של Cloud SQL

  1. יצירת מכונה ב-Cloud SQL עבור דור שני של MySQL. מזינים " סקרים-סקרים או משהו בסגנון של השם. יכול להיות שיחלפו כמה דקות עד שהמכונה תהיה מוכנה. כשהערך יהיה מוכן, הוא אמור להופיע ברשימת המופעים.
  2. עכשיו צריך להשתמש בכלי שורת הפקודה gcloud כדי להריץ את הפקודה הבאה שבה [YOUR_INSTANCE_NAME] מייצג את השם של מופע Cloud SQL שלך. יש לשים לב לערך שמוצג עבור connectionName בשלב הבא. הוא מוצג בפורמט [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME].
gcloud sql instances describe [YOUR_INSTANCE_NAME]

לחלופין, אפשר ללחוץ על המכונה במסוף כדי לראות את שם החיבור של המכונה.

אתחול המופע של Cloud SQL

מתחילים את שרת ה-proxy של Cloud SQL באמצעות connectionName בקטע הקודם.

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

מחליפים את [YOUR_INSTANCE_CONNECTION_NAME] בערך שתועד בקטע הקודם. כך נוצר חיבור מהמחשב המקומי למופע של Cloud SQL לצורך בדיקה מקומית. שרת ה-Proxy של Cloud SQL ימשיך לפעול כל הזמן כדי לבדוק את האפליקציה באופן מקומי.

בשלב הבא, יוצרים משתמש ומסד נתונים חדשים ב-Cloud SQL.

  1. יוצרים מסד נתונים חדש באמצעות Google Cloud Console עבור המופע של Cloud SQL בשם polls-intance. לדוגמה, אפשר להזין "polls" בתור השם.
  2. יוצרים משתמש חדש באמצעות Cloud Console למופע של Cloud SQL בשם polls-intance.

קביעת הגדרות מסד נתונים

  1. יש לפתוח את mysite/settings-changeme.py לעריכה.
  2. משנים את שם הקובץ לשם setting.py.
  3. בשני מקומות צריך להחליף את [YOUR-USERNAME] ואת [YOUR-PASSWORD] בשם המשתמש ובסיסמה של מסד הנתונים שיצרת בקטע הקודם. הפעולה הזו עוזרת בהגדרת החיבור למסד הנתונים עבור פריסת App Engine ובדיקות מקומיות.
  4. בשורה ‘HOST': ‘cloudsql/ [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME]' החליפו את [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME] בשם המכונה שקיבלתם בקטע הקודם.
  5. מריצים את הפקודה הבאה ומעתיקים את הערך connectionName שנוצר בתהליך הבא.
gcloud sql instances describe [YOUR_INSTANCE_NAME]
  1. מחליפים את [YOUR-CONNECTION-NAME] בערך שתועד בשלב הקודם
  2. מחליפים את [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]
  1. סגירה ושמירה של settings.py.
  1. במסוף של Dialogflow, לוחצים על . בכרטיסייה General , מנווטים אל Google Project > Project ID ולוחצים על Google Cloud כדי לפתוח את Cloud Console.
  2. לוחצים על Navigation menu ☰ > IAM & Admin > Service accounts, ואז על ליד שילובי Dialogflow ואז לוחצים על יצירת מפתח.

  1. קובץ JSON ירד למחשב שלך, ותהיה לך צורך בו בקטעי ההגדרה הבאים.
  1. בתיקיית הצ'אט, יש להחליף את key-sample.json בקובץ ה-JSON עם פרטי הכניסה, ולתת לו את השם key.json.
  2. בתיקייה views.py בתיקיית הצ'אט, משנים את GOOGLE_PROJECT_ID = "<YOUR_PROJECT_ID>" למזהה הפרויקט.

יצירת קטגוריה של Cloud Storage עבור אובייקטים סטטיים של ממשק קצה

  1. ב-Cloud Console, לוחצים על Navigation menu ☰ > Storage.

  1. לוחצים על יצירת קטגוריה.
  2. נותנים שם ייחודי לכל העולם.

  1. בוחרים איפה לאחסן את הנתונים. בוחרים באפשרות אזור ובוחרים את המיקום שהכי מתאים לצרכים שלכם.
  2. בוחרים באפשרות רגילה בתור סיווג האחסון המוגדר כברירת מחדל.

  1. בוחרים באפשרות הגדרת הרשאות אחידות ברמת הקטגוריה (מדיניות באקט בלבד), ולאחר מכן לוחצים על המשך כדי ליצור את הקטגוריה.

  1. אחרי יצירת הקטגוריה, לוחצים על תפריט הניווט ☰ > אחסון > דפדפן ומאתרים את הקטגוריה שיצרתם.

  1. לוחצים על לצד הקטגוריה המתאימה ואז לוחצים על עריכת ההרשאות של הקטגוריה.

  1. לוחצים על הוספת חברים, לוחצים על חברים חדשים, מזינים "allUsers&" ואז לוחצים על בחירת תפקיד > מציג אובייקט אחסון. כך תהיה לכל המשתמשים הרשאת גישה לקובצי הקצה הסטטיים. זו לא הגדרת אבטחה אידיאלית לקבצים, אבל היא פועלת למטרה של שיעור Lab מסוים.

יצירת קטגוריה של Cloud Storage עבור תמונות שמשתמשים העלו

כדי להעלות קטגוריה של משתמשים, יש לבצע את אותן ההוראות כדי ליצור קטגוריה נפרדת. מגדירים שוב את ההרשאות כ-"allUsers" , אבל בוחרים באפשרות אחסון אובייקט אחסון וב-Storage Object Viewer בתור התפקידים.

הגדרת הקטגוריה של Cloud Storage ב-settings.py

  1. פתיחת mysite/setting.py
  2. מחפשים את המשתנה GCS_BUCKET ומחליפים את ‘<YOUR-GCS-BUCKET-NAME>' בקטגוריה הסטטית של Cloud Storage.
  3. מחפשים את המשתנה GS_MEDIA_BUCKET_NAME ומחליפים את ‘<YOUR-GCS-BUCKET-NAME-MEDIA>' בשם הקטגוריה של Cloud Storage עבור התמונות.
  4. מחפשים את המשתנה GS_STATIC_BUCKET_NAME ומחליפים את ‘<YOUR-GCS-BUCKET-NAME-STATIC>' בשם הקטגוריה של Cloud Storage בקבצים הסטטיים.
  5. שומרים את הקובץ.
GCS_BUCKET = '<YOUR-GCS-BUCKET-NAME>'
GS_MEDIA_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-MEDIA>'
GS_STATIC_BUCKET_NAME = '<YOUR-GCS-BUCKET-NAME-STATIC>'

הגדרת הקטגוריה של Cloud Storage ב-home.html

  • פותחים את תיקיית הצ'אט, ופותחים את templates ומשנים את השם של home-changeme.html ל-home.html.
  • מחפשים את הקובץ <YOUR-GCS-BUCKET-NAME-MEDIA> ומחליפים אותו בשם הקטגוריה שבו רוצים לשמור את הקובץ שהועלה על ידי המשתמש. כך לא ניתן לאחסן את הקובץ שהעלה המשתמש בממשק הקצה ולשמור את הנכסים הסטטיים בקטגוריה של Cloud Storage. ה-Vision API מפעיל את הקטגוריה של Cloud Storage כדי לאסוף את הקובץ ולבצע את החיזוי.

כדי להריץ את אפליקציית Django במחשב המקומי, צריך להגדיר סביבת פיתוח של Python, כולל Python, pip ו-Virtualenv. הוראות להגדרת סביבת פיתוח של Python.

  1. יצירת סביבת Python מבודדת והתקנת תלויות.
virtualenv env
source env/bin/activate
pip install -r requirements.txt
  1. יש להריץ את ההעברות של Django כדי להגדיר את המודלים שלך.
python3 manage.py makemigrations
python3 manage.py makemigrations polls
python3 manage.py migrate
  1. מפעילים שרת אינטרנט מקומי.
python3 manage.py runserver
  1. בדפדפן האינטרנט, מנווטים אל http://localhost:8000/. אתם אמורים לראות דף אינטרנט פשוט שנראה כך:

דפי האפליקציה לדוגמה מסופקים על ידי שרת האינטרנט Django שפועל במחשב שלך. כשתהיו מוכנים להתקדם, לחצו על Control+C (Command+C ב-Macintosh) כדי להפסיק את שרת האינטרנט המקומי.

שימוש במסוף Admin של Django

  1. יוצרים משתמש-על.
python3 manage.py createsuperuser
  1. מפעילים שרת אינטרנט מקומי.
python3 manage.py runserver
  1. עוברים אל http://localhost:8000/admin/ בדפדפן האינטרנט. כדי להתחבר לאתר האדמין, יש להזין את שם המשתמש והסיסמה שיצרת בזמן הפעלת createsuperuser.

כדי לאסוף את כל התוכן הסטטי לתיקייה אחת, מריצים את הפקודה הבאה, שמעבירים את כל הקבצים הסטטיים של האפליקציה לתיקייה שצוינה ב-STATIC_ROOT ב-settings.py:

python3 manage.py collectstatic

כדי להעלות את האפליקציה, יש להריץ את הפקודה הבאה מספריית האפליקציה שבה נמצא הקובץ app.yaml:

gcloud app deploy

ממתינים להודעה על כך שהעדכון הושלם.

בדפדפן האינטרנט, עוברים אל https://<your_project_id>.appspot.com

הפעם, הבקשה שלך מוגשת על ידי שרת אינטרנט שפועל בסביבה הרגילה של App Engine.

הפקודה app deploy פורסת את האפליקציה כפי שמתואר ב-app.yaml ומגדירה את הגרסה החדשה שנפרסה כגרסת ברירת המחדל. היא גורמת להצגת כל התנועה החדשה.

כשתהיו מוכנים להציג את התוכן שלכם בסביבת ייצור, עליכם לשנות את המשתנה DEBUG ל-False ב-mysite/settings.py.

אפשר לבדוק את הצ'אט בוט בסימולטור, או להשתמש בשילוב של אינטרנט או Google Home שיצרתם בעבר.

  1. User: "hi"
  2. Chatbot: "שלום! אפשר להעלות תמונה כדי לחקור את ציוני הדרך
  3. המשתמש מעלה תמונה.

אפשר להוריד את התמונה, לתת לה שם demo.jpg ולהשתמש בה.

  1. צ'אט בוט: "הקובץ נמצא בתהליך עיבוד. הנה התוצאות: גשר שער הזהב, אזור הפנאי הלאומי של שער הזהב, גשר שער הזהב, גשר שער הזהב, גשר שער הזהב.

באופן כללי, הוא אמור להיראות כך:

אם תרצו להשלים משימות אחרות של Dialogflow, דלגו על הקטע הזה וחזרו אליו מאוחר יותר.

מחיקת הנציג של Dialogflow

  1. לוחצים על ליד הנציג הקיים.

  1. בכרטיסייה כללי, גוללים למטה ולוחצים על מחיקת הנציג.
  2. מקלידים Delete בחלון שמופיע ולוחצים על Delete (מחיקה).

יצרתם צ'אט בוט ב-Dialogflow והטמעתם אותו ב-Vision API. מעכשיו יש לך צ'אט בוט!

מידע נוסף

מידע נוסף זמין ב-Dialogflow GitHub בדוגמאות של הקוד.