AI · RAG|13 min de lectura|

Cómo Construir un Sistema RAG: IA sobre tus Propios Datos

La forma más rentable de que una empresa aproveche la IA sobre su propio conocimiento no es entrenar un modelo — es RAG: darle a un modelo de lenguaje existente acceso a tus documentos en el momento de responder. Sobre el papel suena simple: buscas los fragmentos relevantes y se los pasas al modelo. En la práctica, la diferencia entre un RAG que funciona y uno que alucina está en las decisiones de ingeniería: cómo partes los documentos, cómo recuperas, cómo fundamentas la respuesta y cómo mides si mejora. Esta guía documenta la arquitectura completa de un sistema RAG para producción, con las decisiones que realmente mueven la aguja.

Qué resuelve RAG y qué no

RAG (Retrieval-Augmented Generation, generación aumentada por recuperación) conecta un modelo de lenguaje a un cuerpo de conocimiento externo — tu documentación, tus políticas, tu histórico. En vez de reentrenar el modelo con tus datos, recuperas los fragmentos relevantes para cada pregunta y los inyectas en el prompt como contexto. El modelo responde fundamentándose en esos fragmentos en lugar de en su memoria interna.

Esto resuelve tres problemas de golpe: reduce las alucinaciones (el modelo cita de tus fuentes, no inventa), mantiene la información actualizada (cambias un documento y la respuesta cambia, sin reentrenar nada) y da trazabilidad (puedes mostrar de qué fragmento salió cada afirmación). Lo que RAG no resuelve: si tus datos son un caos, RAG amplifica el caos. La calidad de la recuperación es el techo de la calidad de las respuestas.

La arquitectura de un pipeline RAG

Un sistema RAG tiene dos fases: una de indexación (offline, cuando ingieres documentos) y una de consulta (online, cuando el usuario pregunta). Los componentes:

  • Ingesta y chunking: los documentos se dividen en fragmentos (chunks) de tamaño manejable. Es la decisión que más impacta la calidad final.
  • Embeddings: cada chunk se convierte en un vector numérico que captura su significado semántico mediante un modelo de embeddings.
  • Base de datos vectorial: los vectores se almacenan en un índice que permite buscar por similitud semántica de forma eficiente.
  • Recuperación (retrieval): en cada consulta se busca la pregunta contra el índice y se traen los chunks más relevantes; idealmente combinando búsqueda semántica y por palabra clave.
  • Reranking: un segundo modelo reordena los candidatos recuperados por relevancia real a la pregunta, subiendo la precisión.
  • Generación con grounding: los chunks recuperados se ensamblan en el prompt y el modelo de lenguaje redacta la respuesta fundamentada en ellos, con citas.
La regla mental: la fase de indexación define qué puede encontrar tu sistema; la fase de consulta define qué tan bien lo encuentra. La mayoría de los RAG que fallan lo hacen en la recuperación, no en la generación — el modelo redactó bien, pero le pasaste el contexto equivocado.

Ingesta y chunking: la decisión que más impacta

El chunking parece trivial y es donde más sistemas se rompen. Si los fragmentos son demasiado grandes, diluyen la señal y desperdician contexto; si son demasiado pequeños, pierden el sentido y fragmentan ideas a la mitad. El objetivo es que cada chunk sea una unidad de significado autocontenida.

Chunking con solapamiento y respeto de estructura

Partir por un número fijo de caracteres corta frases por la mitad. La estrategia que funciona: respetar los límites naturales del documento (párrafos, secciones, encabezados) y añadir un solapamiento entre chunks para no perder el contexto en los bordes.

python
# Chunking que respeta estructura, con solapamiento
def chunk_document(text, target_size=800, overlap=150):
    # Partir primero por límites semánticos (párrafos), no por caracteres
    paragraphs = split_on_headings_and_paragraphs(text)
    chunks, current = [], ""
    for para in paragraphs:
        if len(current) + len(para) <= target_size:
            current += "\n\n" + para
        else:
            chunks.append(current.strip())
            # Arrastrar el final del chunk anterior como solapamiento
            current = current[-overlap:] + "\n\n" + para
    if current.strip():
        chunks.append(current.strip())
    return chunks

# Adjunta metadatos a cada chunk: de qué documento y sección viene.
# Son la base de las citas y del filtrado por permisos.
def to_records(chunks, doc_id, source, section):
    return [
        {"text": c, "doc_id": doc_id, "source": source, "section": section}
        for c in chunks
    ]
Guarda siempre los metadatos de origen (documento, sección, fecha, permisos) junto a cada chunk. Los necesitas para tres cosas críticas: mostrar citas verificables, filtrar por qué puede ver cada usuario, y descartar contenido desactualizado. Un chunk sin procedencia es una respuesta que no puedes defender.

Embeddings y la base de datos vectorial

