Notes
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.
Ce tutoriel explique comment créer une solution de génération augmentée de récupération (RAG) à l’aide d’Azure AI Content Understanding. Il couvre les principales étapes de création d’un système RAG solide, propose des conseils pour améliorer la pertinence et la précision, et montre comment se connecter à d’autres services Azure. À la fin, vous pouvez utiliser Content Understanding pour gérer les données modales, améliorer la récupération et aider les modèles IA à fournir des réponses précises et significatives.
Exercices inclus dans ce didacticiel
- Créez des analyseurs. Découvrez comment créer des analyseurs réutilisables pour extraire du contenu structuré à partir de données modales à l’aide de l’extraction de contenu.
- Générez des métadonnées ciblées avec l’extraction de champs. Découvrez comment utiliser l’IA pour générer d’autres métadonnées, telles que des résumés ou des rubriques clés, pour enrichir le contenu extrait.
- Prétraitement du contenu extrait. Explorez les façons de transformer le contenu extrait en incorporations vectorielles pour la recherche sémantique et la récupération.
- Concevoir un index unifié. Développez un index Azure AI Search unifié qui intègre et organise les données modales pour une récupération efficace.
- Récupération de segment sémantique. Extrayez des informations contextuellement pertinentes pour fournir des réponses plus précises et significatives aux requêtes utilisateur.
- Interagir avec des données à l’aide de modèles de conversation Utilisez des modèles de conversation Azure OpenAI pour interagir avec vos données indexées, en activant la recherche conversationnelle, l’interrogation et la réponse.
Conditions préalables
Pour commencer, vous aurez besoin d’un abonnement Azure actif. Si vous n’avez pas de compte Azure, vous pouvez créer un compte gratuit.
Une fois que vous avez votre abonnement Azure, créez une ressource Azure AI Foundry dans le portail Azure.
Cette ressource est répertoriée sous AI Foundry>AI Foundry dans le portail.
Ressource Recherche d’IA Azure : Configurez une ressource Recherche d’IA Azure pour permettre l’indexation et la récupération de données modales.
Déploiement du modèle de conversation Azure OpenAI : Déployez un modèle de conversation Azure OpenAI qui permet des interactions conversationnelles.
Déploiement du modèle d’incorporation : Vérifiez que vous disposez d’un modèle d’incorporation déployé pour générer des représentations vectorielles pour la recherche sémantique.
Version de l’API : Ce tutoriel utilise la dernière version de l’API en préversion.
Environnement Python : Installez Python 3.11 pour exécuter les exemples et scripts de code fournis.
Ce tutoriel est basé sur cet exemple de code qui peut être trouvé dans notre notebook Python. Suivez le fichier README pour créer des ressources essentielles, accorder aux ressources les rôles de contrôle d’accès appropriés (IAM) et installer tous les packages nécessaires pour ce didacticiel.
Les données modales utilisées dans ce didacticiel se composent de documents, d’images, d’audio et de vidéos. Ils sont conçus pour vous guider tout au long du processus de création d’une solution RAG robuste avec Azure AI Content Understanding.
Extraire des données
La génération d’extraction augmentée (RAG*) est une méthode qui améliore les fonctionnalités des modèles de langage volumineux (LLM) en intégrant des données provenant de sources de connaissances externes. La création d’une solution RAG modale robuste commence par extraire et structurer des données à partir de différents types de contenu. Azure AI Content Understanding fournit trois composants clés pour faciliter ce processus : extraction de contenu, extraction de champs et analyseurs. Ensemble, ces composants constituent la base de la création d’un pipeline de données unifié, réutilisable et amélioré pour les flux de travail RAG.
Étapes d’implémentation
Pour implémenter l’extraction de données dans Content Understanding, procédez comme suit :
Créer un analyseur : Définissez un analyseur à l’aide d’API REST ou de nos exemples de code Python.
Effectuer l’extraction de contenu : Utilisez l’analyseur pour traiter les fichiers et extraire du contenu structuré.
(Facultatif) Améliorer avec l’extraction de champs : Si vous le souhaitez, spécifiez des champs générés par l’IA pour enrichir le contenu extrait avec des métadonnées ajoutées.
Créer des analyseurs
Les analyseurs sont des composants réutilisables dans Content Understanding qui simplifient le processus d’extraction de données. Une fois qu’un analyseur est créé, il peut être utilisé à plusieurs reprises pour traiter des fichiers et extraire du contenu ou des champs en fonction de schémas prédéfinis. Un analyseur agit comme un blueprint pour la façon dont les données doivent être traitées, garantissant ainsi la cohérence et l’efficacité entre plusieurs fichiers et types de contenu.
Les exemples de code suivants montrent comment créer des analyseurs pour chaque modalité, en spécifiant les données structurées à extraire, telles que les champs clés, les résumés ou les classifications. Ces analyseurs servent de base pour extraire et enrichir du contenu dans votre solution RAG.
Charger toutes les variables d’environnement et les bibliothèques nécessaires à partir de Langchain
import os
from dotenv import load_dotenv
load_dotenv()
# Load and validate Azure AI Services configs
AZURE_AI_SERVICE_ENDPOINT = os.getenv("AZURE_AI_SERVICE_ENDPOINT")
AZURE_AI_SERVICE_API_VERSION = os.getenv("AZURE_AI_SERVICE_API_VERSION") or "2024-12-01-preview"
AZURE_DOCUMENT_INTELLIGENCE_API_VERSION = os.getenv("AZURE_DOCUMENT_INTELLIGENCE_API_VERSION") or "2024-11-30"
# Load and validate Azure OpenAI configs
AZURE_OPENAI_ENDPOINT = os.getenv("AZURE_OPENAI_ENDPOINT")
AZURE_OPENAI_CHAT_DEPLOYMENT_NAME = os.getenv("AZURE_OPENAI_CHAT_DEPLOYMENT_NAME")
AZURE_OPENAI_CHAT_API_VERSION = os.getenv("AZURE_OPENAI_CHAT_API_VERSION") or "2024-08-01-preview"
AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME = os.getenv("AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME")
AZURE_OPENAI_EMBEDDING_API_VERSION = os.getenv("AZURE_OPENAI_EMBEDDING_API_VERSION") or "2023-05-15"
# Load and validate Azure Search Services configs
AZURE_SEARCH_ENDPOINT = os.getenv("AZURE_SEARCH_ENDPOINT")
AZURE_SEARCH_INDEX_NAME = os.getenv("AZURE_SEARCH_INDEX_NAME") or "sample-doc-index"
# Import libraries from Langchain
from langchain import hub
from langchain_openai import AzureChatOpenAI
from langchain_openai import AzureOpenAIEmbeddings
from langchain.schema import StrOutputParser
from langchain.schema.runnable import RunnablePassthrough
from langchain.text_splitter import MarkdownHeaderTextSplitter
from langchain.vectorstores.azuresearch import AzureSearch
from langchain_core.prompts import ChatPromptTemplate
from langchain.schema import Document
import requests
import json
import sys
import uuid
from pathlib import Path
from dotenv import find_dotenv, load_dotenv
from azure.identity import DefaultAzureCredential, get_bearer_token_provider
# Add the parent directory to the path to use shared modules
parent_dir = Path(Path.cwd()).parent
sys.path.append(str(parent_dir))
Exemple de code : créer un analyseur
from pathlib import Path
from python.content_understanding_client import AzureContentUnderstandingClient
credential = DefaultAzureCredential()
token_provider = get_bearer_token_provider(credential, "https://cognitiveservices.azure.com/.default")
#set analyzer configs
analyzer_configs = [
{
"id": "doc-analyzer" + str(uuid.uuid4()),
"template_path": "../analyzer_templates/content_document.json",
"location": Path("../data/sample_layout.pdf"),
},
{
"id": "image-analyzer" + str(uuid.uuid4()),
"template_path": "../analyzer_templates/image_chart_diagram_understanding.json",
"location": Path("../data/sample_report.pdf"),
},
{
"id": "audio-analyzer" + str(uuid.uuid4()),
"template_path": "../analyzer_templates/call_recording_analytics.json",
"location": Path("../data/callCenterRecording.mp3"),
},
{
"id": "video-analyzer" + str(uuid.uuid4()),
"template_path": "../analyzer_templates/video_content_understanding.json",
"location": Path("../data/FlightSimulator.mp4"),
},
]
# Create Content Understanding client
content_understanding_client = AzureContentUnderstandingClient(
endpoint=AZURE_AI_SERVICE_ENDPOINT,
api_version=AZURE_AI_SERVICE_API_VERSION,
token_provider=token_provider,
x_ms_useragent="azure-ai-content-understanding-python/content_extraction", # This header is used for sample usage telemetry, please comment out this line if you want to opt out.
)
# Iterate through each config and create an analyzer
for analyzer in analyzer_configs:
analyzer_id = analyzer["id"]
template_path = analyzer["template_path"]
try:
# Create the analyzer using the content understanding client
response = content_understanding_client.begin_create_analyzer(
analyzer_id=analyzer_id,
analyzer_template_path=template_path
)
result = content_understanding_client.poll_result(response)
print(f"Successfully created analyzer: {analyzer_id}")
except Exception as e:
print(f"Failed to create analyzer: {analyzer_id}")
print(f"Error: {e}")
Note: Les schémas d’extraction de champs sont facultatifs et ne sont pas obligatoires pour effectuer l’extraction de contenu. Pour exécuter l’extraction de contenu et créer des analyseurs sans définir de schémas de champ, fournissez simplement l’ID d’analyseur et le fichier à analyser.
Les schémas ont été utilisés dans ce didacticiel. Voici un exemple de définition de schéma
Dans l’exemple suivant, nous définissons un schéma pour extraire des informations de base à partir d’un document de facture.
{
"description": "Sample invoice analyzer",
"scenario": "document",
"config": {
"returnDetails": true
},
"fieldSchema": {
"fields": {
"VendorName": {
"type": "string",
"method": "extract",
"description": "Vendor issuing the invoice"
},
"Items": {
"type": "array",
"method": "extract",
"items": {
"type": "object",
"properties": {
"Description": {
"type": "string",
"method": "extract",
"description": "Description of the item"
},
"Amount": {
"type": "number",
"method": "extract",
"description": "Amount of the item"
}
}
}
}
}
}
}
Extraction de contenu et de champs
L’extraction de contenu est la première étape du processus d’implémentation DE RAG. Il transforme les données modales brutes en formats structurés et pouvant faire l’objet d’une recherche. Cette étape fondamentale garantit que le contenu est organisé et prêt pour l’indexation et la récupération. Même si l’extraction de contenu fournit la base de référence pour l’indexation et la récupération, elle peut ne pas répondre entièrement aux besoins spécifiques au domaine ou fournir des insights contextuels plus approfondis. En savoir plus sur les fonctionnalités d’extraction de contenu pour chaque modalité.
L’extraction de champs s’appuie sur l’extraction de contenu à l’aide de l’IA pour générer d’autres métadonnées qui enrichissent la base de connaissances. Cette étape vous permet de définir des champs personnalisés adaptés à votre cas d’usage spécifique, ce qui permet une récupération plus précise et une pertinence accrue de la recherche. L’extraction de champs complète l’extraction de contenu en ajoutant de la profondeur et du contexte, ce qui rend les données plus exploitables pour les scénarios RAG. En savoir plus sur les fonctionnalités d’extraction de champs pour chaque modalité.
Avec les analyseurs créés pour chaque modalité, nous pouvons désormais traiter les fichiers pour extraire du contenu structuré et des métadonnées générées par l’IA en fonction des schémas définis. Cette section montre comment utiliser les analyseurs pour analyser les données modales et fournit un exemple des résultats retournés par les API. Ces résultats présentent la transformation des données brutes en insights actionnables, formant ainsi la base de l’indexation, de la récupération et des flux de travail RAG.
Analyser les fichiers
#Iterate through each analyzer created and analyze content for each modality
analyzer_results =[]
extracted_markdown = []
analyzer_content = []
for analyzer in analyzer_configs:
analyzer_id = analyzer["id"]
template_path = analyzer["template_path"]
file_location = analyzer["location"]
try:
# Analyze content
response = content_understanding_client.begin_analyze(analyzer_id, file_location)
result = content_understanding_client.poll_result(response)
analyzer_results.append({"id":analyzer_id, "result": result["result"]})
analyzer_content.append({"id": analyzer_id, "content": result["result"]["contents"]})
except Exception as e:
print(e)
print("Error in creating analyzer. Please double-check your analysis settings.\nIf there is a conflict, you can delete the analyzer and then recreate it, or move to the next cell and use the existing analyzer.")
print("Analyzer Results:")
for analyzer_result in analyzer_results:
print(f"Analyzer ID: {analyzer_result['id']}")
print(json.dumps(analyzer_result["result"], indent=2))
# Delete the analyzer if it is no longer needed
#content_understanding_client.delete_analyzer(ANALYZER_ID)
Résultats d’extraction
Les exemples de code suivants illustrent la sortie du contenu et de l’extraction de champs à l’aide d’Azure AI Content Understanding. La réponse JSON contient plusieurs champs, chacun servant un objectif spécifique dans la représentation des données extraites.
Champ Markdown : le
markdown
champ fournit une représentation simplifiée et lisible par l’homme du contenu extrait. Il est particulièrement utile pour les préversions rapides ou pour intégrer les données extraites dans des applications qui nécessitent du texte structuré, tel que des bases de connaissances ou des interfaces de recherche. Par exemple, avec un document, lemarkdown
champ peut inclure des en-têtes, des paragraphes et d’autres éléments structurels mis en forme pour faciliter la lisibilité.Sortie JSON : la sortie JSON complète fournit une représentation complète des données extraites, y compris le contenu et les métadonnées générées pendant le processus d’extraction, notamment les propriétés suivantes :
- Champs: Métadonnées générées par l’IA, telles que des résumés, des rubriques clés ou des classifications, adaptées au schéma spécifique défini dans l’analyseur.
- Scores de confiance : Indicateurs de fiabilité des données extraites.
- Étendues : Informations sur l’emplacement du contenu extrait dans le fichier source.
- Métadonnées supplémentaires : Détails tels que les numéros de page, les dimensions et d’autres informations contextuelles.
Le résultat montre l’extraction d’en-têtes, de paragraphes, de tables et d’autres éléments structurels tout en conservant l’organisation logique du contenu. En outre, il présente la capacité d'extraire des champs clés, en fournissant des extractions concises de documents longs.
{
"id": "bcf8c7c7-03ab-4204-b22c-2b34203ef5db",
"status": "Succeeded",
"result": {
"analyzerId": "training_document_analyzer",
"apiVersion": "2024-12-01-preview",
"createdAt": "2024-11-13T07:15:46Z",
"warnings": [],
"contents": [
{
"markdown": "CONTOSO LTD.\n\n\n# Contoso Training Topics\n\nContoso Headquarters...",
"fields": {
"ChapterTitle": {
"type": "string",
"valueString": "Risks and Compliance regulations",
"spans": [ { "offset": 0, "length": 12 } ],
"confidence": 0.941,
"source": "D(1,0.5729,0.6582,2.3353,0.6582,2.3353,0.8957,0.5729,0.8957)"
},
"ChapterAuthor": {
"type": "string",
"valueString": "John Smith",
"spans": [ { "offset": 0, "length": 12 } ],
"confidence": 0.941,
"source": "D(1,0.5729,0.6582,2.3353,0.6582,2.3353,0.8957,0.5729,0.8957)"
},
"ChapterPublishDate": {
"type": "Date",
"valueString": "04-11-2017",
"spans": [ { "offset": 0, "length": 12 } ],
"confidence": 0.941,
"source": "D(1,0.5729,0.6582,2.3353,0.6582,2.3353,0.8957,0.5729,0.8957)"
},
},
"kind": "document",
"startPageNumber": 1,
"endPageNumber": 1,
"unit": "inch",
"pages": [
{
"pageNumber": 1,
"angle": -0.0039,
"width": 8.5,
"height": 11,
"spans": [ { "offset": 0, "length": 1650 } ],
"words": [
{
....
},
],
"lines": [
{
...
},
]
}
],
}
]
}
}
Prétraitement des résultats de la compréhension du contenu
Une fois les données extraites à l’aide d’Azure AI Content Understanding, l’étape suivante consiste à préparer la sortie d’analyse pour l’incorporation dans un système de recherche. Le prétraitement de la sortie garantit que le contenu extrait est transformé en un format adapté à l’indexation et à la récupération. Cette étape implique la conversion de la sortie JSON des analyseurs en chaînes structurées, en préservant à la fois le contenu et les métadonnées pour une intégration transparente dans les flux de travail en aval.
L’exemple suivant montre comment prétraiter les données de sortie des analyseurs, notamment les documents, les images, l’audio et la vidéo. Le processus de conversion de chaque sortie JSON en chaîne structurée permet d’incorporer les données dans un système de recherche basé sur des vecteurs, ce qui permet une récupération efficace et des flux de travail RAG améliorés.
def convert_values_to_strings(json_obj):
return [str(value) for value in json_obj]
#process all content and convert to string
def process_allJSON_content(all_content):
# Initialize empty list to store string of all content
output = []
document_splits = [
"This is a json string representing a document with text and metadata for the file located in "+str(analyzer_configs[0]["location"])+" "
+ v
+ "```"
for v in convert_values_to_strings(all_content[0]["content"])
]
docs = [Document(page_content=v) for v in document_splits]
output += docs
#convert image json object to string and append file metadata to the string
image_splits = [
"This is a json string representing an image verbalization and OCR extraction for the file located in "+str(analyzer_configs[1]["location"])+" "
+ v
+ "```"
for v in convert_values_to_strings(all_content[1]["content"])
]
image = [Document(page_content=v) for v in image_splits]
output+=image
#convert audio json object to string and append file metadata to the string
audio_splits = [
"This is a json string representing an audio segment with transcription for the file located in "+str(analyzer_configs[2]["location"])+" "
+ v
+ "```"
for v in convert_values_to_strings(all_content[2]["content"])
]
audio = [Document(page_content=v) for v in audio_splits]
output += audio
#convert video json object to string and append file metadata to the string
video_splits = [
"The following is a json string representing a video segment with scene description and transcript for the file located in "+str(analyzer_configs[3]["location"])+" "
+ v
+ "```"
for v in convert_values_to_strings(all_content[3]["content"])
]
video = [Document(page_content=v) for v in video_splits]
output+=video
return output
all_splits = process_allJSON_content(analyzer_content)
print("There are " + str(len(all_splits)) + " documents.")
# Print the content of all doc splits
for doc in all_splits:
print(f"doc content", doc.page_content)
Incorporer et indexer du contenu extrait
Une fois que le prétraitement des données extraites d’Azure AI Content Understanding est terminé, l’étape suivante consiste à incorporer et à indexer le contenu pour une récupération efficace. Cette étape implique de transformer les chaînes structurées en incorporations vectorielles à l’aide d’un modèle d’incorporation et de les stocker dans un système Recherche d’IA Azure. En incorporant le contenu, vous activez les fonctionnalités de recherche sémantique, ce qui permet au système de récupérer les informations les plus pertinentes en fonction de la signification plutôt que des correspondances exactes des mots clés. Cette étape est essentielle pour la création d’une solution RAG robuste, car elle garantit que le contenu extrait est optimisé pour les flux de travail de recherche et de récupération avancés.
# Embed the splitted documents and insert into Azure Search vector store
def embed_and_index_chunks(docs):
aoai_embeddings = AzureOpenAIEmbeddings(
azure_deployment=AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME,
openai_api_version=AZURE_OPENAI_EMBEDDING_API_VERSION, # e.g., "2023-12-01-preview"
azure_endpoint=AZURE_OPENAI_ENDPOINT,
azure_ad_token_provider=token_provider
)
vector_store: AzureSearch = AzureSearch(
azure_search_endpoint=AZURE_SEARCH_ENDPOINT,
azure_search_key=None,
index_name=AZURE_SEARCH_INDEX_NAME,
embedding_function=aoai_embeddings.embed_query
)
vector_store.add_documents(documents=docs)
return vector_store
# embed and index the docs:
vector_store = embed_and_index_chunks(all_splits)
Récupération de segment sémantique
Avec le contenu extrait incorporé et indexé, l’étape suivante consiste à utiliser la puissance de la similarité et de la recherche vectorielle pour récupérer les blocs d’informations les plus pertinents. Cette section montre comment exécuter à la fois la similarité et les recherches hybrides, ce qui permet au système d’exposer du contenu en fonction de la signification sémantique plutôt que des correspondances exactes des mots clés. En récupérant des blocs contextuels pertinents, vous pouvez améliorer la précision de vos flux de travail RAG et fournir des réponses plus précises et significatives aux requêtes utilisateur.
# Set your query
query = "japan"
# Perform a similarity search
docs = vector_store.similarity_search(
query=query,
k=3,
search_type="similarity",
)
for doc in docs:
print(doc.page_content)
# Perform a hybrid search using the search_type parameter
docs = vector_store.hybrid_search(query=query, k=3)
for doc in docs:
print(doc.page_content)
Utiliser OpenAI pour interagir avec les données
Avec le contenu extrait incorporé et indexé, la dernière étape de la création d’une solution RAG robuste permet des interactions conversationnelles à l’aide de modèles de conversation OpenAI. Cette section montre comment interroger vos données indexées et appliquer des modèles de conversation OpenAI pour fournir des réponses concises et contextuellement enrichies. En intégrant l’IA conversationnelle, vous pouvez transformer votre solution RAG en un système interactif qui fournit des insights significatifs et améliore l’engagement des utilisateurs. Les exemples suivants vous guident tout au long de la configuration d’un flux conversationnel augmenté par récupération, ce qui garantit une intégration transparente entre vos données et les modèles de conversation OpenAI.
# Setup rag chain
prompt_str = """You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. If you don't know the answer, just say that you don't know. Use three sentences maximum and keep the answer concise.
Question: {question}
Context: {context}
Answer:"""
def setup_rag_chain(vector_store):
retriever = vector_store.as_retriever(search_type="similarity", k=3)
prompt = ChatPromptTemplate.from_template(prompt_str)
llm = AzureChatOpenAI(
openai_api_version=AZURE_OPENAI_CHAT_API_VERSION,
azure_deployment=AZURE_OPENAI_CHAT_DEPLOYMENT_NAME,
azure_ad_token_provider=token_provider,
temperature=0.7,
)
def format_docs(docs):
return "\n\n".join(doc.page_content for doc in docs)
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
return rag_chain
# Setup conversational search
def conversational_search(rag_chain, query):
print(rag_chain.invoke(query))
rag_chain = setup_rag_chain(vector_store)
while True:
query = input("Enter your query: ")
if query=="":
break
conversational_search(rag_chain, query)