Partage via


RAG (Génération Augmentée de Récupération) dans Recherche Azure AI

La RAG (Retrieval Augmented Generation) est une architecture qui augmente les fonctionnalités d’un grand modèle de langage (LLM) (comme ChatGPT) en ajoutant un système de récupération d’informations qui fournit les données. L’ajout d’un système de récupération d’informations vous permet de contrôler la fourniture de données utilisées par un LLM lorsqu’il formule une réponse. Pour une solution d’entreprise, l’architecture RAG signifie que vous pouvez limiter l’IA générative au contenu de votre entreprise provenant de documents et d’images vectorisés et d’autres formats de données, si vous avez incorporé des modèles pour ce contenu.

La décision sur le système de récupération d’informations à utiliser est essentielle, car elle détermine les entrées dans le LLM. Le système de récupération d’informations doit fournir les éléments suivants :

  • Des stratégies d’indexation qui chargent et actualisent à grande échelle, pour tout votre contenu, à la fréquence dont vous avez besoin.

  • Des fonctionnalités de requête et de réglage de pertinence. Le système doit retourner des résultats pertinents, dans les formats courts nécessaires pour répondre aux exigences de longueur de jeton des entrées LLM.

  • Sécurité, portée globale et fiabilité pour les données et les opérations.

  • Intégration à des modèles d’incorporation pour l’indexation, ainsi que des modèles de conversation ou des modèles de compréhension du langage pour la récupération.

Recherche Azure AI est une solution éprouvée pour la récupération d’informations dans une architecture RAG. Elle fournit des fonctionnalités d’indexation et de requête, avec l’infrastructure et la sécurité du cloud Azure. Grâce au code et à d’autres composants, vous pouvez concevoir une solution RAG complète qui inclut tous les éléments de l’IA générative sur votre contenu propriétaire.

Remarque

Vous débutez avec les concepts de copilote et RAG ? Regardez Recherche vectorielle et état de la récupération d’art pour les applications d’IA Générative.

Microsoft propose plusieurs implémentations intégrées pour l’utilisation de Recherche Azure AI dans une solution RAG.

Les approches organisées facilitent la prise en main, mais pour plus de contrôle sur l’architecture, il vous faut une solution personnalisée. Ces modèles créent des solutions de bout en bout :

Le reste de cet article explique comment Recherche Azure AI s’intègre dans une solution RAG personnalisée.

Un résumé général du modèle ressemble à ceci :

  • Commencez par une question ou une demande d’utilisateur (invite).
  • Envoyez-la à Recherche Azure AI pour trouver des informations pertinentes.
  • Envoyez les résultats de recherche les mieux classés au LLM.
  • Utilisez les fonctionnalités de compréhension et de raisonnement du langage naturel du LLM pour générer une réponse à l’invite initiale.

Recherche Azure AI fournit des entrées à l’invite LLM, mais n’entraîne pas le modèle. Dans l’architecture RAG, il n’y a pas d’entraînement supplémentaire. Le LLM est préentraîné à l’aide de données publiques, mais il génère des réponses augmentées par des informations du récupérateur.

Les modèles RAG qui incluent Recherche Azure AI ont les éléments indiqués dans l’illustration suivante.

Diagramme d’architecture de la récupération d’informations avec la recherche et ChatGPT.

  • Expérience utilisateur de l’application (application web) pour l’expérience utilisateur
  • Serveur d’applications ou orchestrateur (couche d’intégration et de coordination)
  • Recherche Azure AI (système de récupération d’informations)
  • Azure OpenAI (LLM pour l’IA générative)

L’application web fournit l’expérience utilisateur, en fournissant la présentation, le contexte et l’interaction utilisateur. Les questions ou les invites d’un utilisateur commencent ici. Les entrées passent par la couche d’intégration, allant d’abord à la recherche d’informations pour obtenir les résultats de la recherche, mais aussi au LLM pour définir le contexte et l’intention.

Le serveur d’applications ou l’orchestrateur est le code d’intégration qui coordonne les documents entre la récupération d’informations et le LLM. Une option consiste à utiliser LangChain pour coordonner le flux de travail. LangChain s’intègre à Recherche Azure AI, ce qui facilite l’intégration de Recherche Azure AI en tant que récupérateur dans votre flux de travail. Le Noyau sémantique est une autre option.

