O que é um banco de dados vetorial? Guia prático com exemplo (pgvector)
Todo sistema de RAG vive ou morre pelo banco vetorial. É ele que decide se a busca devolve o parágrafo certo ou um trecho sem nexo — e, no fim, se o seu agente responde com base no documento ou alucina com cara de confiança.
O problema é que "banco de dados vetorial" virou palavra de ordem antes de virar entendimento. Muita gente já saiu escolhendo entre Pinecone, Qdrant, Weaviate e pgvector sem saber o que essas ferramentas fazem por dentro. Escolher a caixa antes de entender o que ela guarda é receita de retrabalho.
Então vamos do começo, de baixo pra cima: o que é um banco de dados vetorial, como a busca por similaridade funciona de verdade, e como você monta um em cima do Postgres que provavelmente já está rodando no seu projeto. Sem hype. Só engenharia.
TL;DR
- O que é: um banco especializado em guardar e indexar embeddings (vetores) e responder "quais itens são mais parecidos com este?" em milissegundos, em vez de "quais itens são exatamente iguais a este?".
- Como busca: compara a distância entre vetores e devolve os vizinhos mais próximos, usando busca aproximada (ANN) para não varrer a base inteira.
- Stack de exemplo: PostgreSQL + pgvector 0.8.x — a mesma similaridade dos serviços dedicados, dentro do banco que você já tem.
- Quando precisa: RAG, busca semântica, recomendação, deduplicação, memória de agente. Qualquer coisa que dependa de "parecido", não de "igual".
O que é um banco de dados vetorial?
Um banco relacional guarda dado escalar — strings, números, datas — em linhas e colunas, e responde perguntas de igualdade: WHERE email = 'lucas@...', WHERE status = 'pago'. Ou é igual, ou não é. Não existe "quase".
Um banco de dados vetorial resolve outro problema. Ele guarda embeddings: representações numéricas de texto, imagem ou áudio, geralmente com centenas ou milhares de dimensões, onde conteúdos com significado parecido ficam matematicamente próximos. Se você ainda não tem intimidade com essa parte, vale ler antes o que é um embedding — é a matéria-prima que o banco vetorial guarda.
A diferença está na pergunta que ele sabe responder. Como resume a Pinecone, um banco vetorial "aplica uma métrica de similaridade para encontrar o vetor mais parecido com a nossa consulta" — não o idêntico, o mais próximo. Você joga a pergunta "modelo de embedding barato pra português" e ele te devolve os chunks que falam sobre custo de embedding em pt-br, mesmo que nenhum use exatamente essas palavras.
Conceito técnico → aplicação prática → impacto no produto: é essa capacidade de buscar por sentido que sustenta busca semântica, RAG, recomendação, memória de longo prazo de agente e deduplicação. Tudo que depende de "parecido" em vez de "igual" passa por aqui.
Vale a distinção fina: existe índice vetorial (uma biblioteca como FAISS, que só faz a busca) e existe banco de dados vetorial (que junta o índice com o que um banco de verdade precisa: CRUD, filtro por metadado, escala, persistência). O pgvector, que a gente vai usar no exemplo, transforma o Postgres nessa segunda categoria.
Como a busca por similaridade funciona
Aqui é onde a mágica deixa de ser mágica e vira geometria.
Cada embedding é um ponto num espaço de muitas dimensões. Buscar por similaridade é medir distância entre pontos: quanto mais perto, mais parecido. Os três jeitos mais comuns de medir:
- Distância euclidiana (L2): a linha reta entre dois pontos. Menor = mais parecido.
- Similaridade de cosseno: o ângulo entre os vetores, ignorando o tamanho. É a métrica mais usada em texto.
- Produto interno (inner product): útil quando os vetores já vêm normalizados.
O fluxo de uma consulta é sempre o mesmo: você transforma a pergunta em embedding (com o mesmo modelo que gerou os vetores da base), o banco compara esse vetor com os que estão indexados e devolve os k vizinhos mais próximos (o famoso top-k).
O detalhe que separa protótipo de produto é o como essa comparação é feita. A forma ingênua — comparar a pergunta com cada vetor da base, um por um — chama-se brute force (ou busca exata). Funciona lindamente com 10 mil vetores. Com 10 milhões, cada busca vira uma varredura completa e a latência explode.
Por isso os bancos vetoriais usam ANN — Approximate Nearest Neighbor (vizinho mais próximo aproximado). Em vez de garantir o resultado perfeito, eles constroem uma estrutura de índice que acha quase sempre os vizinhos certos, muito mais rápido. O trade-off é explícito e você precisa entendê-lo: quanto mais preciso o resultado, mais lenta a busca. A métrica que mede esse acerto chama-se recall — a fração dos vizinhos verdadeiros que o índice conseguiu recuperar. 95% de recall a 5ms costuma valer muito mais, em produto, do que 100% a 800ms.
HNSW vs IVFFlat: os dois índices que você vai encontrar
Praticamente todo banco vetorial ANN usa um destes dois algoritmos de índice — vale saber a diferença antes de escolher.
HNSW (Hierarchical Navigable Small World) monta um grafo de várias camadas. A busca "cai" da camada mais esparsa para a mais densa, pulando de vizinho em vizinho até chegar perto do alvo. Segundo a documentação do pgvector, o HNSW tem melhor performance de consulta (na relação velocidade × recall), mas constrói o índice mais devagar e consome mais memória.
IVFFlat (Inverted File) divide os vetores em listas (clusters) e, na busca, só olha as listas mais próximas da pergunta. Constrói mais rápido e gasta menos memória, mas a qualidade da consulta é inferior à do HNSW.
A regra prática: comece com HNSW, a menos que tenha um motivo forte pra não fazer isso (base gigante que reindexe o tempo todo, ou pouca RAM). É o default de mercado por ter o melhor equilíbrio entre recall e latência.
Não só acompanhe as novidades — domine. Engenharia de IA na prática, ao vivo, toda semana, na maior comunidade do Brasil.
Entrar no ClãExemplo prático: um banco vetorial com pgvector
Chega de teoria. Você não precisa assinar um serviço dedicado para ter tudo isso. O pgvector — hoje na versão 0.8.x, para Postgres 13+ — transforma o Postgres num banco vetorial completo. Se seu projeto já roda em Postgres (o do 80% dos backends que eu vejo), você já tem 80% do caminho andado. Escrevi um guia dedicado sobre pgvector como memória do agente, mas aqui vai o mínimo pra você ver funcionando.
Primeiro, liga a extensão e cria uma tabela com uma coluna do tipo vector:
CREATE EXTENSION IF NOT EXISTS vector;
-- 3 dimensões só pra caber no exemplo.
-- Na vida real: 1536 (text-embedding-3-small), 1024, etc.
CREATE TABLE documentos (
id bigserial PRIMARY KEY,
conteudo text,
embedding vector(3)
);
Depois, insere os embeddings (na prática você gera esses vetores com um modelo de embedding e grava o array):
INSERT INTO documentos (conteudo, embedding) VALUES
('pgvector no Postgres', '[0.9, 0.1, 0.2]'),
('índice HNSW e recall', '[0.8, 0.2, 0.1]'),
('receita de pão de fermentação','[0.1, 0.9, 0.7]');
Agora a parte que importa: a busca por similaridade. O pgvector expõe a distância como operadores:
<->— distância euclidiana (L2)<=>— distância de cosseno<#>— produto interno negativo
Buscar os 2 documentos mais parecidos com um vetor de consulta é um ORDER BY pela distância:
SELECT conteudo, embedding <=> '[0.85, 0.15, 0.15]' AS distancia
FROM documentos
ORDER BY embedding <=> '[0.85, 0.15, 0.15]'
LIMIT 2;
Repare: não tem WHERE embedding = .... Tem ORDER BY <distância> + LIMIT k. Isso é a busca por similaridade em SQL puro — os dois vetores próximos do "assunto pgvector" voltam primeiro; o pão de fermentação fica pra trás.
Do jeito acima, o Postgres faz brute force (busca exata) — ótimo pra base pequena. Quando ela cresce, você cria o índice HNSW e a mesma query passa a rodar como ANN:
CREATE INDEX ON documentos
USING hnsw (embedding vector_cosine_ops);
Um detalhe de produção: o operador do índice tem que casar com o da query. Índice com vector_cosine_ops serve buscas com <=>; se você busca com <->, precisa de um índice vector_l2_ops. Errar isso faz o Postgres ignorar o índice e cair no brute force sem avisar.
Quando você precisa de um banco vetorial (e quando não)
Nem todo projeto precisa. Você precisa de busca vetorial quando a pergunta certa é "o que é parecido com isso?":
- RAG — recuperar os trechos certos de uma base pra alimentar o LLM. É o caso mais comum. Se RAG ainda é abstrato pra você, comece por o que é RAG.
- Busca semântica — achar por significado, não por palavra-chave exata.
- Recomendação — "produtos parecidos com o que o usuário viu".
- Deduplicação e memória de agente — reconhecer que dois conteúdos dizem a mesma coisa com palavras diferentes.
E quando não: se sua busca é por igualdade exata (SKU, CPF, e-mail, status), banco vetorial é overengineering. WHERE sku = 'RX-7000' é mais rápido, mais barato e não erra. Aliás, embedding puro confunde "RX-7000" com "RX-5000" — pra catálogo que mistura código e semântica, o certo é busca híbrida: BM25 + vetor + RRF, não vetor sozinho. Escolher a ferramenta certa pro tipo de pergunta é metade da engenharia.
FAQ rápido
Preciso de um banco vetorial dedicado (Pinecone, Qdrant) ou pgvector resolve? Pra maioria dos projetos de backend, pgvector resolve — e evita mais uma peça de infra pra manter. Serviços dedicados brilham em escala muito alta (centenas de milhões de vetores) ou quando você quer busca gerenciada sem tocar em índice. Comece no Postgres; migre quando a dor aparecer, não antes.
Qual métrica de distância eu uso?
Para texto, cosseno (<=>) é o default seguro na esmagadora maioria dos casos. Só use L2 ou produto interno se o modelo de embedding recomendar explicitamente.
Quantas dimensões meu vetor vai ter?
Depende do modelo. text-embedding-3-small da OpenAI gera 1536; outros modelos vão de 384 a 4096. O importante é que a coluna vector(n) bata com a saída do modelo, e que você use o mesmo modelo pra indexar e pra consultar.
HNSW ou IVFFlat? HNSW por padrão — melhor recall e latência. IVFFlat só se o tempo de construção do índice ou o consumo de memória forem gargalo real no seu caso.
Fechando
Banco de dados vetorial não é mágica nem buzzword: é um banco que troca a pergunta "o que é igual?" por "o que é parecido?", medindo distância entre embeddings e usando busca aproximada pra fazer isso em milissegundos. Entender essa mecânica — distância, ANN, recall, HNSW — é o que te deixa escolher (e debugar) a ferramenta com critério, em vez de por moda.
O próximo passo é sair do exemplo de 3 dimensões e montar um pipeline de verdade: chunking, embedding e busca com índice. Tem o caminho completo em RAG do zero: chunking, embeddings e busca. E se você quer ver esse tipo de arquitetura sendo construída ao vivo, com código rodando e decisão de produção na mesa, é o que a gente faz toda semana no Clã Beer and Code — a maior comunidade de engenharia de IA do Brasil, onde o pessoal constrói agente que aguenta produção, não slide.
No fim, o banco vetorial é a fundação silenciosa embaixo de todo sistema de IA que entende o que você pediu. Vale conhecer a fundação antes de subir a casa.
{AI Engineer} — apaixonado por Laravel, arquitetura de software e construir produtos com impacto. Compartilho aqui tutoriais, descobertas e reflexões sobre o dia a dia de engenharia.
Conteúdo é o que não falta. Falta quem desembaralhe: o que importa agora é como implementar do jeito certo. No Clã você tem isso ao vivo, toda semana, com quem já filtrou o ruído.
Entrar no Clã