Crea un gateway AI con routing, Model Armor e cache semantica

Questa pagina si applica ad Apigee e Apigee hybrid.

Visualizza la documentazione di Apigee Edge.

Questo tutorial mostra come configurare e utilizzare Apigee come gateway AI che instrada le richieste di modelli linguistici di grandi dimensioni (LLM) a diversi modelli di backend in base a regole di instradamento flessibili e basate su policy. Un gateway AI ti aiuta a proteggere, governare e ottimizzare il traffico dei modelli per gestire i costi e prevenire la proliferazione dei modelli.

Ogni fase del tutorial si basa sulla configurazione precedente aggiungendo una funzionalità specifica tramite file di modelli di funzionalità Apigee (AFT) riutilizzabili:

  • Fase 1: esegui il deployment di un proxy API minimo che funge da interfaccia per un singolo provider LLM.
  • Fase 2: aggiungi la sanificazione di prompt e risposte di Model Armor per filtrare gli input dannosi e prevenire la fuga di dati sensibili.
  • Fase 3: aggiungi il routing del modello tra provider e una cache semantica supportata da Agent Platform Vector Search.
  • Fase 4: configura il failover tra provider per riprovare automaticamente le richieste con un provider secondario se la destinazione principale restituisce un codice di stato HTTP 4xx o 5xx.

Per aggiungere una funzionalità, aggiungi una singola riga al blocco features nel modello. Per visualizzare o scaricare il set completo di file di esempio, inclusi i file AFT e gli script di supporto, consulta il repository di modelli Apigee su GitHub.

Prima di iniziare

Prima di completare questo tutorial, assicurati di disporre di quanto segue:

  • Un progetto Google Cloud attivo con la fatturazione abilitata.
  • Un ambiente Completo disponibile nella tua istanza Apigee. Puoi eseguire il deployment delle policy di Model Armor, SemanticCacheLookup e SemanticCachePopulate solo negli ambienti Completo.
  • Google Cloud CLI (gcloud) installato e configurato con le Credenziali predefinite dell'applicazione (ADC). Per generare le credenziali, esegui gcloud auth application-default login.
  • Un account di servizio di runtime con i seguenti ruoli IAM:
    • roles/aiplatform.user
    • roles/modelarmor.user
    Il account di servizio deve anche avere accesso a tutte le credenziali specifiche del provider.
  • Per le fasi 2, 3 e 4, specifica un percorso della risorsa del modello Model Armor. Ad esempio, projects/YOUR_PROJECT/locations/us-central1/templates/apigee-aft-demo-ma.
  • Per le fasi 3 e 4: una mappa di coppie chiave-valore (KVM) Apigee denominata openai-credentials nel tuo ambiente che contiene una voce api-key con una chiave API OpenAI valida.
  • Per le fasi 3 e 4: un endpoint dell'indice Vertex AI Vector Search di cui è stato eseguito il deployment per la cache semantica. Per la configurazione dell'indice passo passo, consulta il file README del repository di modelli Apigee su GitHub.

Panoramica

Tutte e quattro le fasi accettano la forma della richiesta di completamento della chat di OpenAI all'indirizzo /v1/chat/completions[-stageN], quindi gli stessi SDK client funzionano in ogni fase. Il prefisso del campo model determina la decisione di routing: le richieste per i modelli google/* vengono indirizzate a Gemini su Agent Platform, mentre tutte le altre richieste vengono indirizzate a OpenAI. Questo valore predefinito invertito garantisce che le nuove famiglie di modelli OpenAI, come o1-*, o3-* e chatgpt-*, vengano indirizzate correttamente anziché mancare silenziosamente una corrispondenza del prefisso gpt-*.

Fase Funzionalità aggiunta Percorso di base
1 Hello LLM (richiesta in formato OpenAI a Gemini su Agent Platform) /v1/chat/completions
2 Model Armor (filtri per prompt injection, AI responsabile e Sensitive Data Protection) /v1/chat/completions-stage2
3 Routing tra provider e una cache semantica di Agent Platform Vector Search /v1/chat/completions-stage3
4 Fallback tra provider (il gateway AI completo) /v1/chat/completions-stage4

