~/tools / Embeddings e busca (RAG) / pgvector SQL Builder
pgvector SQL Builder — Escreva SQL do pgvector: tabela, índice HNSW/IVFFlat e consulta de vizinhos
Escreva o SQL para guardar e pesquisar embeddings no PostgreSQL com o pgvector: uma tabela com uma coluna vector(n) ou halfvec(n), um índice HNSW ou IVFFlat com a classe de operador que corresponde à sua distância e uma consulta de vizinhos mais próximos com uma pontuação legível. Ela verifica os limites indicados na documentação do pgvector e estima quanto espaço os vetores ocupam. Nada sai do seu navegador.
Cada vetor ocupa 1,544 bytes, então 10,000 linhas ocupam cerca de 15.4 MB só com os vetores (sem contar índices e outras colunas).
1. Extensão e tabela
CREATE EXTENSION IF NOT EXISTS vector; CREATE TABLE documents ( id bigserial PRIMARY KEY, content text NOT NULL, embedding vector(384) NOT NULL );
2. Índice
CREATE INDEX ON documents USING hnsw (embedding vector_cosine_ops) WITH (m = 16, ef_construction = 64);
3. Busca
PREPARE recebe como $1 o vetor da pergunta obtido de /api/embed. Passe-o como texto, por exemplo '[0.01,-0.02,…]'.
PREPARE search_documents(vector(384)) AS
SELECT id, content, 1 - (embedding <=> $1) AS cosine_similarity
FROM documents
ORDER BY embedding <=> $1
LIMIT 5;
-- EXECUTE search_documents('[0.0123, -0.0456, ...]');Limites e padrões do README e do código-fonte do pgvector 0.8.7, verificados em 2026-11-04. README do pgvector
Tudo é feito no seu navegador. A ferramenta escreve SQL e não se conecta a nada.
O pgvector é uma extensão de código aberto que adiciona ao PostgreSQL a busca por similaridade de vetores, de modo que os embeddings que você cria com o Ollama podem ser guardados no mesmo banco de dados que o restante dos seus dados. Alguns detalhes são fáceis de errar. A coluna deve ter o mesmo número de dimensões que o seu modelo de embeddings. Cada distância tem o seu próprio operador: <=> para a distância de cosseno, <-> para a distância L2, <#> para o produto interno negativo e <+> para a distância L1. Um índice aproximado só é usado se foi criado com a classe de operador da mesma distância, como vector_cosine_ops para <=>, e se a consulta ordena pelo próprio operador em ordem crescente com um LIMIT. Esta ferramenta escreve as três partes a partir de um único conjunto de escolhas: CREATE EXTENSION e CREATE TABLE, CREATE INDEX, e uma instrução PREPARE que devolve as linhas mais próximas com uma pontuação legível (a similaridade de cosseno é 1 menos a distância de cosseno, e o produto interno é <#> multiplicado por -1). Ela aplica os limites do README e do código-fonte do pgvector para a versão 0.8.7: até 16,000 dimensões em uma coluna, índices de até 2,000 dimensões para vector e 4,000 para halfvec, sem classe de operador L1 para IVFFlat, m do HNSW de 2 a 100, e ef_construction de 4 a 1,000 e pelo menos 2 × m. Com HNSW, uma busca devolve no máximo hnsw.ef_search linhas (40 por padrão), então a ferramenta avisa quando LIMIT é maior. Para o IVFFlat, ela preenche lists e probes com os pontos de partida do README: rows / 1000 até 1M linhas, sqrt(rows) acima disso, e sqrt(lists) para probes. O SQL gerado foi executado no pgvector 0.8.7 com PostgreSQL 16 usando vetores reais de 384 dimensões do Ollama, e o EXPLAIN mostrou o índice sendo usado.
A lógica principal desta ferramenta é de código aberto, sob a licença MIT. github.com/seigo5555/toolkitbox-lib/src/pgvector-sql.ts
Casos de uso
- Criar a tabela para os trechos dos seus documentos antes de carregar no PostgreSQL os embeddings do Ollama
- Verificar qual operador combina com qual classe de operador para a distância de cosseno, L2, produto interno ou L1, para que o índice seja realmente usado
- Estimar quanto espaço os vetores ocupam em um VPS pequeno e comparar vector com halfvec
Como usar
- Digite o nome da tabela e o número de dimensões do seu modelo de embeddings. É o comprimento de um vetor de /api/embed; o Embedding Similarity Calculator deste site o mostra.
- Escolha o tipo, a distância e o índice. A documentação do Ollama recomenda a similaridade de cosseno para a maioria das buscas semânticas, e o /api/embed retorna vetores com comprimento 1.
- Copie os três blocos e execute-os no psql ou em outro cliente. Crie um índice IVFFlat depois de carregar os dados; um índice HNSW pode ser criado em uma tabela vazia.
FAQ
Qual distância devo escolher?
A documentação de embeddings do Ollama recomenda a similaridade de cosseno para a maioria dos casos de busca semântica. No pgvector, <=> retorna a distância de cosseno, e a ferramenta a transforma em cosine_similarity com 1 menos a distância. Para vetores com comprimento 1, como os do /api/embed, a distância de cosseno, a distância L2 e o produto interno colocam as linhas na mesma ordem, porque para esses vetores a distância L2 ao quadrado é 2 menos 2 vezes a similaridade de cosseno.
HNSW ou IVFFlat?
O README do pgvector diz que o HNSW tem melhor desempenho de consulta que o IVFFlat (em termos do equilíbrio entre velocidade e recall), mas é construído mais lentamente e usa mais memória, e que pode ser criado em uma tabela vazia porque não há etapa de treinamento. O IVFFlat é construído mais rápido, usa menos memória e deve ser criado depois que a tabela tiver alguns dados. Sem índice, o pgvector faz uma busca exata, que dá recall perfeito.
Por que minha consulta não usa o índice?
O README diz que a consulta precisa de ORDER BY e LIMIT, e que o ORDER BY deve ser o próprio operador de distância em ordem crescente, e não uma expressão como 1 - (embedding <=> …) DESC. O operador também deve corresponder à classe de operador do índice: <=> com vector_cosine_ops, <-> com vector_l2_ops, <#> com vector_ip_ops e <+> com vector_l1_ops. A ferramenta escreve os dois a partir da mesma escolha. O README também observa que uma varredura da tabela pode ser mais rápida quando a tabela é pequena.
Por que recebo menos linhas que LIMIT?
Com HNSW, os resultados são limitados por hnsw.ef_search, que é 40 por padrão; quando testamos LIMIT 100 em uma tabela de 200 linhas, recebemos 40 linhas até aumentarmos hnsw.ef_search para 100. O README acrescenta que a filtragem com WHERE é aplicada depois que o índice é percorrido, então uma condição pode deixar ainda menos linhas. Desde a versão 0.8.0, as varreduras iterativas do índice (SET hnsw.iterative_scan = strict_order ou relaxed_order) percorrem mais do índice quando necessário.
O que é halfvec?
Um tipo de vetor de meia precisão. Cada vetor ocupa 2 × dimensões + 8 bytes em vez de 4 × dimensões + 8, e os índices HNSW e IVFFlat sobre halfvec aceitam até 4,000 dimensões em vez de 2,000. Cada elemento é um número de ponto flutuante de meia precisão, então os valores são guardados com menos precisão.
Meus dados são enviados para algum lugar?
Não. A ferramenta apenas escreve SQL no seu navegador e nunca se conecta a um banco de dados.
Artigos relacionados
- Guarde e pesquise embeddings do Ollama no PostgreSQL com o pgvectorGuarde embeddings do Ollama no PostgreSQL com o pgvector, pesquise-os com HNSW ou IVFFlat e passe os resultados para o /api/chat para que a resposta cite suas fontes.
- Embeddings com o Ollama: o básico para busca e RAGCrie embeddings com o /api/embed do Ollama: os modelos e seus tamanhos, truncate e dimensions, vetores de comprimento unitário e similaridade de cosseno, segundo a documentação oficial.