1. סקירה כללית
בסביבה הקמעונאית המשתנה במהירות של ימינו, חשוב מאוד לספק שירות לקוחות יוצא מן הכלל ולאפשר חוויות קנייה מותאמות אישית. נציג לכם מסע טכני ליצירת אפליקציית צ'אט מבוססת-ידע שנועדה לענות על שאלות של לקוחות, לעזור להם לגלות מוצרים ולהתאים אישית את תוצאות החיפוש. הפתרון החדשני הזה משלב את היכולות של AlloyDB לאחסון נתונים, מנוע לניתוח נתונים פנימי להבנה הקשרית, Gemini (מודל שפה גדול) לאימות הרלוונטיות ו-Agent Builder של Google להפעלה מהירה של עוזר חכם בממשק שיחה.
האתגר: לקוחות קמעונאיים מודרניים מצפים לקבל תשובות מיידיות והמלצות למוצרים שתואמות להעדפות הייחודיות שלהם. שיטות חיפוש מסורתיות לא תמיד מספקות רמה כזו של התאמה אישית.
הפתרון: אפליקציית הצ'אט מבוססת-הידע שלנו מתמודדת עם האתגר הזה באופן ישיר. הוא מתבסס על מאגר ידע עשיר שנוצר מנתוני הקמעונאות שלכם כדי להבין את כוונת הלקוח, להגיב בצורה חכמה ולספק תוצאות רלוונטיות במיוחד.
מה תפַתחו
בשיעור ה-Lab הזה (חלק 1):
- יצירת מכונת AlloyDB וטעינת מערך נתונים של מסחר אלקטרוני
- הפעלת התוספים pgvector ומודל AI גנרטיבי ב-AlloyDB
- יצירת הטמעות מתיאור המוצר
- ביצוע חיפוש בזמן אמת של דמיון קוסינוס לטקסט חיפוש של משתמש
- פריסת הפתרון בפונקציות ללא שרת (serverless) ב-Cloud Run
בחלק השני של ה-Lab נסביר על השלבים ליצירת סוכן.
דרישות
2. ארכיטקטורה
זרימת הנתונים: נבחן מקרוב את האופן שבו הנתונים עוברים במערכת שלנו:
הטמעה:
השלב הראשון הוא להטמיע את הנתונים הקמעונאיים (מלאי, תיאורי מוצרים, אינטראקציות עם לקוחות) ב-AlloyDB.
Analytics Engine:
נשתמש ב-AlloyDB כמנוע לניתוח נתונים כדי לבצע את הפעולות הבאות:
- חילוץ הקשר: המנוע מנתח את הנתונים שמאוחסנים ב-AlloyDB כדי להבין את הקשרים בין מוצרים, קטגוריות, התנהגות לקוחות וכו', לפי הצורך.
- יצירת הטמעות: הטמעות (ייצוגים מתמטיים של טקסט) נוצרות גם עבור השאילתה של המשתמש וגם עבור המידע שמאוחסן ב-AlloyDB.
- חיפוש וקטורי: המנוע מבצע חיפוש דמיון, ומשווה בין ההטמעה של השאילתה לבין ההטמעות של תיאורי מוצרים, ביקורות ונתונים רלוונטיים אחרים. הפונקציה הזו מזהה את 25 השכנים הקרובים הרלוונטיים ביותר.
אימות ב-Gemini:
התשובות הפוטנציאליות האלה נשלחות ל-Gemini להערכה. Gemini קובע אם הן באמת רלוונטיות ובטוחות לשיתוף עם המשתמש.
יצירת תשובה:
התשובות שעברו אימות מובנות כמערך JSON, והמנוע כולו ארוז כפונקציית Cloud Run ללא שרת, שמופעלת מ-Agent Builder.
אינטראקציה שיחתית:
התשובות מוצגות למשתמש בפורמט של שפה טבעית, כדי לאפשר דיאלוג הלוך ושוב. החלק הזה יוסבר בשיעור Lab נוסף.
3. לפני שמתחילים
יצירת פרויקט
- ב-מסוף Google Cloud, בדף לבחירת הפרויקט, בוחרים או יוצרים פרויקט ב-Google Cloud.
- הקפידו לוודא שהחיוב מופעל בפרויקט שלכם ב-Cloud. כך בודקים אם החיוב מופעל בפרויקט
- תשתמשו ב-Cloud Shell, סביבת שורת פקודה שפועלת ב-Google Cloud ומגיעה עם bq שנטען מראש. לוחצים על 'הפעלת Cloud Shell' בחלק העליון של מסוף Google Cloud.