Le système de récupération des informations fournit l’index pouvant faire l’objet d’une recherche, la logique de requête et la charge utile (réponse de requête). L’index de recherche peut contenir des vecteurs ou du contenu non vectoriel. Bien que la plupart des exemples et des démonstrations incluent des champs vectoriels, ce n’est pas une exigence. La requête est exécutée à l’aide du moteur de recherche existant dans Recherche Azure AI, qui peut gérer les requêtes de mot clé (ou de terme) et de vecteur. L’index est créé à l’avance, en fonction d’un schéma que vous définissez et chargé avec votre contenu provenant de fichiers, de bases de données ou de stockage.

Le LLM reçoit l’invite d’origine, ainsi que les résultats de Recherche Azure AI. Le LLM analyse les résultats et formule une réponse. Si le LLM est ChatGPT, l’interaction utilisateur peut être une conversation bidirectionnelle. Si vous utilisez Davinci, l’invite peut être une réponse entièrement composée. Une solution Azure utilise probablement Azure OpenAI, mais il n’y a pas de dépendance absolue à l’égard de ce service spécifique.

La Recherche Azure AI ne fournit pas d’intégration LLM native pour les flux d’invite ou la conservation des conversations. Vous devez donc écrire du code qui gère l’orchestration et l’état. Vous pouvez consulter la source de démonstration (Azure-Samples/azure-search-openai-demo) pour obtenir un blueprint de ce qu’implique une solution complète. Nous vous recommandons également Azure AI Studio ou Azure OpenAI Studio pour créer des solutions de Recherche Azure AI basées sur RAG qui s’intègrent aux LLM.

Dans Recherche Azure AI, tout le contenu pouvant faire l’objet d’une recherche est stocké dans un index de recherche hébergé sur votre service de recherche. Un index de recherche est conçu pour les requêtes rapides avec des temps de réponse de l’ordre de la milliseconde, de sorte que ses structures de données internes existent pour prendre en charge cet objectif. À cette fin, un index de recherche stocke le contenu indexé, et non des fichiers de contenu entiers comme des fichiers PDF ou des images. En interne, les structures de données incluent des index inversés de texte sous forme de jetons, des index vectoriels pour les incorporations et du texte non modifié pour les cas où la correspondance textuelle détaillée est requise (par exemple, dans les filtres, la recherche approximative, les requêtes d’expression régulière).

Lorsque vous configurez les données de votre solution RAG, vous utilisez les fonctionnalités qui créent et chargent un index dans Recherche Azure AI. Un index inclut des champs qui dupliquent ou représentent votre contenu source. Un champ d’index peut être un transfert simple (un titre ou une description dans un document source devient un titre ou une description dans un index de recherche), ou un champ peut contenir la sortie d’un processus externe, tel que la vectorisation ou le traitement des compétences qui génère une représentation ou une description de texte d’une image.

Étant donné que vous connaissez probablement le type de contenu que vous souhaitez rechercher, tenez compte des fonctionnalités d’indexation applicables à chaque type de contenu :

Type de contenu Indexé en tant que Fonctionnalités
texte jetons, texte non modifié Les indexeurs peuvent extraire du texte brut à partir d’autres ressources Azure telles que Stockage Azure et Cosmos DB. Vous pouvez également envoyer (push) n’importe quel contenu JSON à un index. Pour modifier du texte à la volée, utilisez des analyseurs et des normaliseurs pour ajouter un traitement lexical pendant l’indexation. Les mappages de synonymes sont utiles si des documents sources sont manquants dans la terminologie qui peut être utilisée dans une requête.
texte vecteurs 1 Le texte peut être segmenté et vectorisé en externe, puis indexé en tant que champs vectoriels dans votre index.
image jetons, texte non modifié 2 Les compétences pour OCR et l’analyse d’image peuvent traiter des images pour la reconnaissance de texte ou les caractéristiques d’image. Les informations d’image sont converties en texte pouvant faire l’objet d’une recherche et ajoutées à l’index. Les compétences ont une exigence d’indexeur.
image vecteurs 1 Les images peuvent être vectorisées en externe pour une représentation mathématique du contenu de l’image, puis indexées en tant que champs vectoriels dans votre index. Vous pouvez utiliser un modèle open source comme OpenAI CLIP pour vectoriser du texte et des images dans le même espace incorporé.

