Implementar pesquisa semântica e híbrida com o Azure Cosmos DB for NoSQL
Voltar para a trilha AI-200
AI-200Capítulo 10

Estudo para a Certificação Microsoft AI-200

Implementar pesquisa semântica e híbrida com o Azure Cosmos DB for NoSQL

Armazene embeddings junto aos dados operacionais, escolha políticas vetoriais e índices DiskANN, classifique resultados semânticos e híbridos e atualize vetores pelo feed de alterações.

Tempo de estudo sugerido: 105 minutos • Nível intermediário • Reescrita autoral completa com versão resumida de cada tópico, avaliação comentada e laboratório guiado de pesquisa semântica

Escudo neon Microsoft Certified AI-200 com embeddings vetoriais, pesquisa semântica, Azure Cosmos DB e atualização orientada a eventos

1. Transformar documentos operacionais em conhecimento pesquisável por significado

A busca por palavras-chave perde conteúdo quando usuário e autor escolhem termos diferentes. Uma pergunta sobre queda da conexão sem fio ainda pode encontrar um artigo de diagnóstico de WiFi quando ambos os textos são representados por vetores próximos. O for armazena esses embeddings com o documento e seus , dispensando a sincronização de um banco vetorial separado.

  • Persistir embeddings ao lado do conteúdo e dos filtráveis.
  • Configurar políticas e índices vetoriais compatíveis com o modelo.
  • Executar consultas de similaridade, filtradas, híbridas e multivetoriais.
  • Atualizar embeddings automaticamente quando a origem mudar.

Resumo do tópico

A pesquisa semântica compara significado no espaço vetorial; reunir vetores, documentos e simplifica o caminho dos dados de IA.

2. Modelar conteúdo, e embeddings no mesmo documento

Embedding é uma matriz numérica produzida por um modelo de machine learning a partir de texto, imagem ou outro conteúdo. Entradas semanticamente próximas ocupam posições vizinhas em um espaço de muitas dimensões. O modelo define o tamanho: text-embedding-ada-002 gera 1.536 valores e text-embedding-3-large pode gerar 3.072. Mais dimensões podem preservar nuances, mas aumentam armazenamento e indexação.

Um item útil reúne id, texto pesquisável, categoria, produto, data, atributos de acesso e embedding. Os atendem filtros exatos e o vetor fornece classificação semântica. Título e corpo podem compartilhar um vetor ou ocupar caminhos diferentes.

Conteúdo e metadados são convertidos em embedding e armazenados juntos em um documento do Azure Cosmos DB.
O modelo gera o vetor; o o mantém ao lado dos dados representados.

Resumo do tópico

Armazene conteúdo original, filtráveis e embedding compatível com o modelo no mesmo item.

3. Configurar política vetorial e função de distância

A política associa cada caminho de embedding ao tipo, dimensões e função de distância. Os valores devem coincidir com a saída do modelo. Cosseno compara direção e costuma atender embeddings normalizados de texto; produto escalar considera direção e magnitude e equivale ao cosseno para vetores normalizados; Euclidiana mede a distância em linha reta, na qual valores menores representam maior proximidade.

vector_policy = {
    "vectorEmbeddings": [{
        "path": "/embedding",
        "dataType": "float32",
        "distanceFunction": "cosine",
        "dimensions": 1536
    }]
}

indexing_policy = {
    "indexingMode": "consistent",
    "automatic": True,
    "includedPaths": [{"path": "/*"}],
    "excludedPaths": [{"path": "/_etag/?"}, {"path": "/embedding/*"}],
    "vectorIndexes": [{"path": "/embedding", "type": "diskANN"}]
}

Habilite a pesquisa vetorial na conta. Trate o formato como decisão inicial: a documentação atual permite adicionar ou remover caminhos, mas não editar diretamente uma configuração existente; descarte e recrie a política ou o índice quando precisar alterar seus parâmetros.

Resumo do tópico

Caminho, tipo, dimensões e função de distância precisam descrever exatamente os vetores armazenados.

