<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  <channel>
    <title><![CDATA[Sachin Frayne - Elasticsearch Labs]]></title>
    <description><![CDATA[Articles and tutorials from the Search team at Elastic]]></description>
    <copyright><![CDATA[© 2026. Elasticsearch B.V. All Rights Reserved]]></copyright>
    <image>
      <title><![CDATA[Sachin Frayne - Elasticsearch Labs]]></title>
      <url>https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt1121c0bf0e8a6e65/6a88da6340a1841030ef456f/search-labs-thumbnail.png</url>
      <link>https://www.elastic.co/pt/search-labs/author/sachin-frayne</link>
    </image>
    <link>https://www.elastic.co/pt/search-labs/author/sachin-frayne</link>
    <atom:link href="https://www.elastic.co/pt/search-labs/rss/author/sachin-frayne.xml" rel="self" type="application/rss+xml"/>
    <language><![CDATA[pt]]></language>
    <lastBuildDate>Tue, 15 Sep 2026 03:13:35 GMT</lastBuildDate>
  <item>
    <title><![CDATA[A busca vetorial do Elasticsearch é até 8 vezes mais rápida que a do OpenSearch]]></title>
    <description><![CDATA[Explorando os benchmarks de busca vetorial filtrada do OpenSearch x Elasticsearch e por que o desempenho de busca vetorial é fundamental para sistemas de engenharia de contexto.]]></description>
    <content:encoded><![CDATA[<h2>Por que a velocidade de pesquisa é importante para agentes de IA e engenharia de contexto</h2><p>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.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt9daec868eed84658/6a170bef6234e0c322db1a19/d5a52a07773f0942c2baa732dacfe782aac0f415-1600x683.png" alt="OpenSearch x Elasticsearch: taxa de transferência para benchmark de busca vetorial filtrada" /><p>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.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt718c72fb858e4c98/6a170bf00e2e496e7241a132/54ac476ff20a3cf93484298c9ae47612c12fc110-800x417.png" alt="A engenharia de contexto transforma um grande pool de contexto em uma janela de contexto limitada de LLM." /><h2>Por que o desempenho da busca vetorial é crítico?</h2><p></p><p>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.”</p><p>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.</p><p><strong>Passo 1: Interprete a intenção e traduza para restrições.</strong></p><p>O agente transforma a solicitação em filtros estruturados e uma consulta semântica, como:</p><ul><li><p>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</p></li><li><p>Consulta vetorial: “Mochila de bordo resistente à água para notebook de 15 polegadas”</p></li></ul><p><strong>Passo 2: Recuperar candidatos e, em seguida, refinar.</strong></p><p>Frequentemente, repete a recuperação com variações para evitar perder boas correspondências:</p><ul><li><p>"Mochila de viagem com compartimento para laptop"</p></li><li><p>"Mochila urbana resistente à água 15 polegadas"</p></li><li><p>"Mochila leve para cabine"</p></li></ul><p>Cada consulta usa os mesmos filtros de elegibilidade, porque recuperar itens irrelevantes ou indisponíveis é contexto desperdiçado.</p><p><strong>Passo 3: Expanda para confirmar detalhes e reduzir riscos.</strong></p><p>O agente então recupera novamente para verificar os atributos-chave que afetam a resposta final:</p><ul><li><p>Texto sobre materiais e resistência à água</p></li><li><p>Dimensões e ajuste do compartimento para laptop</p></li><li><p>Política de devolução ou restrições de garantia</p></li><li><p>Opções alternativas se o estoque estiver baixo</p></li></ul><p>Isso é engenharia de contexto multietapas: recuperar, raciocinar, recuperar, montar.</p><h2>Por que latência e recall importam para a engenharia de contexto</h2><p>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.</p><p>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.</p><h2>Benchmark</h2><h3>Resultados</h3><p>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.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/bltb562b30a600cc8e1/6a170bf2cf4f253582b2d1b2/c50d1df00968cac18149a2799e6242fbe49b66a0-1600x990.png" alt=" Gráfico 2: Recall x latência média (reclassificação 1)." /><h4>Alguns insights importantes</h4><ul><li><p><code>s_n_r_value</code>: Abreviação de <code>size_numCandidates_rescoreOversample</code> (k e numCandidates=500 definidos como numCandidates nesses testes), por exemplo, <code>100_500_1</code> significa size=100, numCandidates=500 e k=500, rescore oversample=1</p></li><li><p>Recall: Recall@100 medido para essa configuração</p></li><li><p>Latência média (ms): latência média de ponta a ponta por consulta</p></li><li><p>Taxa de transferência: consultas por segundo</p></li><li><p>Recall (%): elevação relativa do recall do Elasticsearch x OpenSearch (Elasticsearch menos OpenSearch)/OpenSearch</p></li><li><p>Latência Xs: a latência média do OpenSearch dividida pela latência média do Elasticsearch</p></li><li><p>Throughput Xs: Throughput do Elasticsearch dividido pelo throughput do OpenSearch</p></li></ul><p>Mecanismo</p><p>`s_n_r_value`</p><p>Recall</p><p>Latência Média (ms)</p><p>Taxa de transferência</p><p>Recall %</p><p>Latência Xs</p><p>Taxa de transferência Xs</p><p>Elasticsearch</p><p>100_250_1</p><p>0,7704</p><p>25</p><p>534,75</p><p>9,70%</p><p>2,28</p><p>1,91</p><p>OpenSearch</p><p>100_250_1</p><p>0,7023</p><p>57,08</p><p>279,58</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_500_1</p><p>0,8577</p><p>25,42</p><p>524,14</p><p>7,20%</p><p>2,4</p><p>2</p><p>OpenSearch</p><p>100_500_1</p><p>0,8001</p><p>60,9</p><p>262,12</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_750_1</p><p>0,8947</p><p>29,67</p><p>528,09</p><p>5,72%</p><p>2,25</p><p>2,21</p><p>OpenSearch</p><p>100_750_1</p><p>0,8463</p><p>66,76</p><p>239,11</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_1000_1</p><p>0,9156</p><p>29,65</p><p>534,5</p><p>4,66%</p><p>2,46</p><p>2,44</p><p>OpenSearch</p><p>100_1000_1</p><p>0,8748</p><p>72,88</p><p>219,01</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_1500_1</p><p>0,9386</p><p>31,84</p><p>497,3</p><p>3,38%</p><p>2,71</p><p>2,68</p><p>OpenSearch</p><p>100_1500_1</p><p>0,9079</p><p>86,16</p><p>185,4</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_2000_1</p><p>0,9507</p><p>34,69</p><p>457,2</p><p>2,57%</p><p>2,98</p><p>2,96</p><p>OpenSearch</p><p>100_2000_1</p><p>0,9269</p><p>103,36</p><p>154,55</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_2500_1</p><p>0,9582</p><p>37,9</p><p>418,43</p><p>1,99%</p><p>3,28</p><p>3,26</p><p>OpenSearch</p><p>100_2500_1</p><p>0,9395</p><p>124,29</p><p>128,53</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_3000_1</p><p>0,9636</p><p>41,86</p><p>379,4</p><p>1,62%</p><p>3,46</p><p>3,44</p><p>OpenSearch</p><p>100_3000_1</p><p>0,9482</p><p>144,67</p><p>110,34</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_4000_1</p><p>0,9705</p><p>50,28</p><p>316,21</p><p>1,06%</p><p>3,87</p><p>3,85</p><p>OpenSearch</p><p>100_4000_1</p><p>0,9603</p><p>194,36</p><p>82,22</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_5000_1</p><p>0,9749</p><p>58,77</p><p>270,91</p><p>0,73%</p><p>4,43</p><p>4,41</p><p>OpenSearch</p><p>100_5000_1</p><p>0,9678</p><p>260,33</p><p>61,38</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_6000_1</p><p>0,9781</p><p>66,75</p><p>238,59</p><p>0,52%</p><p>4,91</p><p>4,89</p><p>OpenSearch</p><p>100_6000_1</p><p>0,973</p><p>327,44</p><p>48,81</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_7000_1</p><p>0,9804</p><p>74,64</p><p>213,49</p><p>0,38%</p><p>5,28</p><p>5,27</p><p>OpenSearch</p><p>100_7000_1</p><p>0,9767</p><p>394,24</p><p>40,53</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_8000_1</p><p>0,9823</p><p>82,28</p><p>193,59</p><p>0,27%</p><p>6,86</p><p>6,83</p><p>OpenSearch</p><p>100_8000_1</p><p>0,9797</p><p>564,14</p><p>28,33</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_9000_1</p><p>0,9837</p><p>90,08</p><p>176,96</p><p>0,16%</p><p>7,63</p><p>7,61</p><p>OpenSearch</p><p>100_9000_1</p><p>0,9821</p><p>687,25</p><p>23,25</p><p></p><p></p><p></p><p>Elasticsearch</p><p>100_10000_1</p><p>0,9848</p><p>97,64</p><p>163,31</p><p>0,08%</p><p>8,38</p><p>8,36</p><p>OpenSearch</p><p>100_10000_1</p><p>0,984</p><p>818,64</p><p>19,53</p><p></p><p></p><p></p><p>Por exemplo, em <code>100_9000_1</code>, 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. </p><p>Veja os <a href="https://github.com/elastic/competitive-benchmarking-studies/tree/main/es-9.3-vs-os-3.5-vector-search/jingra/results/20260220">resultados completos</a>.</p><h3>Metodologia</h3><p>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).</p><p>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.</p><p>OpenSearch</p>GET &lt;INDEX_NAME&gt;/_search
{
  "query": {
    "knn": {
      "&lt;DENSE_VECTOR_FIELD_NAME&gt;": {
        "vector": [...],
        "k": &lt;NUMBER_OF_CANDIDATES&gt;,
        "method_parameters": {
          "ef_search": &lt;NUMBER_OF_CANDIDATES&gt;
        },
        "rescore": {
          "oversample_factor": &lt;OVERSAMPLE&gt;
        },
        "filter": {
          &lt;SOME_FILTER&gt;
        }
      }
    }
  },
  "size": &lt;RESULT_SIZE&gt;,
  "_source": {
    "excludes": [
      "&lt;DENSE_VECTOR_FIELD_NAME&gt;"
    ]
  }
}<ul><li><p><code>"size": &lt;RESULT_SIZE&gt;</code>: Número de resultados retornados ao cliente. Neste benchmark, o tamanho do resultado é 100 para calcular o Recall@100.</p></li><li><p><code>"k": &lt;NUMBER_OF_CANDIDATES&gt;</code>: O número de candidatos a vizinhos mais próximos.</p></li><li><p><code>"ef_search": &lt;NUMBER_OF_CANDIDATES&gt;</code>: O número de vetores a examinar.</p></li><li><p><code>"oversample_factor": &lt;OVERSAMPLE&gt;</code>: Quantos vetores candidatos são recuperados antes da reclassificação.</p></li></ul><p>Elasticsearch</p>GET &lt;INDEX_NAME&gt;/_search
{
  "query": {
    "knn": {
      "field": "&lt;DENSE_VECTOR_FIELD_NAME&gt;",
      "query_vector": [...],
      "k": &lt;NUMBER_OF_CANDIDATES&gt;,
      "num_candidates": &lt;NUMBER_OF_CANDIDATES&gt;,
      "rescore_vector": {
        "oversample": &lt;OVERSAMPLE&gt;
      },
      "filter": {
        &lt;SOME_FILTER&gt;
      }
    }
  },
  "size": &lt;RESULT_SIZE&gt;,
  "_source": {
    "excludes": [
      "&lt;DENSE_VECTOR_FIELD_NAME&gt;"
    ]
  }
}<ul><li><p><code>"size": &lt;RESULT_SIZE&gt;</code>: Número de resultados retornados ao cliente. Neste benchmark, o tamanho do resultado é 100 para calcular o Recall@100.</p></li><li><p><code>"k": &lt;NUMBER_OF_CANDIDATES&gt;</code>: Número de vizinhos mais próximos a retornar de cada shard.</p></li><li><p><code>"num_candidates": &lt;NUMBER_OF_CANDIDATES&gt;</code>: Número de candidatos a vizinhos mais próximos a serem considerados por shard durante a busca <code>knn</code>.</p></li><li><p><code>"oversample": &lt;OVERSAMPLE&gt;</code>: Quantos vetores candidatos são recuperados antes da reclassificação.</p></li></ul><p>Exemplo</p><p><code>Knn</code> consulta, (<code>100_500_1</code>), seria a seguinte:</p><p>OpenSearch</p>GET search_catalog_128/_search
{
  "query": {
    "knn": {
      "search_catalog_embedding": {
        "vector": [...],
        "k": 500,
        "method_parameters": {
          "ef_search": 500
        },
        "rescore": {
          "oversample_factor": 1
        },
        "filter": {
          "term": {
            "valid": true
          }
        }
      }
    }
  },
  "size": 100,
  "_source": {
    "excludes": [
      "search_catalog_embedding"
    ]
  }
}<p>Elasticsearch</p>GET search_catalog_128/_search
{
  "query": {
    "knn": {
      "field": "search_catalog_embedding",
      "query_vector": [...],
      "k": 500,
      "num_candidates": 500,
      "rescore_vector": {
        "oversample": 1
      },
      "filter": {
        "term": {
          "valid": true
        }
      }
    }
  },
  "size": 100,
  "_source": {
    "excludes": [
      "search_catalog_embedding"
    ]
  }
}<p>A configuração completa, juntamente com os scripts do Terraform, os manifestos do Kubernetes e o código de benchmark, está disponível neste <a href="https://github.com/elastic/competitive-benchmarking-studies">repositório</a> na pasta <a href="https://github.com/elastic/competitive-benchmarking-studies/tree/main/es-9.3-vs-os-3.5-vector-search">es-9.3-vs-os-3.5-vector-search</a>.</p><h3>Configuração do Cluster</h3><p>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.</p><p>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ó).</p><p>Também usamos um servidor separado na mesma região para executar o cliente de benchmark e coletar estatísticas de tempo.</p><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt7c7bdd567395d5b7/6a170bf3c1e8a56ee2f882f6/f81002c9186e4c2d3e92f49d72418fee9860fc5e-761x401.png" alt="Configuração de cluster para Elasticsearch e benchmarks do OpenSearch" /><h3>O conjunto de dados</h3><p></p><p>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.</p><p></p><p>Cada documento representa um item do catálogo e inclui:</p><p></p><ul><li><p>Um embedding vetorial denso de 128 dimensões utilizado para recuperação aproximada de kNN.</p></li><li><p>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.</p></li></ul><p></p><p>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.</p><h2>Conclusão</h2><p>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.</p><p>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.</p><h3>Para ler mais</h3><ol><li><p><a href="https://www.elastic.co/search-labs/blog/context-engineering-overview">O que é engenharia de contexto?</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/series/context-engineering-hybrid-search-evolution">A evolução da busca híbrida e da engenharia de contexto</a></p></li><li><p><a href="https://www.elastic.co/search-labs/blog/context-engineering-relevance-ai-agents-elasticsearch">O impacto da relevância na engenharia de contexto para agentes de IA</a></p></li></ol>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/opensearch-vs-elasticsearch-filtered-vector-search</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/opensearch-vs-elasticsearch-filtered-vector-search</guid>
    <category><![CDATA[Banco de dados vetorial]]></category>
    <dc:creator><![CDATA[Sachin Frayne]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt4b38e5114bbf098c/6a170bf560084b3a6c3c459d/fb7ee623925ca6696d643e437ce8efe5fe749079-1280x720.png" length="0" type="image/png"/>
    <pubDate>Wed, 25 Feb 2026 00:00:00 GMT</pubDate>
  </item>
  <item>
    <title><![CDATA[Como implementar a Quantização Binária Aprimorada (BBQ) em seu caso de uso.]]></title>
    <description><![CDATA[Descubra por que você implementaria a Quantização Binária Aprimorada (BBQ) em seu caso de uso e como fazê-lo.]]></description>
    <content:encoded><![CDATA[<p>A pesquisa vetorial fornece a base para implementar a pesquisa semântica para texto ou a pesquisa por similaridade para imagens, vídeos ou áudio. Com a pesquisa vetorial, os vetores são representações matemáticas de dados que podem ser enormes e, às vezes, lentas. A Quantização Binária Melhorada (doravante denominada BBQ) funciona como um método de compressão para vetores. Ele permite que você encontre as correspondências certas enquanto reduz os vetores para torná-los mais rápidos de pesquisar e processar. Este artigo abordará BBQ e rescore_vector, um campo disponível apenas para índices quantizados que repontuam vetores automaticamente.</p><p>Todas as consultas e saídas completas mencionadas neste artigo podem ser encontradas em nosso <a href="https://github.com/elastic/elasticsearch-labs/tree/main/supporting-blog-content/how-and-why-bbq">repositório de código do Elasticsearch Labs</a>.</p><h2>Por que implementar a Quantização Binária Aprimorada (BBQ) no seu caso de uso?</h2>Observação: para uma compreensão mais aprofundada de como funciona a matemática por trás do churrasco, confira a <a href="https://www.elastic.co/pt/search-labs/blog/bbq-implementation-into-use-case#further-learning">seção “Aprendizado adicional”</a> abaixo. Para os propósitos deste blog, o foco está na implementação.<p>Embora a matemática seja fascinante, é crucial entender completamente por que suas buscas vetoriais permanecem precisas. Em última análise, tudo se resume à compressão, já que, com os algoritmos de busca vetorial atuais, o limite é a velocidade de leitura dos dados. Portanto, se você conseguir armazenar todos esses dados na memória, obterá um aumento significativo de velocidade em comparação com a leitura do armazenamento (<a href="https://sre.google/static/pdf/rule-of-thumb-latency-numbers-letter.pdf">a memória é aproximadamente 200 vezes mais rápida que os SSDs</a>).</p><p>Há algumas coisas que você precisa ter em mente:</p><ul><li><p>Índices baseados em gráficos como <a href="https://arxiv.org/pdf/1603.09320">HNSW</a> (Hierarchical Navigable Small World) são os mais rápidos para recuperação de vetores.</p><ul><li><p>HNSW: Um algoritmo de busca aproximado do vizinho mais próximo que constrói uma estrutura de gráfico multicamadas para permitir buscas eficientes de similaridade de alta dimensão.</p></li></ul></li></ul><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt760bd95c206bfa8f/6a17e2ad505ac393f7ad8a95/590f3b3c72a76023a38a0436cd9ff90a9f80e936-1964x1262.png" alt="HNSW: Um algoritmo de busca aproximado do vizinho mais próximo que constrói uma estrutura de gráfico multicamadas para permitir buscas eficientes de similaridade de alta dimensão." /><ul><li><p>O HNSW é fundamentalmente limitado em velocidade pela velocidade de leitura de dados da memória ou, no pior caso, do armazenamento.</p><ul><li><p>O ideal é que você consiga carregar todos os seus vetores armazenados na memória.</p></li></ul></li><li><p>Os modelos de incorporação geralmente produzem vetores com precisão float32, 4 bytes por número de ponto flutuante.</p></li><li><p>E, finalmente, dependendo de quantos vetores e/ou dimensões você tem, você pode rapidamente ficar sem memória para manter todos os seus vetores.</p></li></ul><p>Considerando isso como certo, você verá que um problema surge rapidamente quando você começa a ingerir milhões ou até bilhões de vetores, cada um com potencialmente centenas ou até milhares de dimensões. A seção intitulada “<a href="https://www.elastic.co/pt/search-labs/blog/bbq-implementation-into-use-case#approximate-numbers-on-the-compression-ratios">Números aproximados sobre as taxas de compressão</a>” fornece alguns números aproximados.</p><h2>O que você precisa para começar?</h2><p>Para começar, você precisará do seguinte:</p><ul><li><p>Se estiver usando o Elastic Cloud ou no local, você precisará de uma versão do Elasticsearch superior a 8.18. Embora o BBQ tenha sido introduzido na versão 8.16, neste artigo, você usará <code>vector_rescore</code>, que foi introduzido na versão 8.18.</p></li><li><p>Além disso, você também precisará garantir que haja um <a href="https://www.elastic.co/pt/guide/en/elasticsearch/reference/8.18/ml-settings.html">nó de aprendizado de máquina (ML)</a> no seu cluster. (Observação: um nó de ML com no mínimo 4 GB é necessário para carregar o modelo, mas você provavelmente precisará de nós muito maiores para cargas de trabalho de produção completas.)</p></li><li><p>Se estiver usando o Serverless, você precisará selecionar uma instância otimizada para vetores.</p></li><li><p>Você também precisará de um nível básico de conhecimento sobre bancos de dados vetoriais. Se você ainda não estiver familiarizado com os conceitos de pesquisa vetorial no Elastic, talvez seja interessante primeiro conferir os seguintes recursos:</p><ul><li><p><a href="https://www.elastic.co/pt/search-labs/blog/elastic-vector-database-practical-example">Navegando em um banco de dados de vetores elásticos</a></p></li><li><p><a href="https://www.elastic.co/pt/blog/retrieval-augmented-generation-explained">As grandes ideias por trás da geração aumentada de recuperação</a></p></li></ul></li></ul><h2>Implementação de Quantização Binária Aprimorada (BBQ)</h2><img src="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt18df00df95ff2ca7/6a17e2af414c6411989450df/4d388078495566f0527e931e0c2e38facdce83c6-1503x748.png" alt="Implementação do Elasticsearch BBQ." /><p>Para manter este blog simples, você usará funções integradas quando elas estiverem disponíveis. Neste caso, você tem o modelo de incorporação vetorial <a href="https://www.elastic.co/pt/guide/en/machine-learning/8.17/ml-nlp-e5.html"><code>.multilingual-e5-small</code></a> que será executado diretamente dentro do Elasticsearch em um nó de aprendizado de máquina. Observe que você pode substituir o modelo <code>text_embedding</code> pelo incorporador de sua escolha (<a href="https://www.elastic.co/pt/guide/en/elasticsearch/reference/8.18/infer-service-openai.html">OpenAI</a>, <a href="https://www.elastic.co/pt/guide/en/elasticsearch/reference/8.18/infer-service-google-ai-studio.html">Google AI Studio</a>, <a href="https://www.elastic.co/pt/guide/en/elasticsearch/reference/8.18/infer-service-cohere.html">Cohere</a> e muitos outros). Se o seu modelo preferido ainda não estiver integrado, você também pode <a href="https://www.elastic.co/pt/guide/en/elasticsearch/reference/8.18/bring-your-own-vectors.html">trazer seus próprios embeddings de vetores densos</a>.)</p><p>Primeiro, você precisará criar um ponto final de inferência para gerar vetores para um determinado trecho de texto. Você executará todos esses comandos no Kibana <a href="https://www.elastic.co/pt/guide/en/kibana/8.18/console-kibana.html">Dev Tools Console</a>. Este comando fará o download do <code>.multilingual-e5-small</code>. Se ainda não existir, ele configurará seu endpoint; isso pode levar um minuto para ser executado. Você pode ver a saída esperada no arquivo <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/01-create-an-inference-endpoint-output.json">01-create-an-inference-endpoint-output.json</a> na pasta Saídas. </p>PUT _inference/text_embedding/my_e5_model
{
  "service": "elasticsearch",
  "service_settings": {
    "num_threads": 1,
    "model_id": ".multilingual-e5-small",
    "adaptive_allocations": {
      "enabled": true,
      "min_number_of_allocations": 1
    }
  }
}<p>Quando isso retornar, seu modelo será configurado e você poderá testar se ele funciona conforme o esperado com o seguinte comando. Você pode ver a saída esperada no arquivo <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/02-embed-text-output.json">02-embed-text-output.json</a> na pasta Saídas.</p>POST _inference/text_embedding/my_e5_model
{
  "input": "my awesome piece of text"
}<p>Se você tiver problemas com seu modelo treinado não sendo alocado a nenhum nó, talvez seja necessário iniciar seu modelo manualmente.</p>POST _ml/trained_models/.multilingual-e5-small/deployment/_start<p>Agora vamos criar um novo mapeamento com 2 propriedades, um campo de texto padrão (<code>my_field</code>) e um campo vetorial denso (<code>my_vector</code>) com 384 dimensões para corresponder à saída do modelo de incorporação. Você também substituirá o <code>index_options.type to bbq_hnsw</code>. Você pode ver a saída esperada no arquivo <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/03-create-byte-qauntized-index-output.json">03-create-byte-qauntized-index-output.json</a> na pasta Saídas.</p>PUT bbq-my-byte-quantized-index
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "text"
      },
      "my_vector": {
        "type": "dense_vector",
        "dims": 384,
        "index_options": {
          "type": "bbq_hnsw"
        }
      }
    }
  }
}<p>Para garantir que o Elasticsearch gere seus vetores, você pode usar um <a href="https://www.elastic.co/pt/guide/en/elasticsearch/reference/8.18/ingest.html">Ingest Pipeline</a>. Este pipeline exigirá 3 coisas: o ponto final, (<code>model_id</code>), o <code>input_field</code> para o qual você deseja criar vetores e o <code>output_field</code> para armazenar esses vetores. O primeiro comando abaixo criará um pipeline de ingestão de inferência, que usa o <a href="https://www.elastic.co/pt/guide/en/elasticsearch/reference/current/inference-apis.html">serviço de inferência </a>nos bastidores, e o segundo testará se o pipeline está funcionando corretamente. Você pode ver a saída esperada no arquivo <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/04-create-and-simulate-ingest-pipeline-output.json">04-create-and-simulate-ingest-pipeline-output.json</a> na pasta Outputs. </p>PUT _ingest/pipeline/my_inference_pipeline
{
  "processors": [
    {
      "inference": {
        "model_id": "my_e5_model",
        "input_output": [
          {
            "input_field": "my_field",
            "output_field": "my_vector"
          }
        ]
      }
    }
  ]
}

