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

דרישות מוקדמות
לפני שממשיכים, צריך להשלים את ה-codelabs הבאים:
- יצירת כלי לתזמון פגישות באמצעות Dialogflow
- שילוב של צ'אטבוט של Dialogflow עם Actions on Google
- הסבר על ישויות ב-Dialogflow
- איך יוצרים לקוח Django בחלק הקצה הקדמי של אפליקציית Dialogflow
כדאי גם להבין את המושגים והמבנים הבסיסיים של Dialogflow. אפשר ללמוד עליהם מהסרטונים הבאים במסלול למידה יצירת צ'אט בוט באמצעות Dialogflow:
מה תלמדו
- איך יוצרים נציג ב-Dialogflow
- איך מעדכנים סוכן Dialogflow כדי להעלות קבצים
- איך מגדירים את החיבור ל-Vision API באמצעות Dialogflow fulfillment
- איך מגדירים ומריצים אפליקציית Django frontend ל-Dialogflow
- איך פורסים את אפליקציית הקצה הקדמי של Django ב-Google Cloud ב-App Engine
- איך בודקים את אפליקציית Dialogflow מחזית אתרים בהתאמה אישית
מה תפַתחו
- יצירת נציג ב-Dialogflow
- הטמעה של ממשק קצה ב-Django להעלאת קובץ
- הטמעה של Dialogflow fulfillment כדי להפעיל את Vision API על התמונה שהועלתה
הדרישות
- ידע בסיסי ב-Python
- הבנה בסיסית של Dialogflow
- הבנה בסיסית של Vision API
2. סקירה כללית של הארכיטקטורה
תצרו ממשק צ'אט חדש עם קצה קדמי מותאם אישית של Django, ותוסיפו לו שילוב עם Vision API. תבנו את הקצה הקדמי באמצעות מסגרת Django, תריצו ותבדקו אותה באופן מקומי, ואז תפרסו אותה ב-App Engine. הקצה הקדמי ייראה כך:

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

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

3. מה זה Vision API?
Vision API הוא מודל ML שעבר אימון מראש ומפיק תובנות מתמונות. הוא יכול לספק לכם תובנות רבות, כולל הוספת תוויות לתמונות, זיהוי של פנים וציוני דרך, זיהוי תווים אופטי (OCR) ותיוג של תוכן בוטה. מידע נוסף זמין במאמר בנושא Vision AI.
4. יצירת נציג ב-Dialogflow
- עוברים אל מסוף Dialogflow.
- מתחברים לחשבון. (אם אתם משתמשים בפלטפורמה בפעם הראשונה, עליכם להירשם באמצעות כתובת האימייל שלכם).
- מאשרים את התנאים וההגבלות, ואז נכנסים למסוף.
- לוחצים על
, גוללים לחלק התחתון ולוחצים על יצירת סוכן חדש. 
- מזינים VisionAPI בתור שם הסוכן.
- לוחצים על יצירה.
מערכת Dialogflow יוצרת את שתי כוונות ברירת המחדל הבאות כחלק מהסוכן:
- כוונת הפתיחה שמוגדרת כברירת מחדל מברכת את המשתמשים.
- כוונת ברירת המחדל לגיבוי מזהה את כל השאלות שהבוט לא מבין.
בשלב הזה יש לכם בוט פונקציונלי שמברך את המשתמשים, אבל אתם צריכים לעדכן אותו כדי שהמשתמשים יוכלו להעלות תמונה ולחפש ציוני דרך.
עדכון כוונת ברירת המחדל של הודעת הפתיחה כדי להודיע למשתמש להעלות תמונה
- לוחצים על Default Welcome Intent (כוונת הפתיחה שמוגדרת כברירת מחדל).
- עוברים אל תגובות > ברירת מחדל > תגובה בטקסט או ב-SSML ומזינים את הטקסט 'שלום! אפשר להעלות תמונה כדי לחקור ציוני דרך".

יצירת ישות
- לוחצים על ישויות.