4. Escolher tipos de dados e índices vetoriais

float32 prioriza precisão e simplicidade. float16 reduz aproximadamente pela metade o armazenamento vetorial, geralmente com pouco impacto. int8 e uint8 exigem embeddings quantizados e economizam mais espaço, porém precisam de avaliação de qualidade.

Opções de índice vetorial.
ÍndiceLimites e comportamentoUso típico
flat exata; até 505 dimensões.Coleções pequenas ou validação com recuperação integral.
quantizedFlatVarredura exata comprimida; até 4.096 dimensões.Aproximadamente até 50 mil vetores no escopo.
diskANNÍndice DiskANN aproximado e rápido; até 4.096 dimensões.Coleções grandes com metas de latência e RU.

quantizedFlat e diskANN precisam de pelo menos 1.000 vetores para o índice entrar em ação; abaixo disso ocorre varredura completa. Exclua o caminho do embedding do índice de intervalo comum para não elevar armazenamento e custo de gravação sem benefício.

Fluxo da consulta desde o embedding e os filtros até o índice vetorial, a classificação por similaridade e a pesquisa híbrida.
Índice e consulta equilibram recuperação, latência, volume de resultados e consumo de RU.

Resumo do tópico

Escolha precisão e índice conforme dimensões, escala, latência, recuperação e RU, sempre com testes representativos.

5. Criar o contêiner e gravar embeddings sincronizados

Crie o contêiner com as políticas vetorial e de indexação e uma chave de partição alinhada aos filtros frequentes. Uma base de suporte particionada por /category direciona pesquisas de uma categoria a uma única partição. Gere o embedding do mesmo conteúdo pesquisável e grave documento e vetor juntos.

from azure.cosmos import CosmosClient, PartitionKey

container = database.create_container(
    id="support-knowledge",
    partition_key=PartitionKey(path="/category"),
    indexing_policy=indexing_policy,
    vector_embedding_policy=vector_policy
)
from openai import AzureOpenAI

text = f"{title}
{content}"
response = openai_client.embeddings.create(
    input=text,
    model="text-embedding-ada-002"
)

container.upsert_item({
    "id": document_id,
    "title": title,
    "content": content,
    "category": category,
    "productId": product_id,
    "createdDate": created_date,
    "embedding": response.data[0].embedding
})

Use a mesma implantação do modelo para documentos e consultas. Quando o texto pesquisável mudar, regenere o vetor antes do upsert para evitar divergência entre significado armazenado e conteúdo visível.

Resumo do tópico

Crie primeiro o contêiner vetorial e persista texto, e embedding recém-gerado na mesma operação.

6. Executar consultas VectorDistance parametrizadas

VectorDistance compara o caminho armazenado ao vetor da pergunta pela função definida na política. Gere a consulta com o mesmo modelo dos documentos, pois modelos diferentes formam espaços incompatíveis. Projete a pontuação em SELECT e repita a expressão em ORDER BY para classificar os resultados.

query = """
SELECT TOP 10
    c.id,
    c.title,
    VectorDistance(c.embedding, @queryVector) AS similarity
FROM c
ORDER BY VectorDistance(c.embedding, @queryVector)
"""

results = container.query_items(
    query=query,
    parameters=[{"name": "@queryVector", "value": query_embedding}],
    enable_cross_partition_query=True
)

Envie o vetor como @queryVector. Isso mantém a consulta legível, favorece o reaproveitamento do plano e evita concatenar milhares de números. Sempre limite com TOP N; retornar tudo eleva latência e RUs.

Resumo do tópico

Vetorize a pergunta com o mesmo modelo, use parâmetro, ordene por VectorDistance e limite a resposta.

7. Interpretar pontuações e equilibrar busca indexada e exata

Com similaridade de cosseno, números maiores indicam significados mais próximos: +1 representa direção idêntica; 0,7–0,9 costuma ser alta similaridade; 0,5–0,7, moderada; e valores baixos ou negativos, pouca relação. Essas faixas são pontos de partida e devem ser calibradas com exemplos rotulados.

  • RAG normalmente usa 5–10 trechos para controlar e distrações.
  • Pesquisa para usuários costuma apresentar 10–20 resultados com paginação.
  • Recomendação geralmente exibe 3–5 itens.
  • O índice oferece aproximação rápida; o terceiro argumento true de VectorDistance força varredura exata.

