Embeddings & Similaridade
Embeddings convertem texto em vetores de tamanho fixo onde a similaridade semântica corresponde à proximidade geométrica. Eles potencializam a busca semântica, clustering e recuperação RAG.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
from openai import OpenAI
import numpy as np
client = OpenAI()
emb = client.embeddings.create(model="text-embedding-3-small", input=["texto da consulta"])
vec = np.array(emb.data[0].embedding)
# similaridade de cosseno
def cosine(a, b):
return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))Quando usar isso:
- Busca semântica sobre documentos, código ou artigos de suporte.
- Agrupamento ou desduplicação de conteúdo de texto.
- Etapa de recuperação RAG antes da geração de LLM.
- Sistemas de recomendação baseados em similaridade de texto.
Exemplo de Trabalho
"""embeddings_similarity.py - incorporar, indexar e pesquisar documentos."""
from __future__ import annotations
import numpy as np
from openai import OpenAI
client = OpenAI()
MODEL = "text-embedding-3-small"
documents = [
"FastAPI é um framework web moderno em Python para construir APIs.",
"PyTorch é um framework de deep learning com grafos de computação dinâmicos.",
"pandas 2.2 fornece operações de DataFrame para análise de dados tabulares.",
"pytest é o framework padrão de testes para projetos Python.",
]
def embed_texts(texts: list[str]) -> np.ndarray:
response = client.embeddings.create(model=MODEL, input=texts)
vectors = [item.embedding for item in response.data]
arr = np.array(vectors, dtype=np.float32)
norms = np.linalg.norm(arr, axis=1, keepdims=True)
return arr / norms # Normalização L2 para cosseno via produto escalar
doc_embeddings = embed_texts(documents)
query = "Como eu testo meu código Python?"
query_vec = embed_texts([query])[0]
scores = doc_embeddings @ query_vec # similaridade de cosseno (normalizada)
ranked = sorted(zip(scores, documents), reverse=True)
for score, doc in ranked:
print(f"{score:.3f} {doc}")O que isso demonstra:
- Embedding em lote com OpenAI
text-embedding-3-small. - Normalização L2 para que o produto escalar seja igual à similaridade de cosseno.
- Classificação de documentos por relevância a uma consulta em linguagem natural.
- Correspondência semântica: "testar código Python" classifica pytest em primeiro lugar.
Mergulho Profundo
Como Funciona
- Modelo de embedding codifica texto em um vetor de dimensão fixa (por exemplo, 1536).
- Textos similares produzem vetores com alta similaridade de cosseno.
- Normalização (L2) torna o produto escalar equivalente à similaridade de cosseno.
- Índice vetorial (FAISS, pgvector) permite busca rápida de vizinhos mais próximos em escala.
- O mesmo modelo deve ser usado para indexação e consulta.
Modelos de Embedding
| Modelo | Dims | Provedor | Uso |
|---|---|---|---|
| text-embedding-3-small | 1536 | OpenAI | Propósito geral, custo-benefício |
| text-embedding-3-large | 3072 | OpenAI | Maior qualidade |
| all-MiniLM-L6-v2 | 384 | Local (sentence-transformers) | Offline, rápido |
| voyage-3 | 1024 | Voyage AI | Otimizado para recuperação |
Notas Python
# Embeddings locais com sentence-transformers
from sentence_transformers import SentenceTransformer
model = SentenceTransformer("all-MiniLM-L6-v2")
vectors = model.encode(documents, normalize_embeddings=True)Armadilhas
- Misturar modelos de embedding - modelos diferentes produzem espaços vetoriais incompatíveis. Correção: um modelo por índice; re-incorporar todos os documentos ao mudar de modelo.
- Não normalizar vetores - produto escalar sem normalização não é similaridade de cosseno. Correção: normalizar L2 antes da indexação e busca.
- Incorporar textos muito longos - modelos têm limites de tokens; documentos longos são truncados. Correção: dividir documentos em pedaços antes de incorporar.
- Comparar entre dimensões diferentes - vetores de 384 dimensões vs 1536 dimensões não podem ser comparados. Correção: modelo e dimensão consistentes.
- Ignorar custo de embedding em escala - incorporar milhões de documentos tem um custo. Correção: armazenar embeddings em cache; agrupar requisições; usar modelos menores.
- Expectativa de busca por palavra-chave - embeddings perdem correspondências exatas de palavras-chave. Correção: busca híbrida (embeddings + BM25).
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
| Embeddings de API (OpenAI) | Sem GPU, alta qualidade | Dados não podem sair da sua rede |
| sentence-transformers | Local/offline, grátis | Precisa da mais alta qualidade de recuperação |
| Busca por palavra-chave BM25 | Correspondência exata de termos | Necessita correspondência semântica/paráfrase |
| Híbrido (BM25 + denso) | RAG de produção | Protótipo simples com poucos documentos |
FAQs
O que é similaridade de cosseno?
- Mede o ângulo entre dois vetores: intervalo [-1, 1], tipicamente [0, 1] para texto.
- 1.0 = direção idêntica; 0 = ortogonal (não relacionado).
Quantas dimensões eu preciso?
- 384-1536 para a maioria das aplicações.
- Dimensões maiores capturam nuances, mas custam mais em armazenamento e computação.
- Combine com a configuração do seu banco de dados vetorial.
Devo incorporar consultas e documentos da mesma forma?
- Sim - mesmo modelo, mesmo pré-processamento.
- Alguns modelos têm prefixos diferentes para consulta vs documento (por exemplo, prefixo "query: ").
Como armazeno embeddings?
- PostgreSQL com extensão pgvector.
- Chroma, Qdrant, Pinecone para bancos de dados vetoriais dedicados.
- Veja Bancos de Dados Vetoriais.
Qual é um bom limite de similaridade?
- Depende do modelo e do domínio; tipicamente 0.7-0.85 para correspondências relevantes.
- Calibre em pares de consulta-documento rotulados.
Como reduzo as dimensões dos embeddings?
client.embeddings.create(model="text-embedding-3-small", input=texts, dimensions=512)- OpenAI suporta redução de dimensão Matryoshka.
Posso incorporar código?
- Embeddings de texto geral funcionam para busca de código.
- Modelos especializados (CodeBERT, voyage-code) podem melhorar os resultados.
Como agrupo requisições de embedding?
- OpenAI aceita até 2048 entradas por requisição.
- Agrupe para eficiência de custo em grandes corpora.
O que é busca híbrida?
- Combina scores de recuperação densos (embedding) e esparsos (BM25).
- Reciprocal Rank Fusion mescla listas classificadas.
Como os embeddings se relacionam com RAG?
- Incorpore documentos na ingestão; incorpore a consulta na recuperação.
- Os principais k pedaços similares alimentam o LLM como contexto.
- Veja Noções Básicas de RAG.
Como atualizo embeddings quando os documentos mudam?
- Re-incorpore documentos alterados e insira no índice vetorial.
- Rastreie a versão/hash do documento para evitar vetores desatualizados.
Embeddings são determinísticos?
- O mesmo modelo e entrada produzem o mesmo vetor (pequena variação de ponto flutuante).
- Armazene embeddings em cache por hash de conteúdo para idempotência.
Relacionados
- Noções Básicas de RAG - pipeline de recuperação
- Bancos de Dados Vetoriais - armazenamento e busca
- Chunking & Ingestão - divisão de documentos
- SDKs da OpenAI e Outros - API de embedding
- Recuperação & Re-ranking - busca híbrida
Versões da Stack: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.