Créer une passerelle d'IA avec routage, Model Armor et cache sémantique

Cette page s'applique à Apigee et à Apigee hybrid.

Consultez la documentation d' Apigee Edge.

Ce tutoriel explique comment configurer et utiliser Apigee en tant que passerelle d'IA qui achemine les requêtes de grands modèles de langage (LLM) vers différents modèles de backend en fonction de règles de routage flexibles et basées sur des règles. Une passerelle d'IA vous aide à sécuriser, gérer et optimiser le trafic de vos modèles pour contrôler les coûts et éviter la prolifération des modèles.

Chaque étape du tutoriel s'appuie sur la configuration précédente en ajoutant une fonctionnalité spécifique à l'aide de fichiers de modèles de fonctionnalités Apigee (AFT) réutilisables :

  • Étape 1 : Déployez un proxy d'API minimal qui sert d'interface à un seul fournisseur de LLM.
  • Étape 2 : Ajoutez le nettoyage des prompts et des réponses Model Armor pour filtrer les entrées malveillantes et empêcher les fuites de données sensibles.
  • Étape 3 : Ajoutez le routage de modèle multi-fournisseurs et un cache sémantique basé sur la recherche vectorielle Agent Platform.
  • Étape 4 : Configurez le remplacement entre fournisseurs pour relancer automatiquement les requêtes auprès d'un fournisseur secondaire si la cible principale renvoie un code d'état HTTP 4xx ou 5xx.

Pour ajouter une fonctionnalité, ajoutez une seule ligne au bloc features de votre modèle. Pour afficher ou télécharger l'ensemble complet d'exemples de fichiers, y compris les fichiers AFT et les scripts d'assistance, consultez le dépôt de modèles Apigee sur GitHub.

Avant de commencer

Avant de suivre ce tutoriel, assurez-vous d'avoir les éléments suivants :

  • Un projet Google Cloud actif avec facturation activée.
  • Un environnement complet disponible dans votre instance Apigee. Vous ne pouvez déployer les règles Model Armor, SemanticCacheLookup et SemanticCachePopulate que dans des environnements complets.
  • Google Cloud CLI (gcloud) installé et configuré avec les Identifiants par défaut de l'application (ADC). Pour générer des identifiants, exécutez gcloud auth application-default login.
  • Un compte de service d'exécution avec les rôles IAM suivants :
    • roles/aiplatform.user
    • roles/modelarmor.user
    Le compte de service doit également avoir accès aux identifiants spécifiques au fournisseur.
  • Pour les étapes 2, 3 et 4, spécifiez un chemin d'accès à la ressource du modèle Model Armor. Exemple : projects/YOUR_PROJECT/locations/us-central1/templates/apigee-aft-demo-ma
  • Pour les étapes 3 et 4 : un mappage clé-valeur (KVM) Apigee nommé openai-credentials dans votre environnement, qui contient une entrée api-key avec une clé API OpenAI valide.
  • Pour les étapes 3 et 4 : un point de terminaison d'index de recherche Vertex AI Vector Search déployé pour le cache sémantique. Pour configurer l'index par étapes, consultez le fichier README du dépôt de modèles Apigee sur GitHub.

Présentation

