Criar uma consulta híbrida na IA do Azure Search

A pesquisa híbrida combina texto (palavra-chave) e consultas de vetor em uma única solicitação de pesquisa. Todas as subconsultas na solicitação são executadas em paralelo. Os resultados são mesclados e reordenados por novas pontuações de busca, utilizando a Fusão de Rank Recíproco (RRF) para retornar um conjunto de resultados unificado. Em muitos casos, por testes de parâmetros de comparação, as consultas híbridas com classificação semântica retornam os resultados mais relevantes.

Neste artigo, aprenda a:

  • Configurar uma solicitação básica
  • Formular consultas híbridas com mais parâmetros e filtros
  • Melhorar a relevância usando pesos de vetor ou classificação semântica
  • Otimizar comportamentos de consulta controlando entradas de texto e vetor

Observação

A novidade em 2024-09-01-preview é a capacidade de direcionar filtros apenas para as subconsultas de vetor em uma solicitação híbrida. Isso fornece mais precisão sobre como os filtros são aplicados. Para obter mais informações, consulte filtros de direcionamento para subconsultas de vetor neste artigo.

Pré-requisitos

Escolha uma API ou ferramenta

  • O Gerenciador de Pesquisa no portal do Azure (dá suporte à sintaxe de pesquisa de API estável e de versão prévia) tem uma exibição JSON que permite colar em uma solicitação híbrida.

  • 2024-07-01 versão estável ou uma versão recente da API de visualização se você estiver usando versão prévia de recursos como maxTextRecallSize e countAndFacetMode(versão prévia).

    Para legibilidade, usamos exemplos REST para explicar como as APIs funcionam. Você pode usar um cliente REST como o Visual Studio Code com a extensão REST para criar consultas híbridas. Para obter mais informações, consulte Início Rápido: Busca em vetores usando APIs REST.

  • Pacotes estáveis ou beta mais recentes dos SDKs do Azure (consulte os logs de alterações para suporte a recursos do SDK).

Configurar uma consulta híbrida no Search Explorer

  1. No Gerenciador de pesquisa, verifique se a versão da API é 2024-07-01 ou uma versão mais recente da API de visualização.

  2. Em Exibição, selecione exibição JSON para que você possa colar em uma consulta vetor.

  3. Substitua o modelo de consulta padrão por uma consulta híbrida, como o exemplo "Executar uma consulta híbrida" começando na linha 539 no início rápido do vetor. Para fins de brevidade, o vetor está truncado neste artigo.

    Uma consulta híbrida tem uma consulta de texto especificada em search, e uma consulta de vetor especificada em vectorQueries.vector.

    A consulta de texto e a consulta de vetor podem ser equivalentes ou divergentes, mas é comum que elas compartilhem a mesma intenção.

    {
        "count": true,
        "search": "historic hotel walk to restaurants and shopping",
        "select": "HotelId, HotelName, Category, Tags, Description",
        "top": 7,
        "vectorQueries": [
            {
                "vector": [0.01944167, 0.0040178085, -0.007816401 ... <remaining values omitted> ], 
                "k": 7,
                "fields": "DescriptionVector",
                "kind": "vector",
                "exhaustive": true
            }
        ]
    }
    
  4. Selecione Pesquisar.

Dica

Os resultados da pesquisa são mais fáceis de ler se você ocultar os vetores. Em Opções de Consulta, ative Ocultar valores de vetor nos resultados da pesquisa.

Solicitação de consulta híbrida (API REST)

Uma consulta híbrida combina pesquisa de texto e pesquisa de vetor, em que o parâmetro search usa uma cadeia de caracteres de consulta e vectorQueries.vector usa a consulta de vetor. O mecanismo de pesquisa executa consultas de texto completo e de vetor em paralelo. A união de todas as correspondências é avaliada para relevância usando a Fusão de Classificação Recíproca (RRF) e um único conjunto de resultados é retornado na resposta.

