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
Por João Ricardo Dutra••Conteúdo autoral completo
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.
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.
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.
Índice
Limites e comportamento
Uso típico
flat
exata; até 505 dimensões.
Coleções pequenas ou validação com recuperação integral.
quantizedFlat
Varredura 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.
Í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.
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.
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.
Modelo
Pontos fortes
Escolha para
Push
Entrega automática, balanceamento, checkpoints e operação contínua simples.
ou processador sempre ativo.
Pull
Agendamento, lotes e controle explícitos com menos recursos auxiliares.
Atualização periódica, migração ou orquestração em lote.
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.
Configurar o projeto inicial e o script.
Provisionar conta e contêiner vetorial.
Criar funções VectorDistance parametrizadas.
Carregar chamados e validar correspondência semântica.
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.