O que é similaridade de cosseno e como isso ajuda as LLMs a serem melhores
Definição matemática
A similaridade de cosseno entre dois vetores A e B em um espaço euclidiano é o cosseno do ângulo θ entre eles. Formalmente:
A · B Σᵢ AᵢBᵢ
similaridade(A,B) = ------- = ----------------------------
‖A‖ ‖B‖ √(Σᵢ Aᵢ²) · √(Σᵢ Bᵢ²)
Ou seja: produto interno dos vetores dividido pelo produto das normas L2. Em termos práticos: é o produto interno (dot product) dos vetores normalizados. Quando os vetores já estão normalizados (norma L2 = 1), a similaridade de cosseno se reduz ao dot product:
import numpy as np
def cosine_similarity(a: np.ndarray, b: np.ndarray) -> float:
"""Similaridade de cosseno: valor em [-1, 1]. 1 = idênticos, 0 = ortogonais, -1 = opostos."""
a_norm = a / np.linalg.norm(a)
b_norm = b / np.linalg.norm(b)
return float(np.dot(a_norm, b_norm))
- 1: mesma direção (máxima similaridade)
- 0: ortogonais (sem relação)
- -1: direções opostas
Para embeddings de texto, os valores costumam ficar em [0, 1] porque os modelos geram vetores em semi-espaços onde ângulos > 90° são raros.
Embeddings e espaço semântico
LLMs e modelos de embedding (Sentence-BERT, OpenAI Embeddings, Cohere, etc.) mapeiam texto para vetores densos em R^n (tipicamente n = 384, 768, 1536 ou mais). Nesse espaço:
- Textos semanticamente próximos ficam geometricamente próximos
- A similaridade de cosseno (ou o dot product com vetores normalizados) mede essa proximidade
Ou seja: buscar “textos parecidos” vira buscar “vetores com alto cosseno”.
Por que a similaridade de cosseno ajuda as LLMs
1. Retrieval (RAG) e contexto relevante
Em RAG (Retrieval-Augmented Generation), o fluxo é:
- Indexar: converter documentos em embeddings e armazenar (ex.: vector DB).
- Consultar: converter a pergunta do usuário em embedding.
- Recuperar: buscar os k vetores mais similares ao embedding da pergunta (usando cosseno ou dot product).
- Gerar: injetar esses trechos como contexto na prompt da LLM.
Se o retrieval devolver trechos irrelevantes, a LLM tende a “inventar” ou desviar do tema. Se devolver trechos muito similares à pergunta, o contexto é relevante e a resposta tende a ser mais precisa e ancorada nos dados. A similaridade de cosseno é a métrica que ranqueia quais trechos são mais relevantes.
2. Independência da magnitude (norma)
Ao contrário da distância euclidiana, a similaridade de cosseno não depende do tamanho do vetor, só da direção. Isso é útil porque:
- Documentos longos geram vetores com norma maior; com distância euclidiana, um doc longo poderia ser sempre “mais longe”.
- Com cosseno, um parágrafo curto e um documento longo podem ser igualmente similares à pergunta se o conteúdo semântico for alinhado.
3. Eficiência em produção
Com vetores normalizados (L2 norm = 1), similaridade de cosseno = dot product. Em muitos vector DBs (Pinecone, Weaviate, pgvector, etc.):
- Índices como IVF ou HNSW são otimizados para nearest neighbor por dot product ou cosseno.
- A busca é sub-linear no número de vetores (não precisa comparar com todos).
Isso permite escalar RAG para milhões de chunks sem degradar a latência.
Implementação típica em RAG
# Pseudocódigo de retrieval com similaridade de cosseno
def retrieve(query: str, top_k: int = 5) -> list[Chunk]:
query_embedding = embedding_model.encode(query, normalize_embeddings=True)
# Vector DB retorna os top_k por similaridade de cosseno (ou dot product)
results = vector_db.search(query_embedding, top_k=top_k, metric="cosine")
return [hit.chunk for hit in results]
Normalizar na indexação e na query garante que você está de fato usando cosseno (dot product em vetores unitários).
Resumo
| Conceito | Papel |
|---|---|
| Similaridade de cosseno | Mede alinhamento semântico entre vetores (embedding de pergunta vs. embedding de trechos). |
| RAG | Usa essa métrica para escolher o contexto mais relevante antes de chamar a LLM. |
| Efeito nas LLMs | Menos alucinação e respostas mais precisas quando o contexto recuperado é de alta similaridade à pergunta. |
Quanto melhor o retrieval (e portanto o uso de similaridade de cosseno), melhor tende a ser o desempenho da LLM em tarefas baseadas em conhecimento (QA, suporte, documentação).