Partager via


Créer une requête hybride dans Recherche Azure AI

La recherche hybride combine une ou plusieurs requêtes texte (de mot clé) avec une ou plusieurs requêtes vectorielles dans une requête de recherche unique. Les requêtes s’exécutent en parallèle. Les résultats sont fusionnés et réorganisés par nouveaux scores de recherche, à l’aide de la fusion de classement réciproque (RRF) pour retourner un jeu de résultats unifié.

Dans de nombreux cas, selon les tests de référence, les requêtes hybrides avec un classement sémantique retournent les résultats les plus pertinents.

Pour améliorer la pertinence :

  • Les nouveaux paramètres maxTextRecallSize et countAndFacetMode (préversion) procurent davantage de contrôle sur les entrées de texte dans une requête hybride.

  • La nouvelle pondération vectorielle vous permet de définir le poids relatif de la requête vectorielle. Cette fonctionnalité est particulièrement utile dans les requêtes complexes où deux jeux de résultats distincts ou plus doivent être combinés, comme c’est le cas pour la recherche hybride.

Prérequis

Choisir une API ou un outil

  • 2023-11-01 version stable
  • 2023-10-01-preview, ajoute la vectorisation intégrée au côté vecteur d’une requête hybride
  • 2024-03-01-preview, ajoute des types de données étroits et une quantification scalaire au côté vecteur d’une requête hybride
  • 2024-05-01-preview ajoute maxTextRecallSize et countAndFacetMode spécifiquement pour la recherche hybride
  • Explorateur de recherche dans le portail Azure (cible les comportements 2024-05-01-preview)
  • Packages bêta ou stables plus récents des kits SDK Azure (consultez les journaux de modification pour connaître la prise en charge des fonctionnalités du SDK)

Exécuter une requête hybride dans l’Explorateur de recherche

  1. Dans l’Explorateur de recherche, vérifiez que la version de l’API est 2023-10-01-préversion ou version ultérieure.

  2. Sous Affichage, sélectionnez vue JSON.

  3. Remplacez le modèle de requête par défaut par une requête hybride, par exemple celle commençant à la ligne 539 pour l’exemple de démarrage rapide vectoriel. Par souci de concision, le vecteur est tronqué dans cet article.

    Une requête hybride a une requête de texte spécifiée dans searchet une requête vectorielle spécifiée sous vectorQueries.vector.

    La requête de texte et la requête vectorielle doivent être équivalentes ou au moins pas en conflit. Si les requêtes sont différentes, vous ne bénéficiez pas de l’avantage de l’hybride.

    {
        "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. Sélectionnez Rechercher.

Demande de requête hybride (API REST)

Une requête hybride combine la recherche en texte et la recherche vectorielle, où le paramètre search prend une chaîne de requête et vectorQueries.vector prend la requête vectorielle. Le moteur de recherche exécute des requêtes de texte intégral et de vecteur en parallèle. L’union de toutes les correspondances est évaluée pour la pertinence à l’aide de la fusion de classement réciproque (RRF) et un jeu de résultats unique est retourné dans la réponse.

Les résultats sont renvoyés en texte clair, y compris les vecteurs dans les champs marqués comme retrievable. Étant donné que les vecteurs numériques ne sont pas utiles dans les résultats de recherche, choisissez d’autres champs dans l’index en tant que proxy pour la correspondance vectorielle. Par exemple, si un index a des champs « descriptionVector » et « descriptionText », la requête peut correspondre à « descriptionVector », mais le résultat de la recherche peut afficher « descriptionText ». Utilisez le paramètre select pour spécifier uniquement les champs lisibles par l’homme dans les résultats.

L’exemple suivant illustre une configuration de requête hybride.

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2023-11-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
}

Points essentiels :

  • La chaîne de recherche vectorielle est spécifiée par le biais de la propriété vectorQueries.vector. La requête s’exécute sur le champ « DescriptionVector ». Définissez kind sur « vector » pour indiquer le type de requête. Si vous le souhaitez, définissez la valeur exhaustive sur true pour interroger le contenu complet du champ vectoriel.

  • La recherche par mot clé est spécifiée par le biais de la propriété search. Elle s’exécute en parallèle avec la requête vectorielle.

  • k détermine le nombre de correspondances du plus proche voisin retournées par la requête vectorielle et fournies au ranker RRF.

  • top détermine le nombre de correspondances retournées dans la réponse. Dans cet exemple, la réponse comprend dix résultats, en supposant qu’il y ait au moins dix correspondances dans les résultats fusionnés.

Recherche hybride avec filtre

Cet exemple ajoute un filtre, qui est appliqué aux champs non vectoriels filterable de l’index de recherche.

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2023-11-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"
}