Os resultados são retornados em texto sem formatação, incluindo os vetores nos campos marcados como retrievable. Como os vetores numéricos não são úteis nos resultados da pesquisa, escolha outros campos no índice como um proxy para a correspondência de vetor. Por exemplo, se um índice tiver campos "descriptionVector" e "descriptionText", a consulta poderá corresponder em "descriptionVector", mas o resultado da pesquisa poderá mostrar "descriptionText". Use o parâmetro select para especificar apenas campos legíveis por humanos nos resultados.

O exemplo a seguir mostra uma configuração de consulta híbrida.

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2024-07-01
Content-Type: application/json
api-key: {{admin-api-key}}
{
    "vectorQueries": [
        {
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true,
            "k": 10
        },
        {
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true,
            "k": 10
        }
    ],
    "search": "historic hotel walk to restaurants and shopping",
    "select": "HotelName, Description, Address/City",
    "top": 10
}

Pontos principais:

  • A cadeia de caracteres de consulta de vetor é especificada pela propriedade vectorQueries.vector. A consulta é executada no campo "DescriptionVector". Defina kind como "vetor" para indicar o tipo de consulta. Opcionalmente, defina exhaustive como verdadeiro para consultar o conteúdo completo do campo de vetor.

  • A pesquisa de palavras-chave é especificada por meio da propriedade search. Ele é executado em paralelo com a consulta de vetor.

  • k determina quantas correspondências vizinhas mais próximas são retornadas da consulta de vetor e fornecidas ao classificador RRF.

  • top determina quantas correspondências são retornadas na resposta total. Neste exemplo, a resposta inclui 10 resultados, supondo que haja pelo menos 10 correspondências nos resultados mesclados.

Pesquisa híbrida com filtro

Este exemplo adiciona um filtro que é aplicado aos campos filterable não-vetores do índice de pesquisa.

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2024-07-01
Content-Type: application/json
api-key: {{admin-api-key}}
{
    "vectorQueries": [
        {
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "fields": "DescriptionVector",
            "kind": "vector",
            "k": 10
        }
    ],
    "search": "historic hotel walk to restaurants and shopping",
    "vectorFilterMode": "postFilter",
    "filter": "ParkingIncluded",
    "top": "10"
}

Pontos principais:

  • Os filtros são aplicados ao conteúdo de campos filtrados. Neste exemplo, o campo ParkingIncluded é um booliano e está marcado como filterable no esquema de índice.

  • Em consultas híbridas, os filtros podem ser aplicados antes da execução da consulta para reduzir a superfície de consulta ou após a execução da consulta para cortar os resultados. "preFilter" é o padrão. Para usar postFilter, defina o modo de processamento de filtro, conforme mostrado neste exemplo.

  • Ao pós-filtrar os resultados da consulta, o número de resultados pode ser menor que os n principais.

Pesquisa híbrida com filtros direcionados a subconsultas de vetor (versão prévia)

Usando 2024-09-01-preview, você pode substituir um filtro global na solicitação de pesquisa aplicando um filtro secundário direcionado apenas às subconsultas de vetor em uma solicitação híbrida.

Esse recurso fornece controle refinado, garantindo que os filtros influenciam apenas os resultados da busca em vetores, deixando os resultados da pesquisa baseados em palavra-chave não afetados.

O filtro de destino substitui totalmente o filtro global, incluindo todos os filtros usados para corte de segurança ou pesquisa geoespacial. Nos casos em que os filtros globais são necessários, como o corte de segurança, você deve incluir explicitamente esses filtros no filtro de nível superior e em cada filtro de nível de vetor para garantir que a segurança e outras restrições sejam impostas consistentemente.

Para aplicar filtros de vetor de destino:

Aqui está um exemplo de consulta híbrida que adiciona uma substituição de filtro. O filtro global "Classificação gt 3" é substituído em tempo de execução pelo filterOvrride.

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2024-09-01=preview

