Por que a velocidade de pesquisa é importante para agentes de IA e engenharia de contexto
Nossos benchmarks em um corpus de 20 milhões de documentos mostram que o Elasticsearch entrega uma taxa de transferência até 8 vezes maior que o OpenSearch para busca vetorial filtrada, além de alcançar um Recall@100 superior nas configurações que testamos. A engenharia de contexto depende de mais do que apenas uma recuperação vetorial rápida. As equipes também precisam de fortes controles de relevância, como busca e filtragem híbridas, simplicidade operacional e desempenho previsível, à medida que os fluxos de trabalho evoluem. Mas como os agentes geralmente executam loops de recuperação, raciocínio e recuperação várias vezes por solicitação, a latência de recuperação se torna um multiplicador, então as melhorias aqui se traduzem diretamente em melhor capacidade de resposta de ponta a ponta e menor custo.

Gráfico 1: Taxa de transferência.
Para engenharia de contexto, recuperação não é um passo único. Agentes e aplicativos executam repetidamente loops, como recuperar → raciocinar → recuperar, para refinar consultas, verificar fatos, reunir contexto fundamentado e concluir tarefas. Esse padrão é comum em fluxos de trabalho agentivos e Retrieval-Augmented Generation iterativa (RAG). Como a recuperação pode ser invocada muitas vezes por solicitação do usuário, ela adiciona atraso à resposta e/ou aumenta os custos de infraestrutura.

Figura 1: A engenharia de contexto transforma um grande conjunto de contexto (documentos, memória, ferramentas, histórico de bate-papo) em uma janela de contexto limitada de um modelo de linguagem de grande porte (LLM) por meio de recuperação e curadoria repetidas.
A implementação ótima da engenharia de contexto é uma técnica emergente. As contagens de iterações variam muito de acordo com o fluxo de trabalho. O conceito-chave mais fundamental para esses resultados de benchmark é que a engenharia de contexto é direcional: a recuperação iterativa faz da latência um multiplicador.
Por que o desempenho da busca vetorial é crítico?
Imagine um assistente de compras respondendo à pergunta: “Preciso de uma mochila de mão por menos de R$ 300 que comporte um laptop de 15 polegadas, seja resistente à água e possa chegar até sexta-feira.”
Em produção, o assistente raramente emite uma consulta vetorial e para. Ele executa um ciclo de recuperação para criar o contexto certo, e cada etapa normalmente é limitada por filtros, como disponibilidade, região, promessa de envio, regras de marca e elegibilidade de políticas.
Passo 1: Interprete a intenção e traduza para restrições.
O agente transforma a solicitação em filtros estruturados e uma consulta semântica, como:
- Filtros: em estoque, disponível para entrega no CEP do usuário, entrega até sexta-feira, preço abaixo de R$ 300, listagem válida
- Consulta vetorial: “Mochila de bordo resistente à água para notebook de 15 polegadas”
Passo 2: Recuperar candidatos e, em seguida, refinar.
Frequentemente, repete a recuperação com variações para evitar perder boas correspondências:
- "Mochila de viagem com compartimento para laptop"
- "Mochila urbana resistente à água 15 polegadas"
- "Mochila leve para cabine"
Cada consulta usa os mesmos filtros de elegibilidade, porque recuperar itens irrelevantes ou indisponíveis é contexto desperdiçado.
Passo 3: Expanda para confirmar detalhes e reduzir riscos.
O agente então recupera novamente para verificar os atributos-chave que afetam a resposta final:
- Texto sobre materiais e resistência à água
- Dimensões e ajuste do compartimento para laptop
- Política de devolução ou restrições de garantia
- Opções alternativas se o estoque estiver baixo
Isso é engenharia de contexto multietapas: recuperar, raciocinar, recuperar, montar.
Por que latência e recall importam para a engenharia de contexto
Essas interações podem envolver dezenas de chamadas de recuperação filtradas por sessão de usuário. Isso faz com que a latência por chamada seja um multiplicador direto no tempo de resposta de ponta a ponta, e o baixo recall força tentativas extras ou faz com que o agente perca itens elegíveis, degradando a qualidade da resposta.
Conclusão: em sistemas de engenharia de contexto, os vizinhos mais próximos aproximados (ANN) filtrados não são uma pesquisa única. É uma operação repetida sob restrições, portanto, o desempenho da busca vetorial aparece imediatamente em latência, taxa de transferência e custo, mesmo quando o modelo de linguagem de grande porte (LLM) é o componente mais visível.
Benchmark
Resultados
No gráfico 2, cada ponto representa uma configuração de teste. Os melhores resultados aparecem no canto superior esquerdo, o que significa maior recall com menor latência. Os resultados do Elasticsearch estão consistentemente mais próximos do canto superior esquerdo do que os do OpenSearch, indicando melhor velocidade e precisão sob as mesmas configurações de carga de trabalho.

