Ao terminar este artigo você vai saber o que é um embedding, por que ele permite buscar por significado e não só por palavra exata, e vai ter rodado em Python um exemplo que compara frases e ordena resultados por similaridade, com um modelo local, sem API paga e sem enviar dados para fora da sua máquina.
O que é um embedding?
Embedding é uma lista de números que representa o significado de um texto. Um modelo de embeddings recebe uma frase e devolve um vetor, por exemplo com 384 números. Frases com significado parecido produzem vetores próximos, e frases sem relação produzem vetores distantes.
Pense num mapa. Cada frase vira um ponto, e frases sobre o mesmo assunto ficam na mesma vizinhança. "Quero meu dinheiro de volta" e "Como peço reembolso" ficam perto, apesar de não dividirem palavras importantes. "Receita de bolo de cenoura" fica longe das duas. O mapa real tem centenas de dimensões em vez de duas, mas a intuição é a mesma.
A ideia vem de longe. Em 2013, o trabalho do word2vec mostrou que palavras podem ser representadas por vetores em que a distância reflete a relação de sentido. Hoje existem modelos que fazem isso para frases e parágrafos inteiros, como os descritos no artigo do Sentence-BERT, de 2019.
Para que serve um embedding?
- Busca semântica. Achar documentos pelo sentido da pergunta. É a base do RAG, explicado em RAG na prática.
- Agrupamento. Juntar comentários de clientes por assunto sem definir categorias antes.
- Detecção de duplicados. Encontrar perguntas de suporte que dizem a mesma coisa com outras palavras.
- Recomendação. Sugerir itens parecidos com os que a pessoa já leu.
- Classificação simples. Comparar um texto com exemplos de cada categoria.
Qual a diferença para busca por palavra-chave?
A busca por palavra-chave procura as mesmas palavras. Se o cliente escreve "esqueci o login" e o seu texto de ajuda fala em "redefinir credenciais", a busca comum não encontra. A busca por embeddings compara significado e tende a encontrar. Por outro lado, ela pode falhar em códigos exatos, siglas e nomes próprios, em que a palavra-chave é melhor. Por isso muitos sistemas combinam as duas, como mostra Banco vetorial na prática com pgvector, que traz a busca híbrida.
Como medir se dois embeddings são parecidos?
Com a similaridade do cosseno. Ela mede o ângulo entre dois vetores. O valor vai de -1 a 1, e quanto mais perto de 1, mais parecidos. Quando os vetores são normalizados, ou seja, têm comprimento 1, o cosseno é só o produto escalar, a soma dos produtos dos números correspondentes. É a conta que faremos no código.
Mão na massa: busca por significado em Python
Usaremos a biblioteca sentence-transformers e o modelo paraphrase-multilingual-MiniLM-L12-v2, que lida com português e gera vetores de 384 dimensões. Na primeira execução, o modelo é baixado da internet (algumas centenas de megabytes) e depois fica em cache. Daí em diante tudo roda localmente, sem chave de API.
Instale as dependências, de preferência num ambiente virtual.
pip install sentence-transformers numpy
Crie o arquivo embeddings.py.
from sentence_transformers import SentenceTransformer
import numpy as np
modelo = SentenceTransformer("sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2")
frases = [
"Como faço para pedir reembolso de uma compra?",
"Quero meu dinheiro de volta pelo produto que comprei.",
"Qual é a receita de bolo de cenoura?",
"Preciso trocar a senha da minha conta.",
"Esqueci o login e não consigo entrar no aplicativo.",
]
# normalize_embeddings=True deixa cada vetor com comprimento 1
v = modelo.encode(frases, normalize_embeddings=True)
print("formato:", v.shape)
print("primeiros 5 numeros:", np.round(v[0][:5], 3))
# com vetores normalizados, o produto escalar é a similaridade do cosseno
sim = v @ v.T
for i in range(len(frases)):
for j in range(i + 1, len(frases)):
print(f"{sim[i][j]:.2f} {i} x {j}")
consulta = "Como recuperar o acesso ao app?"
q = modelo.encode([consulta], normalize_embeddings=True)[0]
pontos = v @ q
print("consulta:", consulta)
for k in np.argsort(-pontos):
print(f"{pontos[k]:.2f} {frases[k]}")
Execute com python embeddings.py. Esta foi a saída obtida em nosso teste, com sentence-transformers 6.1.0, torch 2.14.1 (CPU), transformers 5.19.0, numpy 2.5.3 e Python 3.12:
formato: (5, 384)
primeiros 5 numeros: [-0.032 0.014 -0.012 0.037 -0.052]
0.66 0 x 1
-0.03 0 x 2
0.35 0 x 3
0.12 0 x 4
0.16 1 x 2
0.37 1 x 3
0.18 1 x 4
0.12 2 x 3
0.04 2 x 4
0.47 3 x 4
consulta: Como recuperar o acesso ao app?
0.64 Esqueci o login e não consigo entrar no aplicativo.
0.26 Quero meu dinheiro de volta pelo produto que comprei.
0.26 Preciso trocar a senha da minha conta.
0.16 Como faço para pedir reembolso de uma compra?
-0.06 Qual é a receita de bolo de cenoura?
Os números de uma máquina para outra podem variar na terceira casa decimal, conforme versões das bibliotecas.
Como ler o resultado
A primeira linha mostra que cada uma das 5 frases virou um vetor de 384 números. Na tabela de pares, a comparação entre as duas frases sobre reembolso (0 x 1) deu 0,66, a mais alta do grupo, mesmo sem repetir palavras importantes. Já a receita de bolo (frase 2) ficou perto de zero em relação às demais. As duas frases sobre acesso (3 x 4), senha e login, deram 0,47, a segunda maior.
Na consulta "Como recuperar o acesso ao app?", a frase sobre login ficou em primeiro com 0,64, bem acima do resto. Note que a segunda e a terceira posições empataram em 0,26, o que mostra que os valores intermediários não são confiáveis para decidir sozinhos. Em sistemas reais, o que se usa é a ordem dos melhores resultados e, em geral, um limite mínimo de similaridade ajustado com os seus dados.
Como escolher um modelo de embeddings?
- Idioma. Para português, prefira modelos multilíngues. Há modelos menores treinados só em inglês, como o
all-MiniLM-L6-v2, que funcionam pior com português. - Tamanho do vetor. Mais dimensões podem representar mais nuances, mas ocupam mais espaço e deixam a busca mais lenta e cara. O vetor do nosso exemplo tem 384.
- Local ou API. Modelos locais mantêm os dados na sua máquina, o que ajuda em privacidade e custo. APIs pagas costumam ter qualidade maior em alguns casos, cobram por token (veja O que é token em IA) e enviam o texto para o fornecedor.
- Consistência. Todos os textos e as consultas precisam ser vetorizados com o mesmo modelo. Trocar de modelo exige recalcular tudo, pois vetores de modelos diferentes não são comparáveis.
- Avaliação. Teste com perguntas reais do seu domínio e confira se o documento certo aparece entre os primeiros resultados.
Quais são os limites dos embeddings?
- Textos longos precisam ser divididos. Modelos têm um limite de tokens por entrada, e o excedente é cortado. O artigo Chunking: estratégias explica como dividir.
- Negação e detalhes numéricos podem passar despercebidos. "Posso cancelar" e "não posso cancelar" tendem a ficar próximos.
- O modelo reflete os dados com que foi treinado, inclusive vieses. Veja Viés em modelos de IA.
- Similaridade não é verdade. O texto mais parecido com a pergunta não é necessariamente o que responde corretamente a ela.
Próximos passos
Com este exemplo você já tem a peça central de uma busca semântica. Para escalar de 5 frases para milhares de documentos, guarde os vetores num banco vetorial, como no artigo Banco vetorial na prática com pgvector. Para entregar os trechos achados a um LLM e gerar respostas com base neles, siga para RAG na prática.
Resumo
- Embedding é um vetor de números que representa o significado de um texto.
- Textos com sentido parecido têm vetores próximos, medidos pela similaridade do cosseno.
- Dá para gerar embeddings localmente com
sentence-transformers, sem API paga. - Use a ordem do ranking, não o valor absoluto, e teste com os seus dados.
- Use o mesmo modelo em tudo e divida textos longos antes de vetorizar.
Fontes
Consultadas em 09/10/2026.
- Mikolov et al., "Efficient Estimation of Word Representations in Vector Space" (word2vec), 2013: arxiv.org/abs/1301.3781
- Reimers e Gurevych, "Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks", 2019: arxiv.org/abs/1908.10084
- Documentação do Sentence Transformers: sbert.net
- Modelo
paraphrase-multilingual-MiniLM-L12-v2no Hugging Face: huggingface.co/sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2
Código testado em container python:3.12-slim com sentence-transformers 6.1.0, torch 2.14.1 (CPU), transformers 5.19.0 e numpy 2.5.3, em 09/10/2026.