Les quatre étapes acceptent la forme de requête OpenAI Chat Completions sur /v1/chat/completions[-stageN]. Les mêmes SDK client fonctionnent donc à chaque étape. Le préfixe de champ model détermine la décision de routage : les requêtes pour les modèles google/* sont acheminées vers Gemini sur Agent Platform, et toutes les autres requêtes sont acheminées vers OpenAI. Cette valeur par défaut inversée garantit que les nouvelles familles de modèles OpenAI, telles que o1-*, o3-* et chatgpt-*, sont correctement acheminées au lieu de manquer silencieusement une correspondance de préfixe gpt-*.

Étape Fonctionnalité ajoutée Chemin de base
1 Hello LLM (requête au format OpenAI envoyée à Gemini sur Agent Platform) /v1/chat/completions
2 Model Armor (injection de prompt, IA responsable et filtres Sensitive Data Protection) /v1/chat/completions-stage2
3 Routage entre fournisseurs et cache sémantique de recherche vectorielle Agent Platform /v1/chat/completions-stage3
4 La solution de remplacement multiproviseur (la passerelle d'IA complète) /v1/chat/completions-stage4

Étape 1 : Hello LLM

Le proxy minimal sert de façade à une seule cible Gemini via son point de terminaison compatible avec OpenAI. Deux petits fichiers de caractéristiques fournissent le squelette du proxy de base et un extracteur JSON. L'extracteur copie $.model et $.messages[-1].content dans les variables de flux llm.model et llm.prompt afin que les étapes ultérieures disposent d'entrées cohérentes.

llm-base.yaml définit le squelette du proxy de 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 extrait les champs de requête au format 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 définit une cible Agent Platform qui utilise le point de terminaison compatible avec 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

Composez les fichiers de caractéristiques dans le modèle de l'étape 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

Déployez le modèle :

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

Testez le 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"}]}'

Remplacez les éléments suivants :

  • APIGEE_ORG : nom de votre organisation Apigee.
  • APIGEE_HOSTNAME : nom d'hôte de votre groupe d'environnements Apigee, généralement un équilibreur de charge Google Cloud .

Étape 2 : Ajoutez Model Armor

Model Armor inspecte le prompt entrant pour détecter l'injection de prompt, le contenu interdit et les données sensibles avant l'appel cible. Il analyse ensuite la réponse du modèle avant qu'elle n'atteigne le client.

Ajoutez un fichier de caractéristiques au modèle, 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)}"

Le modèle de l'étape 2, 02-add-model-armor.yaml, ajoute une ligne :

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

Le paramètre MA_TEMPLATE_PATH est défini par défaut sur un modèle nommé apigee-aft-demo-ma dans us-central1. Pour utiliser votre propre modèle Model Armor, remplacez le paramètre dans le bloc parameters du modèle.

Étape 3 : Ajoutez le routage multi-fournisseur et le cache sémantique

À l'étape 3, vous allez ajouter une deuxième cible (OpenAI), remplacer la règle de routage unique par un routage basé sur un modèle et configurer un cache sémantique soutenu par Vector Search sur Agent Platform devant les deux cibles.

Pour configurer l'étape 3, ajoutez trois fichiers de caractéristiques au bloc features de votre modèle :

  • target-openai-gpt.yaml : ajoute OpenAI comme point de terminaison cible secondaire.
  • llm-routing.yaml : route les requêtes de manière dynamique en fonction du nom du modèle demandé.
  • llm-semantic-cache.yaml : ajoute un cache sémantique devant les deux fournisseurs.

L'exemple suivant montre comment le fichier de caractéristiques llm-routing.yaml définit la logique de routage :

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

Le cache sémantique s'exécute SemanticCacheLookup dans le PreFlow de requête et SemanticCachePopulate dans le PostFlow de réponse, uniquement en cas de défauts de cache. Les deux règles utilisent un point de terminaison d'index de recherche Vector Search Agent Platform que vous provisionnez séparément. L'extrait suivant montre les parties clés des définitions de règles :

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)

Le modèle de l'étape 3 compose tous les fichiers de caractéristiques :

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"

Déployez le modèle à l'aide de la même commande gcloud beta apigee apis import avec l'option --from-template que vous avez utilisée à l'étape 1.

Étape 4 : Ajouter une solution de remplacement entre fournisseurs

L'étape 4 associe un DefaultFaultRule aux deux cibles. Lorsque la cible principale renvoie un état 4xx ou 5xx, la règle d'erreur envoie un ServiceCallout avec le même prompt à l'autre fournisseur et renvoie cette réponse au client. Le client reçoit une réponse 200 indiquant que l'opération s'est terminée normalement. Il n'a pas besoin de sa propre logique de nouvelle tentative ni de gestion des exceptions.

Le fichier de caractéristiques llm-fallback.yaml ajoute ce comportement. L'exemple suivant est abrégé. Pour obtenir le fichier complet, consultez le dépôt 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

La création de remplacement repose sur deux paramètres :

  • success.codes: 2XX sur les deux blocs httpTargetConnection. Apigee traite toute réponse cible non 2xx comme un échec de la cible et passe directement au flux d'erreur.
  • Une règle RaiseFault dans le PostFlow de réponse de chaque cible, contrôlée par response.status.code >= 400. Cette règle garantit que DefaultFaultRule s'exécute pour chaque réponse d'erreur.

Composez le modèle de l'étape 4, qui ajoute une ligne au modèle de l'étape 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

Déployez le modèle :

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

Vérifier le comportement de bout en bout

Le dépôt GitHub inclut un script routing-diagnostic.sh qui teste tous les chemins de routage et de remplacement avec des requêtes sur des thèmes variés. Étant donné que le cache sémantique court-circuite les requêtes similaires, chaque requête de test doit être formulée de manière distincte.

STAGE=4 ./routing-diagnostic.sh

Le script envoie cinq requêtes via le proxy de l'étape 4 :

  • Un modèle OpenAI canonique
  • Un modèle Gemini avec le préfixe google/
  • Un nom de modèle Gemini sans préfixe, qui est acheminé vers OpenAI selon la valeur par défaut inversée.
  • Un modèle de raisonnement OpenAI
  • Nom de modèle avec le préfixe openai/

Pour chaque requête, le script indique quel fournisseur en amont a diffusé la réponse et si un remplacement a eu lieu.

Pour afficher chaque étape de la règle, chaque appel cible et chaque transition de règle d'erreur pour une seule requête, créez une session de débogage Apigee sur la révision déployée :

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"

Remplacez les éléments suivants :

  • APIGEE_ORG : nom de votre organisation Apigee.
  • APIGEE_ENV : environnement dans lequel vous avez déployé le proxy.
  • REVISION : numéro de révision déployé du proxy aft-demo-04-add-fallback.

Envoyez ensuite une requête qui utilise la solution de repli :

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

Lorsque vous récupérez les messages de la session de débogage capturés à l'aide de l'API Apigee, la trace affiche le flux d'exécution suivant :

  1. Extraire les variables de requête : Apigee extrait les variables llm.model et llm.prompt de la charge utile entrante.
  2. Évaluer les règles de sécurité : la requête passe le filtrage de sécurité Model Armor.
  3. Vérifier le cache sémantique : la recherche ne trouve pas le cache sémantique. La requête continue donc vers une cible.
  4. Évaluer la condition de routage : la condition llm.model StartsWith "google/" renvoie la valeur false.
  5. Routage vers la cible principale : Apigee transfère la requête vers openai-target.
  6. Gérer l'erreur de cible : la cible OpenAI renvoie un code d'état HTTP autre que 2xx, ce qui amène Apigee à générer une erreur de cible.
  7. Exécuter la règle d'erreur : DefaultFaultRule déclenche la séquence de secours en exécutant AM-BuildVertexFallbackRequest, SC-FallbackToVertex et AM-CopyVertexFallbackResponse.
  8. Renvoyer la réponse : le client reçoit une réponse HTTP 200 contenant une charge utile générée par Gemini sur Agent Platform.

Étapes suivantes

  • Configurer l'authentification : implémentez des jetons JWT fédérés, OpenID Connect (OIDC) ou des clés API Apigee devant le proxy pour appliquer des quotas de jetons spécifiques au locataire et des contrôles d'accès des fournisseurs.
  • Surveiller les coûts et la latence : associez des tableaux de bord d'analyse Apigee à votre proxy d'API pour suivre la latence et les coûts opérationnels par modèle.
  • Appliquer des règles de sécurité spécifiques au locataire : configurez des modèles Model Armor par locataire à l'aide du paramètre MA_TEMPLATE_PATH pour appliquer des règles de nettoyage personnalisées au trafic d'entreprise, de développeur et public.
  • Explorer des exemples de configurations : pour télécharger l'ensemble complet d'exemples, y compris le modèle llm-fallback.yaml, huit fichiers de caractéristiques, le script routing-diagnostic.sh et les scripts de provisionnement pour KVM, Model Armor et Agent Platform Vector Search, consultez le dépôt GitHub de la passerelle d'IA progressive Apigee.