שימוש ב-Vector Search 2.0 עם RAG

בדף הזה מוסבר איך מנוע ה-RAG ב-Gemini Enterprise Agent Platform משתמש ב-Vector Search 2.0 ב-Gemini Enterprise Agent Platform, מוצר של Cloud de Confiance by S3NS שמשמש כמערכת מקיפה לאחסון ולאחזור של ייצוגים וקטוריים של המסמכים שלכם. ‫Gemini Enterprise Agent Platform חיפוש וקטורי 2.0 משמש לאחזור מסמכים רלוונטיים על סמך הדמיון הסמנטי של המסמך לשאילתה נתונה.

‫RAG ינהל בשבילכם את האוספים של חיפוש וקטורי 2.0, ותהיה לכם גישה מלאה לאוספים של חיפוש וקטורי 2.0 בפרויקט.

בחירת קצה עורפי של RAG

כשמשתמשים ב-RAG Engine ב-Gemini Enterprise Agent Platform, אפשר לבחור בין אפשרויות שונות של אחסון בקצה העורפי לקורפוסים של RAG. בטבלה הבאה מסוכמים ההבדלים העיקריים:

אפשרות לקצה העורפי הטכנולוגיה הבסיסית ניהול באמצעות מנוע RAG הרשאות הגישה לנתונים בפרויקט תמיכה ב-CMEK
RagManagedVertexVectorSearch ‫Gemini Enterprise Agent Platform חיפוש וקטורי 2.0 מנוהל באופן מלא על ידי Google. גלוי בפרויקט ב- Cloud de Confiance by S3NS לא
VertexVectorSearch ‫Gemini Enterprise Agent Platform חיפוש וקטורי 1.0 המשתמש אמור להגדיר, לנהל ולנקות את המכונה של חיפוש וקטורי 1.0. גלוי בפרויקט ב- Cloud de Confiance by S3NS לא
RagManagedDb Spanner מנוהל באופן מלא על ידי Google. לא גלויים ישירות בפרויקט כן

כדאי לבחור ב-RagManagedVertexVectorSearch כדי ליהנות מהתכונות העדכניות ביותר, מניהול אוטומטי ומשקיפות בנתונים של Vector Search 2.0. אם התמיכה ב-CMEK היא דרישה מחמירה, כדאי לשקול את RagManagedDb, תוך התחשבות בחוסר הניראות הישירה למסד הנתונים בקצה העורפי.

הפעלת Vector Search API

כדי להשתמש ב-RAG Managed Gemini Enterprise Agent Platform חיפוש וקטורי, קודם צריך להפעיל את Vector Search API.

יצירת קורפוס RAG באמצעות RagManagedVertexVectorSearch

בדוגמת הקוד הזו מוסבר איך ליצור קורפוס RAG באמצעות RagManagedVertexVectorSearch.

Python

from vertexai.preview import rag
import vertexai

PROJECT_ID = YOUR_PROJECT_ID
LOCATION = YOUR_RAG_ENGINE_LOCATION
DISPLAY_NAME = YOUR_RAG_CORPUS_DISPLAY_NAME

# Initialize Agent Platform API once per session
vertexai.init(project=PROJECT_ID, location=LOCATION)

vector_db = rag.RagManagedVertexVectorSearch()
rag_corpus = rag.create_corpus(
    display_name=DISPLAY_NAME, backend_config=rag.RagVectorDbConfig(vector_db=vector_db))

REST

מחליפים את המשתנים הבאים:

  • ‫PROJECT_ID: מזהה הפרויקט.
  • ‫LOCATION: האזור שבו הבקשה תעובד.
  • ‫CORPUS_DISPLAY_NAME: השם המוצג של קורפוס ה-RAG.
PROJECT_ID=PROJECT_ID
LOCATION=LOCATION
CORPUS_DISPLAY_NAME=CORPUS_DISPLAY_NAME

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/ragCorpora \
-d '{
      "display_name" : '\""${CORPUS_DISPLAY_NAME}"\"',
      "vector_db_config": {
        "rag_managed_vertex_vector_search": {}
      }
    }'

ייבוא הנתונים אל RagManagedVertexVectorSearch

