Cómo Construir tu Primer Sistema RAG (Retrieval-Augmented Generation) de Forma Económica en AWS
Introducción
La inteligencia artificial ya no es solo para grandes empresas con presupuestos millonarios. Hoy, gracias a herramientas de bajo costo como Amazon Bedrock, pgvector en Amazon RDS, y los modelos de lenguaje como GPT-4 vía API, es posible construir soluciones avanzadas de IA sin necesidad de infraestructura compleja ni grandes inversiones.
Uno de los enfoques más poderosos y aplicables del momento es el sistema RAG (Retrieval-Augmented Generation). Este tipo de arquitectura combina lo mejor de dos mundos: la capacidad de búsqueda semántica de tus propios datos y la generación de respuestas inteligentes con modelos de lenguaje.
En este artículo aprenderás cómo funciona este sistema, qué herramientas necesitas y cómo puedes empezar a construir tu propia solución RAG utilizando recursos económicos en AWS.
¿Qué es un sistema RAG?
Retrieval-Augmented Generation (RAG) es una técnica que mejora las respuestas de un modelo de lenguaje grande (LLM) combinando:
- Recuperación de contexto relevante desde tus propios documentos o base de conocimiento.
- Generación de texto basada en ese contexto, usando un modelo como GPT-4, Claude o Amazon Titan.
¿Por qué usar RAG?
- Puedes hacer que el modelo responda con información actualizada y específica de tu negocio.
- No necesitas entrenar tu propio modelo: usas APIs existentes.
- Reduces el costo y errores de la IA generativa al entregarle datos precisos.
Ejemplo Paso a Paso Completo usando AWS
Paso 1: Almacenamiento de Documentos en Amazon S3
Crea un bucket llamado rag-documentos
desde la consola AWS S3 y sube tus documentos PDF o TXT.
import boto3
s3 = boto3.client('s3')
s3.upload_file('ruta/local/documento.pdf', 'nombre-del-bucket', 'documento.pdf')
Consideraciones: Asegúrate de tener los permisos adecuados en IAM.
Paso 2: Extraer Texto de Documentos usando AWS Lambda
Configura una función Lambda llamada ExtracciónTextoLambda.
Código para extraer texto:
import boto3
import PyPDF2
s3 = boto3.client('s3')
def lambda_handler(event, context):
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
response = s3.get_object(Bucket=bucket, Key=key)
archivo = response['Body'].read()
texto = ""
lector = PyPDF2.PdfReader(io.BytesIO(archivo))
for pagina in lector.pages:
texto += pagina.extract_text()
return texto
Consideraciones: Configura Lambda con las capas necesarias para PyPDF2.
Paso 3: Crear Embeddings usando OpenAI en AWS Lambda
Configura otra función Lambda llamada EmbeddingsLambda para crear embeddings usando OpenAI:
import openai
def lambda_handler(event, context):
texto = event['texto']
openai.api_key = 'tu-api-key'
respuesta = openai.Embedding.create(
input=texto,
model="text-embedding-ada-002"
)
embedding = respuesta['data'][0]['embedding']
return embedding
Consideraciones: Almacena claves de API en AWS Secrets Manager.
Paso 4: Guardar embeddings en Amazon RDS PostgreSQL
Crea y conecta tu base de datos PostgreSQL en AWS RDS:
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE documentos (
id SERIAL PRIMARY KEY,
contenido TEXT,
embedding VECTOR(1536)
);
Configura una función Lambda llamada AlmacenamientoRDSLambda para guardar embeddings en Amazon RDS PostgreSQL:
import psycopg2
def lambda_handler(event, context):
texto = event['texto']
embedding = event['embedding']
conn = psycopg2.connect("dbname='tu_db' user='tu_user' password='tu_pass' host='tu_host'")
cur = conn.cursor()
cur.execute("INSERT INTO documentos (contenido, embedding) VALUES (%s, %s)", (texto, embedding))
conn.commit()
cur.close()
conn.close()
Paso 5: Buscar embeddings similares usando LangChain
Configura una función Lambda llamada BúsquedaSemanticaLambda para buscar embeddings similares usando LangChain:
from langchain.vectorstores import PGVector
from langchain.embeddings import OpenAIEmbeddings
def lambda_handler(event, context):
consulta = event['consulta']
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")
vectorstore = PGVector(
connection_string="postgresql://user:pass@host:5432/db",
embedding_function=embeddings,
collection_name="documentos"
)
docs_similares = vectorstore.similarity_search(consulta)
return [doc.page_content for doc in docs_similares]
Consideraciones: Usa roles IAM y políticas para conexiones seguras a RDS.
Paso 6: Generar Respuestas Contextualizadas con Amazon Bedrock o GPT-4
from langchain.chat_models import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
def lambda_handler(event, context):
contexto = "\n".join(event['documentos'])
consulta = event['consulta']
llm = ChatOpenAI(api_key='tu-api-key', model="gpt-4")
prompt = ChatPromptTemplate.from_template(
"Responde basado en el contexto:\n\nContexto:\n{contexto}\n\nPregunta:\n{consulta}"
)
respuesta = llm.invoke(prompt.format(contexto=contexto, consulta=consulta))
return respuesta.content
Paso 6: Interfaz Visual usando AWS Amplify y Streamlit
Despliega fácilmente tu app Streamlit usando AWS Amplify:
Configura AWS Amplify para desplegar una app Streamlit simple:
import streamlit as st
st.title("Chat con documentación interna")
pregunta = st.text_input("Escribe tu pregunta:")
if pregunta:
# Invocar Lambdas aquí
documentos = llamada_lambda("BúsquedaSemanticaLambda", pregunta)
respuesta = llamada_lambda("GeneracionTextoLambda", {"documentos": documentos, "consulta": pregunta})
st.write(respuesta)
Despliegue en AWS Amplify:
amplify init
amplify add hosting
amplify publish
Consideraciones: Verifica seguridad y rendimiento con AWS Amplify.
Conclusión
Siguiendo estos pasos claros y estructurados, habrás construido un sistema RAG completamente funcional y escalable, utilizando exclusivamente servicios y herramientas de AWS para optimizar costos, rendimiento y seguridad.