Reserve para avaliação, coleções pequenas ou recuperação integral obrigatória. Em produção, use DiskANN ou quantizedFlat, projete apenas campos necessários, direcione a partição e monitore latência e RUs.

Resumo do tópico

Meça limites e recuperação; economize com índice, TOP pequeno, projeção estreita e direcionamento de partição.

8. Combinar classificação vetorial com filtros e partições

Aplicações reais restringem significado por categoria, data, produto, versão, status ou grupo de acesso. Coloque os predicados em WHERE para o otimizador reduzir candidatos antes ou durante a comparação. Pré-filtragem seletiva economiza trabalho; pós-filtragem preserva classificação global, mas pode devolver menos linhas.

query = """
SELECT TOP 10 c.id, c.title,
    VectorDistance(c.embedding, @queryVector) AS similarity
FROM c
WHERE c.category = @category
  AND c.createdDate >= @startDate
ORDER BY VectorDistance(c.embedding, @queryVector)
"""

results = container.query_items(
    query=query,
    parameters=[
        {"name": "@queryVector", "value": query_embedding},
        {"name": "@category", "value": "networking"},
        {"name": "@startDate", "value": "2026-01-01T00:00:00Z"}
    ],
    partition_key="networking"
)
  • documentType separa perguntas frequentes, guias e notas de versão.
  • Intervalos de datas delimitam janelas.
  • productId e versão definem o produto.
  • ARRAY_CONTAINS valida grupos autorizados.
  • status remove conteúdo rascunho, arquivado ou obsoleto.

Se category for a chave, use tanto o filtro WHERE quanto partition_key. Assim a consulta segue diretamente para uma partição.

Resumo do tópico

Filtre dentro da consulta, indexe os campos e informe a chave quando o filtro identificar uma partição.

9. Fundir relevância semântica e textual com RRF

O vetor entende paráfrases; a pesquisa de texto completo reconhece códigos de erro, produtos e termos exatos. A pesquisa híbrida configura políticas e índices dos dois tipos e usa Reciprocal Rank Fusion para combinar as classificações.

SELECT TOP 10 *
FROM c
ORDER BY RANK RRF(
    VectorDistance(c.embedding, @queryVector),
    FullTextScore(c.content, @term1, @term2),
    [2, 1]
)

Os pesos [2, 1] tornam o vetor duas vezes mais influente. Aumente o peso semântico para descrições naturais, o textual para identificadores exatos ou comece empatado e calibre. Avaliar dois sinais custa mais RUs, portanto exija ganho mensurável de relevância.

Resumo do tópico

ORDER BY RANK RRF une VectorDistance e FullTextScore; os pesos expressam a importância relativa.

10. Classificar múltiplos embeddings e testar em escala real

Um documento pode ter embeddings separados de título e conteúdo ou de modalidades diferentes. Chamadas VectorDistance múltiplas podem ser fundidas por RRF; itens fortes em qualquer espaço permanecem candidatos e os fortes em ambos sobem. Cada caminho precisa de política compatível.

Filtros, texto completo e vários vetores aumentam RUs. Teste com volumes e seletividade semelhantes aos da produção, inspecione x-ms--charge e métricas e confirme índices em todos os campos WHERE.

Resumo do tópico

Busca multivetorial amplia relevância, mas cada sinal precisa justificar latência e RUs sob carga realista.

11. Usar o feed de alterações como sinal de atualização

O feed de alterações é habilitado por padrão e registra mudanças na ordem dentro de cada intervalo de chave de partição. O consumidor retoma após interrupções, mas falhas podem repetir trabalho; o processamento deve ser idempotente. Esse fluxo orientado a eventos é superior a varrer todos os documentos periodicamente.

