O que são incorporações? Semelhança de vetores e cossenos explicada de forma simples
Os embeddings permitem que os computadores comparem o significado em vez de combinar palavras exatas. Eles potencializam a pesquisa semântica, recomendações e RAG. Aprenda o que são, como a similaridade é medida e onde eles decepcionaram você.
- Uma incorporação é uma lista de números que representa o significado de um texto, uma imagem ou outros dados.
- Itens semelhantes terminam com números semelhantes, então o significado pode ser comparado com a matemática.
- Semelhança de cosseno compara a direção e é uma maneira comum de avaliar a semelhança de dois embeddings.
- Compare apenas incorporações do mesmo modelo e teste os resultados em seus próprios dados.
Pesquise “como recuperar meu dinheiro” e um bom sistema encontrará uma página intitulada “Política de reembolso”, mesmo que os dois não compartilhem palavras importantes. Essa capacidade vem de embeddings, uma das ideias mais úteis da IA moderna.
Este guia explica incorporações sem matemática pesada. Executamos um pequeno exemplo em Python 3.13 e sua saída é mostrada abaixo. Os vetores nele são aqueles que fizemos à mão, com apenas três números cada, para facilitar a visualização da ideia. Os embeddings reais vêm de um modelo treinado e geralmente têm centenas ou milhares de números.
O que é uma incorporação?
Uma incorporação é uma representação de algo como uma lista de números, chamada vetor. Um modelo é treinado para que itens com significados relacionados obtenham vetores próximos.
"kitten" -> [0.9, 0.8, 0.1]
"cat" -> [0.9, 0.7, 0.2]
"invoice" -> [0.0, 0.1, 0.9]
Uma vez que o texto esteja neste formato, um computador pode calcular quão semelhantes são duas partes de texto, o que não pode ser feito diretamente com palavras. Os embeddings também não se limitam a palavras. Frases, documentos inteiros, imagens, áudio e produtos podem ser incorporados.
Por que não apenas combinar palavras-chave?
| Consulta e documento | Pesquisa por palavra-chave | Incorporando pesquisa |
|---|---|---|
| “dinheiro de volta” e “política de reembolso” | Sente falta, sem palavras compartilhadas | Posso encontrá-lo |
| “laptop” e “notebook” | Sinto falta | Posso encontrá-lo |
| “erro E1042” e uma página com “E1042” | Encontra exatamente | Pode sentir falta |
| “banco” (rio) e “banco” (dinheiro) | Trata-os da mesma forma | Pode separá-los, dado o contexto |
Nosso guia do RAG mostra isso na prática. Uma simples pesquisa de contagem de palavras marcou zero para “Quando posso receber meu dinheiro de volta?” contra um documento de reembolso, uma vez que não trocaram palavras. Observe também a terceira linha: identificadores exatos são um ponto fraco dos embeddings, portanto, a pesquisa por palavra-chave ainda tem um lugar.
Pense em um mapa
Imagine colocar cada palavra em um mapa enorme, onde a localização reflete o significado. “Gato” e “gatinho” sentam-se quase um ao lado do outro, “cachorro” está no mesmo bairro e “fatura” está em uma cidade diferente. Para encontrar palavras relacionadas, basta olhar nas proximidades.
Uma incorporação real funciona da mesma maneira, exceto que o mapa tem centenas de dimensões em vez de duas. As pessoas não conseguem imaginar isso, mas a matemática funciona da mesma forma. Os números individuais geralmente não têm um significado claro, como “peludo”. O que importa é a posição geral.
Um pequeno exemplo de trabalho
Veja como comparar nossos vetores feitos à mão:
import math
def cosine(a, b):
dot = sum(x * y for x, y in zip(a, b))
return dot / (math.sqrt(sum(x * x for x in a)) *
math.sqrt(sum(y * y for y in b)))
vectors = {
"kitten": [0.9, 0.8, 0.1],
"cat": [0.9, 0.7, 0.2],
"dog": [0.8, 0.3, 0.2],
"invoice": [0.0, 0.1, 0.9],
}
for word in ("kitten", "dog", "invoice"):
print(word, round(cosine(vectors["cat"], vectors[word]), 3))
# kitten 0.994
# dog 0.955
# invoice 0.238
Contra “gato”, “gatinho” tem a pontuação mais alta, “cachorro” é o próximo e “fatura” muito mais baixa. Escolhemos esses vetores para produzir esse padrão, então a classificação não prova nada sobre a linguagem real. Mostra apenas como o cálculo se comporta. Uma pesquisa semântica faz a mesma coisa em três etapas: incorporar a consulta, pontuar em cada item armazenado e classificar.
query = [0.85, 0.75, 0.15]
sorted(vectors, key=lambda w: cosine(query, vectors[w]), reverse=True)
# ['kitten', 'cat', 'dog', 'invoice']
Similaridade de cosseno explicada
Cada vetor pode ser pensado como uma seta apontando para a origem. A similaridade de cosseno mede o ângulo entre duas setas, ignorando o comprimento delas. Confirmamos os valores principais:
cosine([1, 2, 3], [2, 4, 6]) # 1.0 same direction
cosine([1, 0], [0, 1]) # 0.0 unrelated (at right angles)
cosine([1, 0], [-1, 0]) # -1.0 opposite directions
| Pontuação | Significado |
|---|---|
| Perto de 1 | Aponte quase na mesma direção, muito semelhante |
| Perto de 0 | Não relacionado |
| Perto de -1 | Aponte em direções opostas |
Veja a primeira linha. [2, 4, 6] é duas vezes mais longo que [1, 2, 3], mas a pontuação é um 1,0 perfeito, porque a direção é tudo o que conta. Isso é útil para texto, onde o comprimento pode refletir coisas como o tamanho do documento, em vez do significado. Tenha cuidado com os limites também. Não existe uma pontuação universal que signifique “semelhante”, pois os intervalos úteis diferem de modelo para modelo, portanto teste com seus próprios dados.
Outras medidas de distância
| Medir | O que parece | Notas |
|---|---|---|
| Semelhança de cosseno | Apenas ângulo | Um padrão comum para texto |
| Produto escalar | Ângulo e comprimento | Rápido e igual a cosseno em vetores normalizados |
| Distância euclidiana | Distância em linha reta | Menor significa mais semelhante |
A diferença é fácil de ver. Esses mesmos dois vetores com pontuação de cosseno de 1,0 têm uma distância euclidiana de 3,742, pois um é mais longo que o outro. Muitos sistemas normalizam vetores, dimensionando cada um para um comprimento de 1. Depois disso, o produto escalar e o cosseno dão a mesma resposta, e confirmamos isso: ambos deram 0,955 para “gato” e “cachorro”. Verifique a documentação do seu modelo para ver qual medida ele recomenda.
Como os embeddings são aprendidos
Ninguém atribui esses números manualmente em sistemas reais. Uma rede neural os aprende durante o treinamento. Uma ideia inicial e influente é que palavras que aparecem em contextos semelhantes tendem a ter significados semelhantes, como “Eu alimentei meu gato” e “Eu alimentei meu cachorro”. Modelos como Word2Vec e GloVe aprenderam vetores de palavras a partir desses padrões.
Mais tarde, modelos baseados em transformadores, como o BERT, tornaram os embeddings sensíveis ao contexto, para que “banco” pudesse obter um vetor diferente em “margem de rio” e “empréstimo bancário”. Muitos modelos modernos incorporam frases ou passagens inteiras de uma só vez. Nosso guia para grandes modelos de linguagem explica como os transformadores lidam com o contexto.
Onde os embeddings são usados
| Usar | Como isso ajuda |
|---|---|
| Pesquisa semântica | Encontra resultados por significado, em vez de palavras exatas |
| pano | Recupera passagens relevantes para um modelo de linguagem |
| Recomendações | Sugere itens semelhantes aos que você gostou |
| Agrupamento | Grupos suportam tickets ou avaliações por tópico |
| Detecção duplicada | Identifica perguntas ou listagens semelhantes |
| Classificação | Fornece recursos para modelos simples |
| Detecção de anomalias | Sinaliza itens longe de todo o resto |
Pesquisando em escala
Nosso exemplo comparou uma consulta com cada item, o que é conhecido como pesquisa exata. Isso funciona bem para milhares de itens, mas fica lento com muitos milhões. Índices de vizinho mais próximo aproximado (ANN), como HNSW, resolvem isso. Eles encontram partidas muito próximas rapidamente, abrindo mão de uma pequena chance de perder a melhor.
Bancos de dados vetoriais e extensões, como pgvector para PostgreSQL, fornecem esses índices junto com filtragem e armazenamento. Nosso guia de banco de dados vetorial aborda as opções. Para um projeto pequeno, você pode não precisar de nenhum, e uma pesquisa na memória é uma ótima maneira de começar.
Dica: considere a pesquisa híbrida antecipadamente. Combinar a incorporação de similaridade com a correspondência de palavras-chave geralmente fornece melhores resultados do que qualquer uma delas isoladamente, principalmente quando os usuários pesquisam códigos de produtos, nomes ou mensagens de erro.
Escolhendo um modelo de incorporação
- Idioma. Se o seu conteúdo estiver em hindi ou tâmil, por exemplo, verifique se o modelo o lida bem.
- Domínio. Os modelos gerais podem ter dificuldades com termos jurídicos ou médicos especializados.
- Dimensões. Mais dimensões podem capturar mais detalhes, mas custam mais armazenamento e memória.
- Custo e hospedagem. Compare uma API hospedada com um modelo aberto que você mesmo pode executar, especialmente para dados privados.
- Comprimento de entrada. Os modelos têm um limite, portanto, documentos longos devem ser divididos em partes primeiro.
O melhor teste são seus próprios dados. Colete cerca de 20 consultas reais junto com os documentos que devem encontrar e compare como cada modelo as classifica. Os benchmarks publicados podem não refletir o seu conteúdo.
Limitações
- Aprisionamento de modelo. Vetores de modelos diferentes não podem ser comparados. Se você mudar de modelo, deverá incorporar tudo novamente.
- Termos exatos. IDs, códigos e nomes raros podem não ser correspondidos de forma confiável.
- Negação. “Reembolsos permitidos” e “reembolsos não permitidos” podem aparecer próximos, apesar de significarem coisas opostas.
- Semelhante não significa correto. Uma correspondência aproximada pode estar desatualizada ou simplesmente errada.
- Viés. Os embeddings podem absorver estereótipos de seus dados de treinamento.
- Cosseno não é mágico. Os pesquisadores questionaram o quão significativo ele é em alguns embeddings aprendidos, portanto, trate as pontuações como um sinal útil e não como uma medida da verdade.
Erros comuns
- Mistura de modelos. Incorpore consultas e documentos com o mesmo modelo e versão.
- Usando um limite de similaridade em todos os lugares. Ajuste-o para cada modelo e tarefa.
- Incorporar documentos enormes inteiros. O significado fica diluído, então separe-os primeiro.
- Ignorando a avaliação. Sem consultas de teste, você não pode dizer se uma mudança ajudou.
- Usando embeddings para tudo. Se os usuários pesquisarem IDs exatos, um índice de banco de dados normal é melhor.
Considerações finais
Uma incorporação transforma significado em números, para que o software possa comparar ideias em vez de sequências. O conceito é simples, enquanto o trabalho prático consiste em escolher um modelo, agrupar os dados e testar em consultas reais. Para experimentar você mesmo, incorpore algumas dezenas de seus próprios documentos com qualquer modelo de incorporação, pesquise-os com perguntas reais e veja onde os resultados o surpreendem.
Perguntas frequentes
O que são incorporações em termos simples?
Incorporações são listas de números que representam significado. Itens com significado semelhante recebem números semelhantes, o que permite ao computador compará-los matematicamente.
O que é similaridade de cosseno?
Ele mede o ângulo entre dois vetores, de -1 a 1. Uma pontuação próxima de 1 significa que eles apontam quase na mesma direção, o que sugere conteúdo semelhante.
Qual é a diferença entre incorporações e tokens?
Um token é um pedaço de texto que um modelo processa. Uma incorporação é um vetor numérico que representa o significado de um token, frase ou documento.
Quantas dimensões uma incorporação deve ter?
Depende do modelo, e centenas a alguns milhares são comuns. Mais pode capturar mais detalhes, mas custa mais armazenamento, então teste o que seu caso de uso precisa.
Preciso de um banco de dados vetorial para usar embeddings?
Não. Coleções pequenas podem ser pesquisadas na memória. Os bancos de dados vetoriais tornam-se úteis com coleções maiores, atualizações frequentes ou necessidades de filtragem.
Continue aprendendo
Precisa de ajuda com testes, WordPress ou SEO?
Ajudamos as equipes a fornecer software melhor e a expandir seus sites. Conte-nos no que você está trabalhando e sugeriremos um próximo passo claro.
Mais guias sobre testes, IA e desenvolvimento moderno
Gostou deste artigo? Escolha um tópico e vá direto para nossos tutoriais mais recentes.
Explicação das alucinações de IA: por que os modelos de linguagem inventam as coisas e como reduzi-las
Explicação das alucinações de IA: o que são, por que os modelos de linguagem as produzem, tipos comuns, como reduzi-las com aterramento e instruções…
Leia o artigo →DevOpsVariáveis de ambiente explicadas: arquivos .env, segredos e configuração bem feitos
Variáveis de ambiente explicadas com exemplos de Python que executamos: leitura e configuração, por que cada valor é uma string, arquivos .env, hera…
Leia o artigo →Desenvolvimento de softwareExplicação da limitação de taxa de API: algoritmos, cabeçalhos e tratamento de erros 429
Limitação de taxa de API explicada com uma simulação que executamos: token bucket, janela fixa, janela deslizante, 429 respostas, cabeçalhos de limi…
Leia o artigo →Automação de testesZombando em Python: unittest.mock, patch e os erros que fazem os testes mentirem
Zombaria em Python com unittest.mock, testado: Mock e return_value, side_effect, patch onde um nome é usado, especificação e autospec, zombaria de d…
Leia o artigo →Teste de softwareCobertura de código explicada: cobertura de linha versus filial e o que 100% realmente significa
Cobertura de código explicada com uma execução cobertura.py real: cobertura de linha, ramal e condição, leitura de um relatório, por que 100% de cob…
Leia o artigo →Bancos de dados e SQLDELETE vs TRUNCATE vs DROP em SQL: diferenças, reversão e quando usar cada um
DELETE vs TRUNCATE vs DROP explicado com SQL testado: o que cada um remove, rollback, aciona, redefinição de identidade, velocidade e como PostgreSQ…
Leia o artigo →Bancos de dados e SQLExibições SQL explicadas: crie, use e evite as armadilhas, com exemplos
Visualizações SQL explicadas com consultas que executamos: criação de uma visualização, resultados ao vivo, ocultação de colunas, desempenho, visual…
Leia o artigo →Desenvolvimento de softwareInterface TypeScript vs tipo: diferenças reais, testadas com o compilador
Interface TypeScript versus tipo, verificada com o compilador real: o que ambos podem fazer, o que apenas um pode fazer, mesclagem de declarações, e…
Leia o artigo →Desenvolvimento de softwarePython *args e **kwargs explicados: funções flexíveis com exemplos claros
Python *args e **kwargs explicados com o código que executamos: empacotamento e descompactação, ordem dos parâmetros, argumentos somente de palavras…
Leia o artigo →Desenvolvimento de softwareFunções Python Lambda: sintaxe, usos reais e quando não usá-los
Funções lambda do Python explicadas com o código que executamos: sintaxe, classificação com chave, mapa e filtro, fechamentos, armadilha de ligação …
Leia o artigo →Inteligência artificialO que são agentes de IA? Como eles funcionam, com um loop de agente simples que você pode executar
O que são agentes de IA? Um guia simples para o loop do agente, ferramentas, memória e proteções, com um pequeno loop Python que executamos, riscos …
Leia o artigo →DevOpsMonitoramento versus observabilidade: a verdadeira diferença, com logs, métricas e rastreamentos
Explicação do monitoramento versus observabilidade: falhas conhecidas e desconhecidas, logs, métricas e rastreamentos, um passo a passo do incidente…
Leia o artigo →DevOpsDocker Volumes vs Bind Mounts: persista os dados do contêiner da maneira certa
Volumes Docker versus montagens de ligação explicadas: por que os dados do contêiner desaparecem, volumes nomeados, montagens de ligação, tmpfs, exe…
Leia o artigo →Automação de testesTDD vs BDD: principais diferenças, um recurso criado de ambas as maneiras e quando usar cada um
TDD vs BDD explicado com um recurso de desconto construído em ambos os sentidos: refatoração vermelho-verde com o código que executamos, cenários da…
Leia o artigo →Teste de softwareTeste de aceitação do usuário (UAT): processo, lista de verificação e exemplos reais
Explicação do teste de aceitação do usuário: quem o executa, como ele difere do controle de qualidade, um processo de sete etapas, um modelo de caso…
Leia o artigo →Bancos de dados e SQLValores SQL NULL explicados: IS NULL, COALESCE, NULLIF e as armadilhas a serem evitadas
Valores SQL NULL explicados com consultas que executamos: lógica de três valores, IS NULL, COALESCE, NULLIF, como agregações, junções e classificaçã…
Leia o artigo →Bancos de dados e SQLInstrução SQL CASE WHEN: sintaxe, exemplos reais e erros comuns
SQL CASE WHEN explicado com consultas que executamos: formulários simples e pesquisados, ordem de condição, pivôs com SUM, truques COUNT, classifica…
Leia o artigo →Desenvolvimento de softwareO que é JWT? JSON Web Tokens explicados com um exemplo prático
O que é JWT? JSON Web Tokens explicados: as três partes, um token construído e adulterado no código que executamos, JWT vs sessões, armazenamento, t…
Leia o artigo →Desenvolvimento de softwareLoop de eventos JavaScript explicado: pilha de chamadas, microtarefas e temporizadores com exemplos
O loop de eventos JavaScript explicado com o código que executamos: pilha de chamadas, filas de tarefas e microtarefas, por que setTimeout 0 não é i…
Leia o artigo →Desenvolvimento de softwareGeradores Python e rendimento explicado: economize memória com exemplos reais
Geradores Python e rendimento explicados com o código que executamos: como eles pausam e reiniciam, medem economia de memória, pipelines, sequências…
Leia o artigo →Inteligência artificialO que são incorporações? Similaridade de vetores e cossenos explicada de forma simples
O que são incorporações? Um guia em linguagem simples para vetores, similaridade de cossenos e pesquisa semântica, com um pequeno exemplo que execut…
Leia o artigo →DevOpsImplantação azul-verde vs canário: diferenças, compensações e como escolher
Explicação da implantação azul-verde versus canário: como cada um funciona, custo, risco e reversão, agrupamento estável de usuários que testamos, m…
Leia o artigo →Automação de testesTestes instáveis: o que os causa e como corrigi-los para sempre
Testes instáveis explicados com demonstrações que executamos: as principais causas, como confirmar e diagnosticar uma, soluções adequadas para tempo…
Leia o artigo →Teste de softwareTeste de carga versus teste de estresse: diferenças, métricas e exemplos k6
Teste de carga versus teste de estresse explicado: o que cada um prova, testes de pico e absorção, as métricas que importam, por que as médias engan…
Leia o artigo →Teste de softwareCaso de teste versus cenário de teste: principais diferenças, exemplos e quando usar cada um
Caso de teste vs cenário de teste explicado: definições claras, uma tabela lado a lado, um recurso de redefinição de senha retirado de cenários para…
Leia o artigo →Bancos de dados e SQLOtimização de consultas SQL: leia planos de execução e corrija consultas lentas, com intervalos
Otimização de consulta SQL testada em um milhão de linhas: leia planos de execução, adicione os índices corretos, corrija filtros não sargáveis, use…
Leia o artigo →Bancos de dados e SQLSQL UNION vs UNION ALL: diferenças, exemplos e desempenho testado
SQL UNION vs UNION ALL explicado com consultas que executamos: duplicatas, as regras que ambos seguem, um bug de dados real, desempenho medido, INTE…
Leia o artigo →Desenvolvimento de softwareTutorial da API JavaScript Fetch: GET, POST, tratamento de erros e tempos limite
Um tutorial da API JavaScript Fetch testado em um servidor local: GET e POST, por que 404 não lança, um auxiliar reutilizável, strings de consulta, …
Leia o artigo →Desenvolvimento de softwareManipulação de arquivos Python: leitura, gravação, CSV, JSON e pathlib com exemplos
Manipulação de arquivos Python explicada com código que executamos: modos abertos, com, leitura de arquivos grandes, CSV, JSON, pathlib, arquivos bi…
Leia o artigo →Desenvolvimento de softwareClasses e objetos Python: tutorial OOP com exemplos reais
Classes e objetos Python explicados com código que executamos: __init__, métodos, atributos de classe vs instância, herança, propriedades, métodos d…
Leia o artigo →Inteligência artificialO que é um modelo de linguagem grande? Como funcionam os LLMs, explicado sem exageros
O que é um modelo de linguagem grande? LLMs explicados em linguagem simples: tokens, incorporações, atenção, treinamento, temperatura e janelas de c…
Leia o artigo →DevOpsComandos Linux para iniciantes: o guia essencial do terminal com exemplos
Comandos Linux para iniciantes, agrupados por tarefa: navegação, arquivos, visualização de logs, grep, pipes, permissões, processos e arquivos, com …
Leia o artigo →Automação de testesSelenium vs Playwright: principais diferenças, código comparado e qual escolher
Selenium vs Playwright comparado: arquitetura, espera, suporte a navegador e linguagem, depuração, o mesmo teste em ambas as ferramentas, conselhos …
Leia o artigo →Teste de softwareParticionamento de equivalência: técnica de design de teste explicada com exemplos resolvidos
Explicação do particionamento de equivalência: como encontrar partições válidas e inválidas, exemplos resolvidos para idades, senhas e cupons, teste…
Leia o artigo →Teste de softwareGravidade vs Prioridade em Testes de Software: Diferenças, Matriz e Exemplos Reais
Explicação da gravidade versus prioridade em testes de software: definições claras, uma matriz de quatro vias com exemplos, escalas de nível, quem d…
Leia o artigo →Bancos de dados e SQLTutorial de subconsultas SQL: tipos, subconsultas correlacionadas e EXISTS com exemplos
Um tutorial de subconsultas SQL com consultas que executamos: subconsultas escalares, IN, FROM e SELECT, subconsultas correlacionadas, EXISTS, a arm…
Leia o artigo →Bancos de dados e SQLTransações SQL e ACID explicados: COMMIT, ROLLBACK e níveis de isolamento
Transações SQL e ACID explicadas com uma transferência bancária que executamos: COMMIT, ROLLBACK, savepoints, locks, níveis de isolamento, leituras …
Leia o artigo →Desenvolvimento de softwareGit merge vs rebase: diferenças, exemplos e quando usar cada um
Git merge vs rebase explicado com saída real do log, uma tabela comparativa, a regra de ouro do rebase e um fluxo de trabalho seguro para equipes.
Leia o artigo →Desenvolvimento de softwareList comprehension em Python: sintaxe, exemplos e quando evitar
List comprehension em Python explicada: sintaxe, filtros, if-else, laços aninhados, tempos medidos e quando um laço for comum é a melhor escolha.
Leia o artigo →Bancos de dados e SQLSQL JOIN explicado com exemplos (Inner, Left, Right, Full)
Entenda os joins SQL passo a passo com tabelas e consultas de exemplo: INNER, LEFT, RIGHT, FULL, CROSS e SELF, além de erros comuns e dicas de desem…
Leia o artigo →