Cache semântico com um endpoint particular (Private Service Connect)

Esta página se aplica à Apigee, mas não à Apigee híbrida.

Confira a documentação da Apigee Edge.

Nesta página, descrevemos como configurar e usar as políticas de cache semântico da Apigee para permitir a reutilização inteligente de respostas com base na semelhança semântica. Neste exemplo, as políticas executam a pesquisa de similaridade em um índice da Pesquisa de vetor implantado em um endpoint particular (Private Service Connect). Ao usar essas políticas no seu proxy de API da Apigee, você reduz a quantidade de chamadas de API de back-end redundantes, diminui a latência e corta custos operacionais.

Antes de começar

Antes de começar, faça o seguinte:

  1. Faça login na sua conta do Google Cloud . Se você começou a usar o Google Cloud, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
  2. 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 the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. Enable the Compute Engine, AI Platform, and Cloud Storage APIs.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. 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.

    Enable the APIs

  5. 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 the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  6. Verify that billing is enabled for your Google Cloud project.

  7. Enable the Compute Engine, AI Platform, and Cloud Storage APIs.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. 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.

    Enable the APIs

  8. Ative e configure a API Text Embeddings da Vertex AI no seu projeto Google Cloud .
  9. Crie (ou tenha acesso a) um índice da Pesquisa vetorial implantado em um endpoint particular (Private Service Connect). Este tutorial não duplica as etapas de configuração da Pesquisa vetorial. Consulte Pré-requisitos do índice da Pesquisa vetorial para ver os requisitos específicos do SemanticCacheLookup e links para a documentação da Pesquisa vetorial.
  10. Confirme se você tem um ambiente intermediário ou abrangente disponível na sua instância do Apigee. As políticas de armazenamento em cache semântico só podem ser implantadas em ambientes intermediários ou abrangentes.
  11. Confirme se você tem um grupo de ambiente com um nome de host de execução que pode ser usado para enviar solicitações ao proxy de API.

Funções exigidas

Para receber as permissões necessárias para criar e usar as políticas de cache semântico, peça ao administrador para conceder a você o papel do IAM de Usuário da AI Platform (roles/aiplatform.user) na conta de serviço usada para implantar proxies do Apigee. Para mais informações sobre a concessão de papéis, consulte Gerenciar o acesso a projetos, pastas e organizações.

Também é possível conseguir as permissões necessárias usando papéis personalizados ou outros papéis predefinidos.

Defina as variáveis de ambiente

No projeto Google Cloud que contém sua instância do Apigee, use o seguinte comando para definir variáveis de ambiente:

export PROJECT_ID=PROJECT_ID
export REGION=REGION
export RUNTIME_HOSTNAME=RUNTIME_HOSTNAME

Em que:

  • PROJECT_ID é o ID do projeto com sua instância da Apigee.
  • REGION é a Google Cloud região da sua instância da Apigee.
  • RUNTIME_HOSTNAME é o nome do host do ambiente de execução da Apigee.

Para confirmar se as variáveis de ambiente estão definidas corretamente, execute o comando a seguir e analise a saída:

echo $PROJECT_ID $REGION $RUNTIME_HOSTNAME

Definir o projeto

Defina o projeto Google Cloud no ambiente de desenvolvimento:

    gcloud auth login
    gcloud config set project $PROJECT_ID

Pré-requisitos do índice da pesquisa de vetor

Este tutorial pressupõe que você já tenha (ou vai criar) um índice da Pesquisa de vetor implantado em um endpoint particular (Private Service Connect). A criação, formatação e implantação de um índice da Pesquisa de vetor estão documentadas nos guias da Pesquisa de vetor. Portanto, este tutorial não duplica essas etapas. Siga a documentação da busca vetorial para:

Ao criar o índice, ele precisa atender aos seguintes requisitos específicos do SemanticCacheLookup:

  • O índice precisa usar STREAM_UPDATE ("indexUpdateMethod": "STREAM_UPDATE") para que as chamadas upsertDatapoints da política SemanticCachePopulate possam ser consultadas quase em tempo real.
  • O índice dimensions precisa corresponder à dimensionalidade de saída do modelo de embeddings usado na política SemanticCacheLookup. Este tutorial usa o gemini-embedding-001, que produz embeddings de 3072 dimensões por padrão. Se você truncar a saída para uma dimensionalidade menor (por exemplo, 768 ou 1536), defina dimensions com o mesmo valor.
  • Crie o índice com a medida de distância (distanceMeasureType) que corresponde ao <DistanceMeasureType> da sua política. O elemento <SimilaritySearch><VertexAI><DistanceMeasureType> na política SemanticCacheLookup é opcional e o padrão é DOT_PRODUCT_DISTANCE; COSINE_DISTANCE também é aceito. A medida de distância do índice e a política <DistanceMeasureType> precisam ser iguais.

O exemplo mínimo a seguir cria um índice compatível. Para conferir o corpo completo da solicitação e todas as opções disponíveis, consulte Criar e gerenciar um índice:

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