Un modelo de embeddings convierte cada chunk en un vector de cientos o miles de dimensiones que ubica el texto en un espacio semántico: dos textos con significado parecido quedan cerca. Para almacenarlos y buscarlos no necesitas una base de datos exótica — PostgreSQL con la extensión pgvector es suficiente para la enorme mayoría de los casos, y evita sumar otra pieza de infraestructura.

sql
-- PostgreSQL + pgvector: almacenamiento y búsqueda por similitud
CREATE EXTENSION IF NOT EXISTS vector;

CREATE TABLE chunks (
  id        bigserial PRIMARY KEY,
  doc_id    text NOT NULL,
  source    text NOT NULL,
  section   text,
  content   text NOT NULL,
  embedding vector(1536)            -- dimensión del modelo de embeddings
);

-- Índice ANN para búsqueda aproximada rápida a escala
CREATE INDEX ON chunks USING hnsw (embedding vector_cosine_ops);

-- Recuperar los 8 chunks más cercanos a la pregunta (ya embebida)
SELECT id, content, source, section
FROM chunks
ORDER BY embedding <=> $1        -- distancia coseno contra el vector de la query
LIMIT 8;

El operador de distancia (aquí coseno) mide qué tan cerca está cada chunk de la pregunta en el espacio semántico. El índice HNSW convierte esa búsqueda en algo que escala a millones de vectores con latencia de milisegundos. Para volúmenes muy grandes o requisitos específicos existen bases dedicadas (Qdrant, Weaviate, Milvos), pero empezar por pgvector es la decisión pragmática.

Recuperación: búsqueda híbrida y reranking

La búsqueda semántica sola tiene un punto ciego: falla con términos exactos que no tienen sinónimos — códigos de producto, nombres propios, siglas internas. La búsqueda por palabra clave (BM25, full-text) es lo contrario: excelente con términos exactos, ciega al significado. La combinación de ambas — búsqueda híbrida — recupera mejor que cualquiera por separado.

python
# Búsqueda híbrida: combinar recuperación semántica y por palabra clave
def hybrid_retrieve(query, k=20):
    q_vector = embed(query)
    semantic = vector_search(q_vector, limit=k)   # pgvector, distancia coseno
    keyword  = fulltext_search(query, limit=k)    # BM25 / tsvector de Postgres

    # Fusión por rango recíproco (RRF): un chunk que aparece alto en
    # ambas listas sube; no depende de escalas de score incompatibles.
    scores = {}
    for rank, item in enumerate(semantic):
        scores[item.id] = scores.get(item.id, 0) + 1 / (60 + rank)
    for rank, item in enumerate(keyword):
        scores[item.id] = scores.get(item.id, 0) + 1 / (60 + rank)

    ranked_ids = sorted(scores, key=scores.get, reverse=True)
    return [load_chunk(cid) for cid in ranked_ids[:k]]

Reranking: el paso que más sube la precisión

La recuperación inicial prioriza recall: trae muchos candidatos (20-30) para no dejar fuera lo relevante. Pero meter 30 chunks en el prompt es caro y diluye la señal. Un modelo de reranking (cross-encoder) toma la pregunta y cada candidato juntos y produce un score de relevancia mucho más preciso que la distancia vectorial. Reordenas y te quedas solo con los mejores 4-6 para el prompt. Este paso, barato de añadir, es de los que más mejora la calidad percibida del sistema.

Ensamblar el prompt y generar con grounding

Con los chunks finales seleccionados, ensamblas el prompt: instrucciones claras, el contexto recuperado y la pregunta. La instrucción clave es exigir que el modelo responda solo con base en el contexto y que cite sus fuentes — así conviertes al modelo en un lector de tus documentos, no en un oráculo que improvisa.

text
SISTEMA:
Eres un asistente que responde únicamente con base en el CONTEXTO provisto.
Reglas:
- Si la respuesta no está en el contexto, di exactamente: "No tengo esa
  información en la documentación disponible." No inventes.
- Cita la fuente de cada afirmación con [source: <nombre>].
- Sé conciso y directo.

CONTEXTO:
{chunks_recuperados_con_su_source}

PREGUNTA:
{pregunta_del_usuario}

Para la generación conviene usar un modelo de lenguaje capaz y actual — por ejemplo, los modelos Claude de Anthropic — a través de su API, sin reentrenarlo: todo el conocimiento específico entra por el contexto en cada consulta. El modelo aporta la comprensión del lenguaje y la redacción; tus datos aportan la verdad.

La instrucción de no inventar es necesaria pero no es una garantía por sí sola. Refuérzala en el diseño: si la recuperación no encontró nada por encima de un umbral de relevancia, no llames al modelo — responde directamente que no hay información. Un RAG que sabe decir 'no lo sé' es más confiable que uno que siempre intenta responder.

Evaluación: cómo saber si tu RAG funciona

