A pesquisa vetorial nativa do Aurabase (RAG, pgvector, embeddings) depende deste mesmo mecanismo de indexação, descrito em detalhes na página Native AI no Postgres. Este guia assume uma tabela Postgres com pgvector já instalado, uma coluna do tipo vectore pelo menos alguns milhares de linhas. Abaixo, uma varredura sequencial simples costuma ser mais rápida que um índice aproximado.
O essencial
- O HNSW não requer nenhuma fase de treinamento, ao contrário do IVFFlat: o índice é construído sobre inserções, disponíveis no pgvector desde a versão 0.5.0.
- Dois parâmetros definem a qualidade do índice na construção:
m(conexões por nó, padrão 16) eef_construction(largura de pesquisa na construção, padrão 64). - Um terceiro parâmetro,
hnsw.ef_search(pgvector padrão: 40), é ajustado para cada solicitação, sem reconstruir o índice, para arbitrar o recall e a latência. - pgvector limita a indexação HNSW do tipo
vectora 2.000 dimensões. Além disso (uma incorporação com dimensões 3072, por exemplo), é necessário um cast parahalfvecpara indexar. - pgvector 0.8.6 é a versão incorporada na imagem do locatário Aurabase Postgres, verificada diretamente no Dockerfile em 24 de agosto de 2026.
O que é um índice HNSW no pgvector?
HNSW significa Mundo Pequeno Navegável Hierárquico. É um índice gráfico: cada vetor torna-se um nó conectado aos seus vizinhos mais próximos, organizado em diversas camadas sobrepostas. Uma pesquisa começa no topo do gráfico, na camada mais esparsa, e depois desce, camada por camada, até os vizinhos mais relevantes. O tempo de busca torna-se assim quase logarítmico, não linear ao longo do número de linhas.
IVFFlat, o outro índice do pgvector, funciona de forma diferente: ele divide o espaço vetorial em listas determinadas por uma passagem de treinamento em uma amostra existente, antes de poder indexar qualquer coisa. O HNSW não possui essa restrição, cada inserção enriquece diretamente o gráfico, o que torna mais simples operar em uma tabela que cresce continuamente. Por outro lado, um índice HNSW consome mais memória e leva mais tempo para ser construído do que um IVFFlat equivalente no mesmo volume.
pgvector introduz suporte HNSW na versão 0.5.0. Versões posteriores adicionam recursos úteis para este guia: o tipo halfvec (0.7.0) para indexar além de 2.000 dimensões e o parâmetro hnsw.iterative_scan (0.8.0) para melhorar o recall em consultas filtradas. Se você comparar o pgvector com uma base vetorial dedicada antes de decidir, nossa comparação pgvector vs Pinecone, Weaviate e Qdrant detalha as compensações.
Verifique sua versão do pgvector antes de criar o índice
Confirme a versão do pgvector instalada primeiro. Uma extensão muito antiga faz com que alguns recursos deste guia falhem silenciosamente, principalmente halfvec e hnsw.iterative_scan.
O HNSW existe desde o pgvector 0.5.0. O tipo halfvec, necessário para indexar embeddings além de 2.000 dimensões, requer pelo menos a versão 0.7.0. O parâmetro hnsw.iterative_scan solicita a versão 0.8.0.
Em projetos Aurabase, a questão não se coloca: a imagem Postgres incorpora pgvector 0.8.6, tanto no cluster Postgres compartilhado (docker/Postgres.Dockerfile, construído diretamente em pgvector/pgvector:0.8.6-pg16-bookworm) quanto nas instâncias Postgres 16 CNPG dedicadas por projeto (docker/Postgres.CNPG.Dockerfile, que herda pgvector 0.8.6 da imagem oficial do CloudNativePG). Verificado em ambos Dockerfiles em 24 de agosto de 2026.
Escolha o tipo certo de coluna de acordo com o tamanho dos seus embeddings
O tipo de coluna depende do tamanho dos seus embeddings, não apenas do modelo que os gera. pgvector armazena um vetor clássico do tipo vector, com um limite de 16.000 dimensões em armazenamento. Mas a indexação HNSW neste tipo é limitada a 2.000 dimensões: além disso, CREATE INDEX falha.
Os modelos de incorporação comuns geralmente excedem esse limite: text-embedding-3-large do OpenAI ou gemini-embedding-2 do Google produzem nativamente até 3.072 dimensões. Para indexar esses vetores com HNSW, converta a coluna em halfvec (precisão de armazenamento reduzida pela metade), o que aumenta o limite de indexação bem além de 2.000 dimensões.
| Dimensões | Coluna | HNSW no vetor | Requer elenco |
|---|---|---|---|
| 768 | incorporação_768 | Sim | Não |
| 1536 | incorporação_1536 | Sim | Não |
| 3072 | incorporação_3072 | Não (> 2.000 escurece) | Sim, elenco::halfvec(3072) |
O mecanismo Aurabase RAG ilustra esse compromisso na produção: três classes de dimensões suportadas (768, 1536, 3072), armazenadas em três colunas distintas da mesma tabela embeddings. As colunas 768 e 1536 são indexadas diretamente em HNSW no tipo vector. A coluna 3072 é indexada por meio de uma conversão ::halfvec(3072), precisamente para contornar o limite de dimensão de 2.000.
Para obter detalhes sobre a ingestão (fragmentação, chamada para o provedor de incorporação, inserção), consulte o tutorial do pipeline RAG em pgvector.
Crie o índice com os parâmetros m e ef_construction
A sintaxe mínima é suficiente para um primeiro índice, com os valores padrão de pgvector.
pgvector então aplica m = 16 e ef_construction = 64. Para ajustar esses valores explicitamente, use a cláusula WITH:
Antes de construir um índice HNSW em uma tabela grande, aumente temporariamente maintenance_work_mem para a sessão: esta é, de acordo com a própria documentação do pgvector, a alavanca mais direta para reduzir o tempo de construção.
O que o parâmetro m muda?
m define o número máximo de conexões que cada nó no gráfico mantém por camada. Um valor mais alto densifica o gráfico: a recuperação aumenta, mas a memória consumida e o tempo de construção também aumentam, de forma aproximadamente linear. O padrão (16) é adequado para a maioria dos casos. Subir para 24 ou 32 é especialmente justificado em grandes embeddings, onde a distinção entre vizinhos próximos e distantes se torna mais precisa.
O que ef_construction muda?
ef_construction define o tamanho da lista de candidatos explorada durante a construção do índice, para cada nó inserido. Um valor mais alto melhora a qualidade do gráfico final, portanto o potencial recall, ao custo de um tempo de construção mais longo. Ao contrário de m, este parâmetro não tem custo na hora da consulta: é um investimento único, pago apenas uma vez na criação do índice.
Índices parciais para diversas classes de dimensão na mesma tabela
Quando uma tabela armazena várias colunas de vetor (uma por classe de dimensão, como faz o Aurabase), indexe cada coluna separadamente com uma cláusula WHERE colonne IS NOT NULL. Este índice parcial evita a indexação de linhas vazias para classes não utilizadas por uma determinada linha, o que reduz o tamanho do índice e agiliza sua construção sem custar nada em recall.
A escolha da classe do operador (vector_cosine_ops, vector_l2_ops ou vector_ip_ops) deve corresponder à métrica na qual o modelo de incorporação foi treinado. Os modelos de incorporação de texto mais recentes são treinados para similaridade de cosseno: vector_cosine_ops (ou halfvec_cosine_ops em uma coluna convertida) é, portanto, a escolha padrão mais segura.
Defina ef_search no momento da consulta
ef_search é definido em cada consulta, não quando o índice é criado. Define o tamanho da lista de candidatos explorados durante a busca: quanto maior for, melhor será o recall, ao custo de maior latência. pgvector define seu valor padrão para 40.
40 raramente é suficiente assim que uma consulta combina pesquisa vetorial com um filtro WHERE aplicado após a varredura do índice (em um namespace, um locatário ou qualquer outro critério de metadados). A varredura HNSW traz de volta ef_search candidatos brutos e, em seguida, o filtro descarta parte deles. Se poucos candidatos sobreviverem, o LIMIT final acaba sendo insuficientemente preenchido.
O mecanismo Aurabase RAG, portanto, expande ef_search dinamicamente de acordo com o top_ksolicitado, em vez de manter o valor fixo de 40: ef = max(top_k × 4, 64). Uma busca pelos 5 resultados mais próximos usa ef_search = 64; uma pesquisa pelos 50 principais usos ef_search = 200. Essa fórmula permanece ajustável por variável de ambiente para implantações que precisam de outra compensação entre recall/latência.
O pgvector 0.8 adiciona uma segunda alavanca para este mesmo problema: hnsw.iterative_scan. No modo strict_order ou relaxed_order, a busca amplia gradativamente sua busca até reunir resultados suficientes após a filtragem, em vez de parar em uma lista fixa de candidatos. Aurabase ativa por padrão em strict_order, mas protege a chamada em um savepoint. Em uma versão do pgvector anterior a 0.8, onde esse parâmetro não existe, a consulta continua no modo degradado em vez de falhar.
Construa o pipeline RAG completo
Este índice HNSW é apenas uma parte do pipeline RAG completo: fragmentação, geração de incorporação, ingestão e pesquisa. Nosso tutorial passo a passo constrói esse pipeline de ponta a ponta no pgvector, desde a primeira inserção até a consulta de similaridade. A documentação técnica também detalha todos os recursos de IA nativos do Aurabase construídos no Postgres.