הדף הזה מתייחס ל-Apigee, אבל לא ל-Apigee Hybrid.
לעיון במסמכי התיעוד של
Apigee Edge
בדף הזה מוסבר איך להגדיר את כללי המדיניות של Apigee בנושא שמירת נתונים במטמון סמנטי ואיך להשתמש בהם כדי לאפשר שימוש חוזר בתגובות בצורה חכמה על סמך דמיון סמנטי. בדוגמה הזו, המדיניות מפעילה את חיפוש הדמיון שלה מול אינדקס חיפוש וקטורי שנפרס בנקודת קצה פרטית (Private Service Connect). השימוש במדיניות הזו ב-Apigee proxy ל-API ממזער קריאות מיותרות ל-API של ה-Backend, מקטין את זמן האחזור ומפחית את עלויות התפעול.
לפני שמתחילים
לפני שמתחילים, צריך לבצע את המשימות הבאות:
-
In the Google Cloud console, on the project selector page, select or create a Google Cloud project.
Roles required to select or create a project
- Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
-
Create a project: To create a project, you need the Project Creator role
(
roles/resourcemanager.projectCreator), which contains theresourcemanager.projects.createpermission. Learn how to grant roles.
-
Verify that billing is enabled for your Google Cloud project.
Enable the Compute Engine, AI Platform, and Cloud Storage APIs.
Roles required to enable APIs
To enable APIs, you need the
serviceusage.services.enablepermission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.- מפעילים ומגדירים את Text embeddings API של Vertex AI בפרויקט Google Cloud .
- צריך ליצור אינדקס של Vector Search (או לקבל גישה לאינדקס כזה) שפרוס בנקודת קצה פרטית (Private Service Connect). ההדרכה הזו לא כוללת את השלבים להגדרת חיפוש וקטורי. אפשר לעיין בדרישות המוקדמות לאינדקס חיפוש וקטורי כדי לראות את הדרישות הספציפיות ל-SemanticCacheLookup וקישורים למסמכי התיעוד של חיפוש וקטורי.
- מוודאים שיש לכם סביבת ביניים או מקיפה שזמינה במופע Apigee שלכם. אפשר לפרוס מדיניות של שמירת נתונים במטמון סמנטי רק בסביבות ביניים או מקיפות.
- מוודאים שיש לכם קבוצת סביבות עם שם מארח של זמן ריצה שאפשר להשתמש בו כדי לשלוח בקשות ל-proxy ל-API.
התפקידים הנדרשים
כדי לקבל את ההרשאות שנדרשות ליצירה ולשימוש במדיניות של שמירת נתונים במטמון סמנטי, צריך לבקש מהאדמין להקצות לכם ב-IAM את התפקיד משתמש ב-AI Platform (roles/aiplatform.user) בחשבון השירות שבו אתם משתמשים כדי לפרוס פרוקסי של Apigee.
כדי לקרוא הסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.
יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.
הגדרה של משתני סביבה
בפרויקט Google Cloud שמכיל את מופע Apigee, משתמשים בפקודה הבאה כדי להגדיר משתני סביבה:
export PROJECT_ID=PROJECT_IDexport REGION=REGIONexport RUNTIME_HOSTNAME=RUNTIME_HOSTNAME
כאשר:
-
PROJECT_IDהוא מזהה הפרויקט עם מופע Apigee. -
REGIONהוא ה Google Cloud אזור של מופע Apigee. -
RUNTIME_HOSTNAMEהוא שם המארח של זמן הריצה של Apigee.
כדי לוודא שמשתני הסביבה מוגדרים בצורה נכונה, מריצים את הפקודה הבאה ובודקים את הפלט:
echo $PROJECT_ID $REGION $RUNTIME_HOSTNAME
הגדרת הפרויקט
מגדירים את Google Cloud הפרויקט בסביבת הפיתוח:
gcloud auth logingcloud config set project $PROJECT_ID
דרישות מוקדמות לאינדקס ב-Vector Search
במדריך הזה אנחנו מניחים שכבר יש לכם אינדקס של חיפוש וקטורי (או שאתם תיצרו כזה) שנפרס בנקודת קצה פרטית (Private Service Connect). המדריכים בנושא חיפוש וקטורי כוללים הסברים על יצירה, עיצוב ופריסה של אינדקס חיפוש וקטורי, ולכן במדריך הזה לא מפורטים השלבים האלה. פועלים לפי התיעוד של חיפוש וקטורי כדי:
- יצירה וניהול של אינדקס.
- הגדרת הפורמט והמבנה של נתוני הקלט.
- יצירת נקודת קצה של אינדקס מסוג Private Service Connect ופריסת האינדקס בה.
כשיוצרים את האינדקס, הוא צריך לעמוד בדרישות הספציפיות הבאות של SemanticCacheLookup:
- האינדקס צריך להשתמש ב-
STREAM_UPDATE("indexUpdateMethod": "STREAM_UPDATE") כדי שהקריאות שלupsertDatapointsבמדיניות SemanticCachePopulate יהפכו לניתנות לשאילתה כמעט בזמן אמת. - האינדקס
dimensionsחייב להיות זהה לממד הפלט של מודל ההטמעה שבו משתמשים במדיניות SemanticCacheLookup. במדריך הזה נשתמש ב-gemini-embedding-001, שיוצר הטמעות תלת-ממדיות של 3,072 כברירת מחדל. אם חותכים את הפלט לממד נמוך יותר (לדוגמה, 768 או 1,536), צריך להגדיר אתdimensionsלאותו ערך. - יוצרים את האינדקס עם מדד המרחק (
distanceMeasureType) שמתאים ל<DistanceMeasureType>המדיניות. האלמנט<SimilaritySearch><VertexAI><DistanceMeasureType>במדיניות SemanticCacheLookup הוא אופציונלי, וערך ברירת המחדל שלו הואDOT_PRODUCT_DISTANCE. המערכת תומכת גם בערךCOSINE_DISTANCE. מדד המרחק של האינדקס ומדיניות<DistanceMeasureType>חייבים להיות זהים.
בדוגמה המינימלית הבאה נוצר אינדקס תואם. גוף הבקשה המלא וכל האפשרויות הזמינות מפורטים במאמר יצירה וניהול של אינדקס.
ACCESS_TOKEN=$(gcloud auth print-access-token) && curl -X POST \ "https://$REGION-aiplatform.googleapis.com/v1/projects/$PROJECT_ID/locations/$REGION/indexes" \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "displayName": "semantic-cache-index", "metadata": { "config": { "dimensions": 3072, "distanceMeasureType": "DOT_PRODUCT_DISTANCE" } }, "indexUpdateMethod": "STREAM_UPDATE" }'
שימו לב לערך המספרי INDEX_ID שמוחזר בתשובה. תצטרכו להשתמש בו במדיניות SemanticCachePopulate. אחרי שיוצרים את האינדקס, יוצרים נקודת קצה של אינדקס Private Service Connect ומפריסים אליה את האינדקס.
כשיוצרים את נקודת הקצה של אינדקס Private Service Connect, היא צריכה לעמוד בדרישות הספציפיות הבאות של SemanticCacheLookup:
projectAllowlistחייב לכלול את פרויקט Apigee שממנו מתבצעת ההתחברות:- Apigee: משתמשים בפרויקט הדייר של Apigee. מקבלים את מזהה פרויקט הדייר מ-Organizations API (השדה
apigeeProjectId).
projectAllowlistאחרי שיוצרים את נקודת הקצה של האינדקס. אם הוספתם לרשימת ההיתרים פרויקט שגוי, אתם צריכים למחוק את נקודת הקצה של האינדקס וליצור אותה מחדש.- Apigee: משתמשים בפרויקט הדייר של Apigee. מקבלים את מזהה פרויקט הדייר מ-Organizations API (השדה
רושמים את הערך המספרי INDEX_ENDPOINT_ID של נקודת הקצה של האינדקס.
הגדרת חשבון השירות ל-proxy של Apigee
ה-proxy של Apigee משתמש בחשבון שירות לקריאות ה-REST שלו ל-Vertex AI: Embeddings API במדיניות SemanticCacheLookup, upsertDatapoints במדיניות SemanticCachePopulate ויעד המודל. מקצים לחשבון השירות את התפקיד AI Platform User (roles/aiplatform.user):
gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:SERVICE_ACCOUNT" \ --role="roles/aiplatform.user"
כאשר SERVICE_ACCOUNT היא כתובת האימייל של חשבון השירות שבו נעשה שימוש בשרת ה-proxy. מפנים לחשבון השירות הזה כשפורסים את ה-proxy ל-API בשלב 4: ייבוא ופריסה של ה-proxy ל-API.
סקירה כללית
מדיניות שמירת הנתונים במטמון הסמנטי עוזרת למשתמשי Apigee עם מודלים של LLM להציג ביעילות הנחיות זהות או דומות מבחינה סמנטית, תוך צמצום הקריאות ל-API של ה-Backend והפחתת צריכת המשאבים.
מדיניות SemanticCacheLookup ו-SemanticCachePopulate מצורפת לזרימות של בקשות ותגובות, בהתאמה, של proxy ל-API של Apigee. כשה-proxy מקבל בקשה, מדיניות SemanticCacheLookup מחלצת את הנחיית המשתמש מהבקשה וממירה את ההנחיה לייצוג מספרי באמצעות Text embeddings API. חיפוש דמיון סמנטי מתבצע באמצעות חיפוש וקטורי כדי למצוא הנחיות דומות. אם נמצא נתון דומה להנחיה, מתבצעת בדיקה במטמון. אם נמצאו נתונים במטמון, התגובה שנשמרה במטמון מוחזרת ללקוח.
אם חיפוש הדמיון לא מחזיר הנחיה קודמת דומה, מודל ה-LLM יוצר תוכן בתגובה להנחיית המשתמש ומאכלס את המטמון של Apigee בתשובה. נוצרת לולאת משוב כדי לעדכן את רשומות אינדקס החיפוש של חיפוש וקטורי, כהכנה לבקשות עתידיות.
בתרחיש הזה, אינדקס חיפוש וקטורי נפרס בנקודת קצה פרטית (Private Service Connect) דרך gRPC. פרטים נוספים על התמיכה ב-Private Service Connect בחיפוש וקטורי זמינים במאמר שאילתות על אינדקסים של גישה לשירותים פרטיים או Private Service Connect.
בקטעים הבאים מתוארים השלבים ליצירה ולהגדרה של מדיניות שמירת נתונים במטמון סמנטי:
- מאמתים את המשאבים ומקבלים את הערכים שנדרשים ל-Apigee.
- מתחברים ל-Service Attachment.
- הרכבת חבילת שרת proxy ל-API
- מייבאים ופורסים את ה-proxy ל-API.
- בודקים את מדיניות השמירה במטמון הסמנטי.
שלב 1: מאמתים את המשאבים ומקבלים את הערכים שנדרשים ל-Apigee
לפני שמגדירים את Apigee, צריך לוודא שנקודת הקצה של אינדקס חיפוש הווקטורים מופעלת ב-Private Service Connect ושהאינדקס נפרס. לאחר מכן קוראים את שני הערכים שפרוקסי Apigee צורך: קובץ השירות וה-DEPLOYED_INDEX_ID.
מוודאים שהאינדקס נפרס ושהקובץ המצורף של השירות Private Service Connect נחשף בנקודת הקצה:
gcloud ai index-endpoints describe INDEX_ENDPOINT_ID \ --project=$PROJECT_ID --region=$REGION \ --format="value(deployedIndexes.privateEndpoints.serviceAttachment)"
הפקודה מחזירה שם משאב של קובץ מצורף לשירות בפורמט projects/TENANT_PROJECT/regions/REGION/serviceAttachments/SERVICE_ATTACHMENT_NAME.
במדריך הזה, הערך הזה נקרא SERVICE_ATTACHMENT. אם הפקודה מחזירה ערך ריק, האינדקס עדיין לא נפרס בנקודת קצה של Private Service Connect. חוזרים אל הדרישות המוקדמות לאינדקס החיפוש הווקטורי ומשלימים את פריסת האינדקס לפני שממשיכים.
קוראים את DEPLOYED_INDEX_ID של האינדקס שנפרס בנקודת הקצה:
gcloud ai index-endpoints describe INDEX_ENDPOINT_ID \ --project=$PROJECT_ID --region=$REGION \ --format="value(deployedIndexes.id)"
במדריך הזה, הערך הזה נקרא DEPLOYED_INDEX_ID. משתמשים בו במדיניות SemanticCacheLookup בשלב 3: בניית חבילת proxy ל-API.
מידע נוסף על פריסה של נקודות קצה פרטיות של אינדקסים ועל שליחת שאילתות אליהן זמין במאמרים פריסת אינדקס לנקודת קצה של Private Service Connect ושליחת שאילתות לאינדקסים של Private Services Access או של Private Service Connect.
שלב 2: התחברות ל-Service Attachment
בשלב הזה מקבלים את המארח הפרטי שאליו מתבצעות הקריאות של ה-proxy <GrpcEndpoint>.
ב-Apigee, יוצרים קובץ מצורף של נקודת קצה ב-Apigee. נקודת הקצה של הקישור היא הצד של צרכן Private Service Connect ב-Apigee: היא מתחברת לצירוף השירות של חיפוש וקטורי ומספקת לכם מארח פרטי שה-proxy קורא לו.
curl -X POST \ -H "Authorization: Bearer $(gcloud auth print-access-token)" \ -H "Content-Type: application/json" \ -d '{ "location": "'"$REGION"'", "serviceAttachment": "SERVICE_ATTACHMENT" }' \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/endpointAttachments?endpointAttachmentId=ENDPOINT_ATTACHMENT"
מבצעים פולינג עד שהערך של state בקובץ המצורף הוא ACTIVE והערך של connectionState הוא ACCEPTED, ואז רושמים את המארח:
curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/endpointAttachments/ENDPOINT_ATTACHMENT"
התשובה מכילה את המארח בשדה host. במדריך הזה, הערך הזה נקרא TARGET_HOST.
כדי להתחבר ל-Vector Search service attachment מהפרוקסי, אפשר להשתמש באחת מהאפשרויות הבאות:
- כתובת ה-IP: משתמשים בכתובת ה-IP שמוחזרת בשדה
hostישירות בתורTARGET_HOST(לדוגמה,7.0.3.4). - רשומת DNS פרטית: אם הגדרתם תחום DNS פרטי ב-Cloud DNS ב Google Cloud פרויקט
עם קישור בין רשתות שכנות (peering) ל-Apigee, אתם יכולים ליצור רשומת A בתחום הפרטי שמפנה לכתובת ה-IP של נקודת הקצה של הקישור ולהשתמש בשם הדומיין הזה (לדוגמה,
vectorsearch.example.com) בתורTARGET_HOST. מידע נוסף זמין במאמרים שימוש ברשומת DNS וקישור באמצעות אזורי שרתי DNS פרטיים.
שלב 3: בניית proxy ל-API
יצירת חבילת ה-proxy
יוצרים את פריסת הספרייה הבאה:
apiproxy/ ├── PROXY_NAME.xml ├── proxies/default.xml ├── targets/default.xml └── policies/ ├── SCL-1.xml └── SCP-1.xml
policies/SCL-1.xml – המדיניות SemanticCacheLookup. בלוק <SimilaritySearch> משתמש ב-<PrivateServiceConnect><GrpcEndpoint> (ללא <URL>).
הערה: כללים של <GrpcEndpoint>:
- הפורמט הוא
grpc://TARGET_HOST:PORT, והסכימה צריכה להיותgrpc://. grpcs://(TLS) לא נתמך בגרסה הזו. - היציאה היא
10000לחיפוש וקטורי. נקודות הקצה של מישור הנתונים ב-Private Service Connect משרתות gRPC ביציאה 10000, ולכן נקודת הקצה היא תמידgrpc://TARGET_HOST:10000. -
TARGET_HOSTיכול להיות כתובת ה-IP של נקודת הקצה של הקישור (משלב 2) או רשומת DNS מותאמת אישית שנוצרה בתחום ה-DNS הפרטי. - הקפיצה של gRPC היא בטקסט פשוט ולא מאומת (מאובטחת על ידי בידוד רשת).
<SemanticCacheLookup async="false" continueOnError="false" enabled="true" name="SCL-1"> <DisplayName>SCL-1</DisplayName> <IgnoreUnresolvedVariables>false</IgnoreUnresolvedVariables> <UserPromptSource>{jsonPath('$.contents[-1].parts[-1].text',request.content,true)}</UserPromptSource> <Embeddings> <VertexAI> <URL>https://REGION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/publishers/google/models/gemini-embedding-001:predict</URL> </VertexAI> </Embeddings> <SimilaritySearch> <VertexAI> <PrivateServiceConnect> <GrpcEndpoint>grpc://TARGET_HOST:10000</GrpcEndpoint> </PrivateServiceConnect> <DeployedIndexID>DEPLOYED_INDEX_ID</DeployedIndexID> <Threshold>0.95</Threshold> </VertexAI> </SimilaritySearch> </SemanticCacheLookup>
policies/SCP-1.xml – המדיניות SemanticCachePopulate. השיטה Populate היא רק ל-REST וחייבים להשתמש ב-<URL> (היא נדחית ב-<PrivateServiceConnect> בזמן הפריסה):
<SemanticCachePopulate async="false" continueOnError="true" enabled="true" name="SCP-1"> <DisplayName>SCP-1</DisplayName> <IgnoreUnresolvedVariables>true</IgnoreUnresolvedVariables> <SimilaritySearch> <VertexAI> <URL>https://REGION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/indexes/INDEX_ID:upsertDatapoints</URL> </VertexAI> </SimilaritySearch> <TTLInSeconds>3600</TTLInSeconds> </SemanticCachePopulate>
targets/default.xml – יעד המודל. היעד שולח קריאה ל-Google API, ולכן הוא צריך אסימון. <GoogleAccessToken> משתמש בחשבון השירות של הפריסה:
<TargetEndpoint name="default"> <PreFlow name="PreFlow"><Request/><Response/></PreFlow> <PostFlow name="PostFlow"><Request/><Response/></PostFlow> <HTTPTargetConnection> <Authentication> <GoogleAccessToken> <Scopes> <Scope>https://www.googleapis.com/auth/cloud-platform</Scope> </Scopes> </GoogleAccessToken> </Authentication> <URL>https://REGION-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/REGION/publishers/google/models/gemini-2.5-flash:generateContent</URL> </HTTPTargetConnection> </TargetEndpoint>
proxies/default.xml – מריצים את מדיניות SemanticCacheLookup על הבקשה ואת מדיניות SemanticCachePopulate על התגובה:
<ProxyEndpoint name="default"> <PreFlow name="PreFlow"> <Request><Step><Name>SCL-1</Name></Step></Request> <Response><Step><Name>SCP-1</Name></Step></Response> </PreFlow> <PostFlow name="PostFlow"><Request/><Response/></PostFlow> <HTTPProxyConnection> <BasePath>/PROXY_NAME</BasePath> </HTTPProxyConnection> <RouteRule name="default"> <TargetEndpoint>default</TargetEndpoint> </RouteRule> </ProxyEndpoint>
PROXY_NAME.xml – מאפיין החבילה:
<APIProxy name="PROXY_NAME"> <BasePaths>/PROXY_NAME</BasePaths> <Policies><Policy>SCL-1</Policy><Policy>SCP-1</Policy></Policies> <ProxyEndpoints><ProxyEndpoint>default</ProxyEndpoint></ProxyEndpoints> <TargetEndpoints><TargetEndpoint>default</TargetEndpoint></TargetEndpoints> </APIProxy>
שלב 4: ייבוא ופריסה של proxy ל-API
מכווצים את החבילה, מייבאים אותה כדי ליצור גרסה חדשה ומפרסים את הגרסה עם חשבון השירות:
TOKEN=$(gcloud auth print-access-token)(cd BUNDLE_DIR && zip -r ../PROXY_NAME.zip apiproxy)curl -X POST -H "Authorization: Bearer $TOKEN" \ -F "file=@PROXY_NAME.zip" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/apis?action=import&name=PROXY_NAME"curl -X POST -H "Authorization: Bearer $TOKEN" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments/ENV/apis/PROXY_NAME/revisions/REVISION/deployments?override=true&serviceAccount=SERVICE_ACCOUNT"
כאשר:
-
BUNDLE_DIRהיא הספרייה שמכילה את התיקייהapiproxy/. הארכיון חייב להכיל את התיקייהapiproxy/ברמה הבסיסית (root). -
ENVהיא סביבת Apigee שבה פורסים את ה-Proxy. הסביבה צריכה להיות סביבת ביניים או מקיפה. -
REVISIONהוא מספר הגרסה שמוחזר על ידי קריאת הייבוא. -
SERVICE_ACCOUNTהיא כתובת האימייל של חשבון השירות שמשמש לפריסת ה-proxy.
מחכים עד שהדוח על הפריסה יציג את ההודעה READY:
curl -s -H "Authorization: Bearer $TOKEN" \ "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/environments/ENV/apis/PROXY_NAME/revisions/REVISION/deployments" | jq .state
שלב 5: בדיקת מדיניות השמירה במטמון הסמנטי
שליחת הנחיה חדשה. זהו אי מציאה במטמון: המודל מופעל והתשובה נשמרת במטמון.
curl -X POST "https://$RUNTIME_HOSTNAME/PROXY_NAME" \ -H "Content-Type: application/json" \ -d '{"contents":[{"role":"user","parts":[{"text":"Explain in one sentence why the sky appears blue."}]}]}'
שולחים שוב את אותו פרומפט. זהו פגיעה במטמון: התשובה מוגשת מהמטמון והמודל לא נקרא.
curl -i -X POST "https://$RUNTIME_HOSTNAME/PROXY_NAME" \ -H "Content-Type: application/json" \ -d '{"contents":[{"role":"user","parts":[{"text":"Explain in one sentence why the sky appears blue."}]}]}'
במקרה של היט, התשובה כוללת את הכותרת Cached-content: true, את אותה תשובה וזמן אחזור נמוך באופן משמעותי.
אפשר גם לאמת את השמירה במטמון באמצעות סשן ניפוי באגים. במקרה של פגיעה, המדיניות SemanticCacheLookup מגדירה את משתני התהליך הבאים:
| משתנה | הערך של היט |
|---|---|
SemanticCacheLookup.SCL-1.dense_embeddings |
וקטור ההטמעה של ההנחיה. |
SemanticCacheLookup.SCL-1.is_nearest_neighbor_hit |
true |
SemanticCacheLookup.SCL-1.cache_hit |
true |
SemanticCacheLookup.SCL-1.cached_llm_response |
התשובה ששמורה במטמון. |
במקרה של התאמה, לא מתבצעת קריאה ליעד של המודל – התהליך מתקצר ומוחזרת התגובה שנשמרה במטמון.
פתרון בעיות
לעיון בהפניה המלאה לשגיאה, אפשר לעיין במדיניות SemanticCacheLookup.