כדי לייבא את הנתונים אל RagManagedVertexVectorSearch, אתם יכולים להשתמש ב-API של ImportRagFiles או ב-API של UploadRagFile.

כדי להעלות קובץ מקומי לקורפוס RAG, קראו את המאמר העלאת קובץ RAG. כדי לייבא נתונים לקורפוס RAG, אפשר להיעזר בדוגמת הקוד הבאה שמראה איך לייבא מ-Cloud Storage. מידע נוסף על מקורות הנתונים שנתמכים ב-RAG

Python

from vertexai.preview import rag
import vertexai

PROJECT_ID = YOUR_PROJECT_ID
LOCATION = YOUR_RAG_ENGINE_LOCATION
CORPUS_ID = YOUR_CORPUS_ID
PATHS = ["gs://my_bucket/my_files_dir"]

# Initialize Agent Platform API once per session
vertexai.init(project=PROJECT_ID, location=LOCATION)

corpus_name = f"projects/{PROJECT_ID}/locations/{LOCATION}/ragCorpora/{CORPUS_ID}"
# This is a non blocking call.
response = await rag.import_files_async(
    corpus_name=corpus_name,
    paths=PATHS,
)

# Wait for the import to complete.
await response.result()

REST

GCS_URI=GCS_URI

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/ragCorpora/${CORPUS_ID}/ragFiles:import \
-d '{
  "import_rag_files_config": {
    "gcs_source": {
      "uris": '\""${GCS_URI}"\"',
      },
  }
}'

יצירת אינדקס לקורפוס

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

סריקה גסה איטית יותר מחיפוש באינדקס, ו-KNN פועל רק על אוספים של עד 100,000 אובייקטים של נתונים. מנוע ה-RAG מאחסן מקטע אחד לכל אובייקט נתונים, כך שברגע שקורפוס חורג מהמגבלה הזו, השליפה נכשלת עד שנוצר אינדקס.

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

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

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

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

כדי ליצור אינדקס, צריך את ההרשאה vectorsearch.indexes.create באוסף, וכדי לספור את אובייקטי הנתונים שלו צריך את ההרשאה vectorsearch.dataObjects.query. שתי ההרשאות נכללות בתפקיד 'אדמין ב-חיפוש וקטורי'‏ (roles/vectorsearch.admin). התפקיד 'בעל הרשאת כתיבה באינדקס החיפוש הווקטורי'‏ (roles/vectorsearch.indexWriter) נותן את ההרשאה הראשונה. צריך גם להפעיל בפרויקט את Vector Search API.

איך מוצאים את מזהי הקורפוסים

בפרויקט, לכל קורפוס יש בדיוק אוסף אחד בשם vertex-rag-RAG_CORPUS_ID. מציגים את רשימת הקורפוסים כדי לקבל את המזהים שלהם.

מחליפים את PROJECT_ID במזהה הפרויקט:

PROJECT_ID=PROJECT_ID
LOCATION=us-central1

curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/ragCorpora?pageSize=100"

החלק המספרי בסוף כל קורפוס name הוא RAG_CORPUS_ID. כל קורפוס מדווח גם על שם המשאב המלא של האוסף ב-vectorDbConfig.ragManagedVertexVectorSearch.collectionName.

התשובה כוללת עד 100 קורפוסים, ועד 25 אם משמיטים את pageSize. אם התגובה כוללת nextPageToken, מעבירים את הערך הזה בתור pageToken כדי לאחזר את הדף הבא.

אם אתם כבר יודעים איזה RAG_CORPUS_ID אתם רוצים להוסיף לאינדקס, אחזרו רק את הקורפוס הזה. התגובה כוללת את אותו collectionName:

curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/ragCorpora/RAG_CORPUS_ID"

בחירת מאגרי הנתונים שרוצים להוסיף לאינדקס

בכל קורפוס, סופרים את אובייקטי הנתונים באוסף שלו. מעבירים filter ריק כדי לספור את כל האוסף:

COLLECTION_ID=vertex-rag-RAG_CORPUS_ID

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://vectorsearch.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/collections/${COLLECTION_ID}/dataObjects:aggregate" \
-d '{"aggregate": "COUNT", "filter": {}}'

