Inteligencia Artificial General
Creación de agentes LLM para RAG desde cero y más allá: una guía completa

Los LLM como GPT-3, GPT-4 y su contraparte de código abierto a menudo tienen dificultades para recuperar información actualizada y, en ocasiones, pueden generar alucinaciones o información incorrecta.
Recuperación-Generación Aumentada (RAG) es una técnica que combina el poder de los LLM con la recuperación de conocimiento externo. RAG nos permite basar las respuestas de LLM en información objetiva y actualizada, lo que mejora significativamente la precisión y confiabilidad del contenido generado por IA.
En esta entrada de blog, exploraremos cómo crear agentes LLM para RAG desde cero, profundizando en la arquitectura, los detalles de implementación y las técnicas avanzadas. Abarcaremos todo, desde los fundamentos de RAG hasta la creación de agentes sofisticados capaces de razonamiento complejo y ejecución de tareas.
Antes de sumergirnos en la construcción de nuestro agente LLM, entendamos qué es RAG y por qué es importante.
RAG, o recuperación-generación aumentada, es un enfoque híbrido que combina la recuperación de información con la generación de texto. En un sistema RAG:
- Se utiliza una consulta para recuperar documentos relevantes de una base de conocimientos.
- Luego, estos documentos se introducen en un modelo de lenguaje junto con la consulta original.
- El modelo genera una respuesta basada tanto en la consulta como en la información recuperada.
Este enfoque tiene varias ventajas:
- Precisión mejorada: Al basar las respuestas en la información recuperada, RAG reduce las alucinaciones y mejora la precisión de los hechos.
- Actualizar informacion: La base de conocimientos se puede actualizar periódicamente, lo que permite que el sistema acceda a información actual.
- Transparencia: El sistema puede proporcionar fuentes para su información, aumentando la confianza y permitiendo la verificación de hechos.
Comprensión de los agentes LLM
Cuando te enfrentas a un problema que no tiene una respuesta sencilla, a menudo necesitas seguir varios pasos, pensar detenidamente y recordar lo que ya has intentado. Los agentes LLM están diseñados exactamente para este tipo de situaciones en aplicaciones de modelos de lenguaje. Combinan un análisis exhaustivo de datos, planificación estratégica, recuperación de datos y la capacidad de aprender de acciones pasadas para resolver problemas complejos.
¿Qué son los agentes LLM?
Los agentes LLM son sistemas avanzados de inteligencia artificial diseñados para crear texto complejo que requiere razonamiento secuencial. Pueden pensar en el futuro, recordar conversaciones pasadas y utilizar diferentes herramientas para ajustar sus respuestas según la situación y el estilo necesario.
Considere una pregunta en el campo legal como: "¿Cuáles son los posibles resultados legales de un tipo específico de incumplimiento de contrato en California?" Un LLM básico con un sistema de recuperación de generación aumentada (RAG) puede recuperar la información necesaria de bases de datos legales.
Para un escenario más detallado: "Ante las nuevas leyes de privacidad de datos, ¿cuáles son los desafíos legales comunes que enfrentan las empresas y cómo los han abordado los tribunales?". Esta pregunta va más allá de la simple búsqueda de datos. Se trata de comprender las nuevas normas, su impacto en las distintas empresas y las respuestas judiciales. Un agente con LLM dividiría esta tarea en subtareas, como recuperar las leyes más recientes, analizar casos históricos, resumir documentos legales y pronosticar tendencias basándose en patrones.
Componentes de los agentes LLM
Los agentes LLM generalmente constan de cuatro componentes:
- Agente/Cerebro: El modelo de lenguaje central que procesa y comprende el lenguaje.
- Planificación: Capacidad de razonar, desglosar tareas y desarrollar planes específicos.
- Salud Cerebral: Mantiene registros de interacciones pasadas y aprende de ellas.
- Uso de herramientas: Integra varios recursos para realizar tareas.
Agente/Cerebro
En el centro de un agente LLM hay un modelo de lenguaje que procesa y comprende el lenguaje basándose en grandes cantidades de datos en los que ha sido entrenado. Empiece por darle una indicación específica, guiando al agente sobre cómo responder, qué herramientas utilizar y los objetivos a alcanzar. Puede personalizar al agente con una persona adecuada para tareas o interacciones particulares, mejorando su desempeño.
Salud Cerebral
El componente de memoria ayuda a los agentes de LLM a manejar tareas complejas manteniendo un registro de acciones pasadas. Hay dos tipos principales de memoria:
- Memoria de corto plazo: Actúa como un bloc de notas y realiza un seguimiento de las discusiones en curso.
- Memoria a largo plazo: Funciona como un diario, almacena información de interacciones pasadas para aprender patrones y tomar mejores decisiones.
Al combinar estos tipos de memoria, el agente puede ofrecer respuestas más personalizadas y recordar las preferencias del usuario a lo largo del tiempo, creando una interacción más conectada y relevante.
Planificación
La planificación permite a los agentes de LLM razonar, descomponer las tareas en partes manejables y adaptar los planes a medida que evolucionan las tareas. La planificación implica dos etapas principales:
- Formulación del plan: dividir una tarea en subtareas más pequeñas.
- Planificar la reflexión: Revisar y evaluar la efectividad del plan, incorporando retroalimentación para perfeccionar las estrategias.
Métodos como la Cadena de Pensamiento (CoT) y el Árbol de Pensamiento (ToT) ayudan en este proceso de descomposición, permitiendo a los agentes explorar diferentes caminos para resolver un problema.
Para profundizar en el mundo de los agentes de IA, incluidas sus capacidades y potencial actuales, considere leer "Auto-GPT y GPT-Engineer: una guía detallada sobre los principales agentes de IA de la actualidad"
Configurar el entorno
Para crear nuestro agente RAG, necesitaremos configurar nuestro entorno de desarrollo. Usaremos Python y varias bibliotecas clave:
- LangChain: Para orquestar nuestro LLM y componentes de recuperación
- Chroma: Como nuestro almacén de vectores para incrustaciones de documentos.
- Modelos GPT de OpenAI: Como nuestro LLM base (puede sustituirlo con un modelo de código abierto si lo prefiere)
- FastAPI: Para crear una API simple para interactuar con nuestro agente
Comencemos configurando nuestro entorno:
# Create a new virtual environment python -m venv rag_agent_env source rag_agent_env/bin/activate # On Windows, use `rag_agent_env\Scripts\activate` # Install required packages pip install langchain chromadb openai fastapi uvicorn
Ahora, creemos un nuevo archivo Python llamado rag_agent.py e importemos las bibliotecas necesarias:
from langchain.embeddings import OpenAIEmbeddings from langchain.vectorstores import Chroma from langchain.text_splitter import CharacterTextSplitter from langchain.llms import OpenAI from langchain.chains import RetrievalQA from langchain.document_loaders import TextLoader import os # Set your OpenAI API key os.environ["OPENAI_API_KEY"] = "your-api-key-here"
Construyendo un sistema RAG simple
Ahora que tenemos nuestro entorno configurado, construyamos un sistema RAG básico. Comenzaremos creando una base de conocimientos a partir de un conjunto de documentos y la usaremos para responder consultas.
Paso 1: preparar los documentos
Primero, necesitamos cargar y preparar nuestros documentos. Para este ejemplo, supongamos que tenemos un archivo de texto llamado knowledge_base.txt con información sobre IA y aprendizaje automático.
# Load the document loader = TextLoader("knowledge_base.txt") documents = loader.load() # Split the documents into chunks text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0) texts = text_splitter.split_documents(documents) # Create embeddings embeddings = OpenAIEmbeddings() # Create a vector store vectorstore = Chroma.from_documents(texts, embeddings)
Paso 2: crear una cadena de control de calidad basada en recuperación
Ahora que tenemos nuestro almacén de vectores, podemos crear una cadena de control de calidad basada en recuperación:
# Create a retrieval-based QA chain qa = RetrievalQA.from_chain_type(llm=OpenAI(), chain_type="stuff", retriever=vectorstore.as_retriever())
Paso 3: consultar el sistema
Ahora podemos consultar nuestro sistema RAG:
query = "What are the main applications of machine learning?" result = qa.run(query) print(result)
Paso 4: crear un agente LLM
Si bien nuestro sencillo sistema RAG es útil, es bastante limitado. Mejorémoslo creando un agente LLM que pueda realizar tareas más complejas y razonar sobre la información que recupera.
Un agente LLM es un sistema de IA que puede usar herramientas y tomar decisiones sobre las acciones a tomar. Crearemos un agente que no solo pueda responder preguntas, sino también realizar búsquedas web y cálculos básicos.
Primero, definamos algunas herramientas para nuestro agente:
from langchain.agents import Tool from langchain.tools import DuckDuckGoSearchRun from langchain.tools import BaseTool from langchain.agents import initialize_agent from langchain.agents import AgentType # Define a calculator tool class CalculatorTool(BaseTool): name = "Calculator" description = "Useful for when you need to answer questions about math" def _run(self, query: str) try: return str(eval(query)) except: return "I couldn't calculate that. Please make sure your input is a valid mathematical expression." # Create tool instances search = DuckDuckGoSearchRun() calculator = CalculatorTool() # Define the tools tools = [Tool(name="Search",func=search.run,description="Useful for when you need to answer questions about current events"), Tool(name="RAG-QA",func=qa.run,description="Useful for when you need to answer questions about AI and machine learning"), Tool(name="Calculator",func=calculator._run,description="Useful for when you need to perform mathematical calculations") ] # Initialize the agent agent = initialize_agent(tools, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True )
Ahora tenemos un agente que puede usar nuestro sistema RAG, realizar búsquedas web y cálculos. Probémoslo:
result = agent.run("What's the difference between supervised and unsupervised learning? Also, what's 15% of 80?") print(result)
Este agente demuestra una ventaja clave de los agentes LLM: pueden combinar múltiples herramientas y pasos de razonamiento para responder consultas complejas.
Mejora del agente con técnicas RAG avanzadas
Si bien nuestro sistema RAG actual funciona bien, existen varias técnicas avanzadas que podemos utilizar para mejorar su rendimiento:
a) Búsqueda semántica con recuperación de pasajes densos (DPR)
En lugar de utilizar una recuperación simple basada en incrustaciones, podemos implementar DPR para una búsqueda semántica más precisa:
from transformers import DPRQuestionEncoder, DPRContextEncoder question_encoder = DPRQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base") context_encoder = DPRContextEncoder.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base") # Function to encode passages def encode_passages(passages): return context_encoder(passages, max_length=512, return_tensors="pt").pooler_output # Function to encode query def encode_query(query): return question_encoder(query, max_length=512, return_tensors="pt").pooler_output
b) Expansión de consultas
Podemos utilizar la expansión de consultas para mejorar el rendimiento de la recuperación:
from transformers import T5ForConditionalGeneration, T5Tokenizer model = T5ForConditionalGeneration.from_pretrained("t5-small") tokenizer = T5Tokenizer.from_pretrained("t5-small") def expand_query(query): input_text = f"expand query: {query}" input_ids = tokenizer.encode(input_text, return_tensors="pt") outputs = model.generate(input_ids, max_length=50, num_return_sequences=3) expanded_queries = [tokenizer.decode(output, skip_special_tokens=True) for output in outputs] return expanded_queries
c) Refinamiento iterativo
Podemos implementar un proceso de refinamiento iterativo donde el agente puede hacer preguntas de seguimiento para aclarar o ampliar su recuperación inicial:
def iterative_retrieval(initial_query, max_iterations=3): query = initial_query for _ in range(max_iterations): result = qa.run(query) clarification = agent.run(f"Based on this result: '{result}', what follow-up question should I ask to get more specific information?") if clarification.lower().strip() == "none": break query = clarification return result # Use this in your agent's process
Implementación de un sistema multiagente
Para gestionar tareas más complejas, podemos implementar un sistema multiagente donde cada agente se especializa en distintas áreas. A continuación, un ejemplo sencillo:
class SpecialistAgent: def __init__(self, name, tools): self.name = name self.agent = initialize_agent(tools, OpenAI(temperature=0), agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True) def run(self, query): return self.agent.run(query) # Create specialist agents research_agent = SpecialistAgent("Research", [Tool(name="RAG-QA", func=qa.run, description="For AI and ML questions")]) math_agent = SpecialistAgent("Math", [Tool(name="Calculator", func=calculator._run, description="For calculations")]) general_agent = SpecialistAgent("General", [Tool(name="Search", func=search.run, description="For general queries")]) class Coordinator: def __init__(self, agents): self.agents = agents def run(self, query): # Determine which agent to use if "calculate" in query.lower() or any(op in query for op in ['+', '-', '*', '/']): return self.agents['Math'].run(query) elif any(term in query.lower() for term in ['ai', 'machine learning', 'deep learning']): return self.agents['Research'].run(query) else: return self.agents['General'].run(query) coordinator = Coordinator({'Research': research_agent, 'Math': math_agent, 'General': general_agent}) # Test the multi-agent system result = coordinator.run("What's the difference between CNN and RNN? Also, calculate 25% of 120.") print(result)
Este sistema de múltiples agentes permite la especialización y puede manejar una gama más amplia de consultas de manera más efectiva.
Evaluación y optimización de agentes RAG
Para garantizar que nuestro agente RAG tenga un buen desempeño, debemos implementar métricas de evaluación y técnicas de optimización:
a) Evaluación de relevancia
Podemos utilizar métricas como BLEU, ROUGE o BERTScore para evaluar la relevancia de los documentos recuperados:
from bert_score import score def evaluate_relevance(query, retrieved_doc, generated_answer): P, R, F1 = score([generated_answer], [retrieved_doc], lang="en") return F1.mean().item()
b) Evaluación de la calidad de las respuestas
Podemos utilizar evaluación humana o métricas automatizadas para evaluar la calidad de las respuestas:
from nltk.translate.bleu_score import sentence_bleu def evaluate_answer_quality(reference_answer, generated_answer): return sentence_bleu([reference_answer.split()], generated_answer.split()) # Use this to evaluate your agent's responses
Direcciones futuras y desafíos
Al mirar hacia el futuro de los agentes RAG, surgen varias direcciones y desafíos interesantes:
a) RAG multimodal: Ampliación de RAG para incorporar datos de imagen, audio y vídeo.
b) RAG federado: Implementación de RAG en bases de conocimiento distribuidas que preservan la privacidad.
c) Aprendizaje continuo: Desarrollar métodos para que los agentes RAG actualicen sus bases de conocimientos y modelos a lo largo del tiempo.
d) Consideraciones éticas: Abordar el sesgo, la equidad y la transparencia en los sistemas RAG.
e) Global: Optimización de RAG para aplicaciones en tiempo real a gran escala.
Conclusión
Desarrollar agentes LLM para RAG desde cero es un proceso complejo pero gratificante. Hemos cubierto los fundamentos de RAG, implementado un sistema simple, creado un agente LLM, mejorado con técnicas avanzadas, explorado sistemas multiagente y analizado estrategias de evaluación y optimización.