Points essentiels :

  • Les filtres sont appliqués au contenu des champs filtrables. Dans cet exemple, le champ ParkingIncluded est une valeur booléenne et elle est marquée comme filterable dans le schéma de l’index.

  • Dans les requêtes hybrides, les filtres peuvent être appliqués avant l’exécution de la requête afin de réduire la surface de requête, ou après l’exécution de la requête afin de réduire les résultats. "preFilter" est la valeur par défaut. Pour utiliser postFilter, définissez le mode de traitement de filtre comme illustré dans cet exemple.

  • Lorsque vous postfiltrez des résultats de requête, le nombre de résultats peut être inférieur à top-n.

En supposant que vous avez activé le classement sémantique et que votre définition d’index inclut une configuration sémantique, vous pouvez formuler une requête qui inclut la recherche vectorielle, ainsi que la recherche par mot clé avec un classement sémantique sur le jeu de résultats fusionné. Si vous le souhaitez, vous pouvez ajouter des légendes et des réponses.

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2023-11-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"
}

Points essentiels :

  • Le classement sémantique accepte jusqu’à 50 résultats de la réponse fusionnée.

  • « queryType » et « semanticConfiguration » sont obligatoires.

  • « captions » et « answers » sont facultatifs. Les valeurs sont extraites du texte détaillé dans les résultats. Une réponse est retournée uniquement si les résultats incluent du contenu ayant les caractéristiques d’une réponse à la requête.

Recherche hybride sémantique avec filtre

Voici la dernière requête de la collection. Il s’agit de la même requête hybride sémantique que l’exemple précédent, mais avec un filtre.

POST https://{{search-service-name}}.search.windows.net/indexes/{{index-name}}/docs/search?api-version=2023-11-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"
}

Points essentiels :

  • Le mode de filtre peut affecter le nombre de résultats accessibles au reranker sémantique. En guise de meilleure pratique, il est judicieux de donner au ranker sémantique le nombre maximal de documents (50). Si les préfiltres ou les postfiltres sont trop sélectifs, vous risquez de sous-servir le ranker sémantique en lui donnant moins de 50 documents avec lesquels travailler.

  • Le préfiltrage est appliqué avant l’exécution de la requête. Si le préfiltre réduit la zone de recherche à 100 documents, la requête vectorielle s’exécute sur le champ « DescriptionVector » pour ces 100 documents, et retourne les k=50 meilleures correspondances. Ces 50 documents correspondants passent ensuite à RRF pour les résultats fusionnés, puis au ranker sémantique.

  • Le postfiltre est appliqué après l’exécution de la requête. Si k=50 retourne 50 correspondances côté requête vectorielle, le postfiltre est appliqué aux 50 correspondances, ce qui réduit le nombre de résultats répondant aux critères de filtre, et vous laisse avec moins de 50 documents à passer au classeur sémantique.

Définir maxTextRecallSize et countAndFacetMode (préversion)

Cette section explique comment ajuster les entrées d’une requête hybride en contrôlant la quantité de résultats classés BM25 qui circulent jusqu’au modèle de classement hybride. Le contrôle de l’entrée classée BM25 vous offre davantage d’options pour le réglage de la pertinence dans les scénarios hybrides.

Conseil

Une autre option à prendre en compte est une technique supplémentaire ou de remplacement, à savoir la pondération vectorielle, qui augmente l’importance des requêtes vectorielles dans la requête.

  1. Utilisez Search – POST ou Search – GET dans 2024-05-01-preview pour spécifier ces paramètres.

  2. Ajoutez un objet de paramètre de requête hybridSearch pour définir le nombre maximal de documents rappelés parmi les résultats classés BM25 d’une requête hybride. Elle contient deux propriétés :

    • maxTextRecallSize spécifie le nombre de résultats classés BM25 à fournir au classeur de fusion de classement réciproque (RRF) utilisé dans les requêtes hybrides. La valeur par défaut est 1000. La valeur maximale est 10 000.

    • countAndFacetMode indique le nombre de résultats classés BM25 (et de facettes si vous les utilisez). La valeur par défaut est tous les documents qui correspondent à la requête. Si vous le souhaitez, vous pouvez définir maxTextRecallSize comme étendue de « count ».

  3. Réduisez maxTextRecallSize si la recherche de similarité vectorielle fournit généralement de meilleures performances que le côté texte de la requête hybride.

  4. Augmentez maxTextRecallSize si vous avez un index volumineux et que le paramètre par défaut ne capture pas un nombre suffisant de résultats. Avec un jeu de résultats classé BM25 plus grand, vous pouvez également définir top, skip et next pour récupérer des parties de ces résultats.

Les exemples REST suivants montrent deux cas d’usage pour définir maxTextRecallSize.

Le premier exemple réduit maxTextRecallSize à 100, limitant le côté texte de la requête hybride à seulement 100 documents. Il définit également countAndFacetMode de façon à inclure uniquement ces résultats à partir 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" 
      } 
    } 