{
    "vectorQueries": [
        {
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "fields": "DescriptionVector",
            "kind": "vector",
            "exhaustive": true,
            "filterOverride": "Address/City eq 'Seattle'",
            "k": 10
        }
    ],
    "search": "historic hotel walk to restaurants and shopping",
    "select": "HotelName, Description, Address/City, Rating",
    "filter": "Rating gt 3"
    "debug": "vector",
    "top": 10
}

Supondo que tenha habilitado o classificador semântico e sua definição de índice inclua uma configuração semântica, você pode formular uma consulta que inclua uma busca em vetores e uma busca por palavra-chave, com uma classificação semântica do conjunto de resultados mesclados. Opcionalmente, você pode adicionar legendas e respostas.

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2024-07-01
Content-Type: application/json
api-key: {{admin-api-key}}
{
    "vectorQueries": [
        {
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "fields": "DescriptionVector",
            "kind": "vector",
            "k": 50
        }
    ],
    "search": "historic hotel walk to restaurants and shopping",
    "select": "HotelName, Description, Tags",
    "queryType": "semantic",
    "semanticConfiguration": "my-semantic-config",
    "captions": "extractive",
    "answers": "extractive",
    "top": "50"
}

Pontos principais:

  • O classificador semântico aceita até 50 resultados da resposta mesclada.

  • "queryType" e "semanticConfiguration" são necessários.

  • "captions" e "answers" são opcionais. Os valores são extraídos do texto verbatim nos resultados. Uma resposta só será retornada se os resultados incluírem conteúdo com as características de uma resposta para a consulta.

Pesquisa semântica híbrida com filtro

Esta é a última consulta na coleção. É a mesma consulta semântica híbrida do exemplo anterior, mas com um filtro.

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2024-07-01
Content-Type: application/json
api-key: {{admin-api-key}}
{
    "vectorQueries": [
        {
            "vector": [
                -0.009154141,
                0.018708462,
                . . . 
                -0.02178128,
                -0.00086512347
            ],
            "fields": "DescriptionVector",
            "kind": "vector",
            "k": 50
        }
    ],
    "search": "historic hotel walk to restaurants and shopping",
    "select": "HotelName, Description, Tags",
    "queryType": "semantic",
    "semanticConfiguration": "my-semantic-config",
    "captions": "extractive",
    "answers": "extractive",
    "filter": "ParkingIsIncluded'",
    "vectorFilterMode": "postFilter",
    "top": "50"
}

Pontos principais:

  • O modo de filtro pode afetar o número de resultados disponíveis para o reclassificador semântico. Como prática recomendada, é inteligente dar ao classificador semântico o número máximo de documentos (50). Se os pré-filtros ou os pós-filtros forem muito seletivos, você poderá estar prejudicando o classificador semântico, dando-lhe menos de 50 documentos para trabalhar.

  • A pré-filtragem é aplicada antes da execução da consulta. Se o pré-filtro reduzir a área de pesquisa para 100 documentos, a consulta vetorial será executada no campo "DescriptionVector" desses 100 documentos, retornando as k=50 melhores correspondências. Esses 50 documentos correspondentes passam para o RRF para obter resultados mesclados e, em seguida, para o classificador semântico.

  • O pós-filtro é aplicado após a execução da consulta. Se k=50 retornar 50 correspondências no lado da consulta de vetor, o pós-filtro será aplicado às 50 correspondências, reduzindo os resultados que atendem aos critérios de filtro, deixando você com menos de 50 documentos para passar para o classificador semântico.

Definir maxTextRecallSize e countAndFacetMode (versão prévia)

Esta seção explica como ajustar as entradas de uma consulta híbrida controlando a quantidade de resultados classificados pelo BM25 que fluem para o modelo de classificação híbrida. O controle sobre a entrada classificada pelo BM25 oferece mais opções de ajuste de relevância em cenários híbridos.

Recomendamos a versão prévia da API REST 2024-05-01-preview.

