פיתוח Assistant חכמה לשופינג באמצעות AlloyDB ו-Vertex AI Agent Builder – חלק 1

1. סקירה כללית

בסביבה הקמעונאית המשתנה במהירות של ימינו, חשוב מאוד לספק שירות לקוחות יוצא מן הכלל ולאפשר חוויות קנייה בהתאמה אישית. נציג לכם מסע טכני ליצירת אפליקציית צ'אט מבוססת-ידע, שמיועדת לענות על שאלות של לקוחות, לעזור להם לגלות מוצרים ולהתאים אישית את תוצאות החיפוש. הפתרון החדשני הזה משלב את היכולות של AlloyDB לאחסון נתונים, מנוע לניתוח נתונים פנימי להבנה הקשרית, Gemini (מודל שפה גדול) לאימות הרלוונטיות ו-Agent Builder של Google להפעלה מהירה של עוזר חכם לשיחות.

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

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

מה תפַתחו

במסגרת שיעור ה-Lab הזה (חלק 1):

  1. יצירה של מכונת AlloyDB וטעינה של מערך נתונים של מסחר אלקטרוני
  2. הפעלת התוספים pgvector ומודל AI גנרטיבי ב-AlloyDB
  3. יצירת הטמעות מתיאור המוצר
  4. ביצוע חיפוש בזמן אמת של דמיון קוסינוס לטקסט חיפוש של משתמש
  5. פריסת הפתרון בפונקציות של Cloud Run ללא שרת

בחלק השני של ה-Lab נסביר על השלבים ליצירת סוכן.

דרישות

  • דפדפן, כמו Chrome או Firefox
  • פרויקט ב-Google Cloud שהחיוב בו מופעל.

2. ארכיטקטורה

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

הטמעה:

השלב הראשון הוא להטמיע את הנתונים הקמעונאיים (מלאי, תיאורי מוצרים, אינטראקציות עם לקוחות) ב-AlloyDB.

מנוע Analytics:

נשתמש ב-AlloyDB כמנוע לניתוח נתונים כדי לבצע את הפעולות הבאות:

  1. חילוץ הקשר: המנוע מנתח את הנתונים שמאוחסנים ב-AlloyDB כדי להבין את הקשרים בין מוצרים, קטגוריות, התנהגות לקוחות וכו', לפי הצורך.
  2. הטבעת יצירה: הטבעות (ייצוגים מתמטיים של טקסט) נוצרות גם עבור השאילתה של המשתמש וגם עבור המידע שמאוחסן ב-AlloyDB.
  3. חיפוש וקטורי: המנוע מבצע חיפוש דמיון, ומשווה בין ההטמעה של השאילתה לבין ההטמעות של תיאורי מוצרים, ביקורות ונתונים רלוונטיים אחרים. הפונקציה הזו מזהה את 25 השכנים הקרובים הרלוונטיים ביותר.

אימות ב-Gemini:

התשובות האפשריות האלה נשלחות ל-Gemini כדי שיעריך אותן. ‫Gemini קובע אם הן באמת רלוונטיות ובטוחות לשיתוף עם המשתמש.

יצירת תשובה:

התשובות שעברו אימות מובנות כמערך JSON, והמנוע כולו ארוז כפונקציית Cloud Run ללא שרת, שמופעלת מ-Agent Builder.

אינטראקציה שיחתית:

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

3. לפני שמתחילים

יצירת פרויקט

  1. ב-מסוף Google Cloud, בדף לבחירת הפרויקט, בוחרים או יוצרים פרויקט ב-Google Cloud.
  2. הקפידו לוודא שהחיוב מופעל בפרויקט שלכם ב-Cloud. כך בודקים אם החיוב מופעל בפרויקט
  3. תשתמשו ב-Cloud Shell, סביבת שורת פקודה שפועלת ב-Google Cloud ומגיעה עם bq שנטען מראש. לוחצים על 'הפעלת Cloud Shell' בחלק העליון של מסוף Google Cloud.

תמונה של לחצן ההפעלה של Cloud Shell

  1. אחרי שמתחברים ל-Cloud Shell, אפשר לבדוק שכבר בוצע אימות ושהפרויקט מוגדר למזהה הפרויקט שלכם באמצעות הפקודה הבאה:
gcloud auth list
  1. מריצים את הפקודה הבאה ב-Cloud Shell כדי לוודא שפקודת gcloud מכירה את הפרויקט.
gcloud config list project
  1. אם הפרויקט לא מוגדר, משתמשים בפקודה הבאה כדי להגדיר אותו:
gcloud config set project <YOUR_PROJECT_ID>
  1. מפעילים את ממשקי ה-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 שבהם ייטען מערך הנתונים של המסחר האלקטרוני.

יצירת אשכול ומופע

  1. עוברים לדף AlloyDB במסוף Cloud. דרך קלה למצוא את רוב הדפים ב-Cloud Console היא לחפש אותם באמצעות סרגל החיפוש של המסוף.
  2. בדף הזה, בוחרים באפשרות CREATE CLUSTER (יצירת אשכול):

f76ff480c8c889aa.png

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

538dba58908162fb.png

  1. כשבוחרים את רשת ברירת המחדל, מוצג מסך כמו זה שבהמשך. בוחרים באפשרות 'הגדרת חיבור'.
    7939bbb6802a91bf.png
  2. משם, בוחרים באפשרות 'שימוש בטווח כתובות IP שהוקצה באופן אוטומטי' ולוחצים על 'המשך'. אחרי שבודקים את המידע, לוחצים על CREATE CONNECTION (יצירת חיבור). 768ff5210e79676f.png
  3. אחרי שמגדירים את הרשת, אפשר להמשיך ליצור את האשכול. לוחצים על CREATE CLUSTER (יצירת אשכול) כדי להשלים את הגדרת האשכול, כמו שמוצג בהמשך:

e06623e55195e16e.png

חשוב לשנות את מזהה המופע ל-shopping-instance".

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

24eec29fa5cfdb3e.png

5. הטמעת נתונים

עכשיו צריך להוסיף טבלה עם הנתונים על החנות. עוברים אל AlloyDB, בוחרים את האשכול הראשי ואז את AlloyDB Studio:

847e35f1bf8a8bd8.png

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

  • שם משתמש : "postgres"
  • מסד נתונים : "postgres"
  • סיסמה : "alloydb"

אחרי שתעברו בהצלחה את תהליך האימות ב-AlloyDB Studio, תוכלו להזין פקודות SQL בכלי העריכה. אפשר להוסיף כמה חלונות של Editor באמצעות סימן הפלוס משמאל לחלון האחרון.

91a86d9469d499c4.png

מזינים פקודות ל-AlloyDB בחלונות של כלי העריכה, ומשתמשים באפשרויות Run (הפעלה), Format (עיצוב) ו-Clear (ניקוי) לפי הצורך.

הפעלת תוספים

כדי ליצור את האפליקציה הזו, נשתמש בתוספים pgvector ו-google_ml_integration. התוסף pgvector מאפשר לכם לאחסן ולחפש הטמעות של וקטורים. התוסף google_ml_integration מספק פונקציות שמשמשות לגישה לנקודות קצה של חיזוי ב-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) );

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

908e33bbff58a6d.png

הטמעת נתונים

בשיעור ה-Lab הזה נשתמש בנתוני בדיקה של כ-200 רשומות בקובץ ה-SQL הזה. הוא מכיל את id, category, sub_category, uri, image ואת content. את שאר השדות ממלאים בהמשך שיעור ה-Lab.

מעתיקים משם את 20 השורות או את הצהרות ההוספה, מדביקים את השורות האלה בכרטיסייה ריקה של כלי העריכה ובוחרים באפשרות 'הפעלה'.

כדי לראות את תוכן הטבלה, מרחיבים את הקטע Explorer עד שרואים את הטבלה בשם apparels. לוחצים על סמל האפשרויות הנוספות (⋮) כדי לראות את האפשרות 'שאילתת הטבלה'. הוראת SELECT תיפתח בכרטיסייה חדשה של Editor.

b31ece70e670ab89.png

מתן הרשאה

מריצים את ההצהרה הבאה כדי להעניק הרשאות הרצה בפונקציה embedding למשתמש postgres:

GRANT EXECUTE ON FUNCTION embedding TO postgres;

נותנים לחשבון השירות של AlloyDB את התפקיד Vertex AI User

עוברים לטרמינל של 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;

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

c69c08d085389f74.png

הערה: יכול להיות שבפרויקטים חדשים ב-Google Cloud במסגרת התוכנית החינמית תהיה בעיה עם המכסה של מספר בקשות ההטמעה שמותרות בשנייה למודלים של הטמעה. מומלץ להשתמש בשאילתת סינון למזהה, ואז לבחור באופן סלקטיבי 1-5 רשומות וכן הלאה, במהלך יצירת ההטמעה.

