Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
En este tutorial se explica cómo crear una solución de generación aumentada por recuperación (RAG) mediante Content Understanding de Azure AI. Trata los pasos clave para crear un sistema RAG sólido, ofrece sugerencias para mejorar la relevancia y la precisión, y muestra cómo conectarse con otros servicios de Azure. Al final, puede usar Content Understanding para controlar los datos multimodales, mejorar la recuperación y ayudar a los modelos de inteligencia artificial a proporcionar respuestas precisas y significativas.
Ejercicios incluidos en este tutorial
- Crear analizadores. Obtenga información sobre cómo crear analizadores reutilizables para extraer contenido estructurado de datos multimodales mediante la extracción de contenido.
- Genere metadatos de destino con extracción de campos. Descubra cómo usar la inteligencia artificial para generar metadatos adicionales, como resúmenes o temas clave, para enriquecer el contenido extraído.
- Preprocesar contenido extraído. Explore formas de transformar el contenido extraído en incrustaciones vectoriales para la búsqueda y recuperación semánticas.
- Diseñar un índice unificado. Desarrolle un índice unificado de Azure AI Search que integre y organice los datos multimodales para una recuperación eficaz.
- Recuperación de fragmentos semánticos. Extraiga información contextualmente relevante para ofrecer respuestas más precisas y significativas a las consultas del usuario.
- Interacción con datos mediante modelos de chat Use modelos de chat de Azure OpenAI para interactuar con los datos indexados, lo que permite la búsqueda conversacional, la consulta y la respuesta.
Prerrequisitos
Para empezar, necesita Una suscripción de Azure activa. Si no tiene una cuenta de Azure, puede crear una suscripción gratuita.
Una vez que tenga la suscripción de Azure, cree un recurso de Azure AI Foundry en Azure Portal.
Este recurso aparece en AI Foundry>AI Foundry en el portal.
Recurso de Azure AI Search: Configure un recurso de Azure AI Search para habilitar la indexación y recuperación de datos multimodales.
Implementación del modelo de chat de Azure OpenAI: Implemente un modelo de chat de Azure OpenAI que permita interacciones conversacionales.
Despliegue del modelo de incrustación: Asegúrese de que tiene desplegado un modelo de incrustación para generar representaciones vectoriales para la búsqueda semántica.
Versión de LA API: En este tutorial se usa la versión preliminar más reciente de la API.
Entorno de Python: Instale Python 3.11 para ejecutar los scripts y ejemplos de código proporcionados.
Este tutorial sigue este código de ejemplo en nuestro cuaderno de Python. Siga el archivo LÉAME para crear recursos esenciales, asignar a los recursos los roles de control de acceso (IAM) adecuados e instalar todos los paquetes necesarios para este tutorial.
Los datos multimodales usados en este tutorial constan de documentos, imágenes, audio y vídeo. Están diseñados para guiarle a través del proceso de creación de una solución RAG sólida con Azure AI Content Understanding.
Extraer datos
La generación aumentada de recuperación (RAG*) es un método que mejora la funcionalidad de los modelos de lenguaje grande (LLM) mediante la integración de datos de orígenes de conocimiento externos. La creación de una solución RAG multimodal robusta comienza con la extracción y estructuración de datos de diversos tipos de contenido. Azure AI Content Understanding proporciona tres componentes clave para facilitar este proceso: extracción de contenido, extracción de campos y analizadores. Juntos, estos componentes forman los cimientos para crear una canalización de datos mejorada, unificada y reutilizable para flujos de trabajo RAG.
Pasos de implementación
Para implementar la extracción de datos en Content Understanding, siga estos pasos:
Cree un analizador: Defina un analizador mediante las API REST o nuestros ejemplos de código de Python.
Realizar extracción de contenido: Use el analizador para procesar archivos y extraer contenido estructurado.
(Opcional) Mejorar con extracción de campos: Opcionalmente, especifique los campos generados por ia para enriquecer el contenido extraído con metadatos agregados.
Creación de analizadores
Los analizadores son componentes reutilizables en Content Understanding que simplifican el proceso de extracción de datos. Una vez creado un analizador, se puede usar repetidamente para procesar archivos y extraer contenido o campos basados en esquemas predefinidos. Un analizador actúa como plano técnico sobre cómo se deben procesar los datos, lo que garantiza la coherencia y la eficacia en varios archivos y tipos de contenido.
Los ejemplos de código siguientes muestran cómo crear analizadores para cada modalidad, especificando los datos estructurados que se van a extraer, como campos clave, resúmenes o clasificaciones. Estos analizadores sirven como base para extraer y enriquecer contenido en la solución RAG.
Carga de todas las variables de entorno y las bibliotecas necesarias desde 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))
Ejemplo de código: creación de un analizador
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: Los esquemas de extracción de campos son opcionales y no son necesarios para realizar la extracción de contenido. Para ejecutar la extracción de contenido y crear analizadores sin definir esquemas de campo, solo tiene que proporcionar el identificador del analizador y el archivo que se va a analizar.
Los esquemas se usaron en este tutorial. Este es un ejemplo de una definición de esquema
En el ejemplo siguiente, definimos un esquema para extraer información básica de un documento de factura.
{
"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"
}
}
}
}
}
}
}
Extracción de contenido y campos
La extracción de contenido es el primer paso en el proceso de implementación de RAG. Transforma los datos multimodales sin procesar en formatos estructurados y buscables. Este paso fundamental garantiza que el contenido está organizado y listo para la indexación y recuperación. Aunque la extracción de contenido proporciona la línea base para la indexación y recuperación, es posible que no aborde completamente las necesidades específicas del dominio o proporcione información contextual más profunda. Obtenga más información sobre las funcionalidades de extracción de contenido para cada modalidad.
La extracción de campos se basa en la extracción de contenido mediante ia para generar más metadatos que enriquecen la base de conocimiento. Este paso le permite definir campos personalizados adaptados a su caso de uso específico, lo que permite una recuperación más precisa y una relevancia de búsqueda mejorada. La extracción de campos complementa la extracción de contenido al añadir profundidad y contexto, haciendo que los datos sean más útiles para escenarios RAG. Obtenga más información sobre las funcionalidades de extracción de campos para cada modalidad.
Con los analizadores creados para cada modalidad, ahora podemos procesar archivos para extraer contenido estructurado y metadatos generados por ia en función de los esquemas definidos. En esta sección se muestra cómo usar los analizadores para analizar datos transversales y se proporciona un ejemplo de los resultados devueltos por las API. Estos resultados muestran la transformación de los datos sin procesar en perspectivas accionables, formando la base para la indexación, recuperación y flujos de trabajo RAG.
Análisis de archivos
#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)
Resultados de extracción
En los ejemplos de código siguientes se muestra la salida del contenido y la extracción de campos mediante Content Understanding de Azure AI. La respuesta JSON contiene varios campos, cada uno de los cuales sirve un propósito específico para representar los datos extraídos.
Campo Markdown: el
markdown
campo proporciona una representación simplificada y legible del contenido extraído. Es especialmente útil para obtener vistas previas rápidas o para integrar los datos extraídos en aplicaciones que requieren texto estructurado, como bases de conocimiento o interfaces de búsqueda. Por ejemplo, con un documento, elmarkdown
campo puede incluir encabezados, párrafos y otros elementos estructurales con formato para facilitar la legibilidad.Salida JSON: la salida JSON completa proporciona una representación completa de los datos extraídos, incluidos el contenido y los metadatos generados durante el proceso de extracción, incluidas las siguientes propiedades:
- Campos: Metadatos generados por ia, como resúmenes, temas clave o clasificaciones, adaptados al esquema específico definido en el analizador.
- Puntuaciones de confianza: Indicadores de confiabilidad de los datos extraídos.
- Intervalos: información sobre la ubicación del contenido extraído en el archivo de origen.
- Metadatos adicionales: Detalles como números de página, dimensiones y otra información contextual.
El resultado muestra la extracción de encabezados, párrafos, tablas y otros elementos estructurales al tiempo que mantiene la organización lógica del contenido. Además, muestra la capacidad de extraer campos clave, proporcionando extracciones concisas de materiales largos.
{
"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": [
{
...
},
]
}
],
}
]
}
}
Preprocesamiento de la salida de comprensión de contenidos
Una vez extraídos los datos mediante Content Understanding de Azure AI, el siguiente paso consiste en preparar la salida del análisis para insertarlos en un sistema de búsqueda. El preprocesamiento de la salida garantiza que el contenido extraído se transforme en un formato adecuado para la indexación y recuperación. Este paso implica convertir la salida JSON de los analizadores en cadenas estructuradas, conservando tanto el contenido como los metadatos para la integración sin problemas en flujos de trabajo de bajada.
En el ejemplo siguiente se muestra cómo preprocesar los datos de salida de los analizadores, incluidos documentos, imágenes, audio y vídeo. El proceso de convertir cada salida JSON en una cadena estructurada establece la base para insertar los datos en un sistema de búsqueda basado en vectores, lo que permite una recuperación eficaz y flujos de trabajo RAG mejorados.
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)
Insertar e indexar contenido extraído
Una vez completado el preprocesamiento de los datos extraídos de Azure AI Content Understanding, el siguiente paso consiste en insertar e indexar el contenido para una recuperación eficaz. Este paso implica transformar las cadenas estructuradas en incrustaciones vectoriales mediante un modelo de inserción y almacenarlas en un sistema de Azure AI Search. Al insertar el contenido, se habilitan las funcionalidades de búsqueda semántica, lo que permite al sistema recuperar la información más relevante en función del significado en lugar de coincidencias exactas de palabras clave. Este paso es fundamental para crear una solución RAG sólida, ya que garantiza que el contenido extraído esté optimizado para flujos de trabajo avanzados de búsqueda y recuperación.
# 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)
Recuperación de fragmentos semánticos
Con el contenido extraído insertado e indizado, el siguiente paso es usar la eficacia de la similitud y la búsqueda de vectores para recuperar los fragmentos de información más relevantes. En esta sección se muestra cómo ejecutar búsquedas híbridas y de similitud, lo que permite al sistema exponer contenido basado en significado semántico en lugar de coincidencias de palabra clave exactas. Al recuperar fragmentos contextualmente relevantes, puede mejorar la precisión de los flujos de trabajo rag y proporcionar respuestas más precisas y significativas a las consultas de usuario.
# 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)
Uso de OpenAI para interactuar con los datos
Con el contenido extraído insertado e indizado, el último paso para crear una solución RAG sólida permite interacciones conversacionales mediante modelos de chat de OpenAI. En esta sección se muestra cómo consultar los datos indexados y aplicar modelos de chat de OpenAI para proporcionar respuestas concisas y contextualmente enriquecidas. Al integrar la inteligencia artificial conversacional, puede transformar la solución RAG en un sistema interactivo que ofrezca información significativa y mejore la interacción del usuario. Los siguientes ejemplos te guían a través de la configuración de un flujo conversacional aumentado con recuperación, asegurando una integración fluida entre tus datos y los modelos de chat de 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)