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.

💡 A única medida que importa

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.

⚠️ Se os dois modelos derem resultado ruim, o problema não é o modelo

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ão1 milhão de trechos ocupamAdequado para
384~1,5 GBAcervos grandes, busca muito rápida, conteúdo simples
768~3 GBO ponto de equilíbrio para a maioria dos casos
1024~4 GBConteúdo técnico denso, jurídico, científico
4096~16 GBRaramente 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.

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

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