Pular para o conteúdo
Atualizado em Categoria: Inteligência Artificial14 min de leitura

O que são embeddings? Representando significado em vetores

Por Lucas Andrade ·

Descubra como palavras, frases e documentos viram vetores que capturam semântica e habilitam busca por similaridade, recomendações e RAG — com intuição, código e armadilhas práticas.

O que são embeddings? Representando significado em vetores
Neste artigo

Computadores não entendem palavras — eles entendem números. Os embeddings são a ponte que resolve esse problema: eles transformam texto, imagens e outros dados em vetores numéricos que capturam significado. Entender embeddings é essencial para qualquer pessoa que queira construir busca semântica, sistemas de recomendação ou aplicações de RAG. Este artigo explica o conceito do zero, com intuição, exemplos de código e os cuidados práticos que separam um protótipo de uma aplicação que funciona em produção.

O problema: como um computador entende significado#

Imagine que você precisa ensinar um programa a saber que "carro" e "automóvel" são quase a mesma coisa, enquanto "carro" e "banana" não têm relação. Se você representar cada palavra apenas por um identificador (carro = 1, automóvel = 2, banana = 3), esses números não carregam nenhuma informação sobre significado. O 2 não está "mais perto" do 1 por serem sinônimos.

A representação clássica, chamada one-hot, sofre do mesmo mal: cada palavra vira um vetor enorme com um único 1 e o resto zeros. Todas as palavras ficam igualmente distantes umas das outras. Não há noção de similaridade.

one-hot, vocabulário de 50.000 palavras:
"carro"     -> [0, 0, ..., 1, ..., 0]   (50.000 posições)
"automóvel" -> [0, 1, ..., 0, ..., 0]   (50.000 posições)

Esses dois vetores são ortogonais: a distância entre "carro" e "automóvel" é exatamente igual à distância entre "carro" e "banana". Além de não capturar significado, o one-hot desperdiça espaço — dezenas de milhares de dimensões para representar uma única palavra.

Precisamos de uma representação onde a proximidade numérica reflita a proximidade de significado, e que use poucas dimensões densas em vez de milhares de zeros. É exatamente isso que um embedding faz.

O que é um embedding#

Um embedding é um vetor de números reais — uma lista de, digamos, 300 ou 1536 valores — que representa um item (palavra, frase, documento, imagem) em um espaço de muitas dimensões. A ideia central é:

Itens com significado parecido ficam próximos nesse espaço; itens diferentes ficam distantes.

"rei"     -> [0.21, -0.43, 0.88, ...]
"rainha"  -> [0.19, -0.40, 0.85, ...]   (próximo de "rei")
"banana"  -> [-0.77, 0.12, -0.05, ...]  (distante de ambos)

Esses números não são definidos à mão. Eles são aprendidos por um modelo a partir de grandes quantidades de dados, observando em quais contextos cada item aparece. A premissa, vinda da linguística, é conhecida como hipótese distribucional: "você conhece uma palavra pelas companhias que ela mantém". Palavras que aparecem em contextos parecidos têm significados parecidos.

Por que "muitas dimensões"?#

Cada dimensão de um embedding pode ser pensada, de forma simplificada, como um "eixo de significado" — um capturando algo próximo de gênero, outro de formalidade, outro de tempo verbal, e assim por diante. Na prática, esses eixos não são interpretáveis um a um; o significado emerge da combinação de todos eles. Por isso embeddings são chamados de representações densas e distribuídas: a informação está espalhada por todo o vetor, não concentrada em uma posição.

A intuição geométrica: relações viram direções#

O que tornou os embeddings famosos foi a descoberta de que eles capturam relações como direções no espaço vetorial. O trabalho seminal de Mikolov et al. (2013) mostrou que operações aritméticas com vetores de palavras produziam resultados semanticamente coerentes.

O exemplo clássico:

vetor("rei") - vetor("homem") + vetor("mulher") ≈ vetor("rainha")

Isso significa que a "direção" que separa homem de mulher é parecida com a que separa rei de rainha. O modelo aprendeu o conceito de gênero como uma direção geométrica, sem que ninguém o programasse para isso. Da mesma forma, relações como capital-país (Paris - França + Itália ≈ Roma) ou singular-plural emergem como padrões no espaço.

É importante não romantizar demais esse resultado: as analogias funcionam bem para alguns pares e mal para outros, e dependem de detalhes do treinamento. Mas a lição central permanece: estrutura semântica vira estrutura geométrica. É essa propriedade que torna os embeddings tão úteis.

