# Cómo crear un sistema RAG con documentos propios

**Categoría:** Inteligencia artificial · **Nivel:** Intermedio · **Lectura:** 14 min
**Publicada:** 2026-07-27 · **Actualizada:** 2026-07-27 · **Autoría:** Underc0de
**Versión HTML (canónica):** https://underc0de.org/guias/inteligencia-artificial/como-crear-un-sistema-rag-con-documentos-propios/

## Respuesta rápida

**RAG** —*Retrieval-Augmented Generation*— es un patrón que combina, en palabras del trabajo original de Lewis y otros en NeurIPS 2020, «memoria **paramétrica** y **no paramétrica** preentrenadas para generación de lenguaje»: lo que el modelo aprendió en su entrenamiento más un índice externo que se consulta en el momento. Un sistema RAG tiene **dos mitades**: una que **indexa** —trocear los documentos, calcular **embeddings** y guardarlos— y otra que **responde** —buscar los fragmentos pertinentes y pasárselos al modelo con la pregunta—. La calidad final depende mucho más de la **recuperación** que del modelo: si el fragmento correcto no llega al contexto, ningún modelo lo adivina.

## Qué es RAG y de dónde viene

El término viene de «*Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks*», de Patrick Lewis y otros, presentado en **NeurIPS 2020**. Su aporte conceptual es la distinción entre dos memorias:

- **Memoria paramétrica:** lo que el modelo aprendió durante el entrenamiento y quedó codificado en sus parámetros. Rápida, siempre disponible, no se puede consultar ni corregir de forma directa.
- **Memoria no paramétrica:** un índice externo que se consulta en el momento. En el trabajo original era «un índice vectorial denso de Wikipedia, accedido con un recuperador neuronal preentrenado». Se puede actualizar, auditar y citar.

Tres consecuencias de mover el conocimiento fuera del modelo: **se actualiza sin reentrenar**, **se puede citar** y **se puede controlar el acceso**.

## Cuándo conviene y cuándo no

| Lo que falta | Qué conviene | Por qué |
|---|---|---|
| Conocimiento que el modelo no vio, o que cambia seguido | **RAG** | Actualizar es reindexar un documento |
| Necesidad de citar la fuente de cada afirmación | **RAG** | Es la única opción que deja rastro verificable |
| Un formato de salida muy específico o un estilo propio | Ajuste fino | Es comportamiento, no conocimiento |
| Una tarea repetitiva con estructura fija y muchos ejemplos | Ajuste fino | Más barato y rápido al responder |
| El modelo divaga o no entendió el pedido | Mejor [prompt](../como-escribir-buenos-prompts/index.md) | La mitad de los proyectos de RAG empiezan resolviendo esto |
| Los documentos son pocos y chicos | Pasarlos enteros | Si todo entra en el contexto, el índice suma complejidad sin aportar |

## Las dos mitades

**Indexar** corre una vez por documento y cada vez que ese documento cambia:

1. **Leer y extraer el texto.** De PDF, HTML, planillas. Se subestima siempre y es donde más información se pierde.
2. **Trocear.** Cortar en fragmentos que sigan siendo comprensibles por sí solos.
3. **Calcular embeddings.** Un vector por fragmento, con el mismo modelo que después se usará para las preguntas.
4. **Guardar.** El vector, el texto y los metadatos: documento, sección, fecha, permisos.

**Responder** corre en cada pregunta: convertir la pregunta en embedding, buscar los fragmentos más cercanos, reordenarlos, armar el prompt y generar la respuesta.

**La calidad final depende mucho más de la recuperación que del modelo.**

## Trocear: la decisión que más pesa

El fragmento tiene que ser **la unidad más chica que siga siendo comprensible por sí sola**. Fragmentos demasiado chicos pierden el contexto que los hace interpretables; demasiado grandes mezclan temas, compiten mal en la búsqueda y desperdician contexto.

- **Cortar por la estructura, no por cantidad de caracteres.** Títulos, secciones, artículos, filas de una tabla.
- **Repetir el encabezado en cada fragmento.** Agregar la ruta de títulos —«Manual de personal › Licencias › Vacaciones»— mejora la recuperación sin costo.
- **Guardar metadatos desde el principio.** Agregarlos después implica reindexar todo.

```python
# Un fragmento no es solo texto: es texto con su procedencia
fragmento = {
    "texto": "Manual de personal > Licencias > Vacaciones\n"
              "El personal con menos de cinco años de antigüedad...",
    "documento": "manual-personal-v7.pdf",
    "seccion": "3.2 Vacaciones",
    "modificado": "2026-03-14",
    "visible_para": ["empleados"],   # se filtra ANTES de buscar
}
```

## Embeddings y búsqueda

Un **embedding** es la representación de un texto como una lista de números, calculada de manera que **textos con significado parecido queden cerca**. Eso permite que «¿cuántos días de vacaciones tengo?» recupere un párrafo sobre «licencia anual ordinaria» sin compartir una palabra.

La contracara: **la búsqueda por significado falla justo donde la textual acierta** —códigos, números de expediente, nombres propios, versiones exactas—. De ahí la **búsqueda híbrida**, que combina las dos y es la mejora de mayor impacto por unidad de esfuerzo.

Después de recuperar, el **reordenamiento**: traer veinte candidatos y quedarse con los cinco mejores. Pocos y pertinentes es mejor que muchos y mediocres, porque cada fragmento irrelevante es una oportunidad de que el modelo se apoye en lo que no debía.

```bash
# Un embedding local, sin que el documento salga del equipo
# La documentación de Ollama incluye embeddings para búsqueda semántica y RAG
ollama pull embeddinggemma
ollama run embeddinggemma "El personal con menos de cinco años..."

# La salida es un arreglo JSON de números: eso es el vector que se guarda
```