8. ביצוע חיפוש וקטור

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

נניח שהמשתמש שואל:

‫"I want womens tops, pink casual only pure cotton."

כדי למצוא התאמות, מריצים את השאילתה הבאה:

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;

בואו נבחן את השאילתה הזו בפירוט:

בשאילתה הזו,

  1. הטקסט של החיפוש של המשתמש הוא: "אני רוצה חולצות נשים, רק ורודות מכותנה טהורה ליום יום".
  2. אנחנו ממירים אותו להטמעות בשיטה embedding() באמצעות המודל: text-embedding-004. השלב הזה אמור להיראות מוכר אחרי השלב הקודם, שבו הפעלנו את פונקציית ההטמעה על כל הפריטים בטבלה.
  3. <=> מייצג את השימוש בשיטת המרחק COSINE SIMILARITY. אפשר למצוא את כל מדדי הדמיון שזמינים בתיעוד של pgvector.
  4. אנחנו ממירים את התוצאה של שיטת ההטמעה לסוג וקטור כדי שתהיה תאימות לווקטורים שמאוחסנים במסד הנתונים.
  5. הערך LIMIT 5 מציין שאנחנו רוצים לחלץ 5 שכנים קרובים לטקסט החיפוש.

התוצאה נראית כך:

4193a68737400535.png

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

הערה חשובה:

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

  1. מכיוון שכבר יצרנו את האשכול, המופע, ההקשר וההטמעות, אנחנו צריכים רק להתקין את התוסף ScaNN באמצעות ההצהרה הבאה:

CREATE EXTENSION IF NOT EXISTS alloydb_scann;

  1. בשלב הבא ניצור את האינדקס (ScaNN):

CREATE INDEX apparel_index ON apparels

USING scann (embedding cosine)

WITH (num_leaves=54);

בדוגמת ה-DDL שלמעלה, apparel_index הוא שם האינדקס

הטבלה שלי היא 'apparels'

‫scann היא שיטת האינדקס

‫'embedding' היא העמודה בטבלה שאני רוצה ליצור לה אינדקס

‫"cosine" היא שיטת המרחק שבה אני רוצה להשתמש עם האינדקס

‫54 הוא מספר המחיצות שיש להחיל על האינדקס הזה. הערך יכול להיות בין 1 ל-1,048,576. מידע נוסף על קביעת הערך הזה זמין במאמר בנושא התאמה של אינדקס ScaNN.

השתמשתי בשורש הריבועי של מספר נקודות הנתונים, כמומלץ במאגר ScaNN (בחלוקה למחיצות, הערך של num_leaves צריך להיות בערך השורש הריבועי של מספר נקודות הנתונים).

  1. בודקים אם האינדקס נוצר באמצעות השאילתה:

SELECT * FROM pg_stat_ann_indexes;

  1. מבצעים חיפוש וקטורי באמצעות אותה שאילתה שבה השתמשנו בלי האינדקס:

select * from apparels

ORDER BY embedding <=> CAST(embedding('textembedding-gecko', 'white tops for girls without any print') as vector(768))

LIMIT 20

השאילתה שלמעלה היא אותה שאילתה שבה השתמשנו במעבדה בשלב 8. עם זאת, עכשיו השדה הזה מתווסף לאינדקס.

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

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.

  1. עוברים למופע הראשי של אשכול AlloyDB ולוחצים על EDIT PRIMARY INSTANCE (עריכת המופע הראשי).

456ffdf292d3c0e0.png

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

6a59351fcd2a9d35.png

אם האפשרות לא מוגדרת כ'מופעלת', מגדירים אותה כ'מופעלת' ואז לוחצים על הלחצן 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.

בדיקת התשובות

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

  1. קודם נשלח בקשה למסד הנתונים כדי לקבל את 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 שורות, וכל שורה תכיל את העמודות הבאות:

  • literature
  • content
  • user_text
  1. כדי לקבוע את התוקף של התשובות, נשתמש בשאילתה מורכבת שבה נסביר איך להעריך את התשובות. היא משתמשת ב-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."
  1. באמצעות השאילתה הזו, נבדוק את איכות התשובות בטבלה 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;
  1. הפונקציה predict_row מחזירה את התוצאה שלה בפורמט JSON. הקוד -> 'candidates' -> 0 -> 'content' -> 'parts' -> 0 -> 'text'" משמש לחילוץ הטקסט בפועל מ-JSON. כדי לראות את ה-JSON בפועל שמוחזר, אפשר להסיר את הקוד הזה.
  2. לבסוף, כדי לקבל את שדה ה-LLM, צריך לחלץ אותו מטבלת x:
SELECT 
LLM_RESPONSE 
FROM 
        x;
  1. אפשר לשלב את שתי השאילתות הבאות לשאילתה אחת.

אם הפעלתם את השאילתות שלמעלה כדי לבדוק את התוצאות הזמניות, תצטרכו למחוק או להסיר את הטבלאות 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, ולכן התשובה בפועל מופיעה בכמה שורות: 14e74d71293b7b9.png

10. העברת האפליקציה לאינטרנט

רוצה להעביר את האפליקציה הזו לאינטרנט? כדי להפוך את מנוע הידע הזה ל-Serverless באמצעות פונקציות Cloud Run:

  1. נכנסים אל Cloud Run Functions במסוף Google Cloud כדי ליצור פונקציית Cloud Run חדשה, או משתמשים בקישור: https://console.cloud.google.com/functions/add.
  2. בוחרים באפשרות פונקציית Cloud Run בתור הסביבה. מזינים את שם הפונקציה retail-engine ובוחרים באזור us-central1. מגדירים את האימות ל'מתן הרשאה להפעלות לא מאומתות' ולוחצים על הבא. בוחרים באפשרות Java 17 כסביבת זמן ריצה ובאפשרות עורך מוטבע לקוד המקור.
  3. כברירת מחדל, נקודת הכניסה מוגדרת כ-gcfv2.HelloHttpFunction. מחליפים את קוד ה-placeholder ב-HelloHttpFunction.java וב-pom.xml של פונקציית Cloud Run בקוד מ-קובץ Java ומ-XML בהתאמה.
  4. חשוב לזכור לשנות את ה-placeholder $PROJECT_ID ואת פרטי הכניסה לחיבור ל-AlloyDB לערכים שלכם בקובץ Java. פרטי הכניסה ל-AlloyDB הם אותם פרטי כניסה שבהם השתמשנו בתחילת ה-codelab הזה. אם השתמשתם בערכים שונים, עליכם לשנות אותם בקובץ Java.
  5. לוחצים על פריסה.

אחרי הפריסה, כדי לאפשר ל-Cloud Function לגשת למופע מסד הנתונים של AlloyDB, ניצור את מחבר ה-VPC.

שלב חשוב:

אחרי שמתחילים את הפריסה, אמורות להופיע פונקציות Cloud Run ב-Cloud Run Functions console של Google. מחפשים את הפונקציה החדשה שנוצרה (retail-engine), לוחצים עליה ואז על עריכה ומשנים את הפרטים הבאים:

  1. מעבר להגדרות של זמן ריצה, build, חיבורים ואבטחה
  2. הגדלת הזמן הקצוב לתפוגה ל-180 שניות
  3. עוברים לכרטיסייה CONNECTIONS (חיבורים):

4e83ec8a339cda08.png

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

8126ec78c343f199.png

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

7baf980463a86a5c.png

  1. לוחצים על CREATE (יצירה). המחבר הזה אמור להופיע עכשיו בהגדרות היציאה.
  2. בוחרים את המחבר החדש שנוצר
  3. בוחרים שכל התנועה תנותב דרך מחבר ה-VPC הזה.
  4. לוחצים על הבא ואז על פריסה.

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 .

והתוצאה:

88bc1ddfb5644a28.png

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

הכלי ליצירת סוכנים בממשק שיחה נבנה!

הנציג נוצר בחלק 2 של שיעור ה-Lab הזה.

12. הסרת המשאבים

אם אתם מתכננים להשלים את חלק 2 של שיעור ה-Lab הזה, דלגו על השלב הזה כי הוא יגרום למחיקת הפרויקט הנוכחי.

כדי לא לצבור חיובים לחשבון Google Cloud על המשאבים שבהם השתמשתם במאמר הזה:

  1. במסוף Google Cloud, עוברים לדף Manage resources.
  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

13. מזל טוב

מעולה! ביצעתם בהצלחה חיפוש דמיון באמצעות AlloyDB, ‏ pgvector וחיפוש וקטורי. באמצעות שילוב היכולות של AlloyDB,‏ Vertex AI ו-Vector Search, עשינו קפיצת מדרגה משמעותית בהנגשת חיפושים לפי הקשר וחיפושים וקטוריים, והפכנו אותם ליעילים ולמבוססים על משמעות אמיתית. בחלק הבא של שיעור ה-Lab מוסבר איך ליצור סוכן.