הדף הזה רלוונטי ל-Apigee ול-Apigee Hybrid.
לצפייה במסמכי התיעוד של
Apigee Edge
במדריך הזה נסביר איך להגדיר את Apigee ולהשתמש בו כשער AI שמנתב בקשות של מודל שפה גדול (LLM) למודלים שונים של קצה עורפי, על סמך כללי ניתוב גמישים שמבוססים על מדיניות. שער AI עוזר לכם לאבטח את התנועה של המודלים, לשלוט בה ולבצע אופטימיזציה שלה כדי לנהל את העלויות ולמנוע התרחבות לא מבוקרת של המודלים.
כל שלב במדריך מתבסס על ההגדרות הקודמות ומוסיף יכולת ספציפית באמצעות קובצי Apigee Feature Template (AFT) לשימוש חוזר:
- שלב 1: פריסת שרת proxy מינימלי של API שמקשר לספק יחיד של מודל שפה גדול (LLM).
- שלב 2: מוסיפים את Model Armor להסרת תוכן זדוני או רגיש מההנחיות ומהתשובות, כדי לסנן קלט זדוני ולמנוע זליגת מידע אישי רגיש.
- שלב 3: הוספת ניתוב משימות למודלים בין ספקים ומטמון סמנטי שמגובה על ידי חיפוש וקטורי בפלטפורמת הסוכנים.
- שלב 4: מגדירים חלופה בין ספקים כדי לנסות שוב באופן אוטומטי לשלוח בקשות לספק משני אם היעד הראשי מחזיר קוד סטטוס HTTP מסוג
4xxאו5xx.
כדי להוסיף יכולת, מוסיפים שורה אחת לבלוק features
בתבנית. כדי לראות או להוריד את כל קבצי הדוגמה, כולל קובצי ה-AFT וסקריפטים של כלי עזר, אפשר לעיין במאגר התבניות של Apigee ב-GitHub.
לפני שמתחילים
לפני שמתחילים, חשוב לוודא שהתנאים הבאים מתקיימים:
- פרויקט פעיל Google Cloud שהחיוב בו מופעל.
- סביבת Comprehensive שזמינה במופע Apigee שלכם. אפשר לפרוס את כללי המדיניות של Model Armor,
SemanticCacheLookupו-SemanticCachePopulateרק בסביבות Comprehensive. - Google Cloud CLI (
gcloud) מותקן ומוגדר עם Application Default Credentials (ADC). כדי ליצור פרטי כניסה, מריצים את הפקודהgcloud auth application-default login. - חשבון שירות של סביבת זמן ריצה עם התפקידים הבאים ב-IAM:
roles/aiplatform.userroles/modelarmor.user
- בשלבים 2, 3 ו-4, מציינים את נתיב המשאב של תבנית Model Armor. לדוגמה,
projects/YOUR_PROJECT/locations/us-central1/templates/apigee-aft-demo-ma. - לשלבים 3 ו-4: מפת מפתח-ערך (KVM) של Apigee בשם
openai-credentialsבסביבה שלכם, שמכילה רשומתapi-keyעם מפתח OpenAI API תקין. - לשלבים 3 ו-4: נקודת קצה של אינדקס חיפוש וקטורי ב-Vertex AI שנפרסה עבור מטמון סמנטי. להוראות מפורטות להגדרת אינדקס, קראו את קובץ ה-README של מאגר התבניות של Apigee ב-GitHub.
סקירה כללית
כל ארבעת השלבים מקבלים את צורת הבקשה של OpenAI Chat Completions בכתובת /v1/chat/completions[-stageN], כך שאותן ערכות SDK של לקוחות פועלות בכל שלב. קידומת השדה model קובעת את החלטת הניתוב: בקשות למודלים של google/* מנותבות אל Gemini ב-Agent Platform, וכל הבקשות האחרות מנותבות אל OpenAI. ההגדרה ההפוכה הזו כברירת מחדל
מוודאת שמשפחות חדשות של מודלים של OpenAI, כמו o1-*,
o3-* ו-chatgpt-*, מנותבות בצורה נכונה במקום
לפספס התאמה של קידומת gpt-* בלי להציג הודעה.
| שלב | היכולת נוספה | נתיב בסיסי |
|---|---|---|
| 1 | Hello LLM (בקשה בפורמט OpenAI ל-Gemini ב-Agent Platform) | /v1/chat/completions |
| 2 | הגנה מוגברת על המודל (החדרת פרומפטים, אתיקה של בינה מלאכותית ומסננים של Sensitive Data Protection) | /v1/chat/completions-stage2 |
| 3 | ניתוב בין ספקים ומטמון סמנטי של Agent Platform חיפוש וקטורי | /v1/chat/completions-stage3 |
| 4 | חלופה בין ספקים (שער AI מלא) | /v1/chat/completions-stage4 |
שלב 1: Hello LLM
הפרוקסי המינימלי פועל מול יעד Gemini יחיד דרך נקודת הקצה (endpoint) שלו שתואמת ל-OpenAI. שני קובצי תכונות קטנים מספקים את שלד ה-proxy הבסיסי ומחלץ JSON. החילוץ מעתיק את $.model ואת $.messages[-1].content למשתני הזרימה llm.model ו-llm.prompt, כדי שבשלבים הבאים יהיו קלטים עקביים.
llm-base.yaml מגדיר את שלד ה-proxy הבסיסי:
gateway: apigee schemaVersion: 1.0.0 name: llm-base type: feature parameters: - name: BASE_PATH default: /v1/chat/completions endpoints: - name: default basePath: "{BASE_PATH}" routes: - name: primary target: gemini-target
llm-openai-format.yaml מחלץ את שדות הבקשה בפורמט OpenAI:
gateway: apigee schemaVersion: 1.0.0 name: llm-openai-format type: feature defaultEndpoint: name: default flows: - name: PreFlow mode: Request steps: - name: EV-ExtractOpenAIRequest policies: - name: EV-ExtractOpenAIRequest type: ExtractVariables content: ExtractVariables: metadata: name: EV-ExtractOpenAIRequest continueOnError: "true" Source: _text: request JSONPayload: Variable: - metadata: name: model JSONPath: _text: "$.model" - metadata: name: prompt JSONPath: _text: "$.messages[-1].content" VariablePrefix: _text: llm
target-vertex-gemini.yaml מגדיר יעד של Agent Platform שמשתמש בנקודת הקצה שתואמת ל-OpenAI:
gateway: apigee schemaVersion: 1.0.0 name: target-vertex-gemini type: feature targets: - name: gemini-target httpTargetConnection: URL: https://aiplatform.googleapis.com/v1/projects/{organization.name}/locations/global/endpoints/openapi/chat/completions Authentication: GoogleAccessToken: Scopes: Scope: https://www.googleapis.com/auth/cloud-platform
יוצרים את קובצי התכונות בתבנית של שלב 1,
01-hello-llm.yaml:
gateway: apigee schemaVersion: 1.0.0 name: aft-demo-01-hello-llm features: - llm-base.yaml - llm-openai-format.yaml - target-vertex-gemini.yaml
פורסים את התבנית:
gcloud beta apigee apis import aft-demo-01-hello-llm \ --from-template=01-hello-llm.yaml \ --organization=APIGEE_ORG
בודקים את שרת ה-proxy:
curl -X POST https://APIGEE_HOSTNAME/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{"model":"google/gemini-2.5-flash", "messages":[{"role":"user","content":"Explain how AI works in a few words"}]}'
מחליפים את מה שכתוב בשדות הבאים:
-
APIGEE_ORG: שם הארגון ב-Apigee. -
APIGEE_HOSTNAME: שם המארח של קבוצת הסביבות ב-Apigee, בדרך כלל מאזן עומסים (LB) של Google Cloud .
שלב 2: הוספת Model Armor
Model Armor בודק את הפרומפט הנכנס כדי לזהות החדרת פרומפטים, תוכן אסור ומידע אישי רגיש לפני הקריאה ליעד. לאחר מכן, הוא סורק את התשובה של המודל לפני שהיא מגיעה ללקוח.
מוסיפים לתבנית קובץ תכונות אחד, llm-model-armor.yaml:
gateway: apigee schemaVersion: 1.0.0 name: llm-model-armor type: feature parameters: - name: MA_TEMPLATE_PATH default: projects/{organization.name}/locations/us-central1/templates/apigee-aft-demo-ma defaultEndpoint: name: default flows: - name: PreFlow mode: Request steps: - name: MA-SanitizeUserPrompt - name: PostFlow mode: Response steps: - name: MA-SanitizeModelResponse policies: - name: MA-SanitizeUserPrompt type: SanitizeUserPrompt content: SanitizeUserPrompt: metadata: name: MA-SanitizeUserPrompt ModelArmor: TemplateName: _text: "{MA_TEMPLATE_PATH}" UserPromptSource: _text: "{llm.prompt}" - name: MA-SanitizeModelResponse type: SanitizeModelResponse content: SanitizeModelResponse: metadata: name: MA-SanitizeModelResponse ModelArmor: TemplateName: _text: "{MA_TEMPLATE_PATH}" UserPromptSource: _text: "{llm.prompt}" LLMResponseSource: _text: "{jsonPath('$.choices[-1].message.content',response.content,true)}"
התבנית של שלב 2, 02-add-model-armor.yaml, מוסיפה שורה אחת:
gateway: apigee schemaVersion: 1.0.0 name: aft-demo-02-add-model-armor features: - llm-base.yaml - llm-openai-format.yaml - target-vertex-gemini.yaml - llm-model-armor.yaml # <-- the change from Stage 1 parameters: - name: BASE_PATH default: /v1/chat/completions-stage2
פרמטר MA_TEMPLATE_PATH מוגדר כברירת מחדל לתבנית בשם
apigee-aft-demo-ma ב-us-central1. כדי להשתמש בתבנית Model Armor משלכם, צריך לבטל את הפרמטר בבלוק parameters של התבנית.
שלב 3: הוספת ניתוב בין ספקים ומטמון סמנטי
בשלב 3, מוסיפים יעד שני (OpenAI), מחליפים את הכלל של נתיב יחיד בניתוב מבוסס-מודל ומגדירים מטמון סמנטי שמגובה על ידי חיפוש וקטורי בפלטפורמת הסוכן לפני שני היעדים.
כדי להגדיר את שלב 3, מוסיפים שלושה קובצי תכונות לבלוק features בתבנית:
-
target-openai-gpt.yaml: הוספת OpenAI כנקודת קצה משנית. -
llm-routing.yaml: ניתוב בקשות באופן דינמי על סמך שם המודל המבוקש. -
llm-semantic-cache.yaml: מוסיף מטמון סמנטי לפני שני הספקים.
בדוגמה הבאה אפשר לראות איך קובץ התכונות llm-routing.yaml מגדיר את לוגיקת הניתוב:
gateway: apigee schemaVersion: 1.0.0 name: llm-routing type: feature parameters: - name: BASE_PATH default: /v1/chat/completions endpoints: - name: default basePath: "{BASE_PATH}" routes: - name: gemini condition: llm.model StartsWith "google/" target: gemini-target - name: openai target: openai-target # default when the condition is false
המטמון הסמנטי פועל SemanticCacheLookup ב-PreFlow של הבקשה ו-SemanticCachePopulate ב-PostFlow של התגובה, רק במקרים של אי מציאה במטמון. שתי כללי המדיניות משתמשים בנקודת קצה של אינדקס חיפוש וקטורי של Agent Platform שאתם מקצים בנפרד. הקטע הבא מציג את החלקים העיקריים של הגדרות המדיניות:
policies: - name: SCLLookup type: SemanticCacheLookup content: SemanticCacheLookup: UserPromptSource: _text: "{llm.prompt}" Embeddings: VertexAI: URL: _text: "https://{EMBEDDINGS_LOCATION}-aiplatform.googleapis.com/v1/projects/{organization.name}/locations/{EMBEDDINGS_LOCATION}/publishers/google/models/{EMBEDDINGS_MODEL}:predict" SimilaritySearch: VertexAI: URL: _text: "https://{VECTOR_INDEX_ENDPOINT_SUBDOMAIN}.{EMBEDDINGS_LOCATION}-{PROJECT_NUMBER}.vdb.vertexai.goog/v1/projects/{organization.name}/locations/{EMBEDDINGS_LOCATION}/indexEndpoints/{VECTOR_INDEX_ENDPOINT_ID}:findNeighbors" DeployedIndexID: _text: "{DEPLOYED_INDEX_ID}" Threshold: _text: "{THRESHOLD}" - name: SCPPopulate type: SemanticCachePopulate # ... (see the GitHub repository for the full definition)
בשלב 3, התבנית מרכיבה את כל קובצי התכונות:
gateway: apigee schemaVersion: 1.0.0 name: aft-demo-03-add-routing-and-cache features: - llm-base.yaml - llm-openai-format.yaml - target-vertex-gemini.yaml - llm-model-armor.yaml - target-openai-gpt.yaml # <-- add OpenAI target - llm-routing.yaml # <-- add model-name routing - llm-semantic-cache.yaml # <-- add semantic cache parameters: - name: BASE_PATH default: /v1/chat/completions-stage3 - name: VECTOR_INDEX_ENDPOINT_ID default: "YOUR_INDEX_ENDPOINT_ID" - name: VECTOR_INDEX_ID default: "YOUR_INDEX_ID" - name: VECTOR_INDEX_ENDPOINT_SUBDOMAIN default: "YOUR_SUBDOMAIN" - name: PROJECT_NUMBER default: "YOUR_PROJECT_NUMBER" - name: DEPLOYED_INDEX_ID default: "YOUR_DEPLOYED_INDEX_ID"
מפעילים את התבנית באמצעות אותה פקודה gcloud beta apigee apis import עם הדגל --from-template שבה השתמשתם בשלב 1.
שלב 4: הוספת חלופה בין ספקים
בשלב 4, מצורף DefaultFaultRule לשני היעדים. כשהיעד הראשי מחזיר סטטוס 4xx או 5xx, כלל השגיאה שולח ServiceCallout עם אותה הנחיה לספק השני ומחזיר את התשובה הזו ללקוח. הלקוח מקבל תגובת 200 תקינה עם השלמה רגילה, ואין צורך בלוגיקה משלו לניסיון חוזר או לטיפול בשגיאות.
קובץ התכונה llm-fallback.yaml מוסיף את ההתנהגות הזו. הדוגמה הבאה מקוצרת. הקובץ המלא זמין במאגר GitHub.
gateway: apigee schemaVersion: 1.0.0 name: llm-fallback type: feature targets: # Vertex primary; on 4xx/5xx, fall back to OpenAI. - name: gemini-target httpTargetConnection: Properties: Property: metadata: name: success.codes _text: "2XX" URL: https://aiplatform.googleapis.com/v1/projects/{organization.name}/locations/global/endpoints/openapi/chat/completions Authentication: GoogleAccessToken: Scopes: Scope: https://www.googleapis.com/auth/cloud-platform flows: - name: PostFlow mode: Response steps: - name: RF-TargetErrorToFault condition: response.status.code >= 400 defaultFaultRule: name: FallbackToOpenAI steps: - name: KVM-GetOpenAIKey - name: AM-BuildOpenAIFallbackRequest - name: SC-FallbackToOpenAI - name: AM-CopyOpenAIFallbackResponse # OpenAI primary; on 4xx/5xx, fall back to Vertex. - name: openai-target httpTargetConnection: Properties: Property: metadata: name: success.codes _text: "2XX" URL: https://api.openai.com/v1/chat/completions flows: - name: PreFlow mode: Request steps: - name: JS-StripOpenAIModelPrefix - name: KVM-GetOpenAIKey - name: AM-SetOpenAIAuth - name: PostFlow mode: Response steps: - name: RF-TargetErrorToFault condition: response.status.code >= 400 defaultFaultRule: name: FallbackToVertex steps: - name: AM-BuildVertexFallbackRequest - name: SC-FallbackToVertex - name: AM-CopyVertexFallbackResponse policies: # RaiseFault converts a target 4xx/5xx into a fault so DefaultFaultRule fires. - name: RF-TargetErrorToFault type: RaiseFault content: RaiseFault: IgnoreUnresolvedVariables: "true" # empty FaultResponse -- DefaultFaultRule builds the real response # ... AM-Build*, SC-Fallback*, AM-Copy* policies -- see GitHub repository
המעבר לגיבוי מסתמך על שתי הגדרות:
-
success.codes: 2XXבשני הבלוקים שלhttpTargetConnection. מערכת Apigee מתייחסת לכל תגובה של יעד שאינה2xxכאל כשל ביעד, ועוברת ישירות לזרימת השגיאות. - מדיניות
RaiseFaultב-PostFlow של התגובה של כל יעד, שמוגבלת על ידיresponse.status.code >= 400. המדיניות הזו מבטיחה שהמדיניותDefaultFaultRuleתפעל בכל תגובת שגיאה.
יוצרים את התבנית של שלב 4, שמוסיפה שורה אחת לתבנית של שלב 3:
gateway: apigee schemaVersion: 1.0.0 name: aft-demo-04-add-fallback features: - llm-base.yaml - llm-openai-format.yaml - target-vertex-gemini.yaml - llm-model-armor.yaml - target-openai-gpt.yaml - llm-routing.yaml - llm-semantic-cache.yaml - llm-fallback.yaml # <-- the change from Stage 3 parameters: - name: BASE_PATH default: /v1/chat/completions-stage4 # ... Model Armor and Vector Search parameters as in Stage 3
פורסים את התבנית:
gcloud beta apigee apis import aft-demo-04-add-fallback \ --from-template=04-add-fallback.yaml \ --organization=APIGEE_ORG
אימות ההתנהגות מקצה לקצה
המאגר ב-GitHub כולל סקריפט routing-diagnostic.sh שמפעיל את כל נתיבי הניתוב והגיבוי עם הנחיות בנושאים שונים. מכיוון שהמטמון הסמנטי מקצר את הדרך להנחיות דומות, כל הנחיה לבדיקה צריכה להיות מנוסחת בצורה שונה.
STAGE=4 ./routing-diagnostic.sh
הסקריפט שולח חמש בקשות דרך שרת ה-proxy של שלב 4:
- מודל קנוני של OpenAI
- מודל Gemini עם הקידומת
google/ - שם של מודל Gemini בלי קידומת, שמופנה ל-OpenAI לפי ברירת המחדל ההפוכה
- מודל חשיבה רציונלית של OpenAI
- שם מודל עם הקידומת
openai/
לכל בקשה, הסקריפט מדווח איזה ספק במעלה הזרם הגיש את התשובה, והאם התרחש מעבר לגיבוי.
כדי לראות כל שלב במדיניות, קריאת יעד ומעבר של כלל שגיאה לבקשה אחת, יוצרים סשן ניפוי באגים ב-Apigee מול הגרסה שנפרסה:
DEBUG_URL="https://apigee.googleapis.com/v1/organizations/APIGEE_ORG/environments/APIGEE_ENV/apis/aft-demo-04-add-fallback/revisions/REVISION/debugsessions" curl -X POST -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \ -H "Content-Type: application/json" \ -d '{"filter":"","count":10,"timeout":"600","validity":600}' \ "$DEBUG_URL"
מחליפים את מה שכתוב בשדות הבאים:
-
APIGEE_ORG: שם הארגון ב-Apigee. -
APIGEE_ENV: הסביבה שבה פרסתם את שרת ה-proxy. -
REVISION: מספר הגרסה שנפרסה של שרת ה-proxy שלaft-demo-04-add-fallback.
לאחר מכן, שולחים בקשה שמפעילה את החלופה:
curl -X POST https://APIGEE_HOSTNAME/v1/chat/completions-stage4 \ -H "Content-Type: application/json" \ -d '{"model":"gpt-4o-mini", "messages":[{"role":"user","content":"Describe nuclear fusion in stars in two sentences."}]}'
כשמאחזרים את ההודעות של סשן ניפוי הבאגים שנלכדו באמצעות Apigee API, המעקב מציג את תהליך הביצוע הבא:
- חילוץ משתני בקשה: Apigee מחלץ את המשתנים
llm.modelו-llm.promptמהמטען הייעודי (payload) הנכנס. - הערכת מדיניות הבטיחות: הבקשה עוברת את סינון האבטחה של Model Armor.
- בדיקה של המטמון הסמנטי: החיפוש לא מוצא את המטמון הסמנטי, ולכן הבקשה ממשיכה ליעד.
- הערכת תנאי הניתוב: התנאי
llm.model StartsWith "google/"מקבל את הערךfalse. - ניתוב ליעד הראשי: Apigee מעבירה את הבקשה אל
openai-target. - טיפול בשגיאת היעד: היעד של OpenAI מחזיר קוד סטטוס של HTTP שהוא לא
2xx, וזה גורם ל-Apigee להציג שגיאת יעד. - הפעלת כלל השגיאה: רכיב
DefaultFaultRuleמפעיל את רצף הגיבוי על ידי הפעלת רכיביםAM-BuildVertexFallbackRequest,SC-FallbackToVertexו-AM-CopyVertexFallbackResponse. - החזרת התשובה: הלקוח מקבל תגובת HTTP
200שמכילה מטען ייעודי (payload) שנוצר על ידי Gemini ב-Agent Platform.
המאמרים הבאים
- הגדרת אימות: מטמיעים מפתחות API של Apigee, OpenID Connect (OIDC) או JWT מאוחד לפני שרת ה-proxy כדי לאכוף מכסות אסימונים ספציפיות לדייר ואמצעי בקרת גישה של הספק.
- מעקב אחרי העלות וזמן האחזור: מחברים את מרכזי הבקרה של Apigee Analytics לשרת ה-proxy ל-API כדי לעקוב אחרי זמן האחזור והעלויות התפעוליות לכל מודל.
- החלת מדיניות בטיחות ספציפית לדייר: מגדירים תבניות של Model Armor לכל דייר באמצעות הפרמטר
MA_TEMPLATE_PATHכדי להחיל כללי הסרת תוכן זדוני או רגיש מותאמים אישית על תנועה ארגונית, תנועה של מפתחים ותנועה ציבורית. - הגדרות לדוגמה: כדי להוריד את קבוצת הדוגמאות המלאה, כולל התבנית
llm-fallback.yaml, שמונה קובצי תכונות, הסקריפטrouting-diagnostic.shוסקריפטים להקצאת משאבים ל-KVM, ל-Model Armor ול-Agent Platform חיפוש וקטורי, עיינו במאגר של Apigee progressive AI gateway ב-GitHub.