- אחרי שמתחברים ל-Cloud Shell, בודקים שכבר בוצע אימות ושהפרויקט מוגדר למזהה הפרויקט שלכם באמצעות הפקודה הבאה:
gcloud auth list
- מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שפקודת gcloud מכירה את הפרויקט.
gcloud config list project
- אם הפרויקט לא מוגדר, משתמשים בפקודה הבאה כדי להגדיר אותו:
gcloud config set project <YOUR_PROJECT_ID>
- מפעילים את ממשקי ה-API הנדרשים.
gcloud services enable alloydb.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
run.googleapis.com \
cloudbuild.googleapis.com \
cloudfunctions.googleapis.com \
aiplatform.googleapis.com
אפשר גם לחפש כל מוצר במסוף או להשתמש בקישור הזה במקום בפקודת gcloud.
אם פספסתם API כלשהו, תמיד תוכלו להפעיל אותו במהלך ההטמעה.
אפשר לעיין במאמרי העזרה בנושא פקודות gcloud ושימוש בהן.
4. הגדרת מסד נתונים
בשיעור ה-Lab הזה נשתמש ב-AlloyDB כמסד הנתונים שיכיל את הנתונים הקמעונאיים. הוא משתמש באשכולות כדי להכיל את כל המשאבים, כמו מסדי נתונים ויומנים. לכל אשכול יש מופע ראשי שמספק נקודת גישה לנתונים. הטבלאות יכילו את הנתונים בפועל.
ניצור אשכול, מכונה וטבלה ב-AlloyDB שבהם ייטען מערך הנתונים של המסחר האלקטרוני.
יצירת אשכול ומופע
- עוברים לדף AlloyDB במסוף Cloud. דרך קלה למצוא את רוב הדפים ב-Cloud Console היא לחפש אותם באמצעות סרגל החיפוש של המסוף.
- בדף הזה, לוחצים על CREATE CLUSTER (יצירת אשכול):

- יוצג מסך כמו זה שבהמשך. יוצרים אשכול ומכונה עם הערכים הבאים:
- מזהה האשכול: "
shopping-cluster" - password: "
alloydb" - תואם ל-PostgreSQL 15
- אזור: "
us-central1" - רשת: "
default"

- כשבוחרים את רשת ברירת המחדל, מוצג מסך כמו זה שבהמשך. בוחרים באפשרות 'הגדרת חיבור'.

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

- אחרי שמגדירים את הרשת, אפשר להמשיך ליצור את האשכול. לוחצים על CREATE CLUSTER (יצירת אשכול) כדי להשלים את הגדרת האשכול, כמו שמוצג בהמשך:

חשוב לשנות את מזהה המופע ל-shopping-instance".
שימו לב: תהליך יצירת האשכול יימשך כ-10 דקות. אחרי שהפעולה תסתיים בהצלחה, יוצג מסך שדומה לזה:

5. הטמעת נתונים
עכשיו צריך להוסיף טבלה עם הנתונים על החנות. עוברים אל AlloyDB, בוחרים את האשכול הראשי ואז בוחרים באפשרות AlloyDB Studio:
יכול להיות שתצטרכו לחכות עד שהמופע שלכם יסיים את תהליך היצירה. אחרי שיוצרים את האשכול, נכנסים ל-AlloyDB באמצעות פרטי הכניסה שיצרתם. משתמשים בנתונים הבאים כדי לבצע אימות ב-PostgreSQL:
- שם משתמש : "
postgres" - מסד נתונים : "
postgres" - סיסמה : "
alloydb"
אחרי שתעברו בהצלחה את תהליך האימות ב-AlloyDB Studio, תוכלו להזין פקודות SQL בכלי העריכה. אפשר להוסיף כמה חלונות של Editor באמצעות סימן הפלוס שמשמאל לחלון האחרון.

