1. סקירה כללית
בתעשיות שונות, חיפוש הקשרי הוא פונקציונליות קריטית שמהווה את הליבה של האפליקציות שלהן. Retrieval Augmented Generation (שליפה משופרת גנרטיבית) הוא מנוע מרכזי בהתפתחות הטכנולוגית החשובה הזו כבר זמן רב, עם מנגנוני השליפה שלו שמבוססים על AI גנרטיבי. מודלים גנרטיביים, עם חלונות הקשר גדולים ואיכות פלט מרשימה, משנים את תחום ה-AI. טכנולוגיית RAG מספקת דרך שיטתית להוספת הקשר לאפליקציות ולסוכנים מבוססי-AI, ומבססת אותם על מסדי נתונים מובְנים או על מידע ממדיה שונים. הנתונים ההקשריים האלה חיוניים כדי להבהיר את האמת ולשפר את הדיוק של הפלט, אבל עד כמה התוצאות האלה מדויקות? האם העסק שלך תלוי במידה רבה בדיוק של ההתאמות ההקשריות והרלוונטיות האלה? אז הפרויקט הזה יתאים לכם בול!
הסוד המלוכלך של חיפוש וקטורי הוא לא רק בנייתו, אלא גם הידיעה אם ההתאמות הווקטוריות טובות באמת. כולנו היינו במצב הזה, בוהים ברשימת תוצאות וחושבים לעצמנו: 'האם זה בכלל עובד?!' בואו נבדוק איך אפשר להעריך את האיכות של התאמות וקטוריות. מה השתנה ב-RAG? הכל! במשך שנים, יצירה משולבת-אחזור (RAG) נראתה כמו יעד מבטיח אבל חמקמק. עכשיו, סוף סוף, יש לנו את הכלים לבניית אפליקציות RAG עם הביצועים והאמינות שנדרשים למשימות קריטיות.
עכשיו יש לנו כבר ידע בסיסי לגבי 3 דברים:
- מהו חיפוש הקשרי לסוכן ואיך מבצעים אותו באמצעות חיפוש וקטורי.
- בנוסף, נכנסנו לעומק של השגת חיפוש וקטורי במסגרת הנתונים שלכם, כלומר במסגרת מסד הנתונים עצמו (כל מסדי הנתונים של Google Cloud תומכים בכך, אם לא ידעתם!).
- אנחנו עשינו צעד נוסף מעבר למה שנעשה בשאר העולם, והסברנו איך אפשר להשיג יכולת RAG קלה של חיפוש וקטורי עם ביצועים ואיכות גבוהים באמצעות יכולת החיפוש הווקטורי של AlloyDB שמבוססת על אינדקס ScaNN.
אם לא קראתם את המאמרים על ניסויי RAG ברמות הבסיסית, הבינונית והמתקדמת, מומלץ לקרוא אותם כאן, כאן וכאן, לפי הסדר שמופיע.
חיפוש פטנטים עוזר למשתמשים למצוא פטנטים שרלוונטיים מבחינת ההקשר לטקסט החיפוש שלהם, וכבר בנינו גרסה של התכונה הזו בעבר. עכשיו נבנה אותו באמצעות תכונות חדשות ומתקדמות של RAG שמאפשרות חיפוש הקשרי עם בקרת איכות לאפליקציה הזו. קדימה, מתחילים!
בתמונה שלמטה מוצג התהליך הכולל של מה שקורה באפליקציה הזו.~ 
מטרה
לאפשר למשתמש לחפש פטנטים על סמך תיאור טקסטואלי עם ביצועים משופרים ואיכות טובה יותר, תוך אפשרות להעריך את איכות ההתאמות שנוצרו באמצעות התכונות העדכניות של RAG ב-AlloyDB.
מה תפַתחו
במסגרת ה-Lab הזה:
- יצירה של מכונת AlloyDB וטעינה של מערך הנתונים הציבורי של פטנטים
- יצירת אינדקס של מטא-נתונים ואינדקס ScaNN
- הטמעה של חיפוש וקטורים מתקדם ב-AlloyDB באמצעות שיטת הסינון המובנית של ScaNN
- הטמעה של תכונת הערכת ההחזרה
- בדיקת התשובה לשאילתה
דרישות
2. לפני שמתחילים
יצירת פרויקט
- ב-מסוף Google Cloud, בדף לבחירת הפרויקט, בוחרים או יוצרים פרויקט ב-Google Cloud.
- הקפידו לוודא שהחיוב מופעל בפרויקט שלכם ב-Cloud. כך בודקים אם החיוב מופעל בפרויקט
- תשתמשו ב-Cloud Shell, סביבת שורת פקודה שפועלת ב-Google Cloud. לוחצים על 'הפעלת 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 בטרמינל של Cloud Shell:
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.
אפשר לעיין במאמרי העזרה בנושא פקודות gcloud ושימוש בהן.
3. הגדרת מסד נתונים
בשיעור ה-Lab הזה נשתמש ב-AlloyDB כמסד הנתונים של נתוני הפטנטים. הוא משתמש באשכולות כדי להכיל את כל המשאבים, כמו מסדי נתונים ויומנים. לכל אשכול יש מופע ראשי שמספק נקודת גישה לנתונים. הטבלאות יכילו את הנתונים בפועל.
ניצור אשכול, מכונה וטבלה של AlloyDB שבהם ייטען מערך הנתונים של הפטנטים.
יצירת אשכול ומופע
- עוברים לדף AlloyDB במסוף Cloud. דרך קלה למצוא את רוב הדפים ב-Cloud Console היא לחפש אותם באמצעות סרגל החיפוש של המסוף.
- בדף הזה, לוחצים על CREATE CLUSTER (יצירת אשכול):