## Anclar la respuesta

```text
Respondé la pregunta usando ÚNICAMENTE los fragmentos de abajo.
Si la respuesta no está en los fragmentos, decí exactamente:
"No encontré esa información en la documentación disponible."
Después de cada afirmación, indicá entre corchetes el número de fragmento.
No uses conocimiento propio ni completes lo que falte.

<fragmentos>
[1] (manual-personal-v7.pdf, 3.2 Vacaciones, 2026-03-14)
El personal con menos de cinco años de antigüedad...

[2] (convenio-2026.pdf, Art. 14, 2026-01-08)
Las licencias se computan en días corridos...
</fragmentos>

Pregunta: ¿cuántos días de vacaciones tengo con tres años de antigüedad?
```

Cuatro elementos hacen el trabajo: la **instrucción exclusiva**, la **salida de escape** con una frase exacta, la **obligación de citar** y los **delimitadores**.

> **Los fragmentos son texto que viene de afuera.** Si los documentos indexados los puede escribir cualquiera —tickets, correos, comentarios—, el contenido recuperado puede traer instrucciones dirigidas al modelo. No se resuelve filtrando palabras: se resuelve no dándole al sistema permisos que no necesita.

## Cómo saber si funciona

Hace falta un conjunto de preguntas reales con su respuesta esperada, y **medir las dos mitades por separado**:

- **Recuperación:** ¿el fragmento que contiene la respuesta apareció entre los recuperados? Se mide sin involucrar al generador.
- **Fundamentación:** ¿lo que respondió está respaldado por los fragmentos que recibió?

Si la recuperación falla, tocar el prompt no sirve: hay que trabajar en el troceado, la búsqueda o el reordenamiento.

## Permisos y privacidad

**El filtro de permisos va antes de la búsqueda, no después.** Si se recupera todo y se descarta lo que la persona no debería ver, cualquier error convierte el buscador interno en una fuga. Y si el fragmento entró al contexto, ya salió del sistema.

- **Qué sale del equipo.** El modelo de embeddings procesa todos los documentos al indexar, y el modelo que redacta ve los fragmentos. Los dos pueden correr localmente: ver [modelos locales con Ollama](../ejecutar-modelos-de-ia-localmente-con-ollama/index.md).
- **Qué queda registrado.** Las preguntas de la gente son datos, y en un buscador interno pueden ser muy delicados.

## Errores frecuentes

- **Empezar por la base vectorial.** Es la decisión menos importante; el troceado es la más importante.
- **Cortar cada 500 caracteres y seguir.**
- **Usar solo búsqueda vectorial.** Los códigos y números exactos se pierden.
- **Usar modelos de embedding distintos para indexar y para preguntar.** Los vectores no son comparables.
- **Meter veinte fragmentos «para que tenga contexto».**
- **No pedir citas.** Sin cita no hay verificación ni diagnóstico.
- **Filtrar permisos después de buscar.**
- **Olvidar reindexar.** Un índice viejo responde con seguridad total lo que decía el documento del año pasado.

## Preguntas frecuentes

**¿Qué es RAG y de dónde sale el nombre?**
De *Retrieval-Augmented Generation*, un trabajo de Lewis y otros en NeurIPS 2020 que combina memoria paramétrica y no paramétrica. En la práctica: buscar el fragmento pertinente en tus documentos y pasárselo al modelo con la pregunta.

**¿Conviene RAG o ajustar el modelo?**
RAG para lo que el modelo no sabe; ajuste para lo que el modelo no hace como querés. Y muchas veces la respuesta es ninguna de las dos, sino un prompt mejor.

**¿De qué tamaño conviene cortar los fragmentos?**
No hay número universal. El criterio: la unidad más chica que siga siendo comprensible por sí sola, cortando por la estructura del documento.

**¿Qué es un embedding y por qué sirve para buscar?**
La representación de un texto como lista de números, donde los significados parecidos quedan cerca. Permite buscar por sentido, pero falla con códigos y números exactos.

**¿Por qué el sistema responde cosas que no están en los documentos?**
O el fragmento correcto nunca llegó —falla de recuperación— o llegó y el modelo mezcló su conocimiento previo —falla de fundamentación—. Se distinguen mirando qué se recuperó.

**¿Se puede armar un RAG sin mandar los documentos a un proveedor externo?**
Sí. El modelo de embeddings y el que redacta pueden correr localmente, a costa de capacidad.

## Fuentes

Fecha de consulta: 27 de julio de 2026.

**Aportes de la comunidad Underc0de**

1. Underc0de, blog. [LangSmith: vulnerabilidad crítica permite robo de claves API y datos en LangChain](https://blog.underc0de.org/langsmith-vulnerabilidad-critica-permite-robo-de-claves-api-y-datos-en-langchain/), 19 de junio de 2025.
2. Underc0de, foro. [Sección Inteligencia artificial](https://underc0de.org/foro/inteligencia-artificial/).

**Literatura y documentación oficial**

3. Lewis, P. y otros. [Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks](https://arxiv.org/abs/2005.11401). NeurIPS 2020.
4. Ollama. [Embeddings](https://docs.ollama.com/capabilities/embeddings).
5. Ollama. [CLI Reference](https://docs.ollama.com/cli).

## Guías relacionadas

- [Evaluación de aplicaciones con modelos de lenguaje](../evaluacion-de-aplicaciones-con-modelos-de-lenguaje/index.md)
- [Cómo ejecutar modelos de IA localmente con Ollama](../ejecutar-modelos-de-ia-localmente-con-ollama/index.md)
- [Seguridad de agentes y aplicaciones de inteligencia artificial](../seguridad-de-agentes-y-aplicaciones-de-ia/index.md)
- [Índice de Inteligencia artificial](../index.md)
