← Resources
TUTORIAL · 2026-02-12
Construye una pipeline RAG de producción sin LangChain (2026)
Puedes desplegar una pipeline RAG de nivel producción en unos pocos cientos de líneas de código componiendo SDKs de proveedores, pgvector y un reranker directamente. Sáltate las abstracciones de LangChain hasta que tengas una necesidad concreta que realmente resuelvan.
Por qué los equipos están desempaquetando LangChain en 2026
Para 2026, eliminar LangChain de producción se ha convertido en un patrón de ingeniería reconocible, con postmortems públicos de equipos que en su día lo evangelizaron. El conjunto de quejas es consistente: capas de abstracción que ocultan lo que realmente se envía al modelo, cambios disruptivos frecuentes entre versiones menores y sesiones de depuración que se convierten en expediciones de espeleología a través de clases wrapper.
El cambio de fondo es que los SDKs de los proveedores han mejorado. Los SDKs de OpenAI, Anthropic y Google ahora incorporan streaming, salidas estructuradas, llamadas a herramientas y batching de primera clase. Voyage, Cohere y Jina exponen endpoints REST limpios para embeddings y reranking. Postgres con pgvector maneja búsqueda ANN hasta aproximadamente 10 M de vectores sin una base de datos vectorial dedicada.
Para la mayoría de las cargas RAG, el framework que querías en 2023 son ahora cuatro llamadas a funciones y una consulta SQL. El valor por defecto razonable en 2026 es empezar con SDKs en bruto, añadir una abstracción de pipeline fina cuando sientas dolor real y tratar los frameworks pesados como opt-in.
Las cinco etapas que necesita toda pipeline RAG
Todo sistema RAG de producción, independientemente del framework, se descompone en las mismas cinco etapas. Nombrarlas explícitamente facilita probar y reemplazar el código por partes.
- Ingesta: cargar documentos fuente, normalizar codificación, eliminar boilerplate.
- Chunking: dividir en unidades de recuperación con IDs estables y metadatos de origen.
- Embed e indexar: codificar chunks en un vector store, junto con un índice léxico para búsqueda híbrida.
- Recuperar y rerankear: extraer un conjunto amplio de candidatos y luego estrecharlo con un reranker cross-encoder.
- Generar y citar: ensamblar un prompt con el contexto recuperado y devolver respuestas con atribución de fuente.
Mantén cada etapa como una función pura con entradas y salidas tipadas. La etapa de recuperación no debería saber qué LLM generará; la etapa de generación no debería saber qué modelo de embedding se usó. Esta separación es lo que los frameworks prometen y rara vez entregan, porque acoplan etapas mediante objetos chain opacos. Escribirlo tú mismo lleva una tarde y elimina una categoría de riesgo de actualización.
Estrategias de chunking: semántico, recursivo y agéntico
El chunking es donde se gana o se pierde la mayor parte de la calidad RAG. Tres patrones dominan en 2026.
El splitting recursivo por caracteres sobre una jerarquía de separadores (párrafos, frases, luego caracteres) es la línea base. Es rápido, determinista y suficientemente bueno para prosa. El chunking semántico embede candidatos a división y fusiona chunks adyacentes cuyos embeddings están próximos, produciendo unidades temáticamente coherentes a mayor coste de ingesta. El chunking agéntico pide a un LLM pequeño que proponga puntos de división para documentos estructurados como contratos o transcripciones, donde los encabezados y los límites de turno importan más que el recuento de caracteres.
def recursive_chunk(text, max_chars=1200, overlap=150):
seps = ["\n\n", "\n", ". ", " "]
def split(s, depth=0):
if len(s) <= max_chars or depth == len(seps):
return [s]
parts, sep = [], seps[depth]
for p in s.split(sep):
parts.extend(split(p, depth + 1))
return parts
raw = split(text)
return [raw[i] + raw[i+1][:overlap] for i in range(len(raw)-1)] + [raw[-1]]
Empieza con recursivo, mide y gradúa a semántico solo en las clases de documento donde la evaluación demuestre que compensa.
Embeddings y rerankers: Voyage, BGE y Cohere
El panorama de retrievers en 2026 es más claro de lo que era hace un año. Voyage AI, ahora parte de MongoDB, ofrece voyage-3-large como un modelo denso de propósito general sólido y lanzó la familia voyage-4 a principios de 2026 con una variante de mezcla de expertos dirigida a la cima del leaderboard RTEB. embed-v4 de Cohere es el otro favorito de producción. Para autoalojamiento open-weight, bge-m3 de BAAI sigue siendo el predeterminado: un solo modelo que soporta recuperación densa, sparse y multivector en más de 100 idiomas, con un contexto de 8192 tokens.
Para reranking, Cohere rerank-v3.5 es el caballo de batalla: un modelo multilingüe, chunks de 4096 tokens y una latencia p50 de aproximadamente 80-150 ms en payloads típicos. Voyage rerank-2 es competitivo y se integra limpiamente si ya usas embeddings de Voyage.
La regla práctica: elige un embedder denso, un reranker y congela el par detrás de una interfaz. Cambiar después cuesta una reindexación, no una reescritura.
Conectando recuperación, generación y citas
Con pgvector consigues búsqueda híbrida y citas en SQL sencillo. Almacena los chunks con su ID de documento, embedding y un tsvector para recall léxico. Recupera un conjunto amplio de candidatos, rerankéalo y pasa los N principales al LLM con IDs de fuente explícitos que se le instruye citar.
import psycopg, voyageai, cohere
vo, co = voyageai.Client(), cohere.Client()
def retrieve(query, k=40, top_n=8):
qvec = vo.embed([query], model="voyage-3-large").embeddings[0]
with psycopg.connect(DSN) as conn:
rows = conn.execute(
"SELECT id, doc_id, text FROM chunks ORDER BY embedding <=> %s LIMIT %s",
(qvec, k)).fetchall()
docs = [r[2] for r in rows]
ranked = co.rerank(model="rerank-v3.5", query=query, documents=docs, top_n=top_n)
return [rows[r.index] for r in ranked.results]
```
Para pgvector, por defecto usa un índice HNSW con m=16 y ef_construction=64, añade un prefiltro de tenant o de recencia para que el escaneo ANN empiece estrecho, y empareja siempre `ORDER BY embedding <=> $1` con un `LIMIT`. Pasa los chunks recuperados al LLM con sus IDs e instrúyele a emitir marcadores de cita; resuelve esos marcadores a URLs de origen en un paso de postproceso.
Evaluación: tasa de aciertos, MRR y fidelidad
Una pipeline RAG sin un arnés de evaluación es una conjetura. Construye el arnés antes de ajustar nada. El kit mínimo es un conjunto etiquetado de consultas de 100 a 500 ejemplos cubriendo los tipos de pregunta que realmente esperas, más tres métricas.
La tasa de aciertos en K responde si el chunk correcto entró en el conjunto de candidatos, lo que aísla la calidad de la recuperación. El mean reciprocal rank captura cuánto subió el chunk correcto, que es lo que paga el reranker por mejorar. La fidelidad, puntuada por un LLM-juez que compara cada afirmación generada con los chunks citados, captura si el modelo alucinó más allá de su contexto.
Ejecuta el arnés en cada cambio: un nuevo tamaño de chunk, un embedder diferente, una edición de prompt. Representa las tres métricas a lo largo del tiempo en el mismo dashboard. Cuando un cambio mejora MRR pero hunde la fidelidad, el reranker está sacando distractores y el prompt de generación necesita guardrails, no más ajuste de recuperación.
Cuándo graduarte a un orquestador gestionado
Las pipelines hechas a mano permanecen mantenibles mientras un solo equipo las posea y el número de etapas sea pequeño. El punto en el que un orquestador gestionado compensa es cuando los no ingenieros necesitan ajustar la recuperación, cuando estás ejecutando muchas pipelines en paralelo para distintas clases de documentos o cuando quieres configuraciones versionadas y enrutamiento A/B sin un redespliegue.
Llegado ese punto, la elección está entre frameworks pesados como LlamaIndex o Haystack y plataformas dirigidas por configuración que exponen las etapas de recuperación como unidades declarativas. osStudio, el editor de orquestación sin código de osFoundry, toma el segundo enfoque: las cinco etapas anteriores son objetos de configuración de primera clase con embeddings y reranking de Voyage gestionados detrás de un único proxy, así que mantienes BYOK en el lado del LLM y evitas el bloqueo de framework en el lado de la recuperación.
La pregunta útil no es framework vs sin framework. Es si tu configuración de pipeline merece ser código, configuración o UI, y esa respuesta cambia a medida que crece el equipo.
Frequently asked questions
- ¿Necesito realmente una base de datos vectorial para RAG?
- Probablemente no hasta que cruces varios millones de vectores. Postgres con pgvector maneja cómodamente hasta unos 10 millones de vectores con un índice HNSW, búsqueda híbrida mediante tsvector y filtros SQL estándar para tenant y recencia. Heredas backups, replicación y control de acceso de la base de datos que ya operas. Las bases de datos vectoriales dedicadas como Qdrant, Milvus o Weaviate compensan su coste operativo cuando necesitas índices sharded de miles de millones, filtrado especializado a QPS muy alto o funciones como recuperación multivector que pgvector aún no iguala. Empieza con pgvector y migra solo cuando un cuello de botella medido lo fuerce.
- ¿Realmente merece la pena un reranker por la latencia?
- Para la mayoría de las cargas con mucha recuperación, sí. Un reranker cross-encoder como Cohere rerank-v3.5 o Voyage rerank-2 normalmente añade entre 80 y 200 milisegundos en p50 sobre un conjunto de candidatos de 40 a 100 chunks, y eleva de forma consistente el mean reciprocal rank entre un 10 y un 30 por ciento frente a la recuperación densa sola. La latencia queda oculta tras cualquier llamada LLM que siga, que suele dominar el presupuesto visible para el usuario. Sáltate el reranker solo para flujos tipo autocompletado críticos en latencia por debajo de 200 milisegundos extremo a extremo, o cuando tu conjunto de candidatos ya sea lo bastante pequeño como para que el ranking denso sea fiable.
- ¿Cómo manejo el solapamiento de chunks sin inflar el almacenamiento?
- Usa solapamientos pequeños del 10 al 15 por ciento del tamaño del chunk, almacenados como offsets de caracteres en el documento de origen en lugar de texto duplicado. En el momento de la recuperación puedes opcionalmente buscar el chunk vecino para expansión de contexto. Esto mantiene el índice ligero y evita pagar por los mismos tokens dos veces durante el embedding. Si necesitas un contexto más rico para la generación, funciona bien un patrón parent-document: indexa chunks pequeños para precisión de recuperación, luego resuelve los aciertos a su sección padre antes de pasarlos al LLM. La búsqueda del padre es una sola consulta indexada y añade latencia despreciable.
- ¿Cuál es la forma más sencilla de evaluar la calidad RAG?
- Construye un conjunto etiquetado de 100 a 200 consultas representativas con los IDs de chunk que deberían recuperarse. Calcula la tasa de aciertos en K y el mean reciprocal rank solo desde la etapa de recuperación, lo que aísla la calidad del retriever del ruido de la generación. Para la fidelidad, usa un LLM-juez que compare cada afirmación generada con los chunks citados y puntúe fundamentada vs no fundamentada. Ejecuta las tres cifras en cada cambio significativo y trata las regresiones como bloqueos. Esta configuración de tres métricas captura la mayoría de las regresiones RAG en la práctica y evita la trampa de optimizar un número mientras dañas silenciosamente otro.
Sources