O que é embedding — e por que sua busca semântica devolve resultado errado
Você montou a busca semântica. Subiu o pgvector, gerou os embeddings, rodou o <=> e... o resultado volta sem nexo. O usuário busca "como cancelar assinatura" e o sistema devolve um artigo sobre "novos planos". Frustração na veia.
A primeira reação de todo dev é a mesma: "o banco vetorial tá ruim". Quase nunca é. O problema mora antes — no embedding. É lá que o sentido do seu texto vira número, e é lá que ele se perde.
Neste post você vai entender o que é embedding de verdade (sem fórmula mágica), por que a busca por similaridade erra, e os três pontos onde 90% das buscas semânticas quebram: modelo errado, vetor não normalizado e chunking mal feito.
TL;DR
- O que é: embedding é a tradução de um texto (ou imagem, ou áudio) para um vetor de números que representa o sentido daquilo, não as palavras.
- Pra que serve: busca semântica, RAG, recomendação, deduplicação, classificação — tudo que precisa medir "isso é parecido com aquilo".
- Por que erra: modelo de embedding inadequado, vetores sem normalização, chunk grande demais ou cortado no meio da frase.
- Stack do exemplo: PostgreSQL + pgvector, modelo
text-embedding-3-smallda OpenAI.
O que é embedding, sem enrolação
Computador não entende "cachorro". Ele entende número.
Embedding é o processo de pegar um pedaço de texto e transformá-lo num vetor — uma lista de números de tamanho fixo. O text-embedding-3-small da OpenAI, por exemplo, devolve um vetor de 1536 dimensões. Cada texto vira um ponto num espaço de 1536 eixos.
O pulo do gato: esse espaço é organizado por significado. Textos com sentido parecido caem perto um do outro, mesmo sem nenhuma palavra em comum. "Adoro programar em Python" e "curto codar numa linguagem com símbolo de cobra" praticamente não compartilham palavras — mas seus vetores ficam colados (Pinecone).
É por isso que embedding destrava busca semântica, recomendação de conteúdo, memória de usuário e classificação inteligente. Você para de comparar palavras e passa a comparar sentido.
E como o computador mede "perto"? Quase sempre com similaridade de cosseno — o ângulo entre dois vetores. Quanto menor o ângulo, mais parecido o sentido. O valor vai de -1 (oposto) a 1 (idêntico), ignorando o tamanho do vetor e olhando só pra direção (Milvus).
Guarda essa palavra: direção. Ela é a raiz de um dos bugs mais comuns.
Por que sua busca devolve lixo
Quando a busca erra, o instinto é mexer no banco — trocar índice, aumentar o k, adicionar filtro. Na maioria das vezes isso é tratar o sintoma. A doença está no embedding. São três focos.
Foco 1: você está usando o modelo errado
O ranking do MTEB — o benchmark que compara modelos de embedding — é ótimo pra ter um ponto de partida. Mas tem uma armadilha: o modelo que lidera o MTEB pode ir mal no seu domínio.
Dois erros clássicos aqui:
- Modelo monolíngue num conteúdo em português. Muito embedding foi treinado majoritariamente em inglês. Joga texto técnico em PT-BR e a noção de similaridade fica grossa — "fatura" e "boleto" deveriam estar colados, e não estão. (E tem domínio onde nenhum embedding sozinho resolve: código, SKU, part-number. "RX-7000" e "RX-5000" são quase idênticos pro vetor. Aí a saída é busca híbrida com BM25 + vetor, não trocar de embedding.)
- Modelos diferentes pra query e pra documento. Esse é o erro silencioso. Você indexou os documentos com um modelo, e na hora da busca embedou a query com outro. São dois espaços vetoriais diferentes. A similaridade vira número aleatório. O sistema não dá erro — só devolve resultado ruim, e você fica caçando bug no lugar errado.
Regra de ouro: o mesmo modelo, a mesma versão, dos dois lados. Sempre.
Foco 2: você esqueceu de normalizar
Lembra da palavra direção? Cosseno só olha pro ângulo. Mas várias implementações, por performance, usam inner product (produto interno) em vez de cosseno puro.
Aqui está o detalhe que derruba gente: inner product e cosseno só dão o mesmo ranking se os vetores estiverem normalizados — com comprimento 1 (McClarence). Se não estiverem, o produto interno passa a premiar vetor "grande" em vez de vetor "parecido". Documento comprido sobe no ranking só por ser comprido. Resultado: lixo relevante por acidente.
No pgvector isso aparece na escolha do operador:
-- distância de cosseno: seguro, normaliza implicitamente
SELECT id, conteudo
FROM documentos
ORDER BY embedding <=> '[0.12, -0.04, ...]'
LIMIT 5;
-- inner product (<#>): mais rápido, MAS só correto se os vetores
-- já vierem normalizados na hora de gravar
SELECT id, conteudo
FROM documentos
ORDER BY embedding <#> '[0.12, -0.04, ...]'
LIMIT 5;
Os operadores do pgvector: <=> é distância de cosseno, <#> é o produto interno negativo, <-> é distância euclidiana (L2). Modelos modernos como os da OpenAI já entregam vetores normalizados — mas no instante em que você trunca um vetor, faz média de chunks ou mistura fontes, a normalização vai embora. Se for usar <#>, normalize na escrita. Se não quer pensar nisso, use <=> e durma tranquilo.
Foco 3: seu chunking está sabotando tudo
Embedding não tem memória infinita. Cada modelo tem uma janela de contexto, e texto que passa do limite é truncado antes de virar vetor — a parte cortada simplesmente não existe na representação (OpenSearch). Você acha que indexou o documento inteiro. Indexou metade.
Aí entra o chunking — quebrar o documento em pedaços antes de embedar. E é onde mora o segundo grande erro:
- Chunk grande demais: uma frase relevante enterrada em nove irrelevantes. O vetor vira uma média borrada de dez assuntos, e a precisão despenca (Pinecone).
- Chunk pequeno demais: falta contexto. O pedaço "ele deve ser cancelado em até 7 dias" sem saber que "ele" é a assinatura não serve pra nada.
- Corte burro: chunking de tamanho fixo ignora a estrutura do texto e corta no meio da frase, partindo o sentido em dois vetores capengas.
Não existe tamanho de chunk universal. Trate chunking como problema de avaliação, não de chute (Pinecone): monte um conjunto de 30–50 queries reais com a resposta certa, e meça. É a única forma honesta de saber se o seu chunking ajuda ou atrapalha. Se quiser ver o chunking certo aplicado de ponta a ponta, com overlap e índice HNSW, o post RAG do zero: chunking, embeddings e busca que funciona mostra o pipeline inteiro.
Consertando, na ordem certa
Antes de trocar de banco vetorial — que é o passo mais caro e o que menos resolve — siga esta ordem:
- Confira o modelo. Mesmo modelo e versão na indexação e na query. Modelo com bom desempenho em português se o conteúdo é PT-BR.
- Confira a normalização. Se usa
<#>, garanta vetores normalizados na escrita. Na dúvida, use<=>. - Confira o chunking. Pedaços com começo e fim de sentido, com um pouco de sobreposição entre eles. Mede com um dataset de avaliação.
- Só então mexa em índice,
ke filtros de metadata.
Repara que três dos quatro passos acontecem antes do banco. É exatamente por isso que "trocar o pgvector" raramente conserta a busca.
FAQ rápido
Embedding e LLM são a mesma coisa? Não. O modelo de embedding só transforma texto em vetor — ele não gera texto. Num RAG, o embedding faz a recuperação (achar os pedaços certos) e o LLM faz a geração (escrever a resposta com base neles). São dois trabalhos distintos.
Quantas dimensões meu embedding precisa ter?
Não é "quanto mais, melhor". Mais dimensões custam mais memória e busca mais lenta. O text-embedding-3-small tem 1536 e resolve a grande maioria dos casos. Comece pequeno, meça, só aumente se a avaliação pedir.
Posso embedar query com um modelo e documentos com outro? Não. São espaços vetoriais diferentes e a similaridade perde o sentido. Mesmo modelo dos dois lados — esse é, de longe, o erro silencioso mais comum.
Preciso re-embedar tudo se trocar de modelo? Sim. Cada modelo cria seu próprio espaço. Trocou o modelo, reprocessa a base inteira — query e documentos.
O embedding é o alicerce, não o detalhe
Busca semântica que erra quase nunca é problema de banco vetorial. É embedding mal escolhido, vetor não normalizado ou chunk mal cortado. Acerte esses três e o pgvector vira coadjuvante — que é o lugar dele.
E embedding é só a porta de entrada. Recuperação é uma peça de um sistema maior: reranking, avaliação, contexto, custo, latência. Decidir onde cada peça entra na arquitetura é o que separa um protótipo de RAG de um produto que aguenta produção — e é exatamente o tipo de decisão que a gente coloca na mesa no Workshop Arquitetando Soluções de IA, com código rodando e arquitetura de verdade, não slide.
O próximo passo, depois de domar o embedding, é colocar a mão na massa: o tutorial de como implementar busca semântica no Laravel com pgvector leva isso pra dentro de uma aplicação real, e se você ainda confunde recuperação com memória, vale ler o que é RAG também.
E depois disso, mede. Monta teu dataset de avaliação antes de qualquer otimização. Sem número, você não está consertando busca — está adivinhando.
{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.
Você também pode gostar
RAG do zero: chunking, embeddings e busca que funciona
RAG não é mágica: é quebrar texto, virar vetor e buscar bem. O passo a passo de um RAG do zero — chunking recursive com overlap, embeddings com text-embedding-3-small e busca por similaridade no Postgres com pgvector e índice HNSW. Errar o chunking é onde 80% dos RAGs nascem ruins.
Busca híbrida: a receita BM25 + vetor + RRF que resolve SKU, part-number e semântica
Embedding puro confunde "RX-7000" com "RX-5000". BM25 puro perde sinônimos. A receita certa é rodar os dois em paralelo e fundir os rankings com Reciprocal Rank Fusion. Neste post, a fórmula que sustenta tudo isso, o pipeline completo em Elasticsearch e como aplicar em catálogo de produto que mistura SKU, part-number e busca semântica.
Como Implementar Busca Semântica no Laravel com Embeddings e PostgreSQL (PGVector)
Neste post vamos explicar passo a passo como você pode transformar a busca da sua aplicação Laravel em algo que entenda o significado por trás das consultas, utilizando embeddings e a extensão pgvector do PostgreSQL para realizar buscas por similaridade semântica diretamente no banco de dados
Glossário do AI Engineer 2026: 30 termos que todo engenheiro precisa saber (sem hype)
Dicionário de campo com 30 termos que aparecem em todo projeto sério de IA em 2026: núcleo, capacidades, padrões agênticos, recuperação, engenharia e operação. Cada termo em uma linha clara, com um exemplo concreto e zero hype. Mais mini-FAQ com 10 perguntas que economizam reunião.