POST _ingest/pipeline/my_inference_pipeline/_simulate
{
  "docs": [
    {
      "_source": {
        "my_field": "my awesome text field"
      }
    }
  ]
}<p>Agora você está pronto para adicionar alguns documentos com os dois primeiros comandos abaixo e testar se suas pesquisas funcionam com o terceiro comando. Você pode verificar a saída esperada no arquivo <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/05-bbq-index-output.json">05-bbq-index-output.json</a> na pasta Outputs. </p>PUT bbq-my-byte-quantized-index/_doc/1?pipeline=my_inference_pipeline
{
    "my_field": "my awesome text field"
}

PUT bbq-my-byte-quantized-index/_doc/2?pipeline=my_inference_pipeline
{
    "my_field": "some other sentence"
}

GET bbq-my-byte-quantized-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<p>Conforme recomendado <a href="https://www.elastic.co/pt/search-labs/blog/better-binary-quantization-lucene-elasticsearch#lucene-benchmarking">nesta publicação</a>, a repontuação e a sobreamostragem são recomendadas quando você dimensiona para quantidades não triviais de dados porque elas ajudam a manter alta precisão de recall enquanto se beneficiam das vantagens da compressão. A partir da versão 8.18 do Elasticsearch, você pode fazer isso dessa maneira usando <a href="https://www.elastic.co/pt/guide/en/elasticsearch/reference/8.18/knn-search.html#dense-vector-knn-search-rescoring">rescore_vector</a>. A saída esperada está no arquivo <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/06-bbq-search-8-18-output.json">06-bbq-search-8-18-output.json</a> na pasta Outputs.</p>GET bbq-my-byte-quantized-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "rescore_vector": {
              "oversample": 3
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<p>Como essas pontuações se comparam àquelas que você obteria com dados brutos? Se você fizer tudo acima novamente, mas com <code>index_options.type: hnsw</code>, verá que as pontuações são muito comparáveis. Você pode ver a saída esperada no arquivo <a href="https://github.com/elastic/elasticsearch-labs/blob/main/supporting-blog-content/how-and-why-bbq/Outputs/07-raw-vector-output.json">07-raw-vector-output.json</a> na pasta Outputs.</p>PUT my-raw-vector-index
{
  "mappings": {
    "properties": {
      "my_field": {
        "type": "text"
      },
      "my_vector": {
        "type": "dense_vector",
        "dims": 384,
        "index_options": {
          "type": "hnsw"
        }
      }
    }
  }
}