Anote o INDEX_ID numérico retornado na resposta. Ele será usado na política SemanticCachePopulate. Depois de criar o índice, crie um endpoint do índice do Private Service Connect e implante o índice nele.

Ao criar o endpoint do índice do Private Service Connect, ele precisa atender aos seguintes requisitos específicos do SemanticCacheLookup:

  • O projectAllowlist precisa incluir o projeto da Apigee que inicia a conexão:
    • Apigee:use o projeto de locatário da Apigee. Extraia o ID do projeto de locatário da API Organizations (campo apigeeProjectId).
    O projectAllowlist não pode ser modificado depois que o endpoint de índice é criado. Se você colocar na lista de permissões o projeto errado, exclua e recrie o endpoint de índice.

Anote o INDEX_ENDPOINT_ID numérico do endpoint do índice.

Configurar a conta de serviço para o proxy da Apigee

O proxy da Apigee usa uma conta de serviço para as chamadas REST da Vertex AI: a API Embeddings na política SemanticCacheLookup, upsertDatapoints na política SemanticCachePopulate e o destino do modelo. Conceda à conta de serviço o papel AI Platform User (roles/aiplatform.user):

gcloud projects add-iam-policy-binding $PROJECT_ID \
  --member="serviceAccount:SERVICE_ACCOUNT" \
  --role="roles/aiplatform.user"

Em que SERVICE_ACCOUNT é o endereço de e-mail da conta de serviço usada pelo proxy. Você faz referência a essa conta de serviço ao implantar o proxy na Etapa 4: importar e implantar o proxy de API.

Visão geral

As políticas de cache semântico ajudam os usuários da Apigee com modelos de LLM a veicular de forma inteligente e eficiente comandos idênticos ou semanticamente semelhantes, minimizando as chamadas de API de back-end e reduzindo o consumo de recursos.

As políticas SemanticCacheLookup e SemanticCachePopulate são anexadas aos fluxos de solicitação e resposta, respectivamente, de um proxy de API do Apigee. Quando o proxy recebe uma solicitação, a política SemanticCacheLookup extrai o comando do usuário da solicitação e o converte em uma representação numérica usando a API Text embeddings. Uma pesquisa de similaridade semântica é realizada usando a Pesquisa vetorial para encontrar comandos semelhantes. Se um ponto de dados de comando semelhante for encontrado, uma pesquisa de cache será realizada. Se os dados em cache forem encontrados, a resposta em cache será retornada ao cliente.

Se a pesquisa de similaridade não retornar um comando anterior semelhante, o modelo de LLM vai gerar conteúdo em resposta ao comando do usuário e preencher o cache da Apigee com a resposta. Um ciclo de feedback é criado para atualizar as entradas do índice da Pesquisa vetorial em preparação para solicitações futuras.

Nesse cenário, o índice da Pesquisa de vetor é implantado em um endpoint particular (Private Service Connect) por gRPC. Confira mais detalhes sobre o suporte do Private Service Connect da Pesquisa vetorial em Consultar índices do acesso a serviços particulares ou do Private Service Connect.

As seções a seguir descrevem as etapas para criar e configurar as políticas de cache semântico:

  1. Verifique seus recursos e receba os valores de que a Apigee precisa.
  2. Conecte-se ao anexo de serviço.
  3. Crie o pacote do proxy de API.
  4. Importe e implante o proxy de API.
  5. Teste as políticas de cache semântico.

Etapa 1: verifique seus recursos e receba os valores necessários para o Apigee

Antes de configurar o Apigee, confirme se o endpoint do índice da Pesquisa vetorial está ativado para o Private Service Connect e se o índice foi implantado. Em seguida, leia os dois valores que o proxy do Apigee consome: o anexo de serviço e o DEPLOYED_INDEX_ID.

Confirme se o índice está implantado e se o endpoint expõe um anexo de serviço do Private Service Connect:

gcloud ai index-endpoints describe INDEX_ENDPOINT_ID \
  --project=$PROJECT_ID --region=$REGION \
  --format="value(deployedIndexes.privateEndpoints.serviceAttachment)"

O comando retorna um nome de recurso de anexo de serviço no formato projects/TENANT_PROJECT/regions/REGION/serviceAttachments/SERVICE_ATTACHMENT_NAME. Neste guia, esse valor é chamado de SERVICE_ATTACHMENT. Se o comando retornar um valor vazio, o índice ainda não foi implantado em um endpoint do Private Service Connect. Volte para Pré-requisitos do índice da Pesquisa vetorial e termine de implantar o índice antes de continuar.

Leia o DEPLOYED_INDEX_ID do índice implantado no endpoint:

gcloud ai index-endpoints describe INDEX_ENDPOINT_ID \
  --project=$PROJECT_ID --region=$REGION \
  --format="value(deployedIndexes.id)"

Neste guia, esse valor é chamado de DEPLOYED_INDEX_ID. Você o usa na política SemanticCacheLookup na Etapa 3: criar o pacote de proxy de API.

