TATECHATLAS
◎ Français
Intelligence artificielle

Configuring Hybrid Search with Vector and Text Fields in Azure AI Search

Guide étape par étape pour créer un index, générer des embeddings et exécuter des requêtes hybrides qui combinent recherche textuelle et recherche vectorielle à l'aide d'Azure AI Search.

Dans ce guide

La recherche hybride est configurée en ajoutant des champs vectoriels au schéma d'index, en générant des embeddings pour le contenu textuel et en formant une requête avec les paramètres search et vectorQueries. Les résultats sont fusionnés à l'aide de l'algorithme RRF (Reciprocal Rank Fusion), et un reranker sémantique peut être activé de façon optionnelle pour réordonner. Étapes clés : définition du schéma d'index, génération d'embeddings, configuration de k et de l'oversampling, construction de la requête avec filtres et facettes, inclusion optionnelle du reranker sémantique, tests, et suivi des quotas et coûts.

1. Définition du schéma d'index avec des champs vectoriels et textuels

Pour commencer, un index Azure AI Search est créé contenant à la fois des champs textuels classiques pour la recherche full-text et des champs vectoriels pour la recherche sémantique. Les champs vectoriels stockent des embeddings numériques dérivés du texte des documents. L'index doit comporter au moins un champ textuel recherchable et un champ vectoriel. Lors de la création d'un index via le portail ou l'API REST, les champs vectoriels sont déclarés avec le type "Edm.Single" et l'attribut "searchable": true, mais ils ne sont pas utilisés pour la recherche full-text ordinaire ; leur rôle est la similarité vectorielle.

Un exemple de la documentation Microsoft Learn montre une requête hybride où le paramètre search est combiné avec des vectorQueries pointant vers les champs DescriptionVector et Description_frVector. Cela permet une seule requête de réaliser à la fois une recherche par mots clés et une recherche sémantique, les résultats étant fusionnés par l'algorithme RRF.

Important : les champs vectoriels ne peuvent pas être utilisés directement dans des filtres. Pour les métadonnées (par exemple, catégorie, géographie) un champ textuel ou numérique séparé, marqué avec les attributs filterable et/ou facetable, est requis.

POST https://my-service.search.windows.net/indexes/hotels-vector-quickstart/docs/search?api-version=2026-04-01\ncontent-type: application/JSON\n{\n  "count": true,\n  "search": "historic hotel walk to restaurants and shopping",\n  "select": "HotelId, HotelName, Category, Description, Address/City, Address/StateProvince",\n  "filter": "geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",\n  "vectorFilterMode": "postFilter",\n  "facets": ["Address/StateProvince"],\n  "vectorQueries": [{\n    "kind": "vector",\n    "vector": [0.1,0.2,…],\n    "k": 50,\n    "fields": "DescriptionVector",\n    "exhaustive": true,\n    "oversampling": 20\n  }],\n  "skip": 0,\n  "top": 10,\n  "queryType": "semantic",\n  "queryLanguage": "en-us",\n  "semanticConfiguration": "my-semantic-config"\n}

2. Génération ou importation d'embeddings pour les champs textuels

Les embeddings peuvent être générés de deux manières : en utilisant les capacités intégrées d'Azure AI Search (pipeline d'indexeur avec Azure OpenAI) ou des modèles externes (embeddings OpenAI, SBERT, etc.) puis chargement des vecteurs directement dans l'index. Dans le premier cas, un skillset est configuré qui découpe automatiquement le texte et appelle le modèle d'embedding. Dans le second cas, les vecteurs sont formés externement et transmis via l'API lors de la création ou de la mise à jour des documents.

La documentation recommande d'utiliser Azure OpenAI pour la génération d'embeddings, spécifiquement le modèle text-embedding-ada-002. Les embeddings doivent avoir la même dimensionalité (par exemple 1536 pour Ada), et cette valeur est spécifiée lors de la création du champ vectoriel.

Lors de l'importation de données via le "Import data" wizard, une option de vectorisation peut être sélectionnée, et le service générera automatiquement des embeddings pour le contenu chargé si une source de données et un skillset adaptés sont configurés.

/* Example call to Azure OpenAI for obtaining an embedding */\nPOST https://my-openai-resource.openai.azure.com/openai/deployments/text-embedding-ada-002/embeddings?api-version=2024-02-15\nHeaders: api-key: YOUR_API_KEY\n{\n  "input": "historic hotel walk to restaurants and shopping"\n}

3. Configuration des paramètres de recherche vectorielle (k, oversampling, exhaustive)

Le paramètre k dans vectorQueries spécifie combien de voisins les plus proches seront retournés pour chaque vecteur. Il est recommandé de définir k >= 50 si un reranker sémantique est utilisé, afin qu'il dispose suffisamment de candidats pour le réordonnancement.