Gráfico 2: Recall x latência média, reclassificação 1.
Alguns insights importantes
s_n_r_value: Abreviação desize_numCandidates_rescoreOversample(k e numCandidates=500 definidos como numCandidates nesses testes), por exemplo,100_500_1significa size=100, numCandidates=500 e k=500, rescore oversample=1- Recall: Recall@100 medido para essa configuração
- Latência média (ms): latência média de ponta a ponta por consulta
- Taxa de transferência: consultas por segundo
- Recall (%): elevação relativa do recall do Elasticsearch x OpenSearch (Elasticsearch menos OpenSearch)/OpenSearch
- Latência Xs: a latência média do OpenSearch dividida pela latência média do Elasticsearch
- Throughput Xs: Throughput do Elasticsearch dividido pelo throughput do OpenSearch
| Mecanismo | `s_n_r_value` | Recall | Latência Média (ms) | Taxa de transferência | Recall % | Latência Xs | Taxa de transferência Xs |
|---|---|---|---|---|---|---|---|
| Elasticsearch | 100_250_1 | 0,7704 | 25 | 534,75 | 9,70% | 2,28 | 1,91 |
| OpenSearch | 100_250_1 | 0,7023 | 57,08 | 279,58 | |||
| Elasticsearch | 100_500_1 | 0,8577 | 25,42 | 524,14 | 7,20% | 2,4 | 2 |
| OpenSearch | 100_500_1 | 0,8001 | 60,9 | 262,12 | |||
| Elasticsearch | 100_750_1 | 0,8947 | 29,67 | 528,09 | 5,72% | 2,25 | 2,21 |
| OpenSearch | 100_750_1 | 0,8463 | 66,76 | 239,11 | |||
| Elasticsearch | 100_1000_1 | 0,9156 | 29,65 | 534,5 | 4,66% | 2,46 | 2,44 |
| OpenSearch | 100_1000_1 | 0,8748 | 72,88 | 219,01 | |||
| Elasticsearch | 100_1500_1 | 0,9386 | 31,84 | 497,3 | 3,38% | 2,71 | 2,68 |
| OpenSearch | 100_1500_1 | 0,9079 | 86,16 | 185,4 | |||
| Elasticsearch | 100_2000_1 | 0,9507 | 34,69 | 457,2 | 2,57% | 2,98 | 2,96 |
| OpenSearch | 100_2000_1 | 0,9269 | 103,36 | 154,55 | |||
| Elasticsearch | 100_2500_1 | 0,9582 | 37,9 | 418,43 | 1,99% | 3,28 | 3,26 |
| OpenSearch | 100_2500_1 | 0,9395 | 124,29 | 128,53 | |||
| Elasticsearch | 100_3000_1 | 0,9636 | 41,86 | 379,4 | 1,62% | 3,46 | 3,44 |
| OpenSearch | 100_3000_1 | 0,9482 | 144,67 | 110,34 | |||
| Elasticsearch | 100_4000_1 | 0,9705 | 50,28 | 316,21 | 1,06% | 3,87 | 3,85 |
| OpenSearch | 100_4000_1 | 0,9603 | 194,36 | 82,22 | |||
| Elasticsearch | 100_5000_1 | 0,9749 | 58,77 | 270,91 | 0,73% | 4,43 | 4,41 |
| OpenSearch | 100_5000_1 | 0,9678 | 260,33 | 61,38 | |||
| Elasticsearch | 100_6000_1 | 0,9781 | 66,75 | 238,59 | 0,52% | 4,91 | 4,89 |
| OpenSearch | 100_6000_1 | 0,973 | 327,44 | 48,81 | |||
| Elasticsearch | 100_7000_1 | 0,9804 | 74,64 | 213,49 | 0,38% | 5,28 | 5,27 |
| OpenSearch | 100_7000_1 | 0,9767 | 394,24 | 40,53 | |||
| Elasticsearch | 100_8000_1 | 0,9823 | 82,28 | 193,59 | 0,27% | 6,86 | 6,83 |
| OpenSearch | 100_8000_1 | 0,9797 | 564,14 | 28,33 | |||
| Elasticsearch | 100_9000_1 | 0,9837 | 90,08 | 176,96 | 0,16% | 7,63 | 7,61 |
| OpenSearch | 100_9000_1 | 0,9821 | 687,25 | 23,25 | |||
| Elasticsearch | 100_10000_1 | 0,9848 | 97,64 | 163,31 | 0,08% | 8,38 | 8,36 |
| OpenSearch | 100_10000_1 | 0,984 | 818,64 | 19,53 |
Por exemplo, em 100_9000_1, o OpenSearch tem uma média de 687 milissegundos por recuperação contra 90 milissegundos no Elasticsearch, e em um ciclo de recuperação de 10 etapas, isso equivale a cerca de 10 x (687 - 90) = seis segundos de tempo adicional de espera.
Veja os resultados completos.
Metodologia
Usando Python para enviar as consultas e acompanhar o tempo de resposta e outras estatísticas, enviamos as seguintes consultas para os motores. Lembre-se de que o desempenho de qualquer mecanismo de busca vetorial depende de como você ajusta seus parâmetros principais: quantos candidatos considerar, quão agressivamente reclassificar e quanto contexto devolver. Essas configurações afetam diretamente tanto o recall (a probabilidade de encontrar a resposta certa) quanto a latência (a rapidez com que você obtém resultados).
Em nossos benchmarks, usamos as mesmas configurações de candidato, reclassificação e tamanho do resultado que você normalmente ajusta em um ciclo de recuperação orientado por agente, e medimos o desempenho do Elasticsearch sob essa carga de trabalho. Depois, executamos o OpenSearch com as mesmas configurações como referência.
OpenSearch
"size": <RESULT_SIZE>: Número de resultados retornados ao cliente. Neste benchmark, o tamanho do resultado é 100 para calcular o Recall@100."k": <NUMBER_OF_CANDIDATES>: O número de candidatos a vizinhos mais próximos."ef_search": <NUMBER_OF_CANDIDATES>: O número de vetores a examinar."oversample_factor": <OVERSAMPLE>: Quantos vetores candidatos são recuperados antes da reclassificação.
Elasticsearch
"size": <RESULT_SIZE>: Número de resultados retornados ao cliente. Neste benchmark, o tamanho do resultado é 100 para calcular o Recall@100."k": <NUMBER_OF_CANDIDATES>: Número de vizinhos mais próximos a retornar de cada shard."num_candidates": <NUMBER_OF_CANDIDATES>: Número de candidatos a vizinhos mais próximos a serem considerados por shard durante a buscaknn."oversample": <OVERSAMPLE>: Quantos vetores candidatos são recuperados antes da reclassificação.
Exemplo
Knn consulta, (100_500_1), seria a seguinte:
OpenSearch
Elasticsearch
A configuração completa, juntamente com os scripts do Terraform, os manifestos do Kubernetes e o código de benchmark, está disponível neste repositório na pasta es-9.3-vs-os-3.5-vector-search.
Configuração do Cluster
Executamos nossos testes em seis servidores em nuvem e2-standard-16, cada um com 16 vCPUs e 64 GB de RAM. Em cada servidor, alocamos 15 vCPUs e 56 GB de RAM para cada pod Kubernetes executando o Node do mecanismo de busca, com 28 GB reservados para o heap da JVM.
Os clusters executavam Elasticsearch 9.3.0 e OpenSearch 3.5.0 (Lucene 10.3.2). Como ambos os sistemas usam a mesma versão do Lucene neste teste de desempenho, as diferenças de taxa de transferência e latência que observamos não podem ser atribuídas apenas ao Lucene, mas sim refletem diferenças na forma como cada mecanismo integra e executa a recuperação e reavaliação filtrada do algoritmo k-vizinhos mais próximos (kNN). Usamos um único índice com três shards principais e uma réplica (ou seja, 6 shards no total, 1 por nó).
Também usamos um servidor separado na mesma região para executar o cliente de benchmark e coletar estatísticas de tempo.