- יוצג מסך כמו זה שבהמשך. יוצרים אשכול ומופע עם הערכים הבאים (אם משכפלים את קוד האפליקציה מהמאגר, חשוב לוודא שהערכים זהים):
- cluster id: "
vector-cluster" - password: "
alloydb" - PostgreSQL 15 / הגרסה המומלצת האחרונה
- אזור: "
us-central1" - רשת: "
default"

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

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

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

חשוב לשנות את מזהה המופע (שאפשר למצוא בזמן ההגדרה של האשכול או המופע) ל
vector-instance. אם אי אפשר לשנות אותו, חשוב להשתמש במזהה המכונה בכל ההפניות הבאות.
שימו לב: תהליך יצירת האשכול יימשך כ-10 דקות. אחרי שהפעולה תצליח, יופיע מסך עם סקירה כללית של האשכול שיצרתם.
4. הטמעת נתונים
עכשיו צריך להוסיף טבלה עם הנתונים על החנות. עוברים אל 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 שבהמשך ב-AlloyDB Studio:
CREATE TABLE patents_data ( id VARCHAR(25), type VARCHAR(25), number VARCHAR(20), country VARCHAR(2), date VARCHAR(20), abstract VARCHAR(300000), title VARCHAR(100000), kind VARCHAR(5), num_claims BIGINT, filename VARCHAR(100), withdrawn BIGINT, abstract_embeddings vector(768)) ;
בעמודה abstract_embeddings אפשר לאחסן את ערכי הווקטור של הטקסט.
מתן הרשאה
מריצים את ההצהרה הבאה כדי להעניק הרשאת הפעלה לפונקציה embedding:
GRANT EXECUTE ON FUNCTION embedding TO postgres;
הענקת התפקיד Vertex AI User לחשבון השירות של AlloyDB
במסוף IAM של Google Cloud, מעניקים לחשבון השירות של AlloyDB (שנראה כך: service-<<PROJECT_NUMBER>>@gcp-sa-alloydb.iam.gserviceaccount.com) גישה לתפקיד Vertex AI User. PROJECT_NUMBER יכיל את מספר הפרויקט.
לחלופין, אפשר להריץ את הפקודה הבאה מ-Cloud Shell Terminal:
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"
טעינת נתוני פטנטים למסד הנתונים
נשתמש ב-Google Patents Public Datasets ב-BigQuery כמערך הנתונים שלנו. נשתמש ב-AlloyDB Studio כדי להריץ את השאילתות. הנתונים מגיעים מקובץ insert_scripts.sql הזה, ואנחנו נריץ אותו כדי לטעון את נתוני הפטנטים.
- במסוף Google Cloud, פותחים את הדף AlloyDB.
- בוחרים את האשכול החדש שנוצר ולוחצים על המופע.
- בתפריט הניווט של AlloyDB, לוחצים על AlloyDB Studio. מתחברים באמצעות פרטי הכניסה.
- לוחצים על סמל הכרטיסייה החדשה בצד שמאל כדי לפתוח כרטיסייה חדשה.
- מעתיקים את הצהרת השאילתה
insertמהסקריפטinsert_scripts.sqlשצוין למעלה אל הכלי לעריכת סקריפטים. אפשר להעתיק 10-50 הצהרות של insert כדי ליצור הדגמה מהירה של תרחיש השימוש הזה. - לוחצים על Run. התוצאות של השאילתה יופיעו בטבלה Results.
הערה: יכול להיות שתשימו לב שהסקריפט להוספה מכיל הרבה נתונים. הסיבה לכך היא שכללנו הטמעות בסקריפטים של התוסף. אם יש בעיות בטעינת הקובץ ב-GitHub, לוחצים על View Raw (הצגת קובץ גולמי). הפעולה הזו מתבצעת כדי שלא תצטרכו (בשלבים הבאים) ליצור יותר מכמה הטמעות (נניח 20-25 לכל היותר) אם אתם משתמשים בחשבון לחיוב עם קרדיט לתקופת ניסיון ב-Google Cloud.
5. יצירת הטמעות לנתוני פטנטים
קודם נבדוק את פונקציית ההטמעה על ידי הרצת שאילתת הדוגמה הבאה:
SELECT embedding('text-embedding-005', 'AlloyDB is a managed, cloud-hosted SQL database service.');
הפונקציה אמורה להחזיר את וקטור ההטמעה, שנראה כמו מערך של מספרים ממשיים, עבור טקסט הדוגמה בשאילתה. כך זה נראה:

עדכון שדה הווקטור abstract_embeddings
מריצים את פקודת ה-DML הבאה כדי לעדכן את תקצירי הפטנטים בטבלה עם ההטמעות המתאימות, רק אם לא הוספתם את נתוני ה-abstract_embeddings כחלק מסקריפט ההוספה:
UPDATE patents_data set abstract_embeddings = embedding( 'text-embedding-005', abstract);
אם אתם משתמשים בחשבון לחיוב עם קרדיט לתקופת ניסיון ב-Google Cloud, יכול להיות שתתקשו ליצור יותר מכמה הטמעות (נניח 20-25 לכל היותר). לכן, כבר כללתי את ההטמעות בסקריפטים של ההוספה, והן אמורות להיות בטבלה שנטענה אם השלמת את השלב 'טעינת נתוני פטנטים למסד הנתונים'.
6. ביצוע RAG מתקדם באמצעות התכונות החדשות של AlloyDB
עכשיו, אחרי שהטבלה, הנתונים וההטמעות מוכנים, אפשר לבצע חיפוש וקטורי בזמן אמת של טקסט החיפוש של המשתמש. כדי לבדוק את זה, מריצים את השאילתה הבאה:
SELECT id || ' - ' || title as title FROM patents_data ORDER BY abstract_embeddings <=> embedding('text-embedding-005', 'Sentiment Analysis')::vector LIMIT 10;
בשאלת החיפוש הזו,
- הטקסט שחיפש המשתמש הוא: "Sentiment Analysis".
- אנחנו ממירים אותו להטמעות בשיטה embedding() באמצעות המודל: text-embedding-005.
- "<=>" מייצג את השימוש בשיטת המרחק COSINE SIMILARITY.
- אנחנו ממירים את התוצאה של שיטת ההטמעה לסוג וקטור כדי שתהיה תואמת לווקטורים שמאוחסנים במסד הנתונים.
- LIMIT 10 מייצג את העובדה שאנחנו בוחרים את 10 ההתאמות הכי קרובות לטקסט החיפוש.
AlloyDB מעלה את RAG של חיפוש וקטורי לרמה הבאה:
יש מספר רב של דברים חדשים. שני תגים שמתמקדים במפתחים הם:
- סינון בתוך השורה
- כלי להערכת זכירת המודעה
סינון בתוך השורה
בעבר, מפתחים היו צריכים להריץ את שאילתת החיפוש הווקטורי ולטפל בסינון ובאחזור. הכלי AlloyDB Query Optimizer בוחר איך להריץ שאילתה עם מסננים. סינון מוטבע הוא טכניקה חדשה לאופטימיזציה של שאילתות, שמאפשרת לאופטימיזטור של שאילתות ב-AlloyDB להעריך את תנאי הסינון של המטא-נתונים ואת החיפוש הווקטורי בו-זמנית, תוך שימוש באינדקסים וקטוריים ובאינדקסים בעמודות המטא-נתונים. כך משתפרים ביצועי ההחזרה, ומפתחים יכולים ליהנות ממה ש-AlloyDB מציע כבר מההתחלה.
סינון מוטבע מתאים במיוחד למקרים עם סלקטיביות בינונית. במהלך החיפוש במדד הווקטורים, AlloyDB מחשב מרחקים רק לווקטורים שתואמים לתנאי הסינון של המטא-נתונים (המסננים הפונקציונליים בשאילתה, שמטופלים בדרך כלל בסעיף WHERE). השיפור הזה משפר משמעותית את הביצועים של השאילתות האלה, ומשלים את היתרונות של סינון אחרי או לפני.
- התקנה או עדכון של התוסף pgvector
CREATE EXTENSION IF NOT EXISTS vector WITH VERSION '0.8.0.google-3';
אם התוסף pgvector כבר מותקן, צריך לשדרג את תוסף הווקטור לגרסה 0.8.0.google-3 ואילך כדי לקבל יכולות של כלי להערכת היזכרות.
ALTER EXTENSION vector UPDATE TO '0.8.0.google-3';
צריך לבצע את השלב הזה רק אם התוסף של הווקטור הוא <0.8.0.google-3>.
הערה חשובה: אם מספר השורות קטן מ-100, לא צריך ליצור את אינדקס ScaNN כי הוא לא רלוונטי למספר קטן יותר של שורות. במקרה כזה, אפשר לדלג על השלבים הבאים.
- כדי ליצור אינדקסים של ScaNN, צריך להתקין את התוסף alloydb_scann.
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
- קודם מריצים את שאילתת החיפוש הווקטורי בלי האינדקס ובלי המסנן המוטמע:
SELECT id || ' - ' || title as title FROM patents_data
WHERE num_claims >= 15
ORDER BY abstract_embeddings <=> embedding('text-embedding-005', 'Sentiment Analysis')::vector LIMIT 10;
התוצאה צריכה להיות דומה ל:

- מריצים עליו את Explain Analyze: (ללא אינדקס וללא סינון מוטבע)

זמן הביצוע הוא 2.4 אלפיות השנייה
- ניצור אינדקס רגיל בשדה num_claims כדי שנוכל לסנן לפי השדה הזה:
CREATE INDEX idx_patents_data_num_claims ON patents_data (num_claims);
- בואו ניצור את אינדקס ScaNN לאפליקציית חיפוש הפטנטים שלנו. מריצים את הפקודה הבאה מ-AlloyDB Studio:
CREATE INDEX patent_index ON patents_data
USING scann (abstract_embeddings cosine)
WITH (num_leaves=32);
הערה חשובה: (num_leaves=32) רלוונטי למערך הנתונים הכולל שלנו עם יותר מ-1,000 שורות. אם מספר השורות קטן מ-100, לא צריך ליצור אינדקס כי הוא לא רלוונטי למספר קטן יותר של שורות.
- הגדרת סינון מוטבע שמופעל באינדקס ScaNN:
SET scann.enable_inline_filtering = on
- עכשיו נריץ את אותה שאילתה עם מסנן וחיפוש וקטורי:
SELECT id || ' - ' || title as title FROM patents_data
WHERE num_claims >= 15
ORDER BY abstract_embeddings <=> embedding('text-embedding-005', 'Sentiment Analysis')::vector LIMIT 10;