הספירה מוחזרת ב-aggregateResults:

{
  "aggregateResults": [
    {
      "count": 95217
    }
  ]
}

יוצרים אינדקס למאגר הזה אם מתקיים אחד מהתנאים הבאים:

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

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

בדיקת הסכימה של Collection

מנוע RAG יוצר כל אוסף עם הסכימה הבאה. השתמשו בשמות האלה כשאתם מציינים את שדה האינדקס ואת שדות הסינון.

שדה סוג תיאור
text_embedding וקטור צפוף ההטמעה של החלק. זה השדה שמוסיפים לאינדקס. מספר המאפיינים תואם למודל ההטמעה של הקורפוס.
corpus_id String המזהה של קורפוס ה-RAG.
file_id String המזהה של קובץ ה-RAG שממנו הגיע החלק.
chunk_id String המזהה של החלק.
chunk_data String הטקסט של החלק.
chunk_data_type String סוג הנתונים של המקטע.
file_original_uri String ה-URI המקורי של קובץ המקור.
rag_metadata String מטא-נתונים שהמשתמש סיפק לחלק.

בוחרים את הגדרות האינדקס.

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

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

מדד מרחק: מגדירים אותו לקוסינוס. מנוע ה-RAG תמיד שולח את COSINE_DISTANCE בבקשות האחזור שלו, ו-חיפוש וקטורי 2.0 דוחה בקשות אחזור שהמדד שלהן לא תואם לאינדקס. אם לא מציינים את המדד, ברירת המחדל היא DOT_PRODUCT. לכן, אם יוצרים אינדקס בלי המדד, אי אפשר לאחזר נתונים מהקורפוס הזה. מנוע RAG מדווח על הכישלון בתור FAILED_PRECONDITION עם ההודעה Failed to process Rag Managed Vertex Vector Search response., שלא מזהה את המדד כגורם. האיות משתנה בהתאם לפלטפורמה: גוף ה-REST מקבל את COSINE_DISTANCE, והדגל של ה-CLI של gcloud מקבל את cosine-distance.

תשתית: משאירים את האינדקס בתשתית שמוגדרת כברירת מחדל ועברה אופטימיזציה לביצועים, כי מרחק קוסינוס לא נתמך בתשתית שעברה אופטימיזציה לאחסון. אינדקס פועל בתשתית ייעודית להצגת מודעות, והחיוב עליו מתבצע כל עוד הוא קיים. ב-v1, ערכי ברירת המחדל של min_replica_count ו-max_replica_count הם 2, כך שכברירת מחדל האינדקס מוגש על ידי שתי רפליקות ולא מותאם אוטומטית לעומס. מידע נוסף זמין במאמר אינדקסים של אוספים.

שדות סינון: מגדירים את filter_fields ל-file_id בלבד. זה השדה היחיד ש-RAG Engine מסנן בזמן האחזור, ורק כשבקשת האחזור מגבילה את החיפוש לקבצים ספציפיים. באופן ספציפי, הערך של corpus_id זהה בכל אובייקט נתונים באוסף נתון, ולכן סינון לפי המאפיין הזה לא מועיל.

בנוסף, בסינון מטא-נתונים אין צורך בשדות סינון נוספים. כשבקשת אחזור מגדירה את ragRetrievalConfig.filter.metadataFilter, מנוע RAG פותר קודם את המסנן לפי המטא-נתונים של הקובץ, ממיר את התוצאה לקבוצה של מזהי קובצי RAG תואמים ושולח את הקבוצה הזו לחיפוש וקטורי בתור אותו מסנן file_id. הוספת rag_metadata אל filter_fields מגדילה את גודל האינדקס בלי לשנות את השליפה.

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

יצירת האינדקס

Python

מחליפים את המשתנים הבאים:

  • ‫PROJECT_ID: מזהה הפרויקט.
  • ‫RAG_CORPUS_ID: המזהה של קורפוס ה-RAG שרוצים להוסיף לאינדקס.
from google.cloud import vectorsearch_v1

client = vectorsearch_v1.VectorSearchServiceClient()

