Criar um gateway de IA com roteamento, Model Armor e cache semântico

Esta página se aplica à Apigee e à Apigee híbrida.

Confira a documentação da Apigee Edge.

Neste tutorial, mostramos como configurar e usar a Apigee como um gateway de IA que encaminha solicitações de modelos de linguagem grandes (LLMs) para diferentes modelos de back-end com base em regras de rota flexíveis e orientadas por políticas. Um gateway de IA ajuda a proteger, controlar e otimizar o tráfego do modelo para gerenciar custos e evitar a proliferação de modelos.

Cada estágio do tutorial se baseia na configuração anterior, adicionando um recurso específico por meio de arquivos reutilizáveis do modelo de recurso da Apigee (AFT, na sigla em inglês):

  • Estágio 1: implantar um proxy de API mínimo que esteja à frente de um único provedor de LLM.
  • Etapa 2: adicione a sanitização de comandos e respostas do Model Armor para filtrar entradas mal-intencionadas e evitar o vazamento de dados sensíveis.
  • Estágio 3: adicionar roteamento de modelos entre provedores e um cache semântico com suporte da Pesquisa Vetorial da Agent Platform.
  • Estágio 4: configure o fallback entre provedores para tentar novamente as solicitações em um provedor secundário se o destino principal retornar um código de status HTTP 4xx ou 5xx.

Para adicionar um recurso, anexe uma única linha ao bloco features no modelo. Para ver ou fazer o download do conjunto completo de arquivos de exemplo, incluindo os arquivos AFT e os scripts auxiliares, consulte o repositório de modelos da Apigee no GitHub.

Antes de começar

Antes de concluir este tutorial, verifique se você tem o seguinte:

  • Um projeto do Google Cloud ativo com o faturamento ativado.
  • Um ambiente abrangente disponível na sua instância da Apigee. É possível implantar políticas do Model Armor, SemanticCacheLookup e SemanticCachePopulate somente em ambientes abrangentes.
  • A CLI do Google Cloud (gcloud) instalada e configurada com Application Default Credentials (ADC). Para gerar credenciais, execute gcloud auth application-default login.
  • Uma conta de serviço de ambiente de execução com os seguintes papéis do IAM:
    • roles/aiplatform.user
    • roles/modelarmor.user
    A conta de serviço também precisa de acesso a credenciais específicas do provedor.
  • Para as etapas 2, 3 e 4, especifique um caminho de recurso de modelo do Model Armor. Por exemplo, projects/YOUR_PROJECT/locations/us-central1/templates/apigee-aft-demo-ma.
  • Para as etapas 3 e 4: um mapa de chave-valor (KVM) da Apigee chamado openai-credentials no seu ambiente que contém uma entrada api-key com uma chave de API válida da OpenAI.
  • Para as etapas 3 e 4: um endpoint de índice da Pesquisa Vetorial da Vertex AI implantado para o cache semântico. Para ver um guia explicativo sobre a configuração do índice, consulte o arquivo README do repositório de modelos da Apigee no GitHub.

Visão geral