PUT my-raw-vector-index/_doc/1?pipeline=my_inference_pipeline
{
    "my_field": "my awesome text field"
}

PUT my-raw-vector-index/_doc/2?pipeline=my_inference_pipeline
{
    "my_field": "some other sentence"
}

GET my-raw-vector-index/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "knn": {
            "field": "my_vector",
            "query_vector_builder": {
              "text_embedding": {
                "model_id": "my_e5_model",
                "model_text": "my awesome search field"
              }
            },
            "k": 10,
            "num_candidates": 100
          }
        }
      ]
    }
  },
  "_source": [
    "my_field"
  ]
}<h2>Números aproximados sobre as taxas de compressão</h2><p>Os requisitos de armazenamento e memória podem rapidamente se tornar um desafio significativo ao trabalhar com pesquisa vetorial. A análise a seguir ilustra como diferentes técnicas de quantização reduzem drasticamente o consumo de memória de dados vetoriais.</p><p>Vetores (V)</p><p>Dimensões (D)</p><p>cru (V x D x 4)</p><p>int8 (V x (D x 1 + 4))</p><p>int4 (V x (D x 0,5 + 4))</p><p>churrasco (V x (D x 0,125 + 4))</p><p>10.000.000</p><p>384</p><p>14,31 GB</p><p>3,61 GB</p><p>1,83 GB</p><p>0,58 GB</p><p>50.000.000</p><p>384</p><p>71,53 GB</p><p>18,07 GB</p><p>9,13 GB</p><p>2,89 GB</p><p>100.000.000</p><p>384</p><p>143,05 GB</p><p>36,14 GB</p><p>18,25 GB</p><p>5,77 GB</p><h2>Conclusão</h2><p>BBQ é uma otimização que você pode aplicar aos seus dados vetoriais para compressão sem sacrificar a precisão. Ele funciona convertendo vetores em bits, permitindo que você pesquise os dados de forma eficaz e capacitando você a dimensionar seus fluxos de trabalho de IA para acelerar pesquisas e otimizar o armazenamento de dados.</p><h2>Aprendizagem adicional</h2><p>Se você estiver interessado em aprender mais sobre churrasco, não deixe de conferir os seguintes recursos:</p><ul><li><p><a href="https://www.elastic.co/pt/search-labs/blog/better-binary-quantization-lucene-elasticsearch">Quantização Binária (BBQ) em Lucene e Elasticsearch</a></p></li><li><p><a href="https://www.elastic.co/pt/search-labs/blog/bit-vectors-elasticsearch-bbq-vs-pq">Melhor Quantização Binária (BBQ) vs. Quantização de Produto</a></p></li><li><p><a href="https://www.elastic.co/pt/search-labs/blog/optimized-scalar-quantization-elasticsearch">Quantização Escalar Otimizada: Quantização Binária Ainda Melhor</a></p></li><li><p><a href="https://www.youtube.com/watch?v=04NzMt2Nigc">Melhor Quantização Binária (BBQ): De Bytes a BBQ, O Segredo para uma Melhor Busca Vetorial por Ben Trent</a></p></li></ul>]]></content:encoded>
    <link>https://www.elastic.co/search-labs/blog/bbq-implementation-into-use-case</link>
    <guid isPermaLink="true">https://www.elastic.co/search-labs/blog/bbq-implementation-into-use-case</guid>
    <category><![CDATA[Banco de dados vetorial]]></category>
    <category><![CDATA[Noções básicas]]></category>
    <dc:creator><![CDATA[Sachin Frayne,Jessica Garson]]></dc:creator>
    <enclosure url="https://static-www.elastic.co/v3/assets/bltefdd0b53724fa2ce/blt3dd0495b536b2615/6a17e2b0414c6488459450e3/66842055367cdd795532b01c167f2a4b03dc65e3-1200x628.png" length="0" type="image/png"/>
    <pubDate>Wed, 23 Apr 2025 00:00:00 GMT</pubDate>
  </item>
  </channel>
</rss>