Toda busca semântica começa com uma escolha que parece técnica e é, na verdade, empírica: qual modelo transforma o seu texto em vetor. A escolha errada custa qualidade em todas as consultas, para sempre — e é a mais fácil de testar direito.
A resposta curta, para quem quer só o caminho seguro: use um modelo multilíngue forte, de dimensão média, e teste dois candidatos no seu próprio acervo antes de indexar tudo. A resposta longa explica por que os rankings públicos enganam.
Por que o ranking não decide
Os rankings de embedding medem desempenho médio em dezenas de conjuntos públicos — artigos científicos, perguntas de fórum, avaliações de produto, quase tudo em inglês. O seu acervo é de contratos jurídicos, ou de laudos técnicos, ou de conversas de atendimento em português com gíria e erro de digitação.
A correlação entre "primeiro do ranking" e "melhor no seu caso" existe, mas é fraca o bastante para que o segundo, o quinto e o décimo mudem de posição quando testados no seu dado. Já vimos modelo bem colocado perder por 9 pontos de recall para um mais modesto num acervo de português técnico.
Recall@k: entre os k trechos que a busca devolveu, o trecho que responde a pergunta estava lá?
Se a resposta certa não foi recuperada, nenhum modelo de linguagem no mundo vai produzir a resposta certa. Todo o resto do sistema depende desse número.
O teste caseiro de uma hora
É simples, é chato e é o que separa decisão de palpite.
1. Monte 50 perguntas com resposta conhecida
Pegue 50 perguntas que as pessoas realmente fazem — do canal de suporte, do histórico de busca, da cabeça de quem atende. Para cada uma, anote qual trecho do seu acervo responde. Meia hora de trabalho.
Duas regras: use as perguntas como foram escritas, com erro de digitação e tudo; e inclua as difíceis, aquelas em que a pergunta usa palavras diferentes das do documento. É exatamente nelas que os modelos se separam.
2. Indexe o mesmo acervo com cada candidato
pip install sentence-transformers
from sentence_transformers import SentenceTransformer
import numpy as np, json
trechos = json.loads(open("trechos.json", encoding="utf-8").read())
textos = [t["texto"] for t in trechos]
for nome in ["Org/modelo-a", "Org/modelo-b"]:
m = SentenceTransformer(nome, device="cuda")
vetores = m.encode(textos, batch_size=64, normalize_embeddings=True,
show_progress_bar=True)
np.save(f"vetores_{nome.split('/')[-1]}.npy", vetores)
3. Meça
def recall_em_k(modelo_nome, perguntas, k=5):
m = SentenceTransformer(modelo_nome, device="cuda")
V = np.load(f"vetores_{modelo_nome.split('/')[-1]}.npy")
acertos = 0
for p in perguntas:
q = m.encode([p["pergunta"]], normalize_embeddings=True)[0]
top = np.argsort(-(V @ q))[:k]
if p["id_trecho_certo"] in [trechos[i]["id"] for i in top]:
acertos += 1
return acertos / len(perguntas)
Rode com k = 1, 3, 5 e 10. O que você quer ver é recall@5 acima de 90%. Abaixo de 80%, não adianta seguir para a geração de resposta: o problema está na recuperação e nenhum ajuste de prompt vai consertar.
Recall baixo com candidatos decentes quase sempre indica fatiamento errado: trechos grandes demais (a resposta se dilui), pequenos demais (perde contexto) ou cortados no meio de uma frase.
Antes de trocar de modelo pela terceira vez, tente trechos de 300 a 600 palavras com sobreposição de 15% e o título da seção repetido no começo de cada um. Esse ajuste costuma valer mais que qualquer troca de modelo.
As três decisões que vêm depois
Dimensão do vetor
Modelos entregam vetores de 384, 768, 1024 ou mais dimensões. Mais dimensão captura mais nuance e custa mais em armazenamento e em tempo de busca.
| Dimensão | 1 milhão de trechos ocupam | Adequado para |
|---|---|---|
| 384 | ~1,5 GB | Acervos grandes, busca muito rápida, conteúdo simples |
| 768 | ~3 GB | O ponto de equilíbrio para a maioria dos casos |
| 1024 | ~4 GB | Conteúdo técnico denso, jurídico, científico |
| 4096 | ~16 GB | Raramente compensa o custo |
Vários modelos modernos permitem truncar o vetor sem reindexar: você gera em 1024 e usa os primeiros 512 se precisar economizar. Se o seu candidato tem essa propriedade, ela vale pontos na escolha.
Assimetria entre pergunta e documento
Alguns modelos esperam prefixos diferentes para a consulta e para o documento — algo como query: e passage:. Parece detalhe e não é: esquecer o prefixo derruba o recall em 10 a 20 pontos, silenciosamente. Leia o cartão do modelo antes de indexar um milhão de trechos.
Rodar onde
Indexar é uma carga em lote, curta e intensa — o caso perfeito para alugar GPU por hora. Um modelo de embedding de porte médio processa na ordem de 2 a 5 mil trechos por segundo numa placa de 24 GB.
- 100 mil trechos: cerca de 1 minuto de GPU
- 1 milhão de trechos: cerca de 10 minutos, algo em torno de R$ 0,50 na RTX 4090 a R$ 2,78 por hora
- 10 milhões: menos de duas horas, ainda abaixo de R$ 10
Ou seja: indexar é barato o suficiente para você reindexar sem medo. Essa constatação muda a postura do projeto — não trate a escolha do modelo como irreversível, trate como algo que você pode refazer numa tarde se descobrir algo melhor.
Indexe o acervo inteiro por alguns reais
Suba uma GPU por hora, gere os vetores do seu conteúdo e desligue. Sem plano mensal, cobrança em reais.
Criar conta →Reordenação: o ganho que vem depois
Depois de escolher o embedding, o maior salto de qualidade não vem de trocá-lo — vem de reordenar. A busca vetorial devolve 30 candidatos rapidamente; um modelo de reordenação lê pergunta e trecho juntos e reorganiza os 30 em ordem de relevância real.
É mais caro por item, por isso só se aplica aos 30, não ao milhão. E costuma render de 5 a 15 pontos de precisão — mais do que qualquer troca de embedding renderia. Se o seu recall@30 é alto mas as respostas ainda vêm ruins, é aqui que está o dinheiro.
Quando reindexar
- Trocou de modelo de embedding: obrigatório. Vetores de modelos diferentes não são comparáveis, e misturar os dois no mesmo índice produz resultado aleatório — sem erro nenhum aparecendo.
- Mudou o tamanho do trecho: obrigatório.
- Adicionou documentos novos: não. Só indexe os novos, com o mesmo modelo.
- Saiu um modelo novo no ranking: só se ele ganhar no seu teste de 50 perguntas. Que agora você já tem pronto.
Conclusão
Escolher embedding não é escolher o primeiro do ranking — é rodar 50 perguntas suas contra dois candidatos e olhar o recall@5. Uma hora de trabalho que evita um sistema de busca medíocre operando por dois anos.
Monte o conjunto de perguntas uma vez. Ele vai servir para escolher o embedding, para decidir o tamanho do trecho, para avaliar a reordenação e para julgar o próximo modelo que aparecer. É o ativo que fica.
Continue: RAG de produção · banco vetorial em 1 clique · medir a mudança