Connect with us

AGI

Construir Agentes LLM para RAG desde Cero y Más Allá: Una Guía Integral

mm
Building LLM Agents for RAG from Scratch and Beyond: A Comprehensive Guide

Los LLM como GPT-3, GPT-4 y su contraparte de código abierto a menudo luchan con la recuperación de información actualizada y sometimes pueden generar alucinaciones o información incorrecta.

Retrieval-Augmented Generation (RAG) es una técnica que combina el poder de los LLM con la recuperación de conocimiento externo. RAG nos permite fundamentar las respuestas de los LLM en información factual y actualizada, mejorando significativamente la precisión y confiabilidad del contenido generado por IA.

En este artículo del blog, exploraremos cómo construir agentes LLM para RAG desde cero, sumergiéndonos profundamente en la arquitectura, los detalles de implementación y las técnicas avanzadas. Cubriremos todo, desde los conceptos básicos 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, debemos entender qué es RAG y por qué es importante.

RAG, o Generación con Recuperación de Información, 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 conocimiento.
  • Estos documentos se alimentan luego a un modelo de lenguaje junto con la consulta original.
  • El modelo genera una respuesta basada en la consulta y la información recuperada.
RAG

RAG

Este enfoque tiene varias ventajas:

  • Precisión mejorada: Al fundamentar las respuestas en información recuperada, RAG reduce las alucinaciones y mejora la precisión factual.
  • Información actualizada: La base de conocimiento se puede actualizar regularmente, lo que permite al sistema acceder a información actual.
  • Transparencia: El sistema puede proporcionar fuentes para su información, aumentando la confianza y permitiendo la verificación de hechos.

Entendiendo los Agentes LLM

 

Cuando enfrentas un problema sin una respuesta simple, a menudo necesitas seguir varios pasos, pensar cuidadosamente y recordar lo que ya has intentado. Los agentes LLM están diseñados precisamente para este tipo de situaciones en aplicaciones de modelos de lenguaje. Combinan un análisis de datos exhaustivo, 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 de IA avanzados diseñados para crear texto complejo que requiere razonamiento secuencial. Pueden pensar adelante, recordar conversaciones pasadas y utilizar diferentes herramientas para ajustar sus respuestas según la situación y el estilo necesario.

Considera una pregunta en el campo legal como: “¿Cuáles son los resultados legales potenciales de una violación específica de contrato en California?” Un LLM básico con un sistema RAG puede recuperar la información necesaria de bases de datos legales.

Para un escenario más detallado: “A la luz de las nuevas leyes de privacidad de datos, ¿cuáles son los desafíos legales comunes que enfrentan las empresas y cómo han abordado los tribunales estos problemas?” Esta pregunta va más allá de simplemente buscar hechos. Se trata de entender nuevas reglas, su impacto en diferentes empresas y las respuestas de los tribunales. Un agente LLM dividiría esta tarea en subtareas, como recuperar las leyes más recientes, analizar casos históricos, resumir documentos legales y predecir tendencias basadas en patrones.

Componentes de los Agentes LLM

Los agentes LLM suelen consistir en cuatro componentes:

  1. Agente/Cerebro: El modelo de lenguaje central que procesa y entiende el lenguaje.
  2. Planificación: La capacidad de razonar, descomponer tareas y desarrollar planes específicos.
  3. Memoria: Mantiene registros de interacciones pasadas y aprende de ellas.
  4. Uso de Herramientas: Integra varios recursos para realizar tareas.

Agente/Cerebro

En el núcleo de un agente LLM se encuentra un modelo de lenguaje que procesa y entiende el lenguaje basado en grandes cantidades de datos en los que se ha entrenado. Comienzas dándole una promoción específica, guiando al agente sobre cómo responder, qué herramientas usar y los objetivos a los que apuntar. Puedes personalizar al agente con una personalidad adecuada para tareas o interacciones específicas, mejorando su rendimiento.

Memoria

El componente de memoria ayuda a los agentes LLM a manejar tareas complejas manteniendo un registro de acciones pasadas. Hay dos tipos principales de memoria:

  • Memoria a Corto Plazo: Actúa como una libreta, llevando un registro de discusiones en curso.
  • Memoria a Largo Plazo: Funciona como un diario, almacenando 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 preferencias de usuario con el tiempo, creando una interacción más conectada y relevante.

