Contáctenos

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

Inteligencia Artificial General

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

mm
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.
RAG

RAG

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:

  1. Agente/Cerebro: El modelo de lenguaje central que procesa y comprende el lenguaje.
  2. Planificación: Capacidad de razonar, desglosar tareas y desarrollar planes específicos.
  3. Salud Cerebral: Mantiene registros de interacciones pasadas y aprende de ellas.
  4. 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.

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 en más de 50 proyectos diversos de ingeniería de software, con un enfoque particular en AI/ML. Mi curiosidad constante también me ha atraído hacia el procesamiento del lenguaje natural, un campo que estoy ansioso por explorar más a fondo.