- לוחצים על Create Entity (יצירת ישות), נותנים לה את השם filename (שם הקובץ) ולוחצים על Save (שמירה).

יצירת כוונת משתמש חדשה
- לוחצים על Intents (כוונות) > Create Intent (יצירת כוונה).
- מזינים Explore uploaded image (חיפוש תמונה שהועלתה) כשם הכוונה.
- לוחצים על משפטי אימון > הוספת משפטי אימון ומזינים את הביטויים "הקובץ הוא
demo.jpg" ו "הקובץ הואtaj.jpeg" כביטויי משתמש עם @filename כיישות.

- לוחצים על תגובות > הוספת תגובה > ברירת מחדל > תגובה בטקסט או ב-SSML. מזינים את הטקסט 'Assessing file' (בדיקת הקובץ) ולוחצים על הוספת תגובות.
- לוחצים על Fulfillment (השלמת בקשה) > Enable fulfillment (הפעלת השלמת בקשה) ומפעילים את האפשרות Enable webhook call for this intent (הפעלת קריאה ל-webhook עבור הכוונה הזו).

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

- מעדכנים את
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"
}
}
- לוחצים על שמירה.
6. הורדה והפעלה של אפליקציית ה-Frontend
- משכפלים את המאגר הזה למחשב המקומי:
https://github.com/priyankavergadia/visionapi-dialogflow.git
- עוברים לספרייה שמכילה את הקוד. אפשרות נוספת היא להוריד את הדוגמה כקובץ ZIP ולחלץ אותה.
cd visionapi-dialogflow
7. הגדרת הסביבה המקומית
כשפורסים את האפליקציה, היא משתמשת ב-Cloud SQL Proxy שמוטמע בסביבה הרגילה של App Engine כדי לתקשר עם מופע Cloud SQL. עם זאת, כדי לבדוק את האפליקציה באופן מקומי, צריך להתקין ולהשתמש בעותק מקומי של Cloud SQL Proxy בסביבת הפיתוח. מידע נוסף זמין במאמר מידע כללי על Cloud SQL Proxy.
כדי לבצע משימות אדמין בסיסיות במופע Cloud SQL, אפשר להשתמש בלקוח Cloud SQL ל-MySQL.
התקנת Cloud SQL Proxy
מורידים ומתקינים את Cloud SQL Proxy באמצעות הפקודה הבאה. משתמשים ב-Cloud SQL Proxy כדי להתחבר למכונה של 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
- יוצרים מכונה של Cloud SQL ל-MySQL מהדור השני. מזינים שם כמו polls-instance או משהו דומה. יכול להיות שיחלפו כמה דקות עד שהמכונה תהיה מוכנה. אחרי שהיא תהיה מוכנה, היא תופיע ברשימת המופעים.
- עכשיו משתמשים בכלי שורת הפקודה של Google Cloud כדי להריץ את הפקודה הבאה, כאשר
[YOUR_INSTANCE_NAME]מייצג את השם של מכונת Cloud SQL. רושמים את הערך שמוצג בשדהconnectionNameכדי להשתמש בו בשלב הבא. הוא מוצג בפורמט[PROJECT_NAME]:[REGION_NAME]:[INSTANCE_NAME].
gcloud sql instances describe [YOUR_INSTANCE_NAME]
לחלופין, אפשר ללחוץ על המכונה במסוף כדי לקבל את שם החיבור של המכונה.

הפעלת המכונה של Cloud SQL
מפעילים את Cloud SQL Proxy באמצעות הפקודה connectionName מהקטע הקודם.
./cloud_sql_proxy -instances="[YOUR_INSTANCE_CONNECTION_NAME]"=tcp:3306
מחליפים את [YOUR_INSTANCE_CONNECTION_NAME] בערך שרשמתם בקטע הקודם. כך נוצר חיבור מהמחשב המקומי למכונת Cloud SQL לצורך בדיקות מקומיות. חשוב להשאיר את Cloud SQL Proxy פועל כל הזמן שבודקים את האפליקציה באופן מקומי.
לאחר מכן, יוצרים משתמש ומסד נתונים חדשים ב-Cloud SQL.
- יוצרים מסד נתונים חדש באמצעות Google Cloud Console עבור מופע Cloud SQL בשם polls-instance. לדוגמה, אפשר להזין את השם 'סקרים'.

- יוצרים משתמש חדש באמצעות Cloud Console עבור מופע Cloud SQL בשם polls-instance.

הגדרת ההגדרות של מסד הנתונים
- פותחים את
mysite/settings-changeme.pyלעריכה. - משנים את שם הקובץ ל-
setting.py. - בשני מקומות, מחליפים את
[YOUR-USERNAME]ואת[YOUR-PASSWORD]בשם המשתמש והסיסמה במסד הנתונים שיצרתם בקטע הקודם. הוא עוזר להגדיר את החיבור למסד הנתונים לפריסה של App Engine ולבדיקה מקומית. - בשורה
‘HOST': ‘cloudsql/ [PROJECT_NAME]:[REGION_NAME]:[INSTANCE_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.
8. הגדרה של חשבון שירות
- במסוף של Dialogflow, לוחצים על
. בכרטיסייה General (כללי), עוברים אל Google Project (פרויקט Google) > Project ID (מזהה הפרויקט) ולוחצים על Google Cloud
כדי לפתוח את Cloud Console. 
- לוחצים על תפריט הניווט ☰ > IAM & Admin > Service accounts (חשבונות שירות), ואז לוחצים על
לצד Dialogflow integrations (שילובים של Dialogflow) ועל Create key (יצירת מפתח).

- קובץ JSON יורד למחשב. תצטרכו אותו בשלבי ההגדרה הבאים.
9. הגדרת נקודת הקצה (endpoint) של Dialogflow detectIntent להפעלה מהאפליקציה
- בתיקיית הצ'אט, מחליפים את
key-sample.jsonבקובץ ה-JSON של פרטי הכניסה ונותנים לו את השםkey.json. - ב-
views.pyבתיקיית הצ'אט, משנים אתGOOGLE_PROJECT_ID = "<YOUR_PROJECT_ID>"למזהה הפרויקט.
10. יצירת קטגוריות ב-Cloud Storage
יצירת קטגוריה של Cloud Storage לאובייקטים סטטיים של חזית האתר
- ב-Cloud Console, לוחצים על תפריט הניווט ☰ > Storage.

- לוחצים על Create Bucket (יצירת מאגר).
- מזינים שם ייחודי בהיקף גלובלי.

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

- בוחרים באפשרות Set permissions uniformly at bucket-level (Bucket Policy Only) (הגדרת הרשאות באופן אחיד ברמת הקטגוריה (מדיניות הקטגוריה בלבד)) ולוחצים על Continue (המשך) כדי ליצור את הקטגוריה.

- אחרי שיוצרים את הדלי, לוחצים על תפריט הניווט ☰ > Storage (אחסון) > Browser (דפדפן) ומאתרים את הדלי שיצרתם.

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

- לוחצים על Add Members (הוספת חברים), לוחצים על New members (חברים חדשים), מזינים allUsers ולוחצים על Select a role (בחירת תפקיד) > Storage Object Viewer (צפייה באובייקט אחסון). ההרשאה הזו מאפשרת גישת צפייה בקבצי ה-frontend הסטטיים ל-allUsers. זו לא הגדרת אבטחה אידיאלית לקבצים, אבל היא מתאימה למטרה של ה-codelab הזה.

יצירת קטגוריה של Cloud Storage לתמונות שהמשתמשים מעלים
פועלים לפי אותן הוראות כדי ליצור קטגוריה נפרדת להעלאת תמונות של משתמשים. מגדירים שוב את ההרשאות ל-allUsers, אבל בוחרים בתפקידים Storage Object Creator ו-Storage Object Viewer.
11. הגדרת קטגוריות של Cloud Storage באפליקציית הקצה הקדמי
הגדרת הקטגוריה של Cloud Storage בקובץ settings.py
- פתיחת
mysite/setting.py. - מאתרים את המשתנה
GCS_BUCKETומחליפים את‘<YOUR-GCS-BUCKET-NAME>' בקטגוריה הסטטית של Cloud Storage. - מאתרים את המשתנה
GS_MEDIA_BUCKET_NAMEומחליפים את‘<YOUR-GCS-BUCKET-NAME-MEDIA>' בשם הקטגוריה של Cloud Storage שבה מאוחסנים האימג'ים. - מאתרים את המשתנה
GS_STATIC_BUCKET_NAMEומחליפים את‘<YOUR-GCS-BUCKET-NAME-STATIC>' בשם הקטגוריה של 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>'
הגדרת קטגוריה של Cloud Storage בקובץ home.html
- פותחים את תיקיית הצ'אטים, פותחים את
templatesומשנים את השם שלhome-changeme.htmlל-home.html. - חפשו את
<YOUR-GCS-BUCKET-NAME-MEDIA>והחליפו אותו בשם הקטגוריה שבה רוצים לשמור את הקובץ שהמשתמש העלה. כך לא תוכלו לאחסן את הקובץ שהמשתמש העלה בחלק הקדמי של האתר, ולשמור את הנכסים הסטטיים בקטגוריה של Cloud Storage. ה-Vision API קורא מקטגוריה של Cloud Storage כדי לאסוף את הקובץ ולבצע את החיזוי.
12. פיתוח והרצה של האפליקציה באופן מקומי
כדי להריץ את אפליקציית Django במחשב המקומי, צריך להגדיר סביבת פיתוח של Python, כולל Python, pip ו-virtualenv. הוראות מפורטות במאמר הגדרת סביבת פיתוח בשפת 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 (Command+C ב-Macintosh) כדי לעצור את שרת האינטרנט המקומי.
שימוש במסוף Admin של Django
- יוצרים משתמש על.
python3 manage.py createsuperuser
- מפעילים שרת אינטרנט מקומי.
python3 manage.py runserver
- בדפדפן האינטרנט, עוברים לכתובת http://localhost:8000/admin/. כדי להתחבר לאתר האדמין, מזינים את שם המשתמש והסיסמה שיצרתם כשביצעתם את הפקודה
createsuperuser.
13. פריסת האפליקציה בסביבה הרגילה של App Engine
מריצים את הפקודה הבאה כדי לאסוף את כל התוכן הסטטי לתיקייה אחת. הפקודה מעבירה את כל הקבצים הסטטיים של האפליקציה לתיקייה שצוינה על ידי STATIC_ROOT ב-settings.py:
python3 manage.py collectstatic
כדי להעלות את האפליקציה, מריצים את הפקודה הבאה מהספרייה של האפליקציה שבה נמצא הקובץ app.yaml:
gcloud app deploy
מחכים להודעה שהעדכון הסתיים.
14. בדיקת אפליקציית הקצה הקדמי
בדפדפן האינטרנט, עוברים אל https://<your_project_id>.appspot.com
הפעם, הבקשה שלכם מטופלת על ידי שרת אינטרנט שפועל בסביבה הרגילה של App Engine.
הפקודה app deploy פורסת את האפליקציה כמו שמתואר במאמר app.yaml ומגדירה את הגרסה שנפרסה כגרסת ברירת המחדל, כך שהיא תציג את כל התנועה החדשה.
15. ייצור
כשמוכנים להציג את התוכן בסביבת הייצור, משנים את המשתנה DEBUG ל-False ב-mysite/settings.py.
16. בדיקת הצ'אטבוט
אתם יכולים לבדוק את הצ'אטבוט בסימולטור, או להשתמש באינטגרציה עם האינטרנט או עם Google Home שיצרתם קודם.
- משתמש: "היי"
- צ'אט בוט: "היי! אפשר להעלות תמונה כדי לחקור ציוני דרך".
- המשתמש מעלה תמונה.
מורידים את התמונה הזו, נותנים לה את השם demo.jpg ומשתמשים בה.

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

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

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