1 La fonctionnalité en disponibilité générale de la prise en charge de vecteurs nécessite d’appeler d’autres bibliothèques ou modèles pour la segmentation et la vectorisation des données. Toutefois, la vectorisation intégrée (préversion) incorpore ces étapes. Pour obtenir des exemples de code montrant les deux approches, consultez le référentiel azure-search-vectors.

2Les compétences sont intégrées pour l’enrichissement par IA. Pour l’OCR et l’analyse des images, le pipeline d’indexation effectue un appel interne aux API Azure AI Vision. Ces compétences transmettent une image extraite à Azure AI pour le traitement et reçoivent la sortie sous forme de texte indexé par Recherche Azure AI.

Les vecteurs offrent le meilleur aménagement pour des contenus différents (plusieurs formats de fichiers et langues), car le contenu est exprimé universellement en représentations mathématiques. Les vecteurs prennent également en charge la recherche de similarité : correspondance sur les coordonnées les plus similaires à la requête vectorielle. Par rapport à la recherche par mot clé (ou recherche de termes) qui correspond aux termes sous forme de jetons, la recherche de similarité est plus nuancé. Il est préférable de choisir s’il existe des exigences d’ambiguïté ou d’interprétation dans le contenu ou dans les requêtes.

Une fois vos données dans un index de recherche, vous utilisez les fonctionnalités de requête de Recherche Azure AI pour récupérer du contenu.

Dans un modèle non-RAG, les requêtes effectuent un aller-retour à partir d’un client de recherche. La requête est envoyée, elle s’exécute sur un moteur de recherche et la réponse est retournée à l’application cliente. La réponse, ou les résultats de la recherche, se composent exclusivement de contenu textuel trouvé dans votre index.

Dans un modèle RAG, les requêtes et les réponses sont coordonnées entre le moteur de recherche et le LLM. La question ou la requête d’un utilisateur est transférée à la fois au moteur de recherche et au LLM en tant qu’invite. Les résultats de la recherche reviennent du moteur de recherche et sont redirigés vers un LLM. La réponse qui retourne à l’utilisateur est l’IA générative, soit une addition ou une réponse du LLM.

Il n’existe aucun type de requête dans Recherche Azure AI, même la recherche sémantique ou vectorielle, qui compose de nouvelles réponses. Seul le LLM fournit l’IA générative. Voici les fonctionnalités de Recherche Azure AI utilisées pour formuler des requêtes :

Fonctionnalité de requête Objectif Pourquoi l'utiliser ?
Syntaxe Lucene simple ou complète Exécution de requêtes sur du texte et du contenu numérique non vectoriel La recherche en texte intégral est idéale pour les correspondances exactes, plutôt que pour les correspondances similaires. Les requêtes de recherche en texte intégral sont classées à l’aide de l’algorithme BM25 et prennent en charge le réglage de la pertinence via les profils de score. Il prend également en charge les filtres et les facettes.
Filtres et facettes S’applique uniquement aux champs de texte ou aux champs numériques (non vectoriel). Réduit la surface de recherche en fonction des critères d’inclusion ou d’exclusion. Ajoute de la précision à vos requêtes.
Classement sémantique Classe à nouveau un jeu de résultats BM25 à l’aide de modèles sémantiques. Produit des légendes et des réponses de courtes qui sont utiles en tant qu’entrées LLM. Plus facile que les profils de score, et en fonction de votre contenu, une technique plus fiable pour le réglage de pertinence.
Recherche vectorielle Exécution de requête sur des champs vectoriels pour la recherche de similarité, où la chaîne de requête est un ou plusieurs vecteurs. Les vecteurs peuvent représenter tous les types de contenu, dans n’importe quelle langue.
Recherche hybride Combine une ou toutes les techniques de requête susmentionnées. Les requêtes vectorielles et non vectorielles s’exécutent en parallèle, tout en étant retournées dans un jeu de résultats unifié. Les gains de précision et de rappel les plus significatifs sont réalisés par le biais de requêtes hybrides.

Structurer la réponse de requête