index = vectorsearch_v1.Index(
    index_field="text_embedding",
    distance_metric=vectorsearch_v1.DistanceMetric.COSINE_DISTANCE,
    filter_fields=["file_id"],
)
request = vectorsearch_v1.CreateIndexRequest(
    parent="projects/PROJECT_ID/locations/us-central1/collections/vertex-rag-RAG_CORPUS_ID",
    index_id="vertex-rag-RAG_CORPUS_ID-index",
    index=index,
)

operation = client.create_index(request=request)

# Wait for the result (note this may take up to several minutes).
operation.result()

REST

מחליפים את המשתנים הבאים:

  • ‫PROJECT_ID: מזהה הפרויקט.
  • ‫RAG_CORPUS_ID: המזהה של קורפוס ה-RAG שרוצים להוסיף לאינדקס.
PROJECT_ID=PROJECT_ID
RAG_CORPUS_ID=RAG_CORPUS_ID
LOCATION=us-central1
COLLECTION_ID=vertex-rag-${RAG_CORPUS_ID}
INDEX_ID=${COLLECTION_ID}-index

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://vectorsearch.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/collections/${COLLECTION_ID}/indexes?indexId=${INDEX_ID}" \
-d '{
      "index_field": "text_embedding",
      "distance_metric": "COSINE_DISTANCE",
      "filter_fields": ["file_id"]
    }'

gcloud

מחליפים את המשתנים הבאים:

  • ‫PROJECT_ID: מזהה הפרויקט.
  • ‫RAG_CORPUS_ID: המזהה של קורפוס ה-RAG שרוצים להוסיף לאינדקס.
gcloud vector-search collections indexes create vertex-rag-RAG_CORPUS_ID-index \
  --collection=vertex-rag-RAG_CORPUS_ID \
  --index-field=text_embedding \
  --distance-metric=cosine-distance \
  --filter-fields=file_id \
  --location=us-central1 \
  --project=PROJECT_ID

הפקודה חוסמת עד שהפעולה מסתיימת, אלא אם מעבירים את --async.

סקר להשלמה

יצירת אינדקס מחזירה פעולה ממושכת:

{
  "name": "projects/PROJECT_ID/locations/us-central1/operations/operation-1770302393524-64a14a54fa197-0dea326c-5a90efda",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.vectorsearch.v1.OperationMetadata",
    "createTime": "2026-02-05T14:39:53.558308609Z",
    "target": "projects/PROJECT_ID/locations/us-central1/collections/vertex-rag-RAG_CORPUS_ID/indexes/vertex-rag-RAG_CORPUS_ID-index",
    "verb": "create",
    "apiVersion": "v1"
  },
  "done": false
}

דוגמים את הפעולה באמצעות השם מהתגובה:

OPERATION_NAME=OPERATION_NAME

curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://vectorsearch.googleapis.com/v1/${OPERATION_NAME}"

כשהערך של done הוא true, השדה response מציין שהאינדקס נוצר בהצלחה, והשדה error מציין את הסיבה לכך שהוא נכשל. יצירת אינדקס נמשכת כמה דקות, ויותר זמן אם הקורפוס גדול.

כדי להציג את הפעולות בפרויקט ובמיקום, מריצים את הפקודה הבאה:

curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://vectorsearch.googleapis.com/v1/projects/PROJECT_ID/locations/us-central1/operations"

כדי לבדוק אינדקס קיים, מריצים את הפקודה הבאה:

gcloud vector-search collections indexes describe vertex-rag-RAG_CORPUS_ID-index \
  --collection=vertex-rag-RAG_CORPUS_ID \
  --location=us-central1 \
  --project=PROJECT_ID

כדי למחוק אינדקס, שצריך לעשות כדי לשנות את ההגדרות הקבועות שלו, מריצים את הפקודה הבאה. האחזור חוזר לסריקת KNN בשיטת Brute-force עד שהאינדקס החלופי נבנה, ונכשל לחלוטין אם הקורפוס חורג מ-100,000 קטעים.

gcloud vector-search collections indexes delete vertex-rag-RAG_CORPUS_ID-index \
  --collection=vertex-rag-RAG_CORPUS_ID \
  --location=us-central1 \
  --project=PROJECT_ID

המאמרים הבאים