Dica

Outra opção a considerar é uma técnica suplementar ou substitutiva, chamada ponderação de vetores, que aumenta a importância das consultas de vetores na solicitação.

  1. Use Search - POST ou Search - GET em 2024-05-01-preview para especificar esses parâmetros.

  2. Adicione um objeto de parâmetro de consulta hybridSearch para definir o número máximo de documentos recuperados por meio dos resultados classificados como BM25 de uma consulta híbrida. Tem duas propriedades:

    • maxTextRecallSize especifica o número de resultados classificados pelo BM25 a serem fornecidos ao classificador de Fusão de Rank Recíproco (RRF) utilizado em consultas híbridas. O padrão é 1.000. O máximo é 10.000.

    • countAndFacetMode informa as contagens dos resultados classificados pelo BM25 (e das facetas, se você as estiver usando). O padrão é todos os documentos que correspondem à consulta. Opcionalmente, você pode incluir o escopo "contagem" em maxTextRecallSize.

  3. Reduza maxTextRecallSize se a pesquisa de similaridade de vetores estiver superando o desempenho do lado do texto da consulta híbrida.

  4. Aumente maxTextRecallSize se você tiver um índice grande e o padrão não estiver capturando um número suficiente de resultados. Com um conjunto maior de resultados com classificação BM25, você também pode definir top, skip e next para recuperar partes desses resultados.

Os exemplos REST a seguir mostram dois casos de uso para a definição de maxTextRecallSize.

O primeiro exemplo reduz maxTextRecallSize para 100, limitando o lado do texto da consulta híbrida a apenas 100 documentos. Ele também define countAndFacetMode para incluir somente os resultados de maxTextRecallSize.

POST https://[service-name].search.windows.net/indexes/[index-name]/docs/search?api-version=2024-05-01-Preview 

    { 
      "vectorQueries": [ 
        { 
          "kind": "vector", 
          "vector": [1.0, 2.0, 3.0], 
          "fields": "my_vector_field", 
          "k": 10 
        } 
      ], 
      "search": "hello world", 
      "hybridSearch": { 
        "maxTextRecallSize": 100, 
        "countAndFacetMode": "countRetrievableResults" 
      } 
    } 

O segundo exemplo aumenta maxTextRecallSize para 5.000. Ele também usa top, skip e next para extrair resultados de grandes conjuntos de resultados. Nesse caso, a solicitação extrai os resultados classificados como BM25, começando na posição 1.500 até 2.000, como a contribuição da consulta de texto para o conjunto de resultados compostos do RRF.

POST https://[service-name].search.windows.net/indexes/[index-name]/docs/search?api-version=2024-05-01-Preview 

    { 
      "vectorQueries": [ 
        { 
          "kind": "vector", 
          "vector": [1.0, 2.0, 3.0], 
          "fields": "my_vector_field", 
          "k": 10 
        } 
      ], 
      "search": "hello world",
      "top": 500,
      "skip": 1500,
      "next": 500,
      "hybridSearch": { 
        "maxTextRecallSize": 5000, 
        "countAndFacetMode": "countRetrievableResults" 
      } 
    } 

Configurar uma resposta de consulta

Ao configurar a consulta híbrida, pense na estrutura de resposta. A resposta é um conjunto de linhas bidimensional. Os parâmetros na consulta determinam quais campos estão em cada linha e quantas linhas estão na resposta. O mecanismo de pesquisa classifica os documentos correspondentes e retorna os resultados mais relevantes.

Campos em uma resposta

Os resultados da pesquisa são compostos por campos retrievable do seu índice de pesquisa. Um resultado pode ter:

  • Todos os campos retrievable (um padrão da API REST).
  • Campos explicitamente listados em um parâmetro "select" na consulta.

Os exemplos neste artigo usaram uma instrução "select" para especificar campos de texto (não vetoriais) na resposta.

Observação