Como medir similaridade entre vetores#

Se itens parecidos ficam próximos, precisamos de uma forma de medir essa proximidade. A métrica mais comum é a similaridade do cosseno, que mede o ângulo entre dois vetores — não importa o tamanho deles, só a direção.

import numpy as np

def similaridade_cosseno(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

# Valor próximo de 1  -> muito parecidos
# Valor próximo de 0  -> sem relação
# Valor próximo de -1 -> opostos

Por que cosseno e não distância euclidiana? Porque, em texto, costuma importar mais a direção do vetor (o "tema") do que sua magnitude. Dois documentos sobre o mesmo assunto podem ter tamanhos diferentes; o cosseno os trata como semelhantes desde que apontem na mesma direção. Muitos modelos já entregam vetores normalizados (norma 1), e nesse caso a similaridade do cosseno vira simplesmente o produto escalar — um detalhe que importa quando você precisa de desempenho.

Na prática, você gera o embedding de uma consulta e compara com os embeddings de milhares de documentos para achar os mais parecidos. Quando essa coleção fica grande, comparar com todos um a um (busca exaustiva) fica caro, e é preciso uma estrutura especializada para buscar com eficiência — assunto de O que é um banco de dados vetorial?, que usa índices aproximados (ANN) para encontrar os vizinhos mais próximos sem varrer a base inteira.

De palavras a frases e documentos#

Os primeiros embeddings representavam palavras isoladas, com um problema: a palavra "manga" (fruta ou parte da roupa) recebia sempre o mesmo vetor, ignorando o contexto. Modelos como Word2Vec e GloVe produziam um vetor estático por palavra.

Os modelos modernos, baseados na arquitetura Transformer, produzem embeddings contextuais: o vetor de uma palavra muda conforme a frase em que ela aparece. Em "comi uma manga doce" e "rasguei a manga da camisa", a palavra "manga" recebe vetores diferentes. Mais que isso, eles geram embeddings de frases e documentos inteiros, condensando todo o significado de um texto em um único vetor. Essa evolução está ligada à própria forma como os Transformers processam contexto, explicada em O que é a arquitetura Transformer e por que ela revolucionou a IA.

Gerar um embedding hoje costuma ser uma chamada de API:

from openai import OpenAI

client = OpenAI()
resp = client.embeddings.create(
    model="text-embedding-3-small",
    input="Como faço para devolver um produto?"
)
vetor = resp.data[0].embedding  # lista de floats
len(vetor)  # 1536

Você também pode rodar modelos de embedding localmente (por exemplo, com a biblioteca sentence-transformers), o que evita enviar dados sensíveis para terceiros e elimina o custo por chamada — ao preço de gerenciar a infraestrutura.

Chunking: o passo que muita gente esquece#

Documentos longos não devem virar um único embedding. Um vetor só não consegue representar bem um PDF de 40 páginas: o significado fica diluído. A prática é dividir o texto em chunks (trechos) de algumas centenas de tokens, com alguma sobreposição, e gerar um embedding por chunk. A qualidade do chunking afeta diretamente a qualidade da busca: chunks curtos demais perdem contexto; longos demais misturam assuntos.

Como um modelo aprende os embeddings#

Vale ter ao menos a intuição de como esses vetores surgem, porque isso explica suas qualidades e seus defeitos. O treinamento clássico do Word2Vec usava uma tarefa de previsão: dada uma palavra, prever as palavras vizinhas (skip-gram), ou o contrário (CBOW). Para acertar essa previsão, o modelo era obrigado a posicionar palavras de contextos parecidos em regiões parecidas do espaço. Os vetores não eram o objetivo declarado — eram um efeito colateral de aprender a prever contexto.

Os modelos de embedding modernos seguem o mesmo princípio, mas com tarefas mais sofisticadas. Muitos usam aprendizado contrastivo: o modelo vê pares de textos que sabidamente combinam (uma pergunta e sua resposta correta, por exemplo) e pares que não combinam, e aprende a aproximar os primeiros e afastar os segundos no espaço vetorial. Esse é o motivo de embeddings treinados para busca (query/documento) muitas vezes superarem embeddings genéricos em tarefas de recuperação: eles foram otimizados exatamente para que perguntas fiquem perto das respostas certas.

A consequência prática é importante: um embedding é tão bom quanto os dados e a tarefa em que foi treinado. Se você precisa casar perguntas curtas com documentos longos, prefira um modelo treinado para assimetria query/documento. Se precisa medir similaridade entre frases parecidas, um modelo de sentence similarity tende a ir melhor.

Aplicações práticas dos embeddings#

Embeddings são a fundação de várias aplicações que parecem mágicas, mas são pura geometria:

  • Busca semântica: encontrar documentos pelo significado, não pelas palavras exatas. Procurar por "como cancelar assinatura" encontra um texto sobre "encerrar plano". Veja Busca semântica: encontrando significado, não palavras.
  • Sistemas de recomendação: itens próximos no espaço são sugeridos juntos.
  • Clustering e classificação: agrupar textos semelhantes ou rotulá-los automaticamente.
  • Detecção de duplicatas: identificar conteúdos quase idênticos.
  • RAG: recuperar trechos relevantes para alimentar um LLM com contexto.

Esse último ponto é central na IA moderna. A técnica de recuperação densa usa embeddings para encontrar passagens relevantes a uma pergunta, superando a busca por palavras-chave em tarefas de perguntas e respostas (Karpukhin et al., 2020). É a base de O que é RAG (Retrieval-Augmented Generation)?, em que um LLM recebe trechos recuperados por similaridade para responder com informação atualizada.

Recuperação densa: embeddings em ação no RAG#

Vale detalhar o caso do dense retrieval, porque ele mostra o poder dos embeddings. A abordagem antiga de busca casava palavras: se a pergunta usava termos diferentes do documento, a busca falhava. A recuperação densa resolve isso codificando pergunta e documentos no mesmo espaço vetorial e medindo similaridade.

Karpukhin et al. (2020) demonstraram que essa técnica, batizada de Dense Passage Retrieval, recupera passagens muito mais relevantes do que métodos tradicionais em perguntas de domínio aberto. O fluxo típico é:

  1. Indexação: gere embeddings de todos os documentos (em chunks) e guarde-os.
  2. Consulta: gere o embedding da pergunta do usuário.
  3. Busca: encontre os documentos com maior similaridade de cosseno.
  4. Geração: passe esses documentos para o LLM produzir a resposta.
# Esboço de um RAG mínimo
pergunta = "como cancelar minha assinatura?"
v_pergunta = embed(pergunta)

# similaridade contra a base já indexada
ranqueados = sorted(
    base,  # lista de {"texto": ..., "vetor": ...}
    key=lambda doc: similaridade_cosseno(v_pergunta, doc["vetor"]),
    reverse=True,
)
contexto = "\n".join(doc["texto"] for doc in ranqueados[:3])
resposta = llm(f"Use o contexto:\n{contexto}\n\nPergunta: {pergunta}")

Busca híbrida: o melhor dos dois mundos#

A recuperação densa não substitui completamente a busca por palavras-chave. Para termos exatos, códigos de produto, nomes próprios e siglas, a busca léxica (como BM25) ainda é muito eficaz. Por exemplo, procurar pelo código "SKU-4471" por similaridade semântica é frágil — esse identificador não tem "significado" para ser capturado. A busca léxica acerta na hora. Por isso, sistemas maduros costumam usar busca híbrida: combinam o ranking semântico dos embeddings com o ranking léxico das palavras-chave. É comum também aplicar um passo de re-ranking, em que um modelo mais caro (um cross-encoder) reordena os poucos candidatos do topo para refinar a relevância. A divisão de trabalho costuma ser: embeddings recuperam um conjunto amplo de candidatos com baixo custo; o re-ranker, mais preciso e mais caro, ordena apenas esse subconjunto.

Avaliando a qualidade da recuperação#

Não dá para melhorar o que você não mede. Antes de declarar que sua busca semântica "funciona", monte um pequeno conjunto de avaliação: perguntas reais com os documentos que deveriam ser recuperados. Métricas comuns são recall@k (entre os k primeiros resultados, qual fração dos documentos certos apareceu) e MRR (quão alto na lista o primeiro resultado certo ficou). Com esse conjunto, você compara modelos de embedding, tamanhos de chunk e estratégias de busca de forma objetiva, em vez de no "achismo".

Cuidados e limitações#

Embeddings são poderosos, mas exigem atenção a alguns pontos:

  • Modelo importa: embeddings de modelos diferentes não são compatíveis entre si. Não misture. E ao trocar o modelo de embedding, você precisa reindexar toda a base, porque os vetores antigos vivem em outro espaço.
  • Custo de dimensão: vetores maiores capturam mais nuance, mas pesam mais no armazenamento e na busca. Alguns modelos modernos permitem truncar o vetor para menos dimensões com perda controlada de qualidade.
  • Domínio: um embedding genérico pode ir mal em jargão muito específico (jurídico, médico). Às vezes vale ajustar (fine-tuning) ou escolher um modelo especializado.
  • Vieses herdados: como aprendem dos dados, embeddings podem refletir vieses sociais presentes no texto — associando profissões a gêneros, por exemplo. Isso exige cuidado em aplicações sensíveis.
  • Idioma: nem todo modelo é bom em português. Verifique se o modelo foi treinado em conteúdo multilíngue antes de assumir que funciona bem em pt-BR.

Um fluxo completo, do texto à resposta#

Para amarrar tudo, vale ver onde cada peça entra num sistema real de busca semântica:

  1. Preparação dos dados. Você coleta os documentos, limpa o texto e divide em chunks com sobreposição. Cada chunk guarda também metadados (origem, título, data) para filtrar e citar depois.
  2. Geração dos embeddings. Passa cada chunk pelo modelo de embedding e obtém um vetor. Aqui você decide modelo, dimensão e se vai normalizar.
  3. Indexação. Os vetores vão para um banco vetorial, que monta um índice aproximado para busca rápida. É o passo que torna viável buscar entre milhões de vetores em milissegundos.
  4. Consulta. Quando o usuário pergunta, você gera o embedding da pergunta com o mesmo modelo usado na indexação — usar modelos diferentes aqui quebra tudo, porque os vetores viveriam em espaços incompatíveis.
  5. Recuperação e uso. Você busca os vizinhos mais próximos, opcionalmente reordena com um re-ranker, e entrega os melhores trechos para a interface (busca) ou para um LLM (RAG).

O ponto que mais gera bugs silenciosos é o passo 4: trocar o modelo de embedding sem reindexar. Os números até saem, a busca até roda, mas os resultados ficam aleatórios porque a pergunta e os documentos não compartilham mais o mesmo espaço.

Perguntas frequentes#

Qual a diferença entre embedding e tokenização? Tokenização quebra o texto em pedaços (tokens) que o modelo consegue processar; é um passo de pré-processamento. O embedding é o vetor de significado associado a esses tokens. São etapas distintas: primeiro tokeniza, depois gera os vetores.

Embeddings só funcionam para texto? Não. A mesma ideia se aplica a imagens, áudio, código e até produtos de e-commerce. Modelos multimodais chegam a colocar texto e imagem no mesmo espaço vetorial, permitindo buscar imagens por descrição textual.

Quantas dimensões devo usar? Depende do modelo e do trade-off entre qualidade e custo. Modelos comuns variam de 384 a 3072 dimensões. Para a maioria dos casos, comece com o tamanho padrão recomendado pelo modelo e só ajuste se tiver restrições reais de armazenamento ou latência.

Preciso normalizar os vetores? Se você usa similaridade do cosseno, a normalização é implícita. Se usa produto escalar como atalho de desempenho, então sim — normalize os vetores antes de armazená-los, para que o produto escalar equivalha ao cosseno.

Conclusão#

Embeddings transformam significado em geometria: itens parecidos viram vetores próximos, e relações semânticas viram direções no espaço. Essa ideia simples, refinada desde os primeiros modelos de palavras até os embeddings contextuais de hoje, sustenta busca semântica, recomendações, clustering e RAG. Dominar embeddings, a similaridade de cosseno e os detalhes práticos — chunking, escolha de modelo, reindexação ao trocar de modelo e busca híbrida — é um passo fundamental para construir aplicações de IA que realmente entendem o que o usuário quer dizer.

Referências#

  • Mikolov, T., Sutskever, I., Chen, K., Corrado, G., Dean, J. (2013). Distributed Representations of Words and Phrases and their Compositionality. NeurIPS.
  • Karpukhin, V., Oğuz, B., Min, S., Lewis, P., Wu, L., Edunov, S., Chen, D., Yih, W. (2020). Dense Passage Retrieval for Open-Domain Question Answering. EMNLP.
  • Mikolov, T., Chen, K., Corrado, G., Dean, J. (2013). Efficient Estimation of Word Representations in Vector Space. ICLR Workshop.
  • Reimers, N., Gurevych, I. (2019). Sentence-BERT: Sentence Embeddings using Siamese BERT-Networks. EMNLP.

Leituras relacionadas

Nenhum comentário ainda

Seja o primeiro a comentar.

Deixe seu comentário

Entre com sua conta Canverly para comentar. Você pode usar a mesma conta em qualquer site da rede.

Entrar com Canverly