Figura 2: Diagrama da configuração dos clusters.
O conjunto de dados
Para este benchmark, usamos um catálogo em grande escala no estilo de comércio eletrônico com conjuntos de dados de 20 milhões de documentos, projetado para refletir a recuperação vetorial filtrada do mundo real em escala.
Cada documento representa um item do catálogo e inclui:
- Um embedding vetorial denso de 128 dimensões utilizado para recuperação aproximada de kNN.
- Campos de metadados estruturados usados para filtragem (por exemplo, validade e disponibilidade do item, além de outras restrições do catálogo), permitindo o padrão comum de produção de recuperar os vizinhos mais próximos, mas somente dentro de um subconjunto elegível.
Escolhemos este conjunto de dados porque ele captura o principal desafio de desempenho que observamos em sistemas agentivos e do tipo RAG em produção: a similaridade vetorial por si só não é suficiente, a recuperação é frequentemente limitada por filtros, e o sistema deve manter um alto índice de recall enquanto mantém a latência baixa sob essas restrições. Comparado a conjuntos de dados menores no estilo QA, um corpus de 20 milhões de documentos também reflete melhor a escala e a pressão dos candidatos que sistemas ANN filtrados enfrentam na prática.
Conclusão
Nas arquiteturas modernas de IA, especialmente aquelas construídas baseadas em engenharia de contexto, a velocidade da busca vetorial não é um pequeno detalhe de implementação. É um multiplicador. Quando agentes e fluxos de trabalho iteram por meio de recuperar → raciocinar → recuperar, o desempenho da recuperação molda diretamente a latência de ponta a ponta, a taxa de transferência e a qualidade do contexto inserido no modelo.
Em nossos benchmarks, o Elasticsearch consistentemente entregou um recall maior com menor latência do que o OpenSearch em cenários onde a correção depende de recuperar o documento correto, e não apenas de um vetor semelhante. Em um conjunto de dados controlado, a diferença é clara, e na produção esses ganhos se acumulam em grandes volumes de chamadas de recuperação, melhorando a capacidade de resposta, aumentando a margem de capacidade e reduzindo custos de infraestrutura.




