Remarque
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de vous connecter ou de modifier des répertoires.
L’accès à cette page nécessite une autorisation. Vous pouvez essayer de modifier des répertoires.
Note
Recherche Azure AI est disponible via le portail Azure, les API REST et les SDK Azure. Il sous-tend également Foundry IQ, la couche de connaissances managée qui transforme le contenu d’entreprise en bases de connaissances réutilisables et prenant en charge les autorisations pour les agents dans le portail Microsoft Foundry.
Si vous segmentez du contenu pour un modèle RAG ou une vectorisation, vous pouvez spécifier une projection d’index pour contrôler l’indexation un-à-plusieurs, où le contenu source (un) est projeté sur un ou plusieurs index (plusieurs). L’intention d’une projection d’index est de contrôler si les éléments du document parent, tels qu’un nom de fichier ou une date de création :
- Répéter pour chaque enfant (segment) dans un index unique
- Sont indexés en tant que documents de recherche autonomes dans le même index
- Ou sont ingérés dans des index distincts
Nous vous recommandons de répéter des champs parents dans un seul index, car le fait d’avoir des formes de document différentes ou de fractionner du contenu en deux index peut être difficile à interroger, en particulier dans la recherche classique où les jointures d’index ne sont pas prises en charge.
Dans Recherche Azure AI, la segmentation est effectuée par les compétences et dépend donc des indexeurs. Pour définir une projection d’index, spécifiez-la dans un ensemble de compétences.
Conditions préalables
Recherche Azure AI, n’importe quel niveau ou région.
Pipeline d’indexation basé sur un indexeur.
Une source de données prise en charge ayant du contenu que vous souhaitez segmenter.
Un index (un ou plusieurs) qui accepte la sortie du pipeline d’indexeur.
Compétence qui segmente le contenu, telle que la compétence Fractionner du texte.
L'ensemble de compétences techniques contient la projection de l'indexeur qui façonne les données pour une indexation multiple. Un ensemble de compétences peut également avoir d’autres compétences, telles qu’une compétence d’incorporation comme AzureOpenAIEmbedding si votre scénario inclut la vectorisation intégrée.
Choisir une approche
Les projections d’index génèrent des documents « enfants » (segments) pour chaque document « parent ». Choisissez comment gérer le contenu parent :
| Approche | Description | Configuration |
|---|---|---|
| Index unique, champs parents répétitifs (recommandé) | Les champs parents se répètent pour chaque bloc. Tous les documents ont une forme uniforme. | Définissez l’indexeur targetIndexName et la projection targetIndexName d’index sur le même index. Définissez projectionMode à skipIndexingParentDocuments. |
| Index unique, formes de document mixte | Les documents parents et les documents segments coexistent. Les documents parents ont des champs de segments null. | Définissez les deux valeurs targetIndexName sur le même index. Défini projectionMode sur includeIndexingParentDocuments (ou omettre, car il s’agit de la valeur par défaut). |
| Deux index distincts ou plus | Index parent pour les recherches de métadonnées, index enfant pour la recherche. Aucune jointure au moment de la requête. | Définissez l’indexeur targetIndexName sur l’index parent. Définissez la projection d’index targetIndexName sur l’index enfant. Le selectors tableau détermine la quantité et la composition de l'indice enfant. |
Pour la plupart des scénarios RAG, utilisez la première approche. Consultez l’exemple classic RAG.
Étapes d’implémentation pour l’approche recommandée
- Créez un index conçu pour les blocs, avec les champs parents inclus.
-
Créez un ensemble de compétences avec une compétence de segmentation et
indexProjections. - Créez un indexeur pointant vers votre source de données prise en charge.
Si votre source de données prend en charge le suivi des modifications, l’indexeur synchronise automatiquement les modifications.
Créer un index pour l’indexation un-à-plusieurs
Que vous créez un index pour les blocs qui répètent des valeurs parentes ou des index distincts pour le placement de champs parent-enfant, l’index principal utilisé pour la recherche est conçu autour des blocs de données. Le schéma d’index doit avoir les champs suivants :
Champ clé de document identifiant de manière unique chaque document. Elle doit être définie comme type
Edm.Stringavec l’analyseurkeyword.Champ associant chaque bloc à son parent. Il doit être de type
Edm.String. Il ne peut pas s’agir du champ clé du document et doit avoirfilterablela valeur true. Il est appelé parent_id dans les exemples et comme valeur de clé projetée dans cet article.Autres champs pour le contenu, tels que le texte ou les champs de bloc vectorisés.
Un index doit exister sur le service de recherche avant de créer l’ensemble de compétences ou d’exécuter l’indexeur. L’ensemble selectors de compétences que vous définissez doit inclure ces champs.
Schéma d’index unique inclus des champs parent et enfant
Un index unique conçu autour de blocs avec le contenu parent répétitif pour chaque bloc est le modèle prédominant pour les scénarios de recherche rag et vectoriel. La possibilité d’associer le contenu parent approprié à chaque bloc est activée par le biais de projections d’index.
Le schéma suivant est un exemple qui répond aux exigences des projections d’index. Dans cet exemple :
- Les champs parents sont les parent_id et le titre, et ils se répètent pour chaque bloc
- Les champs enfants comprennent les segments vectoriels et les segments non vectoriels. Le chunk_id est l’ID de document de cet index.
Vous pouvez utiliser le portail Azure, les API REST ou un Kit de développement logiciel (SDK) Azure pour créer un index.
Utilisez un client REST ou le portail Azure action Ajouter un index et l’option JSON pour créer l’index.
{
"name": "my_consolidated_index",
"fields": [
{"name": "chunk_id", "type": "Edm.String", "key": true, "filterable": true, "analyzer": "keyword"},
{"name": "parent_id", "type": "Edm.String", "filterable": true},
{"name": "title", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "retrievable": true},
{"name": "chunk", "type": "Edm.String","searchable": true,"retrievable": true},
{"name": "chunk_vector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": false, "stored": false, "dimensions": 1536, "vectorSearchProfile": "hnsw"}
],
"vectorSearch": {
"algorithms": [{"name": "hnsw", "kind": "hnsw", "hnswParameters": {}}],
"profiles": [{"name": "hnsw", "algorithm": "hnsw"}]
}
}
Ajouter des projections d’index à un ensemble de compétences
Les projections d’index sont définies à l’intérieur d’une définition d’ensemble de compétences et sont principalement définies en tant que tableau de selectors, où chaque sélecteur correspond à un index cible différent sur le service de recherche. Cette section commence par la syntaxe et les exemples de contexte, suivis de la référence de paramètre.
Les projections d’index sont généralement disponibles. Nous vous recommandons l’API stable la plus récente :
Voici un exemple de charge utile pour une définition des projections d’index que vous pouvez utiliser pour projeter une sortie de pages individuelles par la compétence Fractionnement de texte en tant que vos documents dans l’index de recherche.
Si le document parent contient des métadonnées d’autorisation pour l’accès au niveau du document, tel que metadata_user_ids, metadata_group_idsou metadata_spo_site_url, incluez ces champs dans mappings. Chaque bloc doit les hériter pour que les filtres d’autorisation au moment de la requête s’appliquent. Pour plus d’informations, consultez Choisir où renseigner les champs ACL (version préliminaire).
"indexProjections": {
"selectors": [
{
"targetIndexName": "my_consolidated_index",
"parentKeyFieldName": "parent_id",
"sourceContext": "/document/pages/*",
"mappings": [
{
"name": "chunk",
"source": "/document/pages/*",
"sourceContext": null,
"inputs": []
},
{
"name": "chunk_vector",
"source": "/document/pages/*/chunk_vector",
"sourceContext": null,
"inputs": []
},
{
"name": "title",
"source": "/document/title",
"sourceContext": null,
"inputs": []
}
]
}
],
"parameters": {
"projectionMode": "skipIndexingParentDocuments"
}
}
Informations de référence sur les paramètres
| Paramètres de projection d’index | Définition |
|---|---|
selectors |
Tableau avec des paramètres pour le corpus de recherche principal, généralement l’index conçu autour de blocs. Vous pouvez envoyer du contenu à plusieurs index enfants en spécifiant plusieurs sélecteurs. Les schémas d’index doivent exister sur le service de recherche avant d’exécuter l’indexeur. |
parameters |
Dictionnaire de paramètres des propriétés de configuration spécifiques à la projection d’index. |
Les paramètres ont les éléments suivants dans le cadre de leur définition.
| Paramètres | Définition |
|---|---|
parameters.projectionMode |
Paramètre facultatif fournissant des instructions à l’indexeur. Les valeurs valides incluent includeIndexingParentDocuments et skipIndexingParentDocuments. La meilleure valeur pour ce paramètre est skipIndexingParentDocuments. Vous devez l’utiliser lorsque les documents segmentés sont la cible de recherche principale. Si vous ne définissez pas skipIndexingParentDocuments pour projectionMode, vous obtenez includeIndexingParentDocuments automatiquement, car il s’agit de la valeur par défaut. Cela ajoute des documents de recherche supplémentaires dans votre index, qui sont null pour les segments, mais renseignés avec du contenu spécifique du parent. Par exemple, si cinq fichiers PDF contribuent à 100 blocs à l’index, le nombre de documents dans l’index est de 105. Les cinq documents créés pour les champs parents ont des valeurs Null pour les champs de segment (enfant), ce qui les rend sensiblement différents de la majeure partie des documents dans l’index. Pour cette raison, nous vous recommandons de configurer projectionMode à skipIndexingParentDocuments. |
Les sélecteurs ont les éléments suivants dans le cadre de leur définition.
| Sélecteurs | Définition |
|---|---|
selectors.targetIndexName |
Nom de l’index dans lequel les données d’index sont projetées. Il s’agit de l’index à segment unique avec des champs parents répétés ou de l’index enfant si vous utilisez des index distincts pour le contenu parent-enfant. |
selectors.parentKeyFieldName |
Nom du champ fournissant la clé du document parent. |
selectors.sourceContext |
Annotation d’enrichissement qui définit la granularité à laquelle mapper les données dans des documents de recherche individuels. Pour plus d’informations, consultez contexte de compétence et langage d’annotation d’entrée. |
selectors.mappings |
Tableau de mappages de données enrichies vers des champs de l’index de recherche. Chaque mappage se compose des éléments suivants : name: nom du champ dans l’index de recherche dans lequel les données doivent être indexées. source: chemin d’annotation d’enrichissement à partir duquel les données doivent être extraites. Chacun mapping peut également définir de manière récursive des données avec un champ facultatif sourceContext et inputs similaire à la base de connaissances ou à la compétence Shaper. Selon votre application, ces paramètres vous permettent de mettre en forme des données en champs de type Edm.ComplexType dans l’index de recherche. Certaines llms n’acceptent pas de type complexe dans les résultats de recherche. Par conséquent, le LLM que vous utilisez détermine si un mappage de type complexe est utile ou non. |
Le mappings paramètre est important. Vous devez mapper explicitement chaque champ dans l’index enfant, à l’exception des champs d’ID tels que la clé de document et l’ID parent.
Cette exigence diffère des autres conventions de mappage de champs dans Recherche Azure AI. Pour certains types de sources de données, l’indexeur peut mapper implicitement des champs basés sur des noms similaires ou des caractéristiques connues (par exemple, les indexeurs d’objets blob utilisent le chemin de stockage de métadonnées unique comme clé de document par défaut). Toutefois, pour les projections d’indexeur, vous devez spécifier explicitement chaque mappage de champ du côté « plusieurs » de la relation.
Important
Ne créez pas de mappage de champ pour le champ de clé parent. Cela interrompt le suivi des modifications et l’actualisation des données synchronisées.
Passer en revue les mappages de champs
Les indexeurs sont affiliés à trois types différents de mappages de champs. Avant d’exécuter l’indexeur, vérifiez vos mappages de champs et savez quand utiliser chaque type.
Les mappages de champs sont définis dans un indexeur et utilisés pour mapper un champ source à un champ d’index. Les mappages de champs sont utilisés pour les chemins de données qui extraient les données de la source et les transmettent pour l'indexation, sans aucune étape de traitement intermédiaire. En règle générale, un indexeur peut mapper automatiquement des champs portant le même nom et le même type. Les mappages de champs explicites ne sont requis que lorsqu’il y a des différences. Dans l’indexation un-à-plusieurs et les modèles abordés jusqu’à présent, vous n’avez peut-être pas besoin de mappages de champs.
Les mappages de champs de sortie sont définis dans un indexeur et utilisés pour mapper le contenu enrichi généré par un ensemble de compétences à un champ dans l’index principal. Les segments sont considérés comme du contenu enrichi grâce à la création par une compétence (fractionnement de texte), mais vous n’avez pas besoin de définir un mappage de champ de sortie pour les segments, ni pour les projections d’index définies par un mappage de sélecteur.
Les selectors.mappings sont définis dans un ensemble de compétences et mappés aux champs de l’index enfant. Dans les cas où l’index enfant inclut également des champs parents (comme dans la solution d’index consolidé), vous devez configurer des mappages de champs pour chaque champ qui a du contenu, y compris le champ de titre de niveau parent, en supposant que vous souhaitez que le titre s’affiche dans chaque document segmenté. Si vous utilisez des index parents et enfants distincts, le sélecteur doit avoir des mappages de champs uniquement pour les champs au niveau enfant.
Note
Les mappages de champs de sortie et les mappages de sélecteur acceptent les nœuds d’arborescence de documents enrichis comme entrées sources. Il est essentiel de savoir comment spécifier un chemin d’accès à chaque nœud pour configurer le chemin de données. Pour en savoir plus sur la syntaxe du chemin d’accès, consultez Référencer un chemin d’accès aux nœuds enrichis et à la définition d’ensemble de compétences pour obtenir des exemples.
Exécuter l’indexeur
Une fois que vous avez créé une source de données, des index et un ensemble de compétences, vous êtes prêt à créer et exécuter l’indexeur. Cette étape déclenche l'exécution du pipeline.
Vous pouvez interroger votre index de recherche après le traitement pour tester votre solution.
Cycle de vie du contenu
Selon la source de données sous-jacente, un indexeur peut généralement fournir un suivi des modifications et une détection de suppression en cours. Cette section explique le cycle de vie du contenu de l’indexation un-à-plusieurs en relation avec l’actualisation des données.
Pour les sources de données qui fournissent le suivi des modifications et la détection de suppression, un processus d’indexeur peut récupérer des modifications dans vos données sources. Chaque fois que vous exécutez l’indexeur et l’ensemble de compétences, les projections d’index sont mises à jour si l’ensemble de compétences ou les données sources sous-jacentes ont changé. Toutes les modifications récupérées par l’indexeur sont propagées par le processus d’enrichissement aux projections de l’index, ce qui garantit que vos données projetées sont une représentation actuelle du contenu dans la source de données d’origine. L’activité d’actualisation des données est capturée dans une valeur de clé projetée pour chaque bloc. Cette valeur est mise à jour lorsque les données sous-jacentes changent.
Note
Bien que vous puissiez modifier manuellement les données dans les documents projetés à l’aide de l’API Push d’index, vous devez éviter de le faire. Les mises à jour manuelles d’un index sont remplacées sur l’appel de pipeline suivant, en supposant que le document dans les données sources est mis à jour et que la source de données a activé le suivi des modifications ou la détection de suppression.
Contenu mis à jour
Si vous ajoutez du nouveau contenu à votre source de données, de nouveaux blocs ou documents enfants sont ajoutés à l’index lors de l’exécution suivante de l’indexeur.
Si vous modifiez du contenu existant dans la source de données, les blocs sont mis à jour de manière incrémentielle dans l’index de recherche si la source de données que vous utilisez prend en charge le suivi des modifications et la détection de suppression. Par exemple, si un mot ou une phrase change dans un document, le bloc dans l’index cible qui contient ce mot ou phrase est mis à jour lors de l’exécution de l’indexeur suivant. D’autres types de mises à jour, tels que la modification d’un type de champ et certaines attributions, ne sont pas pris en charge pour les champs existants. Pour plus d’informations sur les mises à jour autorisées, consultez Mettre à jour un schéma d’index.
Certaines sources de données telles que stockage Azure prennent en charge le suivi des modifications et des suppressions par défaut, en fonction de l’horodatage. D’autres sources de données telles que Microsoft OneLake, Azure SQL ou Azure Cosmos DB doivent être configurées pour le suivi des modifications.
Contenu supprimé
Si le contenu source n’existe plus (par exemple, si le texte est raccourci pour avoir moins de blocs), le document enfant correspondant dans l’index de recherche est supprimé. Les documents enfants restants obtiennent également leur clé mise à jour pour inclure une nouvelle valeur de hachage, même si leur contenu n’a pas changé par ailleurs.
Si un document parent est complètement supprimé de la source de données, les documents enfants correspondants sont supprimés uniquement si la suppression est détectée par une dataDeletionDetectionPolicy définition définie sur la définition de source de données. Si vous n’avez pas configuré dataDeletionDetectionPolicy et que vous devez supprimer un document parent de la source de données, vous devez supprimer manuellement les documents enfants s’ils ne sont plus souhaités.
Valeur de clé projetée
Pour garantir l’intégrité des données pour le contenu mis à jour et supprimé, l’actualisation des données dans l’indexation un-à-plusieurs s’appuie sur une valeur de clé projetée côté « plusieurs ». Si vous utilisez la vectorisation intégrée ou l’Assistant Importation de données, la valeur de clé projetée est le parent_id champ d’un côté segmenté ou « plusieurs » de l’index.
Une valeur de clé projetée est un identificateur unique généré par l’indexeur pour chaque document. Il garantit l’unicité et permet le suivi des modifications et des suppressions pour fonctionner correctement. Cette clé contient les segments suivants :
- Hachage aléatoire pour garantir l’unicité. Ce hachage change si le document parent est mis à jour lors des exécutions ultérieures de l’indexeur.
- Clé du document parent.
- Chemin d’annotation d’enrichissement qui identifie le contexte du document généré.
Par exemple, si vous fractionnez un document parent avec la valeur clé « aa1b22c33 » en quatre pages, puis chacune de ces pages est projetée comme son propre document via des projections d’index :
- aa1b22c33
- aa1b22c33_pages_0
- aa1b22c33_pages_1
- aa1b22c33_pages_2
Si le document parent est mis à jour dans les données sources, ce qui peut entraîner des pages plus segmentées, les modifications de hachage aléatoires, d’autres pages sont ajoutées et le contenu de chaque bloc est mis à jour pour correspondre à ce qui se trouve dans le document source.
Exemple d’index parent-enfant distincts
Cette section présente un exemple pour les index parents et enfants distincts. Il s’agit d’un modèle rare, mais il est possible que vous ayez des exigences d’application qui sont les mieux remplies à l’aide de cette approche. Dans ce scénario, vous projetez du contenu parent-enfant en deux index distincts.
Créez deux schémas d’index.
Chaque schéma possède les champs de son grain particulier, avec le champ ID parent commun aux deux index à utiliser dans une requête de recherche. Le corpus de recherche principal est l’index enfant, mais vous pouvez émettre une requête de recherche pour récupérer les champs parents pour chaque correspondance dans le résultat. Recherche Azure AI ne prend pas en charge les jointures au moment de la requête. Votre code d'application ou couche d'orchestration doit donc fusionner ou rassembler les résultats qui peuvent être passés à une application ou à un processus.
L’index parent a un champ et un titre parent_id. La parent_id est la clé de document. Vous n’avez pas besoin de configuration de recherche vectorielle, sauf si vous souhaitez vectoriser des champs au niveau du document parent.
{ "name": "my-parent-index", "fields": [ {"name": "parent_id", "type": "Edm.String", "key":true, "filterable": true}, {"name": "title", "type": "Edm.String", "searchable": true, "filterable": true, "sortable": true, "retrievable": true} ] }L’index enfant a les champs segmentés, ainsi que le champ parent_id. Si vous utilisez des vectorisations intégrées, des profils de scoring, un ranker sémantique ou des analyseurs, vous devez les définir dans l’index enfant.
{ "name": "my-child-index", "fields": [ {"name": "chunk_id", "type": "Edm.String", "key": true, "filterable": true, "analyzer": "keyword"}, {"name": "parent_id", "type": "Edm.String", "filterable": true}, {"name": "chunk", "type": "Edm.String","searchable": true,"retrievable": true}, {"name": "chunk_vector", "type": "Collection(Edm.Single)", "searchable": true, "retrievable": false, "stored": false, "dimensions": 1536, "vectorSearchProfile": "hnsw"} ], "vectorSearch": { "algorithms": [{"name": "hsnw", "kind": "hnsw", "hnswParameters": {}}], "profiles": [{"name": "hsnw", "algorithm": "hnsw"}] }, "scoringProfiles": [], "semanticConfiguration": [], "analyzers": [] }Mettez à jour l’indexeur pour spécifier l’indexeur parent comme cible.
La définition de l’indexeur spécifie les composants du pipeline. Dans la définition de l’indexeur, le nom de l’index à fournir est l’index parent. Si vous avez besoin de mappages de champs pour les champs de niveau parent, définissez-les dans outputFieldMappings. Pour l’indexation un-à-plusieurs qui utilise des index distincts, la définition de l’indexeur peut ressembler à l’exemple suivant.
{ "name": "my-indexer", "dataSourceName": "my-ds", "targetIndexName": "my-parent-index", "skillsetName" : "my-skillset", "parameters": { }, "fieldMappings": (optional) Maps fields in the underlying data source to fields in an index, "outputFieldMappings" : (required) Maps skill outputs to fields in an index, }Ajouter
indexProjectionsà l’ensemble de compétences.Voici un exemple de définition de projection d’index qui spécifie le chemin d’accès aux données que l’indexeur doit utiliser pour indexer le contenu. Il spécifie le nom d’index enfant dans la définition de projection d’index et spécifie les mappages de chaque champ enfant ou de niveau segment. C'est le seul endroit où le nom de l'index enfant est spécifié.
Notez que
parametersest nul et utilise la valeur par défautincludeIndexingParentDocuments. L’indexeur remplit l’index parent. Le tableauselectorspermet de projeter les documents de segments vers l’index enfant."indexProjections": { "selectors": [ { "targetIndexName": "my-child-index", "parentKeyFieldName": "parent_id", "sourceContext": "/document/pages/*", "mappings": [ { "name": "chunk", "source": "/document/pages/*", "sourceContext": null, "inputs": [] }, { "name": "chunk_vector", "source": "/document/pages/*/chunk_vector", "sourceContext": null, "inputs": [] } ] } ], "parameters": {} }Exécutez l’indexeur. Si vous avez déjà exécuté l’indexeur, n’oubliez pas de le réinitialiser en premier.
Vous devez avoir deux index renseignés avec le contenu approprié. Interrogez les index dans l’Explorateur de recherche pour vérifier que chacun possède le contenu approprié.
Étape suivante
La segmentation des données et l’indexation un-à-plusieurs font partie du modèle RAG classique dans Recherche Azure AI. Passez au tutoriel suivant et à l’exemple de code pour en savoir plus.