Todos os quatro estágios aceitam o formato de solicitação de preenchimento de chat da OpenAI em /v1/chat/completions[-stageN], então os mesmos SDKs de cliente funcionam em todos os estágios. O prefixo do campo model impulsiona a decisão de roteamento: solicitações de modelos google/* são roteadas para o Gemini na Agent Platform, e todas as outras solicitações são roteadas para a OpenAI. Esse padrão invertido garante que novas famílias de modelos da OpenAI, como o1-*, o3-* e chatgpt-*, sejam encaminhadas corretamente em vez de perder silenciosamente uma correspondência de prefixo gpt-*.

Fase Recurso adicionado Caminho base
1 Hello LLM (solicitação no formato da OpenAI para o Gemini na Agent Platform) /v1/chat/completions
2 Model Armor (injeção de comandos, IA responsável e filtros da Proteção de Dados Sensíveis) /v1/chat/completions-stage2
3 Roteamento entre provedores e um cache semântico da busca vetorial da Agent Platform /v1/chat/completions-stage3
4 Fallback entre provedores (o gateway de IA completo) /v1/chat/completions-stage4

Etapa 1: Olá, LLM

O proxy mínimo fica na frente de um único destino do Gemini usando o endpoint compatível com a OpenAI. Dois pequenos arquivos de recursos fornecem o esqueleto do proxy base e um extrator JSON. O extrator copia $.model e $.messages[-1].content para as variáveis de fluxo llm.model e llm.prompt para que as etapas posteriores tenham entradas consistentes.

llm-base.yaml define o esqueleto do 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 extrai os campos de solicitação no formato da 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 define um destino da Agent Platform que usa o endpoint compatível com a 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

Crie os arquivos de recursos no modelo da etapa 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

Implante o modelo:

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

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

Substitua:

  • APIGEE_ORG: o nome da organização da Apigee.
  • APIGEE_HOSTNAME: o nome do host do seu grupo de ambiente da Apigee, normalmente um balanceador de carga Google Cloud .

Etapa 2: adicionar o Model Armor

O Model Armor inspeciona o comando recebido em busca de injeção de comandos, conteúdo proibido e dados sensíveis antes da chamada de destino. Em seguida, ele verifica a resposta do modelo antes que ela chegue ao cliente.

Adicione um arquivo de atributo ao modelo, 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)}"

O modelo da etapa 2, 02-add-model-armor.yaml, adiciona uma linha:

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

O parâmetro MA_TEMPLATE_PATH usa como padrão um modelo chamado apigee-aft-demo-ma em us-central1. Para usar seu próprio modelo do Model Armor, substitua o parâmetro no bloco parameters do modelo.

Estágio 3: adicionar roteamento entre provedores e cache semântico

Na Fase 3, você vai adicionar um segundo destino (OpenAI), substituir a regra de rota única pelo roteamento baseado em modelo e configurar um cache semântico com suporte da Pesquisa Vetorial da Agent Platform na frente dos dois destinos.

Para configurar o Estágio 3, anexe três arquivos de atributos ao bloco features no modelo:

  • target-openai-gpt.yaml: adiciona a OpenAI como um endpoint de destino secundário.
  • llm-routing.yaml: encaminha solicitações dinamicamente com base no nome do modelo solicitado.
  • llm-semantic-cache.yaml: adiciona um cache semântico na frente dos dois provedores.

O exemplo a seguir mostra como o arquivo de recursos llm-routing.yaml define a lógica de roteamento:

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

O cache semântico executa SemanticCacheLookup no PreFlow de solicitação e SemanticCachePopulate no PostFlow de resposta, apenas em ausências no cache. As duas políticas usam um endpoint de índice da Pesquisa vetorial da Agent Platform que você provisiona separadamente. O trecho a seguir mostra as partes principais das definições de política:

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)

O modelo da Fase 3 inclui todos os arquivos de recursos:

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"

Implante o modelo usando o mesmo comando gcloud beta apigee apis import com a flag --from-template usada na etapa 1.

Etapa 4: adicionar um substituto entre provedores

O estágio 4 anexa um DefaultFaultRule aos dois destinos. Quando o destino principal retorna qualquer status 4xx ou 5xx, a regra de falha envia um ServiceCallout com o mesmo comando para o outro provedor e retorna essa resposta ao cliente. O cliente recebe uma resposta 200 bem-sucedida com uma conclusão normal e não precisa da própria lógica de nova tentativa ou tratamento de erros.

O arquivo de recurso llm-fallback.yaml adiciona esse comportamento. O exemplo a seguir está abreviado. Para ver o arquivo completo, consulte o repositório do 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

O substituto depende de duas configurações:

  • success.codes: 2XX nos dois blocos httpTargetConnection. A Apigee trata qualquer resposta de destino que não seja 2xx como uma falha de destino e faz a transição direta para o fluxo de falha.
  • Uma política RaiseFault em cada PostFlow de resposta do destino, controlada por response.status.code >= 400. Essa política garante que o DefaultFaultRule seja executado para cada resposta de erro.

Crie o modelo da etapa 4, que adiciona uma linha ao modelo da etapa 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

Implante o modelo:

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

Verificar o comportamento de ponta a ponta

O repositório do GitHub inclui um script routing-diagnostic.sh que exercita todos os caminhos de roteamento e fallback com comandos diversos. Como o cache semântico evita comandos semelhantes, cada comando de teste precisa ser formulado de maneira diferente.

STAGE=4 ./routing-diagnostic.sh

O script envia cinco solicitações pelo proxy da etapa 4:

  • Um modelo canônico da OpenAI
  • Um modelo do Gemini com o prefixo google/
  • Um nome de modelo do Gemini sem um prefixo, que é encaminhado para a OpenAI de acordo com o padrão invertido
  • Um modelo de raciocínio da OpenAI
  • Um nome de modelo com o prefixo openai/

Para cada solicitação, o script informa qual provedor upstream veiculou a resposta e se ocorreu um fallback.

Para ver cada etapa da política, chamada de destino e transição de regra de falha para uma única solicitação, crie uma sessão de depuração da Apigee na revisão implantada:

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"

Substitua:

  • APIGEE_ORG: o nome da organização da Apigee.
  • APIGEE_ENV: o ambiente em que você implantou o proxy.
  • REVISION: o número da revisão implantada do proxy aft-demo-04-add-fallback.

Em seguida, envie uma solicitação que exerça o 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."}]}'

Ao recuperar as mensagens da sessão de depuração capturadas usando a API Apigee, o rastreamento mostra o seguinte fluxo de execução:

  1. Extrair variáveis de solicitação: a Apigee extrai as variáveis llm.model e llm.prompt do payload recebido.
  2. Avaliar políticas de segurança: a solicitação passa pela filtragem de segurança do Model Armor.
  3. Verifique o cache semântico: a pesquisa não encontra o cache semântico, então a solicitação continua para um destino.
  4. Avaliar a condição de roteamento: a condição llm.model StartsWith "google/" é avaliada como false.
  5. Encaminhamento para o destino principal: a Apigee encaminha a solicitação para openai-target.
  6. Processar o erro de destino: o destino da OpenAI retorna um código de status HTTP não 2xx, o que faz com que a Apigee gere um erro de destino.
  7. Executar a regra de falha: o DefaultFaultRule aciona a sequência de substituição executando AM-BuildVertexFallbackRequest, SC-FallbackToVertex e AM-CopyVertexFallbackResponse.
  8. Retornar a resposta: o cliente recebe uma resposta HTTP 200 que contém um payload gerado pelo Gemini na Agent Platform.

A seguir

  • Configurar a autenticação: implemente JWT federado, OpenID Connect (OIDC) ou chaves de API da Apigee na frente do proxy para aplicar cotas de token específicas do locatário e controles de acesso do provedor.
  • Monitore o custo e a latência: anexe painéis de análise do Apigee ao proxy de API para acompanhar a latência e os custos operacionais por modelo.
  • Aplicar políticas de segurança específicas do locatário: configure modelos do Model Armor por locatário usando o parâmetro MA_TEMPLATE_PATH para aplicar regras de limpeza personalizadas em tráfego empresarial, de desenvolvedores e público.
  • Explore exemplos de configurações: para fazer o download do conjunto de exemplos completo, incluindo o modelo llm-fallback.yaml, oito arquivos de recursos, o script routing-diagnostic.sh e scripts de provisionamento para KVM, Model Armor e busca vetorial da Agent Platform, consulte o repositório do gateway de IA progressiva do Apigee no GitHub.