Le paramètre oversampling spécifie un pourcentage supplémentaire de candidats à extraire au-delà de k, ce qui aide à améliorer la qualité des résultats lors de l'utilisation d'index HNSW. Des valeurs typiques allant de 10 à 50 offrent un bon équilibre entre latence et précision.

Le paramètre exhaustive indique s'il faut utiliser une recherche complète pour trouver les voisins les plus proches. Définir exhaustive: true garantit de trouver les vrais k voisins les plus proches, mais augmente la latence. Par défaut false, et pour la plupart des scénarios HNSW suffit.

Dans l'exemple du document hybrid-search-overview, deux vectorQueries sont montrés : l'un avec exhaustive=true et oversampling=20, l'autre avec exhaustive=false et oversampling=10. La configuration dépend de la taille de l'index et des exigences de pertinence.

Note : augmenter k et oversampling augmente la précision, mais aussi la latence de la requête. Testez toujours les valeurs sur un échantillon représentatif de données.

"vectorQueries": [{\n    "kind": "vector",\n    "vector": <array> ,\n    "k": 50,\n    "fields": "DescriptionVector",\n    "exhaustive": true,\n    "oversampling": 20\n }]

4. Formation d'une requête hybride avec search et vectorQueries

Une requête hybride combine le paramètre search (requête full-text) et un ou plusieurs vectorQueries. La requête est envoyée en tant que message HTTP POST unique vers l'index endpoint avec api-version=2026-04-01 (ou la version actuelle).

Le serveur exécute la recherche full-text et la recherche vectorielle en parallèle, puis fusionne les résultats à l'aide de l'algorithme RRF (Reciprocal Rank Fusion). Le RRF attribue à chaque document un rang combiné basé sur sa position dans les deux listes de résultats, permettant la combinaison d'une recherche par mots clés précise et des avantages de similarité sémantique.

Dans la requête, queryType: semantic peut être spécifié pour activer le reranker sémantique, qui applique une lecture machine aux résultats RRF fusionnés et les réordonne en fonction du contexte de la requête. Cela est particulièrement utile pour les requêtes conceptuelles où le sens compte plus que la correspondance de mots.

Les filtres et facettes sont appliqués aux champs autres que les champs vectoriels. Par exemple, filtre géospatial geo.distance ou filtres de catégorie fonctionnent sur le résultat fusionné après RRF. Il est important de tester le comportement vectorFilterMode (preFilter vs postFilter), car l'ordre d'application des filtres affecte la performance et l'ensemble de documents retournés.

Un exemple complet de requête est fourni dans la section 1 et comprend des facettes, un filtre, des vectorQueries et semanticConfiguration.

POST https://my-service.search.windows.net/indexes/hotels-vector-quickstart/docs/search?api-version=2026-04-01\ncontent-type: application/JSON\n{\n  "count": true,\n  "search": "historic hotel walk to restaurants and shopping",\n  "select": "HotelId, HotelName, Category, Description, Address/City, Address/StateProvince",\n  "filter": "geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",\n  "vectorFilterMode": "postFilter",\n  "facets": ["Address/StateProvince"],\n  "vectorQueries": [{\n    "kind": "vector",\n    "vector": [0.1,0.2,…],\n    "k": 50,\n    "fields": "DescriptionVector",\n    "exhaustive": true,\n    "oversampling": 20\n  }],\n  "skip": 0,\n  "top": 10,\n  "queryType": "semantic",\n  "queryLanguage": "en-us",\n  "semanticConfiguration": "my-semantic-config"\n}

5. Application de filtres et facettes sur des champs non vectoriels

Après la fusion RRF, les filtres et facettes opèrent sur l'ensemble final de documents. Cela permet de conserver la fonctionnalité de recherche existante : filtres géospatiaux, filtres d'attributs, buckets de facettes pour la navigation.

Les filtres dans une requête hybride sont appliqués après l'exécution de la recherche full-text et vectorielle (postFilter par défaut), mais peuvent être configurés en vectorFilterMode: preFilter si les documents doivent être exclus avant la recherche vectorielle. Des tests montrent que postFilter donne souvent une meilleure pertinence, car le filtre ne restreint pas les candidats avant la recherche vectorielle.

Les facettes (facets) peuvent être utilisées pour découper les résultats par champs, par exemple Address/StateProvince, comme dans l'exemple. Les résultats de facettes reflètent la distribution parmi les résultats fusionnés, pas uniquement parmi un composant de recherche.

Important de se rappeler que les champs vectoriels ne peuvent pas être filtrés directement. Toute condition de sélection par métadonnées doit s'appuyer sur des champs textuels ou numériques séparés marqués avec les attributs appropriés lors de la création de l'index.

"filter": "geo.distance(Location, geography'POINT(-77.03241 38.90166)') le 300",\n  "facets": ["Address/StateProvince"]

6. Activation optionnelle d'un reranker sémantique pour le réordonnancement

