Retrieval Augmented Generation
RAG = Buscar info relevante + Darla al LLM = Respuestas precisas con fuentes
¿Por qué RAG?
| Sin RAG | Con RAG |
|---|
| LLM solo sabe lo que aprendió | LLM accede a TUS documentos |
| Puede inventar ("alucinar") | Cita fuentes reales |
| Conocimiento estático | Info siempre actualizada |
Arquitectura RAG
┌─────────────────┐
│ Tu pregunta │
└────────┬────────┘
↓
┌─────────────────────────────────────────────┐
│ 1. RETRIEVAL │
│ Query → Vector DB → Top K documentos │
└────────┬────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 2. AUGMENTATION │
│ Prompt + Contexto de documentos │
└────────┬────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ 3. GENERATION │
│ LLM genera respuesta con contexto │
└─────────────────────────────────────────────┘
Flujo de indexación
# 1. Cargar documentos
docs = load_pdfs("./docs/")
# 2. Chunking (dividir en partes)
chunks = split_text(docs, chunk_size=500)
# 3. Embeddings
embeddings = model.embed(chunks)
# 4. Guardar en vector DB
vector_db.add(embeddings, chunks)
Chunking strategies
| Estrategia | Cuando usar |
|---|
| Fixed size | Documentos simples |
| Sentence | Texto natural |
| Semantic | Alta precisión |
| Recursive | Documentos largos |
Prompt template RAG
Responde usando SOLO la información del contexto.
Si no está en el contexto, di "No tengo esa información".
CONTEXTO:
{chunks_relevantes}
PREGUNTA: {user_question}
Métricas de calidad
| Métrica | Qué mide |
|---|
| Relevance | ¿Chunks correctos? |
| Faithfulness | ¿Respuesta basada en contexto? |
| Answer quality | ¿Respuesta útil? |
📚 Caso Real: RAG para Compliance
Las empresas financieras tienen cientos de PDFs de políticas y regulaciones. RAG permite buscar en ellos con lenguaje natural.
Ejemplo: Buscador de Políticas Internas
# Documentos de compliance
docs = [
"politica_aml.pdf",
"manual_kyc.pdf",
"regulacion_cnbv_2024.pdf",
"procedimiento_fraudes.pdf",
"codigo_etica.pdf"
]
# Indexar una vez
for doc in docs:
chunks = split_pdf(doc, chunk_size=500)
embeddings = model.embed(chunks)
vector_db.add(embeddings, chunks, metadata={"source": doc})
# Consulta de empleado
query = "¿Cuál es el límite para transacciones sin verificación adicional?"
# Buscar en todos los documentos
results = vector_db.search(query, top_k=5)
# Respuesta con fuente
response = llm.generate(
prompt=f"Contexto: {results}\n\nPregunta: {query}",
system="Responde citando el documento y sección específica."
)
# "Según la política AML sección 4.2, las transacciones
# mayores a $15,000 MXN requieren verificación adicional..."
Por qué es valioso en Fintech
| Sin RAG | Con RAG |
|---|
| Buscar en 50 PDFs manualmente | Pregunta en lenguaje natural |
| "No sé dónde está esa política" | Respuesta + fuente exacta |
| Empleados inventan respuestas | Basado en documentos reales |
| Auditor pide evidencia → pánico | Link directo al párrafo |
Consideraciones de seguridad
# SIEMPRE incluir la fuente para auditoría
response = {
"answer": "...",
"sources": [
{"doc": "politica_aml.pdf", "page": 12, "section": "4.2"},
{"doc": "manual_kyc.pdf", "page": 5, "section": "2.1"}
],
"confidence": 0.92
}
# Si no hay match confiable, NO inventar
if confidence < 0.7:
response["answer"] = "No encontré información específica. Consulta con Compliance."
💡 RAG para compliance reduce tiempo de búsqueda de horas a segundos, y siempre cita la fuente.
Practica
→ RAG con Documentos PDF