Le deuxième exemple augmente maxTextRecallSize à 5000. Il utilise également top, skip et next pour extraire les résultats à partir de jeux de résultats volumineux. Dans ce cas, la requête extrait les résultats classés BM25 de la position 1500 à la position 2000 en tant que contribution de requête texte au jeu de résultats composite 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" 
      } 
    } 

Configurer une réponse à une requête

Lorsque vous configurez la requête hybride, réfléchissez à la structure de réponse. La réponse est un ensemble de lignes aplati. Les paramètres de la requête déterminent les champs contenus dans chaque ligne et le nombre de lignes dans la réponse. Le moteur de recherche classe les documents correspondants et renvoie les résultats les plus pertinents.

Champs dans une réponse

Les résultats de la recherche sont composés de champs retrievable à partir de votre index de recherche. Le résultat est soit :

  • Tous les champs retrievable (une API REST par défaut).
  • Champs explicitement répertoriés dans un paramètre « select » sur la requête.

Les exemples de cet article utilisent une instruction « select » pour spécifier des champs de texte (non vecteur) dans la réponse.

Remarque

Les vecteurs ne sont pas inversés en texte lisible par l’homme. Évitez donc de les renvoyer dans la réponse. Au lieu de cela, choisissez des champs non vectoriels représentatifs du document de recherche. Par exemple, si la requête cible un champ « DescriptionVector », la réponse renvoie un champ texte équivalent si vous en avez un (« Description »).

Nombre de résultats

Une requête peut correspondre à un nombre quelconque de documents, autant que tous si les critères de recherche sont faibles (par exemple , « search=* » pour une requête Null). Étant donné qu’il est rarement pratique de retourner des résultats non liés, vous devez spécifier un maximum pour la réponse globale :

  • "top": n résultats pour les requêtes par mot clé uniquement (aucun vecteur)
  • "k": n résultats pour les requêtes vectorielles uniquement
  • "top": n résultats pour les requêtes hybrides (avec ou sans sémantique) qui incluent un paramètre « recherche »

« k » et « top » sont facultatifs. Non spécifié, le nombre par défaut de résultats dans une réponse est 50. Vous pouvez définir « haut » et « ignorer » sur la page par le biais de résultats supplémentaires ou modifier la valeur par défaut.

Remarque

Si vous utilisez la recherche hybride dans l’API 2024-05-01-preview, vous pouvez contrôler le nombre de résultats de la requête par mot clé à l’aide de maxTextRecallSize. Combinez-le avec un paramètre pour « k » pour contrôler la représentation à partir de chaque sous-système de recherche (mot clé et vecteur).

Résultats du classeur sémantique

Remarque

Le ranker sémantique peut prendre jusqu’à 50 résultats.

Si vous utilisez le classement sémantique dans l’API 2024-05-01-preview, la meilleure pratique consiste à définir « k » et « maxTextRecallSize » pour obtenir un total d’au moins 50. Vous pouvez ensuite restreindre les résultats retournés à l’utilisateur avec le paramètre « top ».

Si vous utilisez le classement sémantique dans les API précédentes, procédez de la manière suivante :

  • si vous effectuez une recherche par mot-clé uniquement (aucun vecteur), définissez la valeur « top » sur 50
  • si vous effectuez une recherche hybride, définissez "k" sur 50, afin de vous assurer que le classeur sémantique reçoive au moins 50 résultats.

Classement

Plusieurs jeux sont créés pour les requêtes hybrides, avec ou sans le nouveau classement sémantique facultative. Le classement des résultats est calculé par fusion de classement réciproque (RRF).

Dans cette section, comparez les réponses entre la recherche vectorielle unique et la recherche hybride simple pour obtenir le meilleur résultat. Les différents algorithmes de classement, dans ce cas-ci la métrique de similarité de HNSW et la RRF, produisent des scores ayant différentes magnitudes. Ce comportement est inhérent au produit. Les scores RRF peuvent sembler assez faibles, même avec une correspondance de similarité élevée. Les bas scores sont une caractéristique de l’algorithme RRF. Dans une requête hybride avec RRF, la réciproque des documents classés est davantage incluse dans les résultats, étant donné le score relativement plus faible des documents classés de la RRF, par opposition à la recherche vectorielle pure.

Recherche vectorielle unique :@search.score pour des résultats classés par similarité cosinus (fonction de distance de similarité de vecteur par défaut).

{
    "@search.score": 0.8399121,
    "HotelId": "49",
    "HotelName": "Old Carrabelle 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"
    }
}

Recherche hybride : @search.score pour les résultats hybrides classés à l’aide de la fusion de classement réciproque.

{
    "@search.score": 0.032786883413791656,
    "HotelId": "49",
    "HotelName": "Old Carrabelle 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"
    }
}

Étapes suivantes

À l’étape suivante, nous vous recommandons d’évaluer le code de démonstration pour Python, C#, ou Javascript.