Un RAG sin evaluación es una demo con suerte. Como el sistema tiene dos etapas, se mide en dos niveles: qué tan bien recupera y qué tan bien responde. Sin separarlas, no sabes si un error viene de traer el contexto equivocado o de redactar mal sobre el contexto correcto.

  • Métricas de recuperación: con un conjunto de preguntas y sus chunks correctos conocidos, mides context recall (¿trajo el chunk que contenía la respuesta?) y context precision (¿qué proporción de lo recuperado era relevante?). Es lo primero que debes medir — si la recuperación falla, nada aguas abajo se salva.
  • Fidelidad (faithfulness): ¿la respuesta se sostiene solo con el contexto recuperado, o el modelo agregó cosas de su cuenta? Es la métrica directa contra la alucinación.
  • Relevancia de la respuesta: ¿responde realmente lo que se preguntó? Una respuesta fiel pero que no aborda la pregunta también es un fallo.
  • Evaluación con un modelo como juez: para escalar, un LLM evalúa cada respuesta contra el contexto y la pregunta según una rúbrica. Se calibra contra un set anotado a mano y automatiza la regresión en cada cambio del pipeline.

Errores comunes al construir RAG

  • Saltarse el chunking y partir por caracteres fijos: corta ideas a la mitad y es la causa número uno de recuperaciones pobres. Respeta la estructura del documento.
  • Solo búsqueda semántica: falla con siglas, códigos y nombres exactos. La búsqueda híbrida con reranking es el estándar que deberías tener por defecto.
  • No medir la recuperación por separado: sin métricas de retrieval, optimizas a ciegas y culpas al modelo de errores que son de recuperación.
  • Ignorar la gobernanza de datos: sin filtrar por permisos en la recuperación, tu RAG puede filtrar a un usuario información que no debería ver. Los metadatos de acceso no son opcionales.
  • Confiar solo en la instrucción de no alucinar: combínala con un umbral de relevancia que corte la generación cuando no hay contexto suficiente.
El control de acceso es parte de la arquitectura de recuperación, no un añadido posterior. El filtro por permisos del usuario debe aplicarse en la consulta al índice — antes de que un chunk llegue al prompt. Un RAG que recupera sin respetar permisos es una fuga de datos esperando a ocurrir, especialmente bajo la Ley 172-13.

Preguntas frecuentes

¿RAG o afinar (fine-tuning) un modelo con mis datos?
Para la enorme mayoría de los casos empresariales, RAG. El fine-tuning cambia el estilo o el comportamiento del modelo, pero es caro, exige reentrenar cada vez que tus datos cambian y no da trazabilidad. RAG mantiene tus datos fuera del modelo, se actualiza al instante cuando cambias un documento y te permite citar fuentes. Empieza siempre asumiendo RAG; considera fine-tuning solo si necesitas un comportamiento o formato muy específico que el prompting no logra.
¿Qué base de datos vectorial debo usar?
Empieza con PostgreSQL + pgvector si ya usas Postgres — cubre la mayoría de los casos sin sumar infraestructura nueva, soporta búsqueda híbrida junto al full-text de Postgres, y escala a millones de vectores con el índice HNSW. Migra a una base dedicada (Qdrant, Weaviate, Milvus) solo cuando tengas requisitos específicos de escala, filtrado avanzado o rendimiento que pgvector no cubra. No empieces por la opción más compleja.
¿Cómo evito que el sistema alucine?
Con tres capas combinadas: una instrucción explícita de responder solo desde el contexto y admitir cuando no sabe; un umbral de relevancia que corta la generación cuando la recuperación no trajo nada suficientemente cercano; y citas verificables que hacen visible de qué fuente salió cada afirmación. Ninguna capa sola basta, pero juntas reducen la alucinación a niveles manejables. La mejor recuperación es la mejor defensa: si le das el contexto correcto, el modelo rara vez inventa.
¿Cuánto contexto (cuántos chunks) debo pasarle al modelo?
Menos de lo que la intuición sugiere. Recuperas muchos candidatos (20-30) para no perder lo relevante, pero después del reranking pasas solo los mejores 4-6 al prompt. Más contexto no es mejor: diluye la señal, aumenta el costo por consulta y puede empeorar la respuesta al enterrar el fragmento clave entre ruido. La calidad del reranking importa más que la cantidad de chunks.
¿Cuánto tarda construir un RAG en producción?
Un prototipo funcional sobre un conjunto acotado de documentos se levanta en días. La distancia entre ese prototipo y un sistema de producción — con ingesta automatizada, búsqueda híbrida, reranking, control de permisos, evaluación continua y manejo de casos límite — es de semanas, no meses, si se enfoca bien. El error caro es llevar el prototipo a producción sin la capa de evaluación: sin métricas no sabes si cada cambio mejora o empeora el sistema.

¿Quieres poner la IA a trabajar sobre el conocimiento de tu empresa, con respuestas fundamentadas y trazables? Diseñamos e implementamos sistemas RAG en producción — desde la ingesta hasta la evaluación.

Habla con el equipo

Artículos relacionados

Camilo José María Castillo
Camilo José María Castillo

Cofundador y Líder Técnico

IQS | Cómo Construir un Sistema RAG: Guía Técnica | IQS