כפי שאפשר לראות, זמן הביצוע של אותו חיפוש וקטורי קוצר באופן משמעותי. האינדקס של ScaNN עם סינון מוטמע ב-חיפוש וקטורי מאפשר לעשות את זה!!!
עכשיו נבדוק את ה-recall של חיפוש וקטורי עם ScaNN.
כלי להערכת זכירת המודעה
ההחזרה בחיפוש דמיון היא אחוז המקרים הרלוונטיים שאותרו בחיפוש, כלומר מספר התוצאות החיוביות האמיתיות. זהו המדד הנפוץ ביותר למדידת איכות החיפוש. אחד הגורמים לאובדן של recall הוא ההבדל בין חיפוש של השכן הקרוב המשוער (aNN) לבין חיפוש של השכן הקרוב k (מדויק) (kNN). אינדקסים וקטוריים כמו ScaNN של AlloyDB מיישמים אלגוריתמים של חיפוש שכנים קרובים (aNN), ומאפשרים לכם להאיץ את החיפוש הווקטורי במערכי נתונים גדולים בתמורה לפשרה קטנה בזיכרון. מעכשיו, ב-AlloyDB יש לכם אפשרות למדוד את האיזון הזה ישירות במסד הנתונים עבור שאילתות ספציפיות, ולוודא שהוא נשאר יציב לאורך זמן. אפשר לעדכן את הפרמטרים של השאילתה והאינדקס בהתאם למידע הזה כדי לשפר את התוצאות והביצועים.
מהי הלוגיקה שמאחורי שליפת תוצאות חיפוש?
בהקשר של חיפוש וקטורי, recall (החזרה) מתייחס לאחוז הווקטורים שהאינדקס מחזיר שהם השכנים הקרובים האמיתיים. לדוגמה, אם שאילתת שכנים קרובים לגבי 20 השכנים הקרובים ביותר מחזירה 19 מהשכנים הקרובים ביותר של נתוני האמת, אז ה-recall הוא 19/20x100 = 95%. החזרה היא המדד שמשמש לאיכות החיפוש, והיא מוגדרת כאחוז התוצאות שהוחזרו שהן הכי קרובות באופן אובייקטיבי לווקטורים של השאילתה.
אפשר למצוא את הזיכרון של שאילתת וקטור באינדקס וקטור עבור הגדרה נתונה באמצעות הפונקציה evaluate_query_recall. הפונקציה הזו מאפשרת לכם לכוונן את הפרמטרים כדי להשיג את תוצאות ההחזרה של שאילתת הווקטור שאתם רוצים.
הערה חשובה:
אם נתקלתם בשגיאה 'ההרשאה נדחתה' באינדקס HNSW בשלבים הבאים, דלגו כרגע על כל הקטע הערכת ההחזרה. יכול להיות שזה קשור להגבלות גישה בשלב הזה, כי הוא רק הושק בזמן שבו נכתב ה-codelab הזה.
- מגדירים את הדגל Enable Index Scan באינדקס ScaNN ובאינדקס HNSW:
SET scann.enable_indexscan = on
SET hnsw.enable_index_scan = on
- מריצים את השאילתה הבאה ב-AlloyDB Studio:
SELECT
*
FROM
evaluate_query_recall($$
SELECT
id || ' - ' || title AS title,
abstract
FROM
patents_data
where num_claims >= 15
ORDER BY
abstract_embeddings <=> embedding('text-embedding-005',
'sentiment analysis')::vector
LIMIT 25 $$,
'{"scann.num_leaves_to_search":1, "scann.pre_reordering_num_neighbors":10}',
ARRAY['scann']);
הפונקציה evaluate_query_recall מקבלת את השאילתה כפרמטר ומחזירה את הזיכרון שלה. אני משתמש באותה שאילתה שבה השתמשתי כדי לבדוק את הביצועים כשאילתת הקלט של הפונקציה. הוספתי את SCaNN כשיטת האינדקס. אפשרויות נוספות לפרמטרים מפורטות במאמרי העזרה.
ההחזרה של שאילתת חיפוש הווקטורים הזו שבה השתמשנו:

אני רואה שה-RECALL הוא 70%. עכשיו אוכל להשתמש במידע הזה כדי לשנות את פרמטרים האינדקס, השיטות והפרמטרים של השאילתה, ולשפר את ההחזרה של התוצאות בחיפוש הווקטורי הזה.
7. בדיקה באמצעות שאילתה ופרמטרים של אינדקס שעברו שינוי
עכשיו נבדוק את השאילתה על ידי שינוי פרמטרים של שאילתה על סמך ה-recall שקיבלנו.
- שיניתי את מספר השורות בערכת התוצאות ל-7 (לעומת 25 קודם) ואני רואה שיפור בזיכרון, כלומר 86%.

