Módulo 8: RAG Evaluation + Proyecto Integrador
Proyecto Final: Advanced RAG System Evaluado
Descripción del proyecto
Este es el proyecto culminante de toda la guía. Cierra el ciclo completo: integra los componentes técnicos que construiste en módulos 2-7 (chunking inteligente, query optimization, hybrid search, re-ranking, metadata filtering, Pinecone production) con la disciplina operacional de evaluación que acabas de aprender en M08.
No es "juntar componentes". Es demostrar que el pipeline completo funciona end-to-end, escala bajo carga real, mantiene calidad medida con números, y opera con la rigurosidad que distingue un sistema profesional de un demo. Es el portfolio piece que un entrevistador senior va a mirar y decir "este candidato realmente sabe operar RAG en producción".
Al terminar tendrás un repositorio público production-ready que cuenta una historia cuantitativa: "el sistema baseline tenía faithfulness 0.74 y p95 latencia 800ms; después de aplicar las técnicas de la guía, faithfulness es 0.92 y p95 es 350ms, validado contra golden dataset de 100 queries con CI/CD que bloquea regresiones automáticamente".
Esta historia, contada con datos, es lo que diferencia "estudié RAG" de "puedo construir y operar RAG profesionalmente".
Objetivo del proyecto
Construir e integrar un sistema RAG completo con seis dimensiones operacionales:
- Pipeline RAG end-to-end funcionando: query → expansion → hybrid retrieval → re-ranking → metadata filtering → generation
- Infraestructura productiva sobre Pinecone con multi-tenancy y observabilidad
- Golden dataset versionado con 50-100 queries representativas y ground truth validado
- Pipeline de evaluación automatizado con RAGAS, métricas segmentadas y reportes JSON+MD
- Quality gates con thresholds calibrados, regression testing y baseline versionado
- CI/CD activo en GitHub Actions con smoke en PR, full nightly y diff comments en pull requests
Arquitectura del sistema completo
┌──────────────────────────────────────────────────────────────────┐
│ User Query (with TenantContext) │
└──────────────────────────┬───────────────────────────────────────┘
│
▼
┌──────────────────────┐
│ Query Optimization │ M03
│ (expand, rewrite) │
└──────────┬───────────┘
│
▼
┌──────────────────────────────┐
│ Hybrid Retrieval │ M05
│ (BM25 + semantic, RRF fuse) │
└──────────┬───────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Metadata Filtering │ M06
│ (FilterSpec → namespace + filter) │
└──────────┬──────────────────────────┘
│
▼
┌─────────────────────┐
│ Re-ranking │ M04
│ (cross-encoder) │
└──────────┬──────────┘
│
▼
┌─────────────────┐
│ Generation │
│ (gpt-4o-mini) │
└────────┬────────┘
│
▼
┌──────────────────────┐
│ Evaluation Logging │ M08
│ (trace + metrics) │
└──────────────────────┘
Cada caja es un componente que viste construir en módulos previos. Tu trabajo es integrarlos manteniendo interfaces limpias.
Stack obligatorio
| Capa | Tecnología | Cápsula origen |
|---|---|---|
| Vector DB | Pinecone serverless | M07 |
| Embeddings | OpenAI text-embedding-3-small | M02, M07 |
| Generación | OpenAI gpt-4o-mini | — |
| BM25 | rank-bm25 | M05 |
| Re-ranker | sentence-transformers cross-encoder | M04 |
| Eval framework | RAGAS | M08 |
| API | FastAPI | M07 |
| Observability | structlog + Prometheus | M07 |
| CI/CD | GitHub Actions | M08 |
| Tests | pytest | — |
Estructura del repositorio
advanced-rag-system/
├── app/
│ ├── pipeline.py # AdvancedRAGSystem orchestrator
│ ├── retrieval/
│ │ ├── hybrid.py # M05 hybrid search
│ │ ├── reranker.py # M04 cross-encoder
│ │ └── pinecone_backend.py # M07
│ ├── query/
│ │ └── optimizer.py # M03 expansion
│ ├── tenant.py # TenantContext from M07
│ ├── metadata.py # FilterSpec from M06
│ ├── generation.py # LLM generation with grounding prompt
│ ├── observability.py # structlog + traces
│ └── api.py # FastAPI endpoints
├── eval/
│ ├── loader.py # Golden dataset loader
│ ├── runner.py # Pipeline executor
│ ├── metrics.py # RAGAS wrapper
│ ├── thresholds.py # Quality gates
│ ├── reporter.py # JSON + MD reports
│ └── baseline.json # Versioned baseline
├── golden_dataset/
│ ├── v1.0.0.json # 50+ queries
│ ├── META.json
│ ├── PROCESS.md
│ └── CHANGELOG.md
├── scripts/
│ ├── evaluate.py # CLI principal
│ ├── migrate_from_chroma.py
│ ├── benchmark.py
│ ├── compare_baseline.py
│ └── update_baseline.py
├── tests/
│ ├── test_isolation.py # Multi-tenant safety
│ ├── test_pipeline.py
│ └── test_quality_gates.py
├── .github/workflows/
│ ├── rag-eval-smoke.yml
│ ├── rag-eval-nightly.yml
│ └── rag-eval-compare.yml
├── docker-compose.yml
├── pyproject.toml
├── BENCHMARK.md
├── DECISION.md
└── README.md
Funcionalidades obligatorias
1) Pipeline RAG integrado
# app/pipeline.py
from typing import Awaitable
class AdvancedRAGSystem:
def __init__(
self,
query_optimizer,
hybrid_retriever,
reranker,
generator,
tracer,
):
self.query_optimizer = query_optimizer
self.hybrid_retriever = hybrid_retriever
self.reranker = reranker
self.generator = generator
self.tracer = tracer
async def answer_with_context(
self,
query: str,
tenant: TenantContext,
filter_spec: FilterSpec | None = None,
) -> RAGResponse:
trace = self.tracer.start_trace(query=query, tenant_id=tenant.tenant_id)
expanded = await self.query_optimizer.expand(query)
trace.record("query_expansion", {"variants": expanded})
candidates = await self.hybrid_retriever.retrieve(
queries=expanded,
tenant=tenant,
filter_spec=filter_spec or FilterSpec(),
top_k=50,
)
trace.record("retrieval", {"n_candidates": len(candidates)})
reranked = await self.reranker.rerank(query=query, documents=candidates, top_k=5)
trace.record("rerank", {"final_top_k": 5})
answer = await self.generator.generate(query=query, context=reranked)
trace.record("generation", {"answer_length": len(answer)})
return RAGResponse(
answer=answer,
sources=reranked,
trace_id=trace.trace_id,
)
Por qué este diseño:
- Inyección de dependencias: cada componente es testeable en isolation
- Tracing built-in: cada etapa registra métricas, latencia y decisiones
- Async nativo: paralelizable bajo carga sin reescribir
- TenantContext obligatorio: aislamiento garantizado por tipos, no por convención
2) Golden dataset y evaluación
Mínimo 50 queries con la distribución de M08/04. Tu pipeline debe correr python scripts/evaluate.py --mode smoke en menos de 2 minutos.
3) Quality gates en CI
Smoke evaluation en cada PR bloqueando merge si:
- Faithfulness < 0.85
- Answer Relevancy < 0.80
- Context Recall < 0.80
- O regresión > 2% vs baseline en cualquier métrica core
4) Observabilidad
Cada query del API genera:
{
"trace_id": "...",
"tenant_id": "...",
"query": "...",
"stages": {
"expansion": {"latency_ms": 180, "variants": 3},
"retrieval": {"latency_ms": 120, "candidates": 50},
"rerank": {"latency_ms": 250, "final": 5},
"generation": {"latency_ms": 850, "tokens": 142}
},
"total_latency_ms": 1400,
"cost_usd": 0.0023
}
Validaciones obligatorias
Lista de invariantes que tu sistema debe garantizar:
- Toda query require
TenantContextválido - No hay llamada directa a
index.queryfuera desecure_query - Cache key incluye
tenant_id(test pass: dos tenants no comparten cache) - CI bloquea merge si quality gates fallan
- Logs estructurados JSON con
trace_id,tenant_id,latency_mspor stage - Test suite incluye
test_isolation.py,test_pipeline.py,test_quality_gates.py - README incluye tabla comparativa M1 vs M8 con métricas reales
Criterios de éxito
- ✅ Precision@5 y Recall@20 mejoran ≥30% vs baseline simple RAG (M01-style)
- ✅ Métricas RAGAS superan thresholds en evaluación contra golden dataset
- ✅ p95 latencia ≤500ms bajo concurrencia=50
- ✅ CI/CD corre sin intervención manual; al menos 5 PRs pasaron por el pipeline
- ✅ README final explica arquitectura con diagrama, decisiones técnicas y resultados cuantitativos
- ✅ Repo es demostrable como portfolio project
Tabla comparativa final M1 → M8 (obligatoria)
Esta tabla cierra la narrativa de toda la guía. Es lo primero que un revisor mira:
| Módulo | Técnica añadida | Precision@5 | Recall@20 | Faithfulness | p95 (ms) |
|---|---|---|---|---|---|
| M1 (baseline) | RAG simple | 0.65 | 0.58 | 0.74 | 800 |
| M2 | Chunking optimization | 0.71 | 0.62 | 0.79 | 760 |
| M3 | Query expansion | 0.74 | 0.78 | 0.82 | 870 |
| M4 | Cross-encoder rerank | 0.85 | 0.78 | 0.88 | 990 |
| M5 | Hybrid + RRF | 0.88 | 0.84 | 0.89 | 940 |
| M6 | Metadata filtering | 0.89 | 0.84 | 0.90 | 720 |
| M7 | Pinecone production | 0.89 | 0.84 | 0.91 | 350 |
| M8 | Eval-driven tuning | 0.91 | 0.86 | 0.93 | 350 |
Reemplaza estos números con los tuyos reales. La estructura importa más que los valores específicos: cada fila debe mostrar el aporte cuantitativo de un módulo.
Rúbrica de evaluación (100 puntos)
Integración técnica (40 pts)
- (15 pts) Pipeline completo end-to-end funcional con todas las etapas
- (10 pts) Multi-tenant con TenantContext y aislamiento testeado
- (10 pts) Hybrid + reranking + filtering correctamente compuestos
- (5 pts) Observabilidad con tracing por etapa
Evaluación (30 pts)
- (10 pts) Golden dataset versionado con 50+ queries balanceadas
- (10 pts) Pipeline de evaluación automatizado, modo smoke + full
- (10 pts) Regression testing con baseline y thresholds calibrados
Operación (20 pts)
- (10 pts) CI/CD funcional: smoke en PR, full nightly, diff comments
- (10 pts) Manejo de errores con retry, timeouts, fallbacks
Comunicación técnica (10 pts)
- (10 pts) README profesional con tabla comparativa, decisiones documentadas, diagramas
Extra credit (+15)
- (+5 pts) Dashboard simple de métricas históricas (Grafana o Streamlit)
- (+5 pts) Evaluación segmentada (easy/medium/hard, por categoría)
- (+5 pts) Reporte automático en Slack al fallar nightly eval
Errores comunes y cómo evitarlos
- Integrar módulos sin medir impacto real → cada técnica debe agregar fila a la tabla comparativa con su delta. Si no puedes mostrar la mejora cuantitativa, la técnica no aporta.
- Dataset trivial → 50% del golden dataset debe ser muestreado de tráfico real, no inventado. Métricas perfectas en dataset trivial son teatro.
- Thresholds inventados → calibra empíricamente con 5+ runs estables (M08/06). Thresholds copiados de blogs no aplican a tu sistema.
- CI/CD sin bloqueo → si el quality gate no bloquea merge, no es gate, es decoración.
--enforce-thresholdsdebe estar activo. - README sin narrativa cuantitativa → "el sistema mejoró" es inútil. Lo que cuenta es "faithfulness 0.74 → 0.93, validado contra 100 queries". Pin la tabla comparativa al inicio del README.
- Sin plan de rollback → si un PR pasa quality gates pero rompe en producción, ¿cómo vuelves? Documenta el procedimiento en
DECISION.md. - Ignorar segmentación → métricas globales esconden problemas. Reporta por difficulty: si "hard" cae 15% pero "easy" sube 5%, el promedio engaña.
Documentos a entregar
README.md
- Diagrama de arquitectura
- Tabla comparativa M1 → M8
- Setup en 5 minutos
- Cómo correr evaluación
- Cómo deploy
BENCHMARK.md (de M07)
- Latencia ChromaDB vs Pinecone
- Throughput bajo concurrencia
- Estimación de costos a 12 meses
DECISION.md (de M07)
- Trade-offs evaluados
- Recomendación con razones cuantitativas
- Plan de rollback
EVAL.md (nuevo en M08)
- Cómo se construyó el golden dataset
- Metodología de calibración de thresholds
- Reportes históricos de quality
golden_dataset/PROCESS.md
- Quién anotó, cuándo, criterios
- Cómo se mantiene (ciclo trimestral)
Recursos para el proyecto
- RAGAS Documentation - Framework de evaluación.
- Pinecone Production Guides - Operación vector DB.
- GitHub Actions Documentation - CI/CD.
- FastAPI Production Patterns - Deploy de APIs.
- structlog - Logging estructurado.
- LangChain Retrieval Concepts - Patrones de retrieval.
- Anthropic on Building Eval-Driven Products - Filosofía operacional.
Cierre de la guía
Con este proyecto cierras una progresión completa. Empezaste construyendo RAG simple. Aprendiste por qué falla en producción. Aplicaste técnicas avanzadas: chunking inteligente, query optimization, hybrid search, re-ranking, metadata filtering. Migraste a infraestructura productiva. Y agregaste la disciplina de evaluación que convierte un sistema "que funciona" en un sistema "que sigue funcionando".
Lo que tienes ahora es una capacidad profesional concreta: diseñar, implementar, escalar y evaluar sistemas RAG avanzados con criterios objetivos de calidad. Esta capacidad es escasa en la industria — la mayoría de equipos están atorados en RAG simple sin saber por qué falla y sin métricas para diagnosticar.
El siguiente paso natural es especializarte en extensiones de frontera:
- Agentic RAG: sistemas donde el LLM decide cuándo y cómo recuperar
- Multimodal retrieval: imágenes, video, audio en el mismo pipeline
- Adaptive retrieval: el sistema aprende de feedback y ajusta sus estrategias
- Multi-step reasoning: queries que requieren múltiples retrievals encadenados
- Self-RAG y reflective retrieval: el sistema evalúa su propia calidad y reintentar
Pero antes de saltar a frontera, valida que dominas los fundamentos publicando este proyecto: README claro, código limpio, métricas honestas, CI/CD activo. Es la prueba más fuerte de tu capacidad.
Felicidades por llegar hasta aquí. La diferencia entre quien empezó la guía y quien la termina es real y medible — la cuentan los números en tu tabla comparativa final.
Creado: Marzo 13, 2026
Versión: 2.0