Fase 1: Hello LLM

Il proxy minimo si interfaccia con un singolo target Gemini tramite il suo endpoint compatibile con OpenAI. Due piccoli file di funzionalità forniscono lo scheletro del proxy di base e un estrattore JSON. L'estrattore copia $.model e $.messages[-1].content nelle variabili di flusso llm.model e llm.prompt in modo che le fasi successive abbiano input coerenti.

llm-base.yaml definisce lo scheletro del proxy di base:

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 estrae i campi di richiesta nel formato 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 definisce una destinazione Agent Platform che utilizza l'endpoint compatibile con 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

Componi i file delle funzionalità nel modello della fase 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

Esegui il deployment del template:

gcloud beta apigee apis import aft-demo-01-hello-llm \
  --from-template=01-hello-llm.yaml \
  --organization=APIGEE_ORG

Testa il 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"}]}'

Sostituisci quanto segue:

  • APIGEE_ORG: il nome della tua organizzazione Apigee.
  • APIGEE_HOSTNAME: il nome host del tuo gruppo di ambienti Apigee, in genere un bilanciatore del carico Google Cloud .

Fase 2: aggiungi Model Armor

Model Armor ispeziona il prompt in entrata per rilevare prompt injection, contenuti non consentiti e dati sensibili prima della chiamata di destinazione. Quindi, scansiona la risposta del modello prima che raggiunga il client.

Aggiungi un file di funzionalità al modello, 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)}"

Il modello della fase 2, 02-add-model-armor.yaml, aggiunge una riga:

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

Per impostazione predefinita, il parametro MA_TEMPLATE_PATH utilizza un modello denominato apigee-aft-demo-ma in us-central1. Per utilizzare il tuo modello Model Armor, esegui l'override del parametro nel blocco parameters del modello.

Fase 3: aggiungi il routing tra provider e la cache semantica

Nella fase 3, aggiungi un secondo target (OpenAI), sostituisci la regola di instradamento singolo con l'instradamento basato su modello e configuri una cache semantica supportata da Vector Search della piattaforma Agent davanti a entrambi i target.

Per configurare la Fase 3, aggiungi tre file di caratteristiche al blocco features nel modello:

  • target-openai-gpt.yaml: aggiunge OpenAI come endpoint di destinazione secondario.
  • llm-routing.yaml: instrada le richieste in modo dinamico in base al nome del modello richiesto.
  • llm-semantic-cache.yaml: aggiunge una cache semantica davanti a entrambi i provider.

L'esempio seguente mostra come il file di caratteristiche llm-routing.yaml definisce la logica di routing:

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

La cache semantica esegue SemanticCacheLookup nel PreFlow della richiesta e SemanticCachePopulate nel PostFlow della risposta, solo in caso di fallimenti della cache. Entrambe le policy utilizzano un endpoint dell'indice Vector Search di Agent Platform di cui esegui il provisioning separatamente. Il seguente estratto mostra le parti chiave delle definizioni delle policy:

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)

Il modello della fase 3 include tutti i file delle funzionalità:

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"

Esegui il deployment del modello utilizzando lo stesso comando gcloud beta apigee apis import con il flag --from-template che hai utilizzato nella fase 1.

Fase 4: aggiungi il fallback tra fornitori

La fase 4 associa un DefaultFaultRule a entrambe le destinazioni. Quando il target principale restituisce uno stato 4xx o 5xx, la regola di errore invia un ServiceCallout con lo stesso prompt all'altro provider e restituisce la risposta al client. Il client riceve una risposta 200 con esito positivo e un completamento normale e non ha bisogno di una propria logica di ripetizione o gestione degli errori.

Il file delle funzionalità llm-fallback.yaml aggiunge questo comportamento. L'esempio seguente è abbreviato. Per il file completo, consulta il repository 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