המשמעות היא שאני יכול לשנות בזמן אמת את מספר ההתאמות שמוצגות למשתמשים כדי לשפר את הרלוונטיות של ההתאמות בהתאם להקשר החיפוש של המשתמשים.
- ננסה שוב על ידי שינוי הפרמטרים של האינדקס:
בבדיקה הזו, אשתמש ב"מרחק L2" במקום בפונקציית מרחק הדמיון "קוסינוס". אשנה גם את מגבלת השאילתה ל-10 כדי להראות אם יש שיפור באיכות של תוצאות החיפוש גם עם מספר גדול יותר של תוצאות חיפוש.
[BEFORE] שאילתה שמשתמשת בפונקציית המרחק של דמיון קוסינוס:
SELECT
*
FROM
evaluate_query_recall($$
SELECT
id || ' - ' || title AS title,
abstract
FROM
patents_data
where num_claims >= 15
ORDER BY
abstract_embeddings <=> embedding('text-embedding-005',
'sentiment analysis')::vector
LIMIT 10 $$,
'{"scann.num_leaves_to_search":1, "scann.pre_reordering_num_neighbors":10}',
ARRAY['scann']);
הערה חשובה מאוד: "איך אנחנו יודעים שהשאילתה הזו משתמשת בדמיון קוסינוס?" אתם שואלים. אפשר לזהות את פונקציית המרחק לפי השימוש בסימן "<=>" שמייצג את מרחק הקוסינוס.
קישור ל-Docs לפונקציות של מרחק בחיפוש וקטורי.
התוצאה של השאילתה שלמעלה היא:

כפי שאפשר לראות, ערך ה-RECALL הוא 70% בלי לבצע שינוי בלוגיקה של האינדקס. זוכרים את אינדקס ScaNN שיצרנו בשלב 6 בקטע 'patent_index'? אותו אינדקס עדיין בתוקף בזמן שהרצנו את השאילתה שלמעלה.
עכשיו ניצור אינדקס עם שאילתה שמשתמשת בפונקציית מרחק אחרת: מרחק L2: <->
drop index patent_index;
CREATE INDEX patent_index_L2 ON patents_data
USING scann (abstract_embeddings L2)
WITH (num_leaves=32);
ההצהרה drop index נועדה לוודא שאין אינדקס מיותר בטבלה.
עכשיו אפשר להריץ את השאילתה הבאה כדי להעריך את ה-RECALL אחרי שינוי פונקציית המרחק של הפונקציונליות של חיפוש וקטורים.
[AFTER] שאילתה שמשתמשת בפונקציית המרחק של דמיון קוסינוס:
SELECT
*
FROM
evaluate_query_recall($$
SELECT
id || ' - ' || title AS title,
abstract
FROM
patents_data
where num_claims >= 15
ORDER BY
abstract_embeddings <-> embedding('text-embedding-005',
'sentiment analysis')::vector
LIMIT 10 $$,
'{"scann.num_leaves_to_search":1, "scann.pre_reordering_num_neighbors":10}',
ARRAY['scann']);
התוצאה של השאילתה שלמעלה היא:

איזה שינוי מדהים בערך ההחזרה, 90%!!!
יש עוד פרמטרים שאפשר לשנות באינדקס, כמו num_leaves וכו', על סמך ערך ההחזרה הרצוי ומערך הנתונים שבו האפליקציה משתמשת.
8. הסרת המשאבים
כדי לא לצבור חיובים לחשבון Google Cloud על המשאבים שבהם השתמשתם במאמר הזה:
- במסוף Google Cloud, עוברים לדף resource manager.
- ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
- כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.
- לחלופין, אפשר פשוט למחוק את אשכול AlloyDB (אם לא בחרתם במיקום us-central1 לאשכול בזמן ההגדרה, צריך לשנות את המיקום בהיפר-קישור הזה) שיצרנו זה עתה לפרויקט הזה, על ידי לחיצה על הלחצן DELETE CLUSTER (מחיקת האשכול).
9. מזל טוב
מעולה! יצרתם בהצלחה שאילתת חיפוש פטנטים לפי הקשר באמצעות חיפוש וקטורי מתקדם ב-AlloyDB, כדי להשיג ביצועים גבוהים ולבסס את החיפוש על משמעות. יצרתי אפליקציה מרובת-כלים מבוססת-סוכנים עם בקרת איכות, שמשתמשת ב-ADK ובכל מה שקשור ל-AlloyDB שדיברנו עליו כאן, כדי ליצור סוכן לחיפוש וניתוח וקטורים של פטנטים עם ביצועים גבוהים ואיכותיים. אפשר לצפות בסרטון כאן: https://youtu.be/Y9fvVY0yZTY
אם רוצים ללמוד איך ליצור סוכן כזה, אפשר לעיין ב-codelab הזה.