Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Questa esercitazione illustra come creare una soluzione di generazione avanzata di recupero usando Azure Content Understanding in Foundry Tools. Vengono illustrati i passaggi principali per creare un sistema RAG sicuro, offre suggerimenti per migliorare la pertinenza e l'accuratezza e illustra come connettersi ad altri servizi di Azure. Alla fine, è possibile usare Content Understanding per gestire i dati categorici, migliorare il recupero e aiutare i modelli di intelligenza artificiale a fornire risposte accurate e significative.
Esercizi inclusi in questa esercitazione
- Creare analizzatori. Informazioni su come creare analizzatori riutilizzabili per estrarre contenuto strutturato da dati multifunzionali usando l'estrazione di contenuto.
- Generare metadati di destinazione con l'estrazione dei campi. Informazioni su come usare l'intelligenza artificiale per generare altri metadati, ad esempio riepiloghi o argomenti chiave, per arricchire il contenuto estratto.
- Pre-elaborare il contenuto estratto. Esplorare i modi per trasformare il contenuto estratto in incorporamenti vettoriali per la ricerca semantica e il recupero.
- Progettare un indice unificato. Sviluppare un indice unificato di Azure AI Search che integri e organizzi dati multimodali per un recupero efficiente.
- Recupero di blocchi semantici. Estrarre informazioni contestualmente rilevanti per fornire risposte più precise e significative alle query degli utenti.
- Interagire con i dati usando i modelli di chat Usare i modelli di chat OpenAI di Azure per interagire con i dati indicizzati, abilitare la ricerca conversazionale, l'esecuzione di query e le risposte.
Prerequisiti
Per iniziare, è necessaria una sottoscrizione di Azure attiva. Se non si dispone di un account di Azure, è possibile creare una sottoscrizione gratuita.
Dopo aver creato la sottoscrizione di Azure, creare una risorsa Microsoft Foundry nel portale di Azure.
Questa risorsa è elencata in Foundry>Foundry nel portale.
Risorsa di Ricerca Intelligenza Artificiale di Azure: Configurare una risorsa di Ricerca Intelligenza Artificiale di Azure per abilitare l'indicizzazione e il recupero di dati multimodali.
Distribuzione del modello di chat OpenAI di Azure: Distribuire un modello di chat OpenAI di Azure che consente interazioni conversazionali.
Distribuzione del modello di incorporamento: Assicurarsi di avere un modello di incorporamento distribuito per generare rappresentazioni vettoriali per la ricerca semantica.
Versione API: Questa esercitazione usa la versione più recente dell'API di anteprima.
Ambiente Python: Installare Python 3.11 per eseguire gli esempi di codice e gli script forniti.
Questa esercitazione si basa su questo codice di esempio, che è disponibile nel notebook Python. Seguire readme per creare risorse essenziali, concedere alle risorse i ruoli di controllo di accesso appropriati (IAM) e installare tutti i pacchetti necessari per questa esercitazione.
I dati multimodali usati in questo tutorial sono costituiti da documenti, immagini, audio e video. Sono progettati per guidare l'utente nel processo di creazione di una soluzione RAG affidabile con La comprensione dei contenuti di Azure in Foundry Tools.
Estrarre dati
La generazione aumentata di recupero (RAG*) è un metodo che migliora la funzionalità dei modelli di linguaggio di grandi dimensioni integrando dati da fonti esterne di conoscenze. La creazione di una soluzione RAG affidabile inizia con l'estrazione e la strutturazione dei dati da diversi tipi di contenuto. Azure Content Understanding offre tre componenti chiave per facilitare questo processo: estrazione del contenuto, estrazione dei campi e analizzatori. Insieme, questi componenti costituiscono la base per la creazione di una pipeline di dati unificata, riutilizzabile e migliorata per i flussi di lavoro RAG.
Passaggi di implementazione
Per implementare l'estrazione dei dati in Informazioni sul contenuto, seguire questa procedura:
Creare un analizzatore: Definire un analizzatore usando le API REST o gli esempi di codice Python.
Eseguire l'estrazione del contenuto: Usare l'analizzatore per elaborare i file ed estrarre contenuto strutturato.
(Facoltativo) Migliorare con l'estrazione dei campi: Facoltativamente, specificare i campi generati dall'intelligenza artificiale per arricchire il contenuto estratto con metadati aggiunti.
Creare analizzatori
Gli analizzatori sono componenti riutilizzabili in Content Understanding che semplificano il processo di estrazione dei dati. Dopo aver creato un analizzatore, può essere usato ripetutamente per elaborare i file ed estrarre il contenuto o i campi in base a schemi predefiniti. Un analizzatore funge da progetto per l'elaborazione dei dati, garantendo coerenza ed efficienza tra più file e tipi di contenuto.
Gli esempi di codice seguenti illustrano come creare analizzatori per ogni modalità, specificando i dati strutturati da estrarre, ad esempio campi chiave, riepiloghi o classificazioni. Questi analizzatori fungono da base per estrarre e arricchire il contenuto nella soluzione RAG.
Caricare tutte le variabili di ambiente e le librerie necessarie da Langchain
import os
from dotenv import load_dotenv
load_dotenv()
# Load and validate Foundry Tools 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))
Esempio di codice: Creare l'analizzatore
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}")
Nota: Gli schemi di estrazione dei campi sono facoltativi e non sono necessari per l'estrazione del contenuto. Per eseguire l'estrazione del contenuto e creare analizzatori senza definire schemi di campo, specificare solo l'ID analizzatore e il file da analizzare.
Gli schemi sono stati usati in questa esercitazione. Ecco un esempio di definizione dello schema
Nell’esempio seguente viene definito uno schema per estrarre informazioni di base da una fattura.
{
"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"
}
}
}
}
}
}
}
Estrazione di contenuti e campi
L'estrazione del contenuto è il primo passaggio del processo di implementazione rag. Trasforma i dati non elaborati in formati strutturati e ricercabili. Questo passaggio fondamentale garantisce che il contenuto sia organizzato e pronto per l'indicizzazione e il recupero. Mentre l'estrazione del contenuto fornisce la baseline per l'indicizzazione e il recupero, potrebbe non soddisfare completamente esigenze specifiche del dominio o fornire informazioni contestuali più approfondite. Altre informazioni sulle funzionalità di estrazione del contenuto per ogni modalità.
L'estrazione dei campi si basa sull'estrazione di contenuto usando l'intelligenza artificiale per generare altri metadati che arricchiscono la knowledge base. Questo passaggio consente di definire campi personalizzati personalizzati in base al caso d'uso specifico, consentendo un recupero più preciso e una maggiore rilevanza per la ricerca. L'estrazione dei campi integra l'estrazione del contenuto aggiungendo profondità e contesto, rendendo i dati più interattivi per gli scenari RAG. Altre informazioni sulle funzionalità di estrazione dei campi per ogni modalità.
Con gli analizzatori creati per ogni modalità, è ora possibile elaborare i file per estrarre contenuto strutturato e metadati generati dall'intelligenza artificiale in base agli schemi definiti. Questa sezione illustra come usare gli analizzatori per analizzare i dati multimodali, e fornisce un esempio dei risultati restituiti dalle API. Questi risultati illustrano la trasformazione dei dati non elaborati in informazioni dettagliate interattive, formando le basi per l'indicizzazione, il recupero e i flussi di lavoro RAG.
Analizzare i file
#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)
Risultati dell'estrazione
Gli esempi di codice seguenti illustrano l'output del contenuto e dell'estrazione di campi usando Azure Content Understanding. La risposta JSON contiene più campi, ognuno dei quali serve uno scopo specifico per rappresentare i dati estratti.
Campo Markdown: il
markdowncampo fornisce una rappresentazione semplificata e leggibile del contenuto estratto. È particolarmente utile per le anteprime rapide o per l'integrazione dei dati estratti in applicazioni che richiedono testo strutturato, ad esempio knowledge base o interfacce di ricerca. Ad esempio, con un documento, ilmarkdowncampo può includere intestazioni, paragrafi e altri elementi strutturali formattati per semplificare la leggibilità.Output JSON: l'output JSON completo fornisce una rappresentazione completa dei dati estratti, inclusi il contenuto e i metadati generati durante il processo di estrazione, incluse le proprietà seguenti:
- Campi: Metadati generati dall'intelligenza artificiale, ad esempio riepiloghi, argomenti chiave o classificazioni, personalizzati in base allo schema specifico definito nell'analizzatore.
- Punteggio di attendibilità: Indicatori dell'affidabilità dei dati estratti.
- Si estende a: informazioni sulla posizione dei contenuti estratti all’interno del file di origine.
- Metadati aggiuntivi: Dettagli quali numeri di pagina, dimensioni e altre informazioni contestuali.
Il risultato mostra l'estrazione di intestazioni, paragrafi, tabelle e altri elementi strutturali mantenendo l'organizzazione logica del contenuto. Inoltre, dimostra la capacità di estrarre campi chiave, fornendo estrazioni concise da materiali estesi.
{
"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": [
{
...
},
]
}
],
}
]
}
}
Output della pre-elaborazione da parte di comprensione dei contenuti
Dopo aver estratto i dati usando Azure Content Understanding, il passaggio successivo consiste nel preparare l'output di analisi per l'incorporamento all'interno di un sistema di ricerca. La pre-elaborazione dell'output garantisce che il contenuto estratto venga trasformato in un formato adatto per l'indicizzazione e il recupero. Questo passaggio comporta la conversione dell'output JSON dagli analizzatori in stringhe strutturate, mantenendo sia il contenuto che i metadati per l'integrazione senza problemi nei flussi di lavoro downstream.
L'esempio seguente illustra come pre-elaborare i dati di output degli analizzatori, inclusi documenti, immagini, audio e video. Il processo di conversione di ogni output JSON in una stringa strutturata consente di incorporare i dati in un sistema di ricerca basato su vettori, consentendo un recupero efficiente e flussi di lavoro RAG avanzati.
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)
Incorporare e indicizzare il contenuto estratto
Dopo aver pre-elaborato i dati estratti da Azure Content Understanding, il passaggio successivo consiste nell'incorporare e indicizzare il contenuto per un recupero efficiente. Questo passaggio implica la trasformazione delle stringhe strutturate in incorporamenti vettoriali usando un modello di incorporamento e l'archiviazione in un sistema di Ricerca di intelligenza artificiale di Azure. Incorporando il contenuto, si abilitano le funzionalità di ricerca semantica, consentendo al sistema di recuperare le informazioni più rilevanti in base al significato anziché alle corrispondenze esatte delle parole chiave. Questo passaggio è fondamentale per la creazione di una soluzione RAG affidabile, in quanto garantisce che il contenuto estratto sia ottimizzato per flussi di lavoro avanzati di ricerca e recupero.
# 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)
Recupero di blocchi semantici
Con il contenuto estratto incorporato e indicizzato, il passaggio successivo consiste nell'usare la potenza della somiglianza e della ricerca vettoriale per recuperare i blocchi di informazioni più rilevanti. In questa sezione viene illustrato come eseguire ricerche sia di somiglianza che di ricerca ibrida, consentendo al sistema di visualizzare il contenuto in base al significato semantico anziché alle corrispondenze esatte delle parole chiave. Recuperando blocchi contestualmente rilevanti, è possibile migliorare la precisione dei flussi di lavoro RAG e fornire risposte più accurate e significative alle query utente.
# 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)
Usare OpenAI per interagire con i dati
Con il contenuto estratto incorporato e indicizzato, il passaggio finale nella creazione di una soluzione RAG affidabile consiste nell'abilitare interazioni conversazionali usando modelli di chat OpenAI. Questa sezione illustra come eseguire query sui dati indicizzati e applicare modelli di chat OpenAI per fornire risposte concise e contestualmente avanzate. Integrando l'intelligenza artificiale conversazionale, è possibile trasformare la soluzione RAG in un sistema interattivo che offre informazioni dettagliate significative e migliora il coinvolgimento degli utenti. Gli esempi seguenti illustrano come configurare un flusso di conversazione con aumento del recupero, garantendo una perfetta integrazione tra i dati e i modelli di chat 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)