Modelos de consumo.
ModeloPontos fortesEscolha para
PushEntrega automática, balanceamento, checkpoints e operação contínua simples. ou processador sempre ativo.
PullAgendamento, lotes e controle explícitos com menos recursos auxiliares.Atualização periódica, migração ou orquestração em lote.
Alterações passam pelo feed do Azure Cosmos DB até uma Função do Azure que regenera o embedding.
O contêiner de concessão mantém checkpoints e evitam regeneração desnecessária.

Resumo do tópico

Use o feed como origem durável de eventos e torne o manipulador seguro para repetição.

12. Processar alterações com , concessões e atualização seletiva

O gatilho do cuida da propriedade de partições e dos checkpoints. O contêiner de concessão registra a faixa de cada instância e o avanço do processamento, permitindo coordenação, e escala horizontal. Um contêiner pequeno com 400 RU/s costuma bastar.

import azure.functions as func

app = func.FunctionApp()

@app.cosmos_db_trigger(
    arg_name="documents",
    container_name="support-knowledge",
    database_name="support-db",
    connection="CosmosDBConnection",
    lease_container_name="leases",
    create_lease_container_if_not_exists=True
)
def refresh_embeddings(documents: func.DocumentList):
    for document in documents:
        if needs_refresh(document):
            document["embedding"] = create_embedding(document)
            document["contentHash"] = content_hash(document)
            container.upsert_item(document)

Não regenere embeddings por mudanças apenas em . Compare título, conteúdo, descrição e resumo ou guarde do texto usado. Atualize e vetor juntos; categoria, status e permissão podem então evitar chamadas caras quando não alteram a semântica.

Resumo do tópico

Gatilho e concessões fornecem orquestração confiável; comparação de conteúdo controla custo.

13. Escalar com segurança e manter controle pelo modelo pull

Para picos, envie vários textos por chamada quando permitido, aplique repetição com exponencial e desacople detecção e vetorização pelo . Filas prioritárias podem tratar guias ativos antes do arquivo histórico.

iterator = container.query_items_change_feed(start_time="Beginning")

for page in iterator.by_page():
    for change in page:
        process_idempotently(change)
    save_checkpoint(iterator.continuation_token)
  • Persista o de continuação entre lotes.
  • Trate documento excluído como não encontrado benigno.
  • Use contra sobrescritas concorrentes.
  • Envie falhas repetidas a uma fila de mensagens mortas.
  • Monitore ChangeFeedProcessorHostLag e aumente instâncias quando o atraso crescer.

Resumo do tópico

Agrupe, repita, registre checkpoint e monitore; isole falhas e mantenha cada atualização idempotente.

14. Laboratório guiado, revisão da avaliação e referências Microsoft

O laboratório de aproximadamente 30 minutos implanta uma conta do for com pesquisa vetorial, cria políticas e índices, carrega chamados com embeddings pré-calculados, implementa funções Python de similaridade e testa tudo em Flask. Requer assinatura do com permissão de implantação, , versão atual da CLI do e Python 3.12 ou posterior.

  1. Configurar o projeto inicial e o script.
  2. Provisionar conta e contêiner vetorial.
  3. Criar funções VectorDistance parametrizadas.
  4. Carregar chamados e validar correspondência semântica.
  5. Testar o fluxo pela interface Flask.

Revisão da avaliação

  • text-embedding-ada-002: float32, 1.536 dimensões e cosseno.
  • Reduzir TOP de 100 para 10–20 resultados úteis.
  • Filtrar category no WHERE e passar partition_key.
  • Combinar VectorDistance e FullTextScore com ORDER BY RANK RRF.
  • Usar gatilho do para atualizar sem .
  1. Pesquisa de vetor no para
  2. Pesquisa híbrida no for
  3. Função de sistema VectorDistance
  4. Trabalhar com o feed de alterações do
  5. Usar o feed de alterações com o
  6. Tutorial de embeddings do

Resumo do tópico

O laboratório integra política, índice, geração de embedding, consulta e validação; a avaliação reforça as decisões centrais.