Implementación de RAG agéntico usando Claude 3.5 Sonnet, LlamaIndex y Milvus
A medida que los sistemas de IA siguen evolucionando rápidamente, depender únicamente de los modelos de lenguaje grandes (LLMs) ya no es suficiente para satisfacer las diversas necesidades de las industrias actuales. Estos desafíos crecientes requieren el desarrollo de arquitecturas más complejas que puedan resolver problemas de manera más eficiente y eficaz.
En el Unstructured Data Meetup organizado por Zilliz, Bill Zhang, Director de Ingeniería en Zilliz, presentó el concepto de Sistemas de IA compuesta, que apareció en el blog de Berkeley AI Research (BAIR). Este enfoque modular integra múltiples componentes para gestionar diversas tareas en lugar de depender de un único modelo de IA, ofreciendo resultados más personalizados y eficientes. Puedes ver la presentación de Bill en el canal de Zilliz YouTube.
En este blog, recapitularemos los puntos clave de Bill, incluida la evolución de las arquitecturas de aplicaciones de LLM, los conceptos de Generación aumentada por recuperación (RAG) y RAG agéntico, y sus desafíos y beneficios. También te guiaremos en la creación de un RAG agéntico usando Claude 3.4 Sonnet, LlamaIndex y la base de datos vectorial Milvus.
El desarrollo de la arquitectura de las aplicaciones LLM
Los LLM han formado parte del panorama de la IA durante más de una década, pero la aparición de modelos fundacionales disponibles públicamente, en particular ChatGPT de OpenAI, durante los últimos tres años ha acelerado significativamente el desarrollo de aplicaciones LLM, impulsando su rápida expansión. En el Unstructured Data Meetup, Bill resumió los componentes clave de las arquitecturas de IA actuales y su desarrollo.
Figure 1- LLM System Evolution .png
Figura 1: Evolución del sistema LLM
Depender únicamente del conocimiento preentrenado de los LLM
La forma más sencilla de usar un LLM es confiar en su conocimiento “propio” para responder a tu consulta. Sin embargo, este método tiene una limitación: los LLM no pueden cubrir todos los temas o casos de uso, lo que puede dar lugar a respuestas inexactas o “alucinadas”. Una forma de abordar este problema es usar múltiples LLM, cada uno adaptado a diferentes tipos de preguntas, pero este método haría que el sistema fuera demasiado complejo y difícil de escalar.
Sistemas de IA compuesta: añadir componentes adicionales a tu canalización de LLM
Entonces, ¿cómo podemos resolver este problema? La solución reside en los sistemas de IA compuesta. Añadir componentes adicionales a la canalización de LLM puede mejorar el rendimiento del sistema. Un ejemplo común es la Generación aumentada por recuperación (RAG). RAG introduce una "base de conocimiento" o "contexto," que normalmente se almacena en una base de datos vectorial como Milvus o Zilliz Cloud (el Milvus gestionado), donde se guarda información específica para búsquedas por similitud. Puedes acceder a información personalizada para tu caso de uso introduciendo tu conocimiento en el sistema RAG. RAG aprovecha la potencia del LLM combinada con un prompt personalizado compuesto por la consulta del usuario y el contexto recuperado de la base de datos vectorial, produciendo respuestas más precisas y relevantes.
Agentes
Entonces, ¿necesitamos implementar más módulos? Eso depende del caso de uso específico. Sin embargo, al igual que los LLMs, RAG también tiene limitaciones, ya que depende del modelo específico. Por ejemplo, ¿qué ocurre si tu consulta implica realizar una tarea de comparación, pero tu modelo ha sido entrenado para resumir? ¿Cómo se pueden gestionar eficazmente distintos tipos de preguntas? Aquí es donde entra en práctica un módulo adicional: Agents. Los agentes de IA son sistemas complejos que añaden pasos “similares a los humanos” en el pipeline, como razonamiento, herramientas utilizadas o planificación. Profundicemos primero en los conceptos básicos de RAG para comprender los beneficios de los agentes.
Generación Aumentada por Recuperación (RAG)
Como se mencionó anteriormente, los sistemas RAG mejoran la salida de los LLM al incorporar una base de datos vectorial como base de conocimiento. Los pasos básicos para construir un sistema RAG pueden resumirse de la siguiente manera:
Fragmentación: Dividir documentos en piezas más pequeñas para mejorar la relevancia del contenido recuperado de la base de datos vectorial mediante búsqueda semántica, una característica central de las bases de datos vectoriales como Zilliz Cloud y Milvus.
Embedding: Vectorizar (crear representaciones numéricas de) los fragmentos que se ingerirán en la base de datos vectorial.
Prompt: Instrucciones dadas al LLM para buscar en la base de datos vectorial basándose en la consulta para obtener la respuesta
Consulta: La pregunta dada al LLM
Estos pasos se basan principalmente en la similitud. El modelo busca los fragmentos más similares en la base de datos y genera la respuesta más precisa basándose en eso.
Figure 2- Basic steps of RAG .png
Figura 2: Pasos básicos de RAG
Sin embargo, una búsqueda de similitud semántica no es una solución mágica. La respuesta resultante también será insuficiente si los fragmentos más similares no son lo suficientemente precisos. Bill exploró algunas de las debilidades de los sistemas RAG, particularmente en casos de uso donde los LLM pueden no rendir de manera óptima, incluyendo resumen, comparación y preguntas de varias partes.
Sin embargo, el problema con RAG, concretamente su falta de capacidades de razonamiento y su incapacidad para recuperar con precisión los documentos requeridos, puede abordarse eficazmente mediante la introducción de Agents. Estas Entidades desempeñan un papel crucial en todo el proceso, ofreciendo una solución potencial a los desafíos planteados por RAG.
RAG agéntico
Ahora que entendemos las limitaciones de los LLM y RAG, podemos explorar más a fondo los beneficios de los agentes. En el diagrama siguiente, los agentes LLM contienen varios componentes que interactúan entre sí en un proceso iterativo. Ahora, no se trata solo de similitud, sino también de planificación, razonamiento, uso de herramientas y memorización.
Figure 3- LLM Agents .png
Figura 3: Agentes LLM
Aunque existen varias arquitecturas y frameworks agénticos, uno de los más populares es ReAct (Reasoning/Acting). ReAct implica varios pasos: planificación/razonamiento, actuación (uso de herramientas), observación/evaluación y generación de respuestas. Bill destacó estos pasos como parte de un proceso iterativo.
En el paso de observación/evaluación, si el modelo no encuentra la respuesta, seguirá buscando alternativas volviendo al paso de razonamiento o incluso solicitando un prompt adicional al usuario.
Figure 4- ReAct Framework.png
Figura 4: Framework ReAct (Fuente)
Entonces, ¿cómo podemos usar estos agentes en un pipeline RAG? Lo bueno es que pueden implementarse dentro de todos los pasos del pipeline, ya sea en el enrutamiento/planificación hacia el pipeline RAG posterior o en la llamada a herramientas. Incluso la base de conocimiento puede considerarse una herramienta o un framework ReAct.
Figura 5- Cómo funciona un RAG agéntico .png
Figura 5: Cómo funciona un RAG agéntico
Durante la charla, Bill explicó cinco posibles implementaciones agénticas dentro de un pipeline RAG:
Enrutamiento: La consulta del usuario se redirige a una base de conocimiento específica relevante para la consulta.
- Ejemplo: Si el usuario pide recomendaciones para tipos específicos de libros, la consulta puede enrutarse a la base de conocimiento, que contiene información sobre esos tipos de libros.
Planificación de consultas: La consulta se divide en subconsultas, y cada subconsulta se dirige al pipeline RAG relevante.
- Ejemplo: Si quieres conocer los resultados financieros de una empresa durante los últimos tres años, el agente crea subconsultas para cada año y dirige cada una a la base de conocimiento adecuada.
Uso de herramientas: Un LLM interactúa con una API o herramienta externa, determinando los parámetros necesarios para la interacción.
- Ejemplo: Si un usuario solicita un pronóstico del tiempo, el LLM llama a una API meteorológica, determina parámetros como la ubicación y la fecha, y procesa la respuesta de la API para proporcionar la respuesta.
ReAct: Un proceso iterativo que incorpora razonamiento y acción, incluidos pasos de planificación, uso de herramientas y observación.
- Ejemplo: Para generar un itinerario de viaje detallado, el sistema razona las necesidades del usuario, usa APIs para recopilar información sobre atracciones, restaurantes y alojamiento, observa los resultados en cuanto a precisión y relevancia, y luego proporciona un plan de viaje completo.
Planificación dinámica de consultas: El agente ejecuta múltiples tareas o subconsultas en paralelo en lugar de secuencialmente y agrega los resultados
Ejemplo: Si quieres comparar los resultados financieros de dos empresas y calcular la diferencia en una métrica específica, el agente procesa datos para ambas empresas en paralelo y luego combina los resultados para proporcionar la comparación. LLMCompiler es un framework de ejemplo que permite una orquestación eficiente y eficaz de llamadas a funciones en paralelo.
Figura 6- LLM Compiler.png
Figura 6: LLM Compiler (Fuente)
Así que los agentes añaden una capa adicional al pipeline RAG, mejorando y optimizando la eficiencia general del proceso. Sin embargo, al igual que los LLMs y RAG como sistemas independientes, los agentes también presentan algunos desafíos, como controlar sus pasos internos y personalizarlos para lograr los mejores resultados en casos de uso específicos.
Ahora mostremos un pipeline agéntico simple usando la base de datos vectorial Milvus.
RAG agéntico usando Claude 3.5 Sonnet, LlamaIndex y Milvus
El siguiente notebook es un ejemplo de un pipeline RAG agéntico construido con LlamaIndex como framework agéntico, Milvus como base de datos vectorial y Claude 3.5 Sonnet como LLM. En esta sección, te guiaré sobre cómo construir este RAG agéntico.
También puedes consultar el código completo en este notebook.
Paso 1: Carga de datos
Usamos las páginas de preguntas frecuentes de la Documentación de Milvus 2.4.x como conocimiento privado en nuestro RAG, lo cual es una buena fuente de datos para un pipeline RAG simple.
!pip install -qq llama-index pymilvus llama-index-vector-stores-milvus llama-index-llms-anthropic
!wget https://github.com/milvus-io/milvus-docs/releases/download/v2.4.6-preview/milvus_docs_2.4.x_en.zip
!unzip -q /content/milvus_docs_2.4.x_en.zip -d /content/milvus_docs
from llama_index.core import SimpleDirectoryReader
# load documents
documents = SimpleDirectoryReader(
input_files=["/content/milvus_docs/en/faq/operational_faq.md"]
).load_data()
print("Document ID:", documents[0].doc_id)
Paso 2: Variables de entorno
Necesitamos importar dos CLAVES DE API: Anthropic y OpenAI.
import os
from google.colab import userdata
os.environ["ANTHROPIC_API_KEY"] = userdata.get('ANTHROPIC_API_KEY')
os.environ["OPENAI_API_KEY"] = userdata.get('OPENAI_API_KEY')
Paso 3: Indexación de datos
Se crea un índice de los documentos usando la base de datos vectorial Milvus. Esta será nuestra base de conocimiento. Como OpenAI es el modelo de embeddings predeterminado en LlamaIndex (se puede cambiar), necesitamos definir las mismas dimensiones (dim = 1536) en MilvusVectorStore. Además, se creará una base de datos local después de ejecutar el siguiente código, que contendrá nuestra base de conocimiento.
from llama_index.core import VectorStoreIndex, StorageContext
from llama_index.vector_stores.milvus import MilvusVectorStore
vector_store = MilvusVectorStore(dim=1536)
storage_context = StorageContext.from_defaults(vector_store=vector_store)
index = VectorStoreIndex.from_documents(documents, storage_context=storage_context)
Paso 4: Motor de consulta simple
Primero probemos el motor de consulta sin un agente. Está impulsado por Claude 3.5 Sonnet y busca contenido relevante dentro de nuestro índice.
llm = Anthropic(model="claude-3-5-sonnet-20240620")
query_engine = index.as_query_engine(similarity_top_k=5, llm=llm)
res = query_engine.query("What is the maximum vector dimension supported in Milvus?")
print(res)
"""
Output:
Milvus supports vectors with up to 32,768 dimensions by default. However, if you need to work with vectors of even higher dimensionality, you have the option to increase the value of the 'Proxy.maxDimension' parameter. This allows Milvus to accommodate vectors with dimensions exceeding the default limit.
"""
Paso 5: Motor de consulta agéntico
Ahora, añadimos QueryEngineTool, que actuará como una herramienta envoltorio para el motor de consulta, que será utilizada por el agente.
from llama_index.core import VectorStoreIndex
from llama_index.core.tools import QueryEngineTool, ToolMetadata
from llama_index.llms.anthropic import Anthropic
llm = Anthropic(model="claude-3-5-sonnet-20240620")
query_engine = index.as_query_engine(similarity_top_k=5, llm=llm)
query_engine_tool = QueryEngineTool(
query_engine=query_engine,
metadata=ToolMetadata(
name="knowledge_base",
description=(
"Provides information about Milvus FAQ."
"Use a detailed plain text question as input to the tool."
),
),
)
Paso 6: Creación del agente de IA
El agente utilizado en este caso es el FunctionCallingAgentWorker de LlamaIndex, que emplea reflexión crítica sobre la respuesta de la consulta usando la herramienta del motor de consulta para generar una respuesta mejorada.
from llama_index.core.agent import FunctionCallingAgentWorker
agent_worker = FunctionCallingAgentWorker.from_tools(
[query_engine_tool], llm=llm, verbose=True
)
agent = agent_worker.as_agent()
response = agent.chat("What is the maximum vector dimension supported in Milvus?")
print(str(response))
"""
Output:
Added user message to memory: What is the maximum vector dimension supported in Milvus?
=== LLM Response ===
To answer your question about the maximum vector dimension supported in Milvus, I'll need to consult the Milvus FAQ knowledge base. Let me do that for you.
=== Calling Function ===
Calling function: knowledge_base with args: {"input": "What is the maximum vector dimension supported in Milvus?"}
=== Salida de la función ===
Milvus admite vectores con hasta 32,768 dimensiones de forma predeterminada. Sin embargo, si necesitas trabajar con vectores de dimensionalidad aún mayor, tienes la opción de aumentar el valor del parámetro 'Proxy.maxDimension'. Esto permite que Milvus admita vectores con dimensiones que superan el límite predeterminado.
=== Respuesta del LLM ===
Basándome en la información de la base de conocimientos de preguntas frecuentes de Milvus, puedo darte la siguiente respuesta:
La dimensión vectorial máxima admitida en Milvus es 32,768 de forma predeterminada. Esto significa que, listo para usar, Milvus puede manejar vectores con hasta 32,768 dimensiones, lo cual es adecuado para la mayoría de las aplicaciones.
Sin embargo, es importante señalar que Milvus ofrece flexibilidad para casos en los que podrías necesitar trabajar con vectores de dimensionalidad aún mayor. Si tu caso de uso requiere vectores con dimensiones superiores a 32,768, tienes la opción de aumentar este límite. Esto se puede hacer ajustando el parámetro 'Proxy.maxDimension' en la configuración de Milvus.
Entonces, para resumir:
1. Dimensión máxima predeterminada: 32,768
2. Se puede aumentar: Sí, modificando el parámetro 'Proxy.maxDimension'
Esta flexibilidad permite que Milvus admita una amplia gama de casos de uso, desde aplicaciones típicas de aprendizaje automático e IA hasta escenarios más especializados que podrían requerir vectores de dimensionalidad extremadamente alta.
Basándome en la información de la base de conocimientos de preguntas frecuentes de Milvus, puedo darte la siguiente respuesta:
La dimensión vectorial máxima admitida en Milvus es 32,768 de forma predeterminada. Esto significa que, listo para usar, Milvus puede manejar vectores con hasta 32,768 dimensiones, lo cual es adecuado para la mayoría de las aplicaciones.
Sin embargo, es importante señalar que Milvus ofrece flexibilidad para casos en los que podrías necesitar trabajar con vectores de dimensionalidad aún mayor. Si tu caso de uso requiere vectores con dimensiones superiores a 32,768, tienes la opción de aumentar este límite. Esto se puede hacer ajustando el parámetro 'Proxy.maxDimension' en la configuración de Milvus.
Entonces, para resumir:
1. Dimensión máxima predeterminada: 32,768
2. Se puede aumentar: Sí, modificando el parámetro 'Proxy.maxDimension'
Esta flexibilidad permite que Milvus admita una amplia gama de casos de uso, desde aplicaciones típicas de aprendizaje automático e IA hasta escenarios más especializados que podrían requerir vectores de dimensionalidad extremadamente alta.
"""
La salida del agente proporciona una respuesta más detallada, incluida la fuente de la información, el razonamiento detrás de la respuesta y algunas sugerencias adicionales relacionadas con el tema. Esto nos ayuda a comprender mejor la respuesta dada por el modelo LLM.
La arquitectura RAG agéntica
La arquitectura completa del RAG agéntico que acabamos de construir es como se muestra a continuación.
La arquitectura RAG agéntica construida con Milvus, LlamaIndex y Cluade 3.5 Sonnet.png
Figura 7: La arquitectura RAG agéntica construida con Milvus, LlamaIndex y Cluade 3.5 Sonnet
Conclusión
En su charla, Bill Zhang exploró el panorama en evolución de los sistemas LLM, destacando el cambio de modelos independientes a arquitecturas más complejas que incorporan RAG y agentes. Cada componente—LLMs, RAG y agentes—tiene fortalezas y debilidades. El concepto de Compound AI permite la creación de sistemas modulares diseñados para abordar diversos cuellos de botella, mejorando así la eficiencia general del pipeline.
Aunque los resultados de estos sistemas avanzados son prometedores y las implementaciones listas para producción son cada vez más comunes, siguen existiendo varios desafíos, particularmente en la gestión y personalización del comportamiento de los agentes dentro de estos sistemas. Ajustar finamente estos componentes para que funcionen eficientemente en casos de uso específicos es un área de desarrollo continua.
Recursos adicionales sobre GenAI, VectorDB y ML
Sigue leyendo

A Developer's Guide to Exploring Milvus 2.6 Features on Zilliz Cloud
Milvus 2.6 marks a shift from “vector search + glue code” to a more advanced retrieval engine, and it is now Generally Available (GA) on Zilliz Cloud (a managed Milvus service).

Our Journey to 35K+ GitHub Stars: The Real Story of Building Milvus from Scratch
Join us in celebrating Milvus, the vector database that hit 35.5K stars on GitHub. Discover our story and how we’re making AI solutions easier for developers.

Vector Databases vs. Graph Databases
Use a vector database for AI-powered similarity search; use a graph database for complex relationship-based queries and network analysis.