Le reranker sémantique est disponible en ajoutant queryType: semantic et en spécifiant semanticConfiguration dans la requête. Le reranker utilise la lecture machine pour analyser les résultats RRF fusionnés et les réordonner en fonction de la correspondance sémantique avec la requête.

Cette amélioration de la qualité de recherche est utile pour les requêtes où la proximité conceptuelle compte (par exemple, synonymes, recherche multilingue). Des benchmarks montrent que la recherche hybride avec reranker sémantique fournit une amélioration significative de la pertinence par rapport à une recherche vectorielle ou par mots clés pure.

La configuration du reranker sémantique est définie au niveau de l'index (section "semantic configurations"). Dans la requête, le nom de la configuration est indiqué, ainsi que la langue de la requête (queryLanguage).

Si le reranker sémantique n'est pas nécessaire, une requête peut être envoyée sans queryType: semantic. Dans ce cas, les résultats sont classés uniquement en fonction du RRF, combinant BM25 (pour le texte) et HNSW/eKNN (pour les vecteurs).

 "queryType": "semantic",\n  "queryLanguage": "en-us",\n  "semanticConfiguration": "my-semantic-config"

7. Tests et itération de k, oversampling et comportement des filtres

Après déploiement, il est nécessaire d'expérimenter avec k, oversampling et comportement des filtres (preFilter/postFilter) pour trouver le ratio vitesse-précision optimal pour votre domaine.

Testez différentes valeurs de k (par exemple 10, 50, 100) et d'oversampling (10, 20, 50) sur un échantillon représentatif de requêtes. Faites attention aux changements dans @search.rerankerScore et à l'ordre des documents dans la réponse.

Comparez les résultats avec et sans reranker sémantique. Si k est trop petit, le reranker sémantique ne recevra suffisamment de candidats, et le réordonnancement sera moins efficace.

Surveillez la latence des requêtes : augmenter k et oversampling augmente le temps de réponse. Trouvez le k minimum qui fournit une pertinence acceptable lors de l'utilisation du reranker sémantique.

Utilisez les outils de débogage du portail Azure ou de l'API REST : le paramètre count: true permet de voir le compte total des correspondances, et le champ @search.rerankerScore montre l'évaluation du reranker sémantique.

/* Example checking results with count */\n{\n  "count": true,\n  "search": "...",\n  "vectorQueries": [{"kind": "vector", "vector": [...], "k": 50, ...}],\n  "top": 10\n}

8. Déploiement et suivi des quotas et coûts d'index vectoriel

Assurez-vous que votre service de recherche a été créé après le 3 avril 2024 - ces services offrent des quotas d'index vectoriel supérieurs. Si le service est plus ancien, il peut être mis à jour pour obtenir des quotas plus importants.

La génération d'embeddings via Azure OpenAI ou d'autres modèles engendre des frais du côté du fournisseur de modèle. Ces coûts doivent être pris en compte lors de la planification du volume de données et de la fréquence de mise à jour.

Surveillance de l'utilisation des index vectoriels via les métriques Azure Monitor : nombre de champs vectoriels, dimensionalité, nombre de documents. Dépasser les quotas peut entraîner des erreurs d'indexation ou de requête.

Pour la recherche hybride, surveillez la latence des requêtes : de grands k et oversampling augmentent la charge. Si la latence devient inacceptable, réduisez oversampling ou vérifiez à nouveau la configuration HNSW.

Il est recommandé de définir des alertes de dépassement de quota et de vérifier régulièrement l'état de l'index, surtout après de gros lots de documents.

/* Checking service version and quotas */\nGET https://my-service.search.windows.net?api-version=2026-04-01\nHeaders: api-key: YOUR_API_KEY

Points à vérifier

  • L'index contient au moins un champ textuel recherchable et un champ vectoriel avec une dimensionalité d'embedding correspondante.
  • Les embeddings sont générés et chargés dans les champs vectoriels (via indexer ou API directe).
  • La requête hybride inclut search et vectorQueries avec les bonnes valeurs de k et de champs.
  • Lors de l'utilisation du reranker sémantique, queryType: semantic et semanticConfiguration sont définis.
  • Les filtres et facettes référencent des champs textuels/numériques, pas directement les champs vectoriels.
  • La version du service n'est pas antérieure au 3 avril 2024 pour des quotas vectoriels accrus.
  • Surveillance des coûts des embeddings et de la latence des requêtes est activée.

Les champs vectoriels ne peuvent pas être utilisés directement dans des filtres. Pour les métadonnées (par exemple, catégorie, géographie) un champ textuel ou numérique séparé marqué avec les attributs filterable et/ou facetable est requis.

Sources

  1. Microsoft Learn: vector search ↗
  2. Microsoft Learn: hybrid search ↗
  3. scikit-learn: precision_score ↗
Retour en haut ↑