Para mais informações sobre como implantar e consultar endpoints de índice particulares, consulte Implantar um índice em um endpoint do Private Service Connect e Consultar índices do Private Services Access ou do Private Service Connect.

Etapa 2: conectar-se ao anexo de serviço

Essa etapa fornece o host particular que as chamadas <GrpcEndpoint> do proxy fazem. Na Apigee, crie um anexo de endpoint da Apigee. O anexo de endpoint é o lado do consumidor do Private Service Connect do Apigee: ele se conecta ao anexo de serviço da busca vetorial e oferece um host particular que o proxy chama.

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"

Pesquise até que o state do anexo seja ACTIVE e o connectionState seja ACCEPTED. Em seguida, anote o host:

curl -s -H "Authorization: Bearer $(gcloud auth print-access-token)" \
  "https://apigee.googleapis.com/v1/organizations/$PROJECT_ID/endpointAttachments/ENDPOINT_ATTACHMENT"

A resposta contém o host no campo host. Neste guia, esse valor é chamado de TARGET_HOST.

Para se conectar ao anexo de serviço da busca vetorial do seu proxy, use uma destas opções:

  • O endereço IP:use o endereço IP retornado no campo host diretamente como TARGET_HOST (por exemplo, 7.0.3.4).
  • Um registro DNS particular:se você configurou uma zona de DNS privada do Cloud DNS no projeto Google Cloud com peering de DNS para a Apigee, crie um registro A na sua zona particular apontando para o endereço IP do anexo de endpoint e use esse nome de domínio (como vectorsearch.example.com) como TARGET_HOST. Para mais informações, consulte Usar um registro DNS e Conectar-se a zonas de peering de DNS particular.

Etapa 3: criar o pacote de proxy de API

Criar o pacote de proxy

Crie o seguinte layout de diretório:

apiproxy/
├── PROXY_NAME.xml
├── proxies/default.xml
├── targets/default.xml
└── policies/
    ├── SCL-1.xml
    └── SCP-1.xml

policies/SCL-1.xml: a política SemanticCacheLookup. O bloco <SimilaritySearch> usa <PrivateServiceConnect><GrpcEndpoint> (sem <URL>).

Observação: regras de <GrpcEndpoint>:

  • O formato é grpc://TARGET_HOST:PORT, e o esquema precisa ser grpc://. O grpcs:// (TLS) não é compatível com esta versão.
  • A porta é 10000 para a busca vetorial. Os endpoints do plano de dados do Private Service Connect atendem ao gRPC na porta 10000. Portanto, o endpoint é sempre grpc://TARGET_HOST:10000.
  • TARGET_HOST pode ser o endereço IP do anexo de endpoint (da Etapa 2) ou um registro DNS personalizado criado na sua zona de DNS particular.
  • O salto gRPC é texto simples e não autenticado (protegido por isolamento de rede).
<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: a política SemanticCachePopulate. O preenchimento é somente REST e precisa usar <URL> (rejeita <PrivateServiceConnect> no momento da implantação):

<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: o destino do modelo. O destino chama uma API do Google, então precisa de um token. <GoogleAccessToken> usa a conta de serviço da implantação:

<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: execute a política SemanticCacheLookup na solicitação e a política SemanticCachePopulate na resposta:

<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: o descritor do pacote.

<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>

Etapa 4: importar e implantar o proxy de API

Compacte o pacote, importe-o para criar uma nova revisão e implante a revisão com sua conta de serviço:

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"

Em que:

  • BUNDLE_DIR é o diretório que contém a pasta apiproxy/. O arquivo precisa conter a pasta apiproxy/ na raiz.
  • ENV é o ambiente da Apigee em que você implanta o proxy. O ambiente precisa ser intermediário ou abrangente.
  • REVISION é o número da revisão retornado pela chamada de importação.
  • SERVICE_ACCOUNT é o endereço de e-mail da conta de serviço usada para implantar o proxy.

Aguarde até que a implantação informe 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

Etapa 5: testar as políticas de cache semântico

Envie um novo comando. Isso é uma ausência no cache: o modelo é chamado e a resposta é armazenada em cache.

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

Envie o mesmo comando de novo. Isso é uma ocorrência em cache: a resposta é veiculada do cache e o modelo não é chamado.

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

No hit, a resposta inclui o cabeçalho Cached-content: true, a mesma resposta e uma latência visivelmente menor.

Também é possível verificar o cache com uma sessão de depuração. Em um acerto, a política SemanticCacheLookup define as seguintes variáveis de fluxo:

Variável Valor em um hit
SemanticCacheLookup.SCL-1.dense_embeddings O vetor de embedding do comando.
SemanticCacheLookup.SCL-1.is_nearest_neighbor_hit true
SemanticCacheLookup.SCL-1.cache_hit true
SemanticCacheLookup.SCL-1.cached_llm_response A resposta armazenada em cache.

Em uma ocorrência, o destino do modelo não é invocado. O fluxo é interrompido e retorna a resposta em cache.

Solução de problemas

Para conferir a referência completa de erros, consulte a política SemanticCacheLookup.

A seguir