RAG en producción con pgvector y Supabase: la arquitectura que sí escala
El 80% de los RAG que se demuestran en LinkedIn no llegarían a producción. Esta es la arquitectura que sí — con números, decisiones y trade-offs reales.


RAG (Retrieval-Augmented Generation) es la técnica más subestimada y peor implementada de la práctica empresarial de IA. Subestimada porque no es glamorosa — son embeddings, índices y prompts. Mal implementada porque la mayoría copia un tutorial de OpenAI cookbook y se asume listo para producción.
Esta guía describe la arquitectura RAG que usamos en WITS para clientes en México: PostgreSQL con pgvector como base, Supabase cuando aplica como capa de auth y storage, Python + FastAPI para el orquestador. Sin Pinecone, sin Weaviate, sin lock-in costoso — al menos hasta que el volumen lo justifique.
Por qué pgvector + Postgres en lugar de un vector DB dedicado
Para volúmenes hasta 10-50 millones de vectores y latencias de retrieval <200ms, pgvector cubre la necesidad. Las ventajas operativas son enormes:
- Una sola base de datos: vectores, metadata, ACL, audit logs en el mismo Postgres
- Joins entre vectores y tablas relacionales — clave para filtrado por permisos, tenant, idioma
- Tu equipo ya sabe operar Postgres: backups, replicación, monitoreo
- Sin egress fees ni renovación de contratos: pgvector es open source, corre en cualquier Postgres ≥13
- pgvector 0.7+ soporta HNSW + cuantización; performance comparable a vector DBs dedicados en la mayoría de casos B2B
Cuándo sí pasarse a un vector DB dedicado: >100M vectores, latencias <50ms requeridas, o queries de geometrías altamente complejas. Para el 90% de proyectos B2B en México, pgvector es la opción correcta.
Las 7 etapas del pipeline RAG productivo
1. Ingesta
Conectores específicos por origen: PDFs (PyMuPDF para texto + tablas), Markdown (parser nativo respetando estructura), Office (mammoth para .docx), Confluence/Notion (APIs nativas), código (tree-sitter para AST). Cada conector emite documentos con metadata: source_id, version, lang, permissions, parent_path.
2. Chunking
El chunking es la decisión más subestimada. Cuatro estrategias y cuándo usar cada una:
| Estrategia | Cuándo usar | Tamaño típico |
|---|---|---|
| Fixed (carácter o token) | Texto homogéneo (artículos, blogs) | 500-1500 tokens, overlap 10-15% |
| Recursive (separadores naturales) | Documentos mixtos, default razonable | 800-1200 tokens |
| Semantic (clusterizado por embeddings) | Texto narrativo largo donde la coherencia importa | Variable, ~1000 tokens |
| Structural (por encabezados/secciones) | Markdown/HTML/docs técnicos con jerarquía | 1 sección = 1 chunk |
3. Embeddings
Modelos que recomendamos en 2026: text-embedding-3-large de OpenAI (1536 dim, balance calidad/costo), Voyage-3 cuando se justifica (mejor para código y multilingüe), all-mpnet-base-v2 self-hosted si los datos no pueden salir. Costo típico de OpenAI: $0.13 por millón de tokens — irrelevante en la mayoría de proyectos B2B.
4. Indexación en pgvector
HNSW (Hierarchical Navigable Small World) es el índice por default desde pgvector 0.5. Parámetros: m=16, ef_construction=64 como punto de partida. Para >10M vectores, considerar cuantización (vector_l2_ops_quantized) para reducir storage 4× con pérdida marginal de accuracy.
5. Hybrid search: semántica + keyword
Búsqueda solo semántica falla en queries con jerga técnica, números o nombres propios. Solución: combinar vector search con BM25 (full-text search nativo de Postgres con tsvector) y fusionar con Reciprocal Rank Fusion (RRF). En clientes hemos visto recall@10 subir de 78% a 91% con solo agregar BM25.
6. Reranking
Cross-encoder ligero (Cohere Rerank, BGE-reranker-large) que recibe top-50 de hybrid search y reordena top-10. Mejora precision@5 entre 15-30% con costo de ~20-50ms adicionales por query. Casi siempre vale la pena.
7. Generación con citaciones obligatorias
El LLM recibe los top-k chunks como contexto + prompt que obliga a citar fuente para cada afirmación. Cada citación es trazable al chunk → documento origen → metadata original. Sin esto no es RAG productivo, es chatbot con esteroides.
Trazabilidad: la diferencia entre RAG y oráculo opaco
Trazabilidad significa que cada respuesta puede auditarse: qué chunks se recuperaron, qué prompt se envió, qué generó el modelo, qué documentos cita la respuesta final. Sin esto, el sistema falla las primeras dos auditorías de seguridad o legal y termina en el cementerio de POCs.
- Cada respuesta guarda: query, embedding, top-k chunks recuperados, scores, prompt enviado, output, latency
- UI muestra fuentes con link al documento original — no "según mis fuentes"
- Logs estructurados que permiten responder "¿por qué dijo X?" en post-mortem
- Versionado de embeddings + chunks: si reindezas, sabes qué versión generó cada respuesta histórica
Evaluación: cómo saber si funciona
Métricas que importan, en orden de prioridad:
| Métrica | Qué mide | Benchmark productivo |
|---|---|---|
| Recall@10 | % de preguntas donde el chunk correcto está en top-10 | >85% |
| MRR (Mean Reciprocal Rank) | Posición promedio del primer chunk relevante | >0.7 |
| Faithfulness | % de afirmaciones del output sustentadas por contexto | >90% |
| Answer Relevancy | % de respuestas que efectivamente contestan la pregunta | >85% |
| Citation Accuracy | % de citas que apuntan al doc correcto | >95% |
Frameworks útiles: Ragas, TruLens, DeepEval. Set de evaluación de 50-200 preguntas curadas con respuestas ideales — chico pero representativo es mejor que grande y descuidado.
Cuándo NO usar RAG
- El conocimiento cabe en el prompt (<8k tokens estables): pásalo en system prompt y olvida RAG
- Necesitas razonamiento sobre toda la base, no recuperación de pasajes (mejor structured data + SQL)
- El dominio es ultra-narrow y estable: fine-tuning probablemente sea más barato a largo plazo
- Latencia <100ms requerida y volumen alto: cache + LLM directo bate al pipeline RAG
Stack mínimo viable que recomendamos
- PostgreSQL 16 + pgvector 0.7+ (o Supabase, que ya lo trae)
- Python 3.12 + FastAPI + SQLModel para el orquestador
- OpenAI o Anthropic para LLM principal; Voyage o OpenAI para embeddings
- Cohere Rerank para reranking (free tier suficiente para la mayoría)
- Sentry o Datadog para observabilidad de latencia y errores
- Ragas para evaluación continua (CI/CD del RAG)
Costo operativo total para un knowledge base productivo de 100k documentos / 1k queries diarias: $300-$800 USD/mes. Costo de implementación con WITS: $400k-$700k MXN típicamente, según complejidad de los conectores y volumen de evaluación requerida.
Errores que vemos repetidamente
- 1Saltarse la evaluación: no midas, no mejoras
- 2Chunking sin pensar: aceptar el default de la librería sin probar alternativas
- 3Solo búsqueda semántica: pierdes 10-20% de recall en queries con keywords
- 4Sin reranking: top-k bruto del retriever rara vez es óptimo
- 5Sin citaciones: el sistema pierde credibilidad la primera vez que alucina
- 6Sin filtrado por permisos: clásica fuga de información cross-tenant
- 7Sobre-ingeniería temprana: vector DB dedicado cuando pgvector cubre
Lo que también te preguntas
¿Por qué Supabase y no Pinecone?
Supabase ofrece Postgres gestionado con pgvector, auth, storage y APIs en un solo proveedor. Para PyMEs y startups en México es operativamente más simple y 10× más barato que Pinecone para volúmenes <10M vectores. Cuando justifique, migrar a Pinecone o vector DB dedicado es un cambio acotado.
¿Cuánto tarda implementar un RAG productivo?
MVP funcional con 1-2 fuentes de datos: 4-6 semanas. RAG productivo con 5+ conectores, evaluación continua y trazabilidad: 10-16 semanas. Multi-tenant con permisos finos y compliance: 16-24 semanas.
¿Necesito un equipo de ML para RAG?
No. RAG es 80% data engineering + 20% prompting; no requiere training de modelos. Un equipo backend sólido (Python + Postgres) puede implementarlo con guía de un consultor que ya pasó por las decisiones difíciles.
¿Qué pasa cuando la fuente de datos cambia?
Pipeline de re-indexación incremental: detecta cambios (timestamp o hash), re-procesa solo los documentos afectados, marca chunks viejos como deprecated y agrega nuevos. La trazabilidad mantiene historial: respuestas históricas se mantienen explicables aunque el contenido cambió.