Il fallback si basa su due impostazioni:

  • success.codes: 2XX su entrambi i blocchi httpTargetConnection. Apigee considera qualsiasi risposta del target diversa da 2xx come un errore del target e passa direttamente al flusso di errore.
  • Un criterio RaiseFault nel PostFlow della risposta di ogni target, controllato da response.status.code >= 400. Questa policy garantisce che DefaultFaultRule venga eseguito per ogni risposta di errore.

Componi il template della Fase 4, che aggiunge una riga al template della Fase 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

Esegui il deployment del modello:

gcloud beta apigee apis import aft-demo-04-add-fallback \
  --from-template=04-add-fallback.yaml \
  --organization=APIGEE_ORG

Verifica il comportamento end-to-end

Il repository GitHub include uno script routing-diagnostic.sh che esercita tutti i percorsi di routing e di riserva con prompt di argomenti diversi. Poiché la cache semantica bypassa i prompt simili, ogni prompt di test deve essere formulato in modo distinto.

STAGE=4 ./routing-diagnostic.sh

Lo script invia cinque richieste tramite il proxy di fase 4:

  • Un modello OpenAI canonico
  • Un modello Gemini con il prefisso google/
  • Un nome di modello Gemini senza prefisso, che indirizza a OpenAI in base al valore predefinito invertito
  • Un modello di ragionamento di OpenAI
  • Un nome del modello con il prefisso openai/

Per ogni richiesta, lo script indica quale provider upstream ha fornito la risposta e se si è verificato un fallback.

Per visualizzare ogni passaggio della policy, ogni chiamata di destinazione e ogni transizione della regola di errore per una singola richiesta, crea una sessione di debug di Apigee per la revisione di cui è stato eseguito il deployment:

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"

Sostituisci quanto segue:

  • APIGEE_ORG: il nome della tua organizzazione Apigee.
  • APIGEE_ENV: l'ambiente in cui hai eseguito il deployment del proxy.
  • REVISION: il numero di revisione di cui è stato eseguito il deployment del proxy aft-demo-04-add-fallback.

Invia quindi una richiesta che attiva il 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."}]}'

Quando recuperi i messaggi della sessione di debug acquisiti utilizzando l'API Apigee, la traccia mostra il seguente flusso di esecuzione:

  1. Estrai variabili richiesta: Apigee estrae le variabili llm.model e llm.prompt dal payload in entrata.
  2. Valuta le norme di sicurezza: la richiesta supera il filtro di sicurezza di Model Armor.
  3. Controlla la cache semantica: la ricerca non trova la cache semantica, quindi la richiesta continua verso una destinazione.
  4. Valuta la condizione di routing: la condizione llm.model StartsWith "google/" restituisce false.
  5. Route verso il target principale: Apigee inoltra la richiesta a openai-target.
  6. Gestisci l'errore del target: il target OpenAI restituisce un codice di stato HTTP diverso da 2xx, il che fa sì che Apigee generi un errore del target.
  7. Esegui la regola di errore: DefaultFaultRule attiva la sequenza di fallback eseguendo AM-BuildVertexFallbackRequest, SC-FallbackToVertex e AM-CopyVertexFallbackResponse.
  8. Restituzione della risposta: il client riceve una risposta HTTP 200 contenente un payload generato da Gemini su Agent Platform.

Passaggi successivi

  • Configura l'autenticazione: implementa JWT federato, OpenID Connect (OIDC) o chiavi API Apigee davanti al proxy per applicare quote di token specifiche per il tenant e controlli degli accessi del provider.
  • Monitora costi e latenza: collega i dashboard di analisi Apigee al tuo proxy API per monitorare la latenza e i costi operativi in base al modello.
  • Applica policy di sicurezza specifiche per il tenant: configura i template Model Armor per tenant utilizzando il parametro MA_TEMPLATE_PATH per applicare regole di sanificazione personalizzate al traffico aziendale, degli sviluppatori e pubblico.
  • Esplora le configurazioni di esempio: per scaricare il set di esempi completo, incluso il modello llm-fallback.yaml, otto file di funzionalità, lo script routing-diagnostic.sh e gli script di provisioning per KVM, Model Armor e Agent Platform Vector Search, consulta il repository del gateway AI progressiva di Apigee su GitHub.