Os vetores não são submetidos a engenharia reversa em texto legível por humanos, portanto, evite retorná-los na resposta. Em vez disso, escolha campos não vetoriais que sejam representativos do documento de pesquisa. Por exemplo, se a consulta tiver como alvo um campo "DescriptionVector", retorne um campo de texto equivalente, se você tiver um ("Description") na resposta.

Número de resultados

Uma consulta pode corresponder a qualquer número de documentos, até mesmo a todos eles, se os critérios de pesquisa forem fracos (por exemplo, "search=*" para uma consulta nula). Como nem sempre é prático retornar resultados não associados, você deve especificar um máximo para a resposta geral:

  • "top": n resultados para consultas somente palavra-chave (sem vetor)
  • "k": n resultados de consultas somente de vetores
  • "top": n resultados de consultas híbridas (com ou sem semântica) que incluem um parâmetro "search"

Tanto "k" quanto "top" são opcionais. Não especificado, 50 é o número padrão de resultados em uma resposta. Você pode definir "top" e "skip" para percorrer mais resultados ou alterar o padrão.

Observação

Se você estiver usando a pesquisa híbrida na API 2024-05-01-preview, poderá controlar o número de resultados da consulta de palavra-chave usando maxTextRecallSize. Combine isso com uma configuração de "k" para controlar a representação de cada subsistema de pesquisa (palavra-chave e vetor).

Resultados do classificador semântico

Observação

O classificador semântico pode levar até 50 resultados.

Se você estiver usando o classificador semântico na API 2024-05-01-preview, uma boa prática é configurar "k" e "maxTextRecallSize" para somar pelo menos 50 no total. Em seguida, você pode restringir os resultados retornados ao usuário com o parâmetro "top".

Se você estiver usando o classificador semântico em APIs anteriores, faça o seguinte:

  • se a pesquisa somente de palavra-chave (sem vetor) definir "top" como 50
  • se a pesquisa híbrida definir "k" como 50, para garantir que o classificador semântico obtenha pelo menos 50 resultados.

Classificação

Vários conjuntos são criados para consultas híbridas, com ou sem a reclassificação semântica opcional. A classificação dos resultados é calculada pela RRF.

Nesta seção, compare as respostas entre a busca em vetores única e a pesquisa híbrida simples para obter o melhor resultado. Os diferentes algoritmos de classificação, a métrica de similaridade do HNSW e a RRF, respectivamente, produzem pontuações que têm magnitudes diferentes. Este é o comportamento padrão. As pontuações da RRF podem parecer bem baixas, mesmo com uma correspondência de alta similaridade. Pontuações mais baixas são uma característica do algoritmo da RRF. Em uma consulta híbrida com a RRF, mais da recíproca dos documentos classificados são incluídos nos resultados, dada a pontuação relativamente menor dos documentos classificados pela RRF, em vez da busca em vetores tão somente.

Pesquisa de Vetor Único: @search.score para resultados ordenados por similaridade de cosseno (função padrão de distância de similaridade de vetor).

{
    "@search.score": 0.8399121,
    "HotelId": "49",
    "HotelName": "Swirling Currents Hotel",
    "Description": "Spacious rooms, glamorous suites and residences, rooftop pool, walking access to shopping, dining, entertainment and the city center.",
    "Category": "Luxury",
    "Address": {
    "City": "Arlington"
    }
}

Pesquisa Híbrida: @search.score para resultados híbridos classificados usando a Fusão de Classificação Recíproca.

{
    "@search.score": 0.032786883413791656,
    "HotelId": "49",
    "HotelName": "Swirling Currents Hotel",
    "Description": "Spacious rooms, glamorous suites and residences, rooftop pool, walking access to shopping, dining, entertainment and the city center.",
    "Category": "Luxury",
    "Address": {
    "City": "Arlington"
    }
}

Próximas etapas

Como próxima etapa, é recomendável revisar o código de demonstração para Python, C# ou JavaScript.