La réponse d’une requête fournit l’entrée au LLM, de sorte que la qualité de vos résultats de recherche est essentielle au succès. Les résultats sont un jeu de lignes tabulaires. La composition ou la structure des résultats dépend des éléments suivants :

  • Les champs qui déterminent quelles parties de l’index sont incluses dans la réponse.
  • Les lignes qui représentent une correspondance à partir de l’index.

Les champs apparaissent dans les résultats de recherche lorsque l’attribut est « récupérable ». Une définition de champ dans le schéma d’index a des attributs et ils déterminent si un champ est utilisé dans une réponse. Seuls les champs « récupérables » sont retournés dans des résultats de requête de texte intégral ou vectoriel. Par défaut, tous les champs « récupérables » sont retournés, mais vous pouvez utiliser « sélectionner » pour spécifier un sous-ensemble. En plus d’être « récupérable », il n’existe aucune restriction sur le champ. Les champs peuvent être de n’importe quelle longueur ou type. En ce qui concerne la longueur, il n’existe aucune limite de longueur de champ maximale dans Recherche Azure AI, mais il existe des limites sur la taille d’une requête d’API.

Les lignes sont des correspondances avec la requête, classées par pertinence, similarité ou les deux. Par défaut, les résultats sont limités aux 50 premières correspondances pour la recherche en texte intégral ou les correspondances k plus proche voisin pour la recherche vectorielle. Vous pouvez modifier les valeurs par défaut pour augmenter ou diminuer la limite jusqu’à 1 000 documents maximum. Vous pouvez également utiliser les paramètres de pagination Top et Skip pour récupérer les résultats sous forme de série de résultats paginés.

Classer par pertinence

Lorsque vous travaillez avec des processus complexes, une grande quantité de données et des attentes pour les réponses en millisecondes, il est essentiel que chaque étape ajoute de la valeur et améliore la qualité du résultat final. Côté récupération des informations, le paramétrage de pertinence est une activité qui améliore la qualité des résultats envoyés au LLM. Seuls les documents correspondants les plus pertinents ou les plus similaires doivent être inclus dans les résultats.

La pertinence s’applique à la recherche par mot clé (non vectoriel) et aux requêtes hybrides (à travers des champs non vectoriels). Dans Recherche Azure AI, il n’existe aucun réglage de pertinence pour la recherche de similarité et les requêtes vectorielles. Le classement BM25 est l’algorithme de classement pour la recherche en texte intégral.

Le réglage de la pertinence est pris en charge par le biais de fonctionnalités qui améliorent le classement BM25. Ces approches comprennent ce qui suit :

  • Des profils de score qui augmentent le score de recherche si des correspondances sont trouvées dans un champ de recherche spécifique ou sur d’autres critères.
  • Un classement sémantique qui classe à nouveau un jeu de résultats BM25, à l’aide de modèles sémantiques de Bing pour réorganiser les résultats pour une meilleure adéquation sémantique à la requête d’origine.

Dans les tests de comparaison et de référence, les requêtes hybrides avec des champs de texte et de vecteur, complétées par le classement sémantique sur les résultats classés par BM25, produisent les résultats les plus pertinents.

Exemple de code d’une requête Recherche Azure AI pour les scénarios RAG

Le code suivant est copié à partir du fichier retrievethenread.py à partir d’un site de démonstration. Il produit content pour le LLM à partir des résultats de la recherche de requête hybride. Vous pouvez écrire une requête plus simple, mais cet exemple comprend la recherche vectorielle et la recherche par mot clé avec le reclassement sémantique et la vérification orthographique. Dans la démonstration, cette requête est utilisée pour obtenir le contenu initial.

# Use semantic ranker if requested and if retrieval mode is text or hybrid (vectors + text)
if overrides.get("semantic_ranker") and has_text:
    r = await self.search_client.search(query_text,
                                  filter=filter,
                                  query_type=QueryType.SEMANTIC,
                                  query_language="en-us",
                                  query_speller="lexicon",
                                  semantic_configuration_name="default",
                                  top=top,
                                  query_caption="extractive|highlight-false" if use_semantic_captions else None,
                                  vector=query_vector,
                                  top_k=50 if query_vector else None,
                                  vector_fields="embedding" if query_vector else None)
else:
    r = await self.search_client.search(query_text,
                                  filter=filter,
                                  top=top,
                                  vector=query_vector,
                                  top_k=50 if query_vector else None,
                                  vector_fields="embedding" if query_vector else None)
if use_semantic_captions:
    results = [doc[self.sourcepage_field] + ": " + nonewlines(" . ".join([c.text for c in doc['@search.captions']])) async for doc in r]
else:
    results = [doc[self.sourcepage_field] + ": " + nonewlines(doc[self.content_field]) async for doc in r]
content = "\n".join(results)

Code d’intégration et LLM

Une solution RAG qui inclut Recherche Azure AI nécessite d’autres composants et du code pour créer une solution complète. Alors que les sections précédentes ont abordé la récupération d’informations par le biais de Recherche Azure AI et quelles fonctionnalités sont utilisées pour créer et interroger du contenu pouvant faire l’objet d’une recherche, cette section présente l’intégration et l’interaction LLM.

Les notebooks dans les référentiels de démonstration constituent un point de départ idéal, car ils affichent des modèles pour transmettre des résultats de recherche à un LLM. La plupart du code d’une solution RAG se compose d’appels au LLM. Vous devez donc développer une compréhension du fonctionnement de ces API, qui est en dehors de l’étendue de cet article.

Le bloc-cellules suivant dans les notebooks chat-read-retrieve-read.ipynb affiche les appels de recherche dans le contexte d’une session de conversation :

# Execute this cell multiple times updating user_input to accumulate chat history
user_input = "Does my plan cover annual eye exams?"

# Exclude category, to simulate scenarios where there's a set of docs you can't see
exclude_category = None

if len(history) > 0:
    completion = openai.Completion.create(
        engine=AZURE_OPENAI_GPT_DEPLOYMENT,
        prompt=summary_prompt_template.format(summary="\n".join(history), question=user_input),
        temperature=0.7,
        max_tokens=32,
        stop=["\n"])
    search = completion.choices[0].text
else:
    search = user_input

# Alternatively simply use search_client.search(q, top=3) if not using semantic ranking
print("Searching:", search)
print("-------------------")
filter = "category ne '{}'".format(exclude_category.replace("'", "''")) if exclude_category else None
r = search_client.search(search, 
                         filter=filter,
                         query_type=QueryType.SEMANTIC, 
                         query_language="en-us", 
                         query_speller="lexicon", 
                         semantic_configuration_name="default", 
                         top=3)
results = [doc[KB_FIELDS_SOURCEPAGE] + ": " + doc[KB_FIELDS_CONTENT].replace("\n", "").replace("\r", "") for doc in r]
content = "\n".join(results)

prompt = prompt_prefix.format(sources=content) + prompt_history + user_input + turn_suffix

completion = openai.Completion.create(
    engine=AZURE_OPENAI_CHATGPT_DEPLOYMENT, 
    prompt=prompt, 
    temperature=0.7, 
    max_tokens=1024,
    stop=["<|im_end|>", "<|im_start|>"])

prompt_history += user_input + turn_suffix + completion.choices[0].text + "\n<|im_end|>" + turn_prefix
history.append("user: " + user_input)
history.append("assistant: " + completion.choices[0].text)

print("\n-------------------\n".join(history))
print("\n-------------------\nPrompt:\n" + prompt)

Comment commencer

  • Passez en revue les concepts et stratégies d’indexation pour déterminer la façon dont vous souhaitez ingérer et actualiser des données. Déterminez s’il faut utiliser la recherche vectorielle, la recherche par mot clé ou la recherche hybride. Le type de contenu que vous devez rechercher et le type de requêtes que vous souhaitez exécuter détermine la conception d’index.

  • Vérifiez la création de requêtes pour en savoir plus sur la syntaxe et les exigences des demandes de recherche.

Remarque

Certaines fonctionnalités Recherche Azure AI sont destinées à l’interaction humaine et ne sont pas utiles dans un modèle RAG. Plus précisément, vous pouvez ignorer l’autocomplétion et les suggestions. D’autres fonctionnalités telles que les facettes et orderby peuvent être utiles, mais elles seraient rares dans un scénario RAG.

Voir aussi