מזינים פקודות ל-AlloyDB בחלונות של כלי העריכה, ומשתמשים באפשרויות Run (הפעלה), Format (עיצוב) ו-Clear (ניקוי) לפי הצורך.
הפעלת תוספים
כדי לבנות את האפליקציה הזו, נשתמש בתוספים pgvector ו-google_ml_integration. התוסף pgvector מאפשר לכם לאחסן ולחפש הטבעות וקטוריות. התוסף google_ml_integration מספק פונקציות שמשמשות לגישה לנקודות קצה (endpoints) של חיזוי ב-Vertex AI כדי לקבל חיזויים ב-SQL. מפעילים את התוספים האלה על ידי הפעלת פקודות ה-DDL הבאות:
CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE;
CREATE EXTENSION IF NOT EXISTS vector;
כדי לבדוק אילו תוספים הופעלו במסד הנתונים, מריצים את פקודת ה-SQL הבאה:
select extname, extversion from pg_extension;
צור טבלה
יוצרים טבלה באמצעות הצהרת ה-DDL הבאה:
CREATE TABLE
apparels ( id BIGINT,
category VARCHAR(100),
sub_category VARCHAR(50),
uri VARCHAR(200),
image VARCHAR(100),
content VARCHAR(2000),
pdt_desc VARCHAR(5000),
embedding vector(768) );
אחרי שהפקודה שלמעלה תופעל בהצלחה, תוכלו לראות את הטבלה במסד הנתונים. למטה מוצגת דוגמה לצילום מסך:

הטמעת נתונים
בשיעור ה-Lab הזה נשתמש בנתוני בדיקה של כ-200 רשומות בקובץ ה-SQL הזה. הוא מכיל את id, category, sub_category, uri, image ואת content. תמלאו את שאר השדות בהמשך שיעור ה-Lab.
מעתיקים משם את 20 השורות או את הצהרות ההוספה, מדביקים את השורות האלה בכרטיסייה ריקה בעורך ולוחצים על RUN.
כדי לראות את תוכן הטבלה, מרחיבים את הקטע 'כלי המחקר' עד שרואים את הטבלה שנקראת apparels. לוחצים על סמל האפשרויות הנוספות (⋮) כדי לראות את האפשרות 'שאילתת הטבלה'. משפט SELECT ייפתח בכרטיסייה חדשה של Editor.

מתן הרשאה
מריצים את ההצהרה הבאה כדי להעניק הרשאות הרצה בפונקציה embedding למשתמש postgres:
GRANT EXECUTE ON FUNCTION embedding TO postgres;
הענקת התפקיד Vertex AI User לחשבון השירות של AlloyDB
עוברים לטרמינל של Cloud Shell ומריצים את הפקודה הבאה:
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
6. הקשר
חוזרים לדף AlloyDB Instance (מופע AlloyDB).
כדי ליצור הטמעה, אנחנו צריכים context, כלומר את כל המידע שאנחנו רוצים לכלול בשדה אחד. אנחנו נעשה את זה על ידי יצירת תיאור מוצר (שנקרא לו pdt_desc). במקרה שלנו, נשתמש בכל המידע על כל מוצר, אבל כשאתם תעשו את זה עם הנתונים שלכם, אתם יכולים לעצב את הנתונים בכל דרך שנראית לכם משמעותית לעסק שלכם.
מריצים את ההצהרה הבאה מ-AlloyDB Studio של המופע החדש שיצרתם. הפעולה הזו תעדכן את השדה pdt_desc בנתוני ההקשר:
UPDATE
apparels
SET
pdt_desc = CONCAT('This product category is: ', category, ' and sub_category is: ', sub_category, '. The description of the product is as follows: ', content, '. The product image is stored at: ', uri)
WHERE
id IS NOT NULL;
ה-DML הזה יוצר סיכום פשוט של ההקשר באמצעות המידע מכל השדות שזמינים בטבלה ומהתלויות האחרות (אם יש כאלה בתרחיש לדוגמה). כדי לקבל מידע והקשר מדויקים יותר, אתם יכולים לעבד את הנתונים בכל דרך שנראית לכם משמעותית לעסק.
7. יצירת הטמעות להקשר
למחשבים קל יותר לעבד מספרים מאשר לעבד טקסט. מערכת הטמעה ממירה טקסט לסדרה של מספרים עם נקודה עשרונית, שאמורים לייצג את הטקסט, לא משנה איך הוא מנוסח, באיזו שפה הוא כתוב וכו'.
אפשר לתאר מיקום ליד הים. יכול להיות שהיא תהיה 'על המים', 'על חוף הים', 'הליכה מהחדר אל האוקיינוס', 'sur la mer', 'на берегу океана' וכו'. כל המונחים האלה נראים שונים, אבל המשמעות הסמנטית שלהם, או במינוח של למידת מכונה, ההטמעות שלהם, צריכה להיות קרובה מאוד זו לזו.
עכשיו, אחרי שהנתונים וההקשר מוכנים, נריץ את ה-SQL כדי להוסיף את ההטבעות של תיאור המוצר לטבלה בשדה embedding. יש מגוון של מודלים להטמעה שאפשר להשתמש בהם. אנחנו משתמשים ב-text-embedding-004 מ-Vertex AI. חשוב להשתמש באותו מודל הטמעה לאורך כל הפרויקט.
הערה: אם אתם משתמשים בפרויקט קיים ב-Google Cloud שנוצר לפני זמן מה, יכול להיות שתצטרכו להמשיך להשתמש בגרסאות ישנות יותר של מודל הטמעת הטקסט, כמו textembedding-gecko.
UPDATE
apparels
SET
embedding = embedding( 'text-embedding-004',
pdt_desc)
WHERE
TRUE;
כדאי לעיין שוב בapparelsטבלה כדי לראות כמה הטמעות. חשוב להריץ מחדש את הצהרת ה-SELECT כדי לראות את השינויים.
SELECT
id,
category,
sub_category,
content,
embedding
FROM
apparels;
הפונקציה אמורה להחזיר את וקטור ההטמעה, שנראה כמו מערך של מספרים ממשיים, עבור טקסט הדוגמה בשאילתה, כמו שמוצג בהמשך:

הערה: יכול להיות שיהיו בעיות במכסות בפרויקטים חדשים ב-Google Cloud במסגרת התוכנית החינמית, כשמדובר במספר בקשות ההטמעה שמותרות בשנייה למודלים של הטמעה. מומלץ להשתמש בשאילתת סינון למזהה, ואז לבחור באופן סלקטיבי 1-5 רשומות וכן הלאה, במהלך יצירת ההטמעה.
8. ביצוע חיפוש וקטורי
עכשיו, אחרי שהטבלה, הנתונים וההטמעות מוכנים, אפשר לבצע את החיפוש הווקטורי בזמן אמת של טקסט החיפוש של המשתמש.
נניח שהמשתמש שואל:
"אני רוצה חולצות לנשים, ורודות ליום-יום מכותנה טהורה בלבד".
כדי למצוא התאמות, מריצים את השאילתה הבאה:
SELECT
id,
category,
sub_category,
content,
pdt_desc AS description
FROM
apparels
ORDER BY
embedding <=> embedding('text-embedding-004',
'I want womens tops, pink casual only pure cotton.')::vector
LIMIT
5;
בואו נבחן את השאילתה הזו בפירוט:
בשאלת החיפוש הזו,
- הטקסט שהמשתמש חיפש הוא: "אני רוצה חולצות נשים, ורודות ליום-יום, רק מכותנה טהורה".
- אנחנו ממירים אותו להטמעות בשיטה
embedding()באמצעות המודל:text-embedding-004. השלב הזה אמור להיראות מוכר אחרי השלב הקודם, שבו הפעלנו את פונקציית ההטמעה על כל הפריטים בטבלה. -
<=>מייצג את השימוש בשיטת המרחק COSINE SIMILARITY. אפשר למצוא את כל מדדי הדמיון שזמינים בתיעוד של pgvector. - אנחנו ממירים את התוצאה של שיטת ההטמעה לסוג וקטור כדי שתהיה תואמת לווקטורים שמאוחסנים במסד הנתונים.
- הערך LIMIT 5 מייצג את העובדה שאנחנו רוצים לחלץ 5 שכנים קרובים ביותר לטקסט החיפוש.
התוצאה נראית כך:

כפי שאפשר לראות בתוצאות, ההתאמות קרובות מאוד לטקסט החיפוש. נסו לשנות את הצבע כדי לראות איך התוצאות משתנות.
הערה חשובה:
נניח שאנחנו רוצים לשפר את הביצועים (זמן השאילתה), היעילות וההחזרה של תוצאת החיפוש הווקטורי הזו באמצעות אינדקס ScaNN. כדי להשוות את ההבדל בתוצאה עם האינדקס ובלי האינדקס, אפשר לקרוא את השלבים בבלוג הזה. לנוחותכם, ריכזנו כאן את השלבים ליצירת אינדקס:
- מכיוון שכבר יצרנו את האשכול, המופע, ההקשר וההטמעות, אנחנו צריכים רק להתקין את התוסף ScaNN באמצעות ההצהרה הבאה:
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
- בשלב הבא ניצור את האינדקס (ScaNN):
CREATE INDEX apparel_index ON apparels
USING scann (embedding cosine)
WITH (num_leaves=54);
בדוגמת ה-DDL שלמעלה, apparel_index הוא שם האינדקס
הטבלה שלי היא 'apparels'
scann היא שיטת האינדקס
'embedding' היא העמודה בטבלה שאני רוצה ליצור לה אינדקס
'cosine' היא שיטת המרחק שבה אני רוצה להשתמש עם האינדקס
54 הוא מספר המחיצות שיש להחיל על האינדקס הזה. הערך יכול להיות בין 1 ל-1048576. מידע נוסף על קביעת הערך הזה זמין במאמר בנושא שיפור של אינדקס ScaNN.
השתמשתי בשורש הריבועי של מספר נקודות הנתונים, כמומלץ במאגר ScaNN (בחלוקה למחיצות, הערך של num_leaves צריך להיות בערך השורש הריבועי של מספר נקודות הנתונים).
- בודקים אם האינדקס נוצר באמצעות השאילתה:
SELECT * FROM pg_stat_ann_indexes;
- מבצעים חיפוש וקטורי באמצעות אותה שאילתה שבה השתמשנו בלי האינדקס:
select * from apparels
ORDER BY embedding <=> CAST(embedding('textembedding-gecko', 'white tops for girls without any print') as vector(768))
LIMIT 20
השאילתה שלמעלה היא אותה שאילתה שבה השתמשנו במעבדה בשלב 8. אבל עכשיו השדה הזה מתווסף לאינדקס.
- כדי לבדוק, מריצים שאילתת חיפוש פשוטה עם האינדקס ובלי האינדקס (על ידי השמטת האינדקס):
white tops for girls without any print
הטקסט של החיפוש שלמעלה בשאילתת החיפוש הווקטורי בנתוני ההטבעות שעברו אינדוקס מוביל לתוצאות חיפוש איכותיות ויעילות. היעילות משתפרת משמעותית (במונחים של זמן ביצוע: 10.37 אלפיות השנייה ללא ScaNN ו-0.87 אלפיות השנייה עם ScaNN) עם האינדקס. מידע נוסף על הנושא הזה זמין בבלוג.
9. אימות ההתאמה באמצעות מודל LLM
לפני שנמשיך וניצור שירות להחזרת ההתאמות הטובות ביותר לאפליקציה, נשתמש במודל AI גנרטיבי כדי לוודא שהתשובות הפוטנציאליות האלה באמת רלוונטיות ובטוחות לשיתוף עם המשתמש.
איך מוודאים שהמופע מוגדר ל-Gemini
קודם צריך לבדוק אם השילוב של Google ML כבר מופעל באשכול ובמופע שלכם. ב-AlloyDB Studio, מזינים את הפקודה הבאה:
show google_ml_integration.enable_model_support;
אם הערך הוא on, אפשר לדלג על 2 השלבים הבאים ולעבור ישירות להגדרת השילוב של AlloyDB ו-Vertex AI Model.
- עוברים למופע הראשי של אשכול AlloyDB ולוחצים על EDIT PRIMARY INSTANCE (עריכת המופע הראשי).

- עוברים לקטע Flags (דגלים) באפשרויות ההגדרה המתקדמות. מוודאים שהערך של
google_ml_integration.enable_model_support flagמוגדר ל-on, כמו שמוצג בהמשך:

אם היא לא מוגדרת כ'מופעלת', מגדירים אותה כ'מופעלת' ואז לוחצים על הלחצן UPDATE INSTANCE (עדכון המופע). השלב הזה יימשך כמה דקות.
שילוב של מודלים של AlloyDB ו-Vertex AI
עכשיו אפשר להתחבר ל-AlloyDB Studio ולהריץ את פקודת ה-DML הבאה כדי להגדיר גישה למודל Gemini מ-AlloyDB, באמצעות מזהה הפרויקט במקום שצוין. יכול להיות שתקבלו אזהרה על שגיאת תחביר לפני הרצת הפקודה, אבל היא אמורה לפעול בצורה תקינה.
קודם כול, יוצרים את החיבור למודל Gemini 1.5 כמו שמוצג למטה. חשוב לזכור להחליף את $PROJECT_ID בפקודה שלמטה במזהה הפרויקט ב-Google Cloud.
CALL
google_ml.create_model( model_id => 'gemini-1.5',
model_request_url => 'https://us-central1-aiplatform.googleapis.com/v1/projects/$PROJECT_ID/locations/us-central1/publishers/google/models/gemini-1.5-pro:streamGenerateContent',
model_provider => 'google',
model_auth_type => 'alloydb_service_agent_iam');
כדי לבדוק את המודלים שהוגדרו לגישה, מריצים את הפקודה הבאה ב-AlloyDB Studio:
select model_id,model_type from google_ml.model_info_view;
לבסוף, צריך להעניק למשתמשי מסד הנתונים הרשאה להפעיל את הפונקציה ml_predict_row כדי להריץ תחזיות באמצעות מודלים של Google Vertex AI. מריצים את הפקודה הבאה:
GRANT EXECUTE ON FUNCTION ml_predict_row to postgres;
הערה: אם אתם משתמשים בפרויקט קיים ב-Google Cloud ובאשכול או במופע קיימים של AlloyDB שנוצרו לפני זמן מה, יכול להיות שתצטרכו להסיר את ההפניות הישנות למודל gemini-1.5 וליצור אותן מחדש באמצעות הצהרת ה-CALL שלמעלה, ולהריץ שוב את הפקודה grant execute on function ml_predict_row אם תיתקלו בבעיות בהפעלות הקרובות של gemini-1.5.
בדיקת התשובות
בקטע הבא נשתמש בשאילתה גדולה אחת כדי לוודא שהתשובות שמתקבלות מהשאילתה סבירות, אבל יכול להיות שיהיה קשה להבין את השאילתה. עכשיו נבחן את החלקים ונראה איך הם מתחברים בעוד כמה דקות.
- קודם נשלח בקשה למסד הנתונים כדי לקבל את 5 ההתאמות הכי קרובות לשאילתת משתמש. אנחנו מקודדים את השאילתה באופן קשיח כדי לפשט את התהליך, אבל אל דאגה, אנחנו נבצע אינטרפולציה של השאילתה בהמשך. אנחנו כוללים את תיאור המוצר מהטבלה
apparelsומוסיפים שני שדות חדשים – אחד שמשלב את התיאור עם האינדקס, והשני עם הבקשה המקורית. הנתונים נשמרים בטבלה בשםxyz(זה רק שם זמני לטבלה).
CREATE TABLE
xyz AS
SELECT
id || ' - ' || pdt_desc AS literature,
pdt_desc AS content,
'I want womens tops, pink casual only pure cotton.' AS user_text
FROM
apparels
ORDER BY
embedding <=> embedding('text-embedding-004',
'I want womens tops, pink casual only pure cotton.')::vector
LIMIT
5;
הפלט של השאילתה הזו יהיה 5 השורות הדומות ביותר שקשורות לשאילתת המשתמש. הטבלה החדשה xyz תכיל 5 שורות, ולכל שורה יהיו העמודות הבאות:
literaturecontentuser_text
- כדי לקבוע את התוקף של התשובות, נשתמש בשאילתה מורכבת שבה נסביר איך להעריך את התשובות. היא משתמשת בערכים
user_textו-contentבטבלהxyzכחלק מהשאילתה.
"Read this user search text: ', user_text,
' Compare it against the product inventory data set: ', content,
' Return a response with 3 values: 1) MATCH: if the 2 contexts are at least 85% matching or not: YES or NO 2) PERCENTAGE: percentage of match, make sure that this percentage is accurate 3) DIFFERENCE: A clear short easy description of the difference between the 2 products. Remember if the user search text says that some attribute should not be there, and the record has it, it should be a NO match."
- באמצעות השאילתה הזו, נבדוק את איכות התשובות בטבלה
xyz.
CREATE TABLE
x AS
SELECT
json_array_elements( google_ml.predict_row( model_id => 'gemini-1.5',
request_body => CONCAT('{
"contents": [
{ "role": "user",
"parts":
[ { "text": "Read this user search text: ', user_text, ' Compare it against the product inventory data set: ', content, ' Return a response with 3 values: 1) MATCH: if the 2 contexts are at least 85% matching or not: YES or NO 2) PERCENTAGE: percentage of match, make sure that this percentage is accurate 3) DIFFERENCE: A clear short easy description of the difference between the 2 products. Remember if the user search text says that some attribute should not be there, and the record has it, it should be a NO match."
} ]
}
] }'
)::json))-> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text'
AS LLM_RESPONSE
FROM
xyz;
- הפונקציה
predict_rowמחזירה את התוצאה שלה בפורמט JSON. הקוד-> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text'"משמש לחילוץ הטקסט בפועל מ-JSON. כדי לראות את ה-JSON בפועל שמוחזר, אפשר להסיר את הקוד הזה. - לבסוף, כדי לקבל את שדה ה-LLM, צריך רק לחלץ אותו מטבלת x:
SELECT
LLM_RESPONSE
FROM
x;
- אפשר לשלב את השאילתות האלה לשאילתה אחת כמו בדוגמה הבאה.
אם הפעלתם את השאילתות שלמעלה כדי לבדוק את תוצאות הביניים, תצטרכו למחוק או להסיר את הטבלאות xyz ו-x ממסד הנתונים של AlloyDB לפני שתפעילו את השאילתה הזו.
SELECT
LLM_RESPONSE
FROM (
SELECT
json_array_elements( google_ml.predict_row( model_id => 'gemini-1.5',
request_body => CONCAT('{
"contents": [
{ "role": "user",
"parts":
[ { "text": "Read this user search text: ', user_text, ' Compare it against the product inventory data set: ', content, ' Return a response with 3 values: 1) MATCH: if the 2 contexts are at least 85% matching or not: YES or NO 2) PERCENTAGE: percentage of match, make sure that this percentage is accurate 3) DIFFERENCE: A clear short easy description of the difference between the 2 products. Remember if the user search text says that some attribute should not be there, and the record has it, it should be a NO match."
} ]
}
] }'
)::json))-> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text'
AS LLM_RESPONSE
FROM (
SELECT
id || ' - ' || pdt_desc AS literature,
pdt_desc AS content,
'I want womens tops, pink casual only pure cotton.' user_text
FROM
apparels
ORDER BY
embedding <=> embedding('text-embedding-004',
'I want womens tops, pink casual only pure cotton.')::vector
LIMIT
5 ) AS xyz ) AS X;
יכול להיות שזה עדיין נראה מרתיע, אבל אני מקווה שזה קצת יותר ברור עכשיו. התוצאות מציינות אם יש התאמה, מה אחוז ההתאמה וכוללות הסבר על הסיווג.
שימו לב שמודל Gemini מוגדר כברירת מחדל להזרמת נתונים, ולכן התשובה בפועל מפוזרת על פני כמה שורות: 
10. העברת האפליקציה לאינטרנט
מוכנים להעביר את האפליקציה הזו לאינטרנט? כדי להפוך את מנוע הידע הזה ל-Serverless באמצעות Cloud Run Functions:
- נכנסים אל Cloud Run Functions במסוף Google Cloud כדי ליצור פונקציית Cloud Run חדשה, או משתמשים בקישור: https://console.cloud.google.com/functions/add.
- בוחרים באפשרות פונקציית Cloud Run בתור הסביבה. מזינים את שם הפונקציה retail-engine ובוחרים באזור us-central1. מגדירים את האימות ל'מתן הרשאה להפעלות לא מאומתות' ולוחצים על הבא. בוחרים באפשרות Java 17 כסביבת זמן ריצה ובאפשרות עורך מוטבע לקוד המקור.
- כברירת מחדל, נקודת הכניסה מוגדרת כ-"
gcfv2.HelloHttpFunction". מחליפים את קוד ה-placeholder ב-HelloHttpFunction.javaוב-pom.xmlשל פונקציית Cloud Run בקוד מ-קובץ Java ומ-XML בהתאמה. - חשוב לזכור לשנות את ה-placeholder $PROJECT_ID ואת פרטי הכניסה לחיבור ל-AlloyDB לערכים שלכם בקובץ Java. פרטי הכניסה ל-AlloyDB הם אותם פרטים שבהם השתמשנו בתחילת ה-codelab הזה. אם השתמשתם בערכים שונים, אתם צריכים לשנות אותם בקובץ Java.
- לוחצים על פריסה.
אחרי הפריסה, כדי לאפשר לפונקציה של Cloud Functions לגשת למכונת מסד הנתונים של AlloyDB, ניצור את מחבר ה-VPC.
שלב חשוב:
אחרי שמתחילים את הפריסה, הפונקציות אמורות להופיע במסוף Cloud Run Functions של Google. מחפשים את הפונקציה החדשה שנוצרה (retail-engine), לוחצים עליה, ואז לוחצים על עריכה ומשנים את הפרטים הבאים:
- מעבר להגדרות של זמן הריצה, ה-build, החיבורים והאבטחה
- הגדלת משך הזמן הקצוב לתפוגה ל-180 שניות
- עוברים לכרטיסייה CONNECTIONS (חיבורים):

- בהגדרות של Ingress, מוודאים שהאפשרות Allow all traffic (התרת כל התנועה) מסומנת.
- בקטע Egress settings (הגדרות יציאה), לוחצים על התפריט הנפתח Network (רשת), בוחרים באפשרות Add New VPC Connector (הוספת מחבר VPC חדש) ופועלים לפי ההוראות שמופיעות בתיבת הדו-שיח שקופצת:

- נותנים שם למחבר ה-VPC ומוודאים שהאזור זהה לאזור של המכונה. משאירים את ערך הרשת כברירת מחדל ומגדירים את תת-הרשת כטווח IP מותאם אישית עם טווח ה-IP 10.8.0.0 או ערך דומה שזמין.
- מרחיבים את האפשרות SHOW SCALING SETTINGS (הצגת הגדרות שינוי הגודל) ומוודאים שההגדרה מוגדרת בדיוק כמו שמופיע כאן:

- לוחצים על CREATE (יצירה). המחבר אמור להופיע עכשיו בהגדרות היציאה.
- בוחרים את המחבר החדש שנוצר.
- בוחרים באפשרות שכל התנועה תנותב דרך מחבר ה-VPC הזה.
- לוחצים על הבא ואז על פריסה.
11. בדיקת האפליקציה
אחרי שפורסים את פונקציית Cloud Functions המעודכנת, נקודת הקצה אמורה להופיע בפורמט הבא:
https://us-central1-YOUR_PROJECT_ID.cloudfunctions.net/retail-engine
כדי לבדוק את זה ב-Cloud Shell Terminal, מריצים את הפקודה הבאה:
gcloud functions call retail-engine --region=us-central1 --gen2 --data '{"search": "I want some kids clothes themed on Disney"}'
אפשר גם לבדוק את הפונקציה של Cloud Run באופן הבא:
PROJECT_ID=$(gcloud config get-value project)
curl -X POST https://us-central1-$PROJECT_ID.cloudfunctions.net/retail-engine \
-H 'Content-Type: application/json' \
-d '{"search":"I want some kids clothes themed on Disney"}' \
| jq .
והתוצאה:

זהו! זה כל מה שצריך כדי לבצע חיפוש וקטורי של דמיון באמצעות מודל ההטמעות בנתוני AlloyDB.
פיתוח הצ'אט בוט
הסוכן נוצר בחלק 2 של שיעור ה-Lab הזה.
12. הסרת המשאבים
אם אתם מתכננים להשלים את חלק 2 של שיעור ה-Lab הזה, דלגו על השלב הזה כי הוא יגרום למחיקת הפרויקט הנוכחי.
כדי לא לצבור חיובים לחשבון Google Cloud על המשאבים שבהם השתמשתם במאמר הזה:
- במסוף Google Cloud, עוברים לדף Manage resources.
- ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
- כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
13. מזל טוב
מעולה! ביצעתם בהצלחה חיפוש דמיון באמצעות AlloyDB, pgvector ו-Vector Search. שילוב היכולות של AlloyDB, Vertex AI ו-Vector Search מאפשר לנו לעשות קפיצת מדרגה משמעותית ולהפוך את החיפושים ההקשריים והווקטוריים לנגישים, ליעילים ולמבוססים על משמעות אמיתית. בחלק הבא של שיעור ה-Lab מוסבר איך ליצור סוכן.