Planificación

La planificación permite a los agentes LLM razonar, descomponer tareas en partes manejables y adaptar planes a medida que las tareas evolucionan. La planificación implica dos etapas principales:

  • Formulación de Plan: Descomponer una tarea en sub-tareas más pequeñas.
  • Reflexión del Plan: Revisar y evaluar la efectividad del plan, incorporando retroalimentación para refinar 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 sumergirte más en el mundo de los agentes de IA, incluyendo sus capacidades actuales y potencial, considera leer “Auto-GPT & GPT-Engineer: Una Guía en Profundidad sobre los Agentes de IA Líderes de Hoy”

Configuración del Entorno

Para construir nuestro agente RAG, necesitamos configurar nuestro entorno de desarrollo. Estaremos utilizando Python y varias bibliotecas clave:

  • LangChain: Para orquestar nuestros componentes LLM y de recuperación.
  • Chroma: Como nuestra tienda de vectores para incrustaciones de documentos.
  • Modelos GPT de OpenAI: Como nuestro LLM base (puedes sustituir esto con un modelo de código abierto si lo prefieres).
  • FastAPI: Para crear una API simple para interactuar con nuestro agente.

Comencemos configurando nuestro entorno:


# Crea un nuevo entorno virtual
python -m venv rag_agent_env
source rag_agent_env/bin/activate # En Windows, usa `rag_agent_env\Scripts\activate`

# Instala los paquetes requeridos
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

# Establece tu clave API de OpenAI
os.environ["OPENAI_API_KEY"] = "tu-clave-api-aquí";

Construir un Sistema RAG Simple

Ahora que tenemos nuestro entorno configurado, construyamos un sistema RAG básico. Comenzaremos creando una base de conocimiento a partir de un conjunto de documentos, y luego usaremos esto 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 alguna información sobre IA y aprendizaje automático.


# Carga el documento
loader = TextLoader("knowledge_base.txt")
documents = loader.load()

# Divide los documentos en fragmentos
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)

# Crea incrustaciones
embeddings = OpenAIEmbeddings()

# Crea una tienda de vectores
vectorstore = Chroma.from_documents(texts, embeddings)

Paso 2: Crear una Cadena de Preguntas y Respuestas Basada en Recuperación

Ahora que tenemos nuestra tienda de vectores, podemos crear una cadena de preguntas y respuestas basada en recuperación:


# Crea una cadena de preguntas y respuestas basada en recuperación
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 = "¿Cuáles son las aplicaciones principales del aprendizaje automático?"
result = qa.run(query)
print(result)

Paso 4: Crear un Agente LLM

Mientras que nuestro sistema RAG simple es útil, es bastante limitado. Mejoremoslo 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 qué acciones realizar. Crearemos un agente que no solo pueda responder preguntas, sino también realizar búsquedas en la 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 una herramienta de calculadora
class CalculatorTool(BaseTool):
name = "Calculadora"
description = "Útil para cuando necesitas responder preguntas sobre matemáticas"

def _run(self, query: str)
try:
return str(eval(query))
except:
return "No pude calcular eso. Asegúrate de que tu entrada sea una expresión matemática válida."

# Crea instancias de herramientas
search = DuckDuckGoSearchRun()
calculator = CalculatorTool()

# Define las herramientas
tools = [Tool(name="Búsqueda",func=search.run,description="Útil para cuando necesitas responder preguntas sobre eventos actuales"),
Tool(name="RAG-Preguntas y Respuestas",func=qa.run,description="Útil para cuando necesitas responder preguntas sobre IA y aprendizaje automático"),
Tool(name="Calculadora",func=calculator._run,description="Útil para cuando necesitas realizar cálculos matemáticos")
]

# Inicializa el agente
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 en la web y realizar cálculos. Probémoslo:


result = agent.run("¿Cuál es la diferencia entre aprendizaje supervisado y no supervisado? También, ¿cuál es el 15% de 80?")
print(result)

Este agente demuestra una ventaja clave de los agentes LLM: pueden combinar múltiples herramientas y pasos de razonamiento para responder preguntas complejas.

Mejorar el Agente con Técnicas RAG Avanzadas

Mientras que nuestro sistema RAG actual funciona bien, hay varias técnicas avanzadas que podemos usar para mejorar su rendimiento:

a) Búsqueda Semántica con Recuperación de Pasajes Densos (DPR)

En lugar de usar una recuperación basada en incrustaciones simples, 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")

# Función para codificar pasajes
def encode_passages(passages):
return context_encoder(passages, max_length=512, return_tensors="pt").pooler_output

# Función para codificar la consulta
def encode_query(query):
return question_encoder(query, max_length=512, return_tensors="pt").pooler_output

b) Expansión de Consulta

Podemos usar la expansión de consulta para mejorar el rendimiento de 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"expandir consulta: {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"Basado en este resultado: '{result}', ¿qué pregunta de seguimiento debería hacer para obtener información más específica?")
if clarification.lower().strip() == "ninguna":
break
query = clarification
return result

# Usa esto en el proceso de tu agente

Implementación de un Sistema de Agentes Múltiples

Para manejar tareas más complejas, podemos implementar un sistema de agentes múltiples donde diferentes agentes se especializan en diferentes áreas. Aquí hay un ejemplo simple:


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)

# Crea agentes especializados
research_agent = SpecialistAgent("Investigación", [Tool(name="RAG-Preguntas y Respuestas", func=qa.run, description="Para preguntas sobre IA y aprendizaje automático")])
math_agent = SpecialistAgent("Matemáticas", [Tool(name="Calculadora", func=calculator._run, description="Para cálculos")])
general_agent = SpecialistAgent("General", [Tool(name="Búsqueda", func=search.run, description="Para consultas generales")])

class Coordinator:
def __init__(self, agents):
self.agents = agents

def run(self, query):
# Determina qué agente usar
if "calcular" in query.lower() or any(op in query for op in ['+', '-', '*', '/']):
return self.agents['Matemáticas'].run(query)
elif any(term in query.lower() for term in ['ia', 'aprendizaje automático', 'aprendizaje profundo']):
return self.agents['Investigación'].run(query)
else:
return self.agents['General'].run(query)

coordinator = Coordinator({'Investigación': research_agent, 'Matemáticas': math_agent, 'General': general_agent})

# Prueba el sistema de agentes múltiples
result = coordinator.run("¿Cuál es la diferencia entre CNN y RNN? También, calcula el 25% de 120.")
print(result)

Este sistema de agentes múltiples 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 asegurarnos de que nuestro agente RAG esté funcionando bien, necesitamos implementar métricas de evaluación y técnicas de optimización:

a) Evaluación de Relevancia

Podemos usar 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 la Respuesta

Podemos usar evaluación humana o métricas automatizadas para evaluar la calidad de la respuesta:


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())

# Usa esto para evaluar las respuestas de tu agente

Dirigirnos al Futuro y Desafíos

Mientras miramos hacia el futuro de los agentes RAG, varias direcciones emocionantes y desafíos emergen:

a) RAG Multi-modal: Extender RAG para incorporar datos de imagen, audio y video.

b) RAG Federado: Implementar RAG en bases de conocimiento distribuidas y de privacidad.

c) Aprendizaje Continuo: Desarrollar métodos para que los agentes RAG actualicen sus bases de conocimiento y modelos con el tiempo.

d) Consideraciones Éticas: Abordar sesgo, equidad y transparencia en los sistemas RAG.

e) Escalabilidad: Optimizar RAG para aplicaciones a gran escala y en tiempo real.

Conclusión

Construir agentes LLM para RAG desde cero es un proceso complejo pero gratificante. Hemos cubierto los conceptos básicos de RAG, implementado un sistema simple, creado un agente LLM, mejorado con técnicas avanzadas, explorado sistemas de agentes múltiples y discutido estrategias de evaluación y optimización.

He pasado los últimos cinco años sumergiéndome en el fascinante mundo del Aprendizaje Automático y el Aprendizaje Profundo. Mi pasión y experiencia me han llevado a contribuir a más de 50 proyectos de ingeniería de software diversos, con un enfoque particular en AI/ML. Mi curiosidad continua también me ha llevado hacia el Procesamiento de Lenguaje Natural, un campo que estoy ansioso por explorar más a fondo.