Inicio/Blog/RAG Explicado: Cómo Funciona y Tutorial Práctico [2026]
Volver al Blog
Tutoriales IA2 de febrero de 202618 min

RAG Explicado: Cómo Funciona y Tutorial Práctico [2026]

Qué es RAG (Retrieval Augmented Generation), cómo funciona, y tutorial paso a paso para implementarlo con LangChain y OpenAI.

RAG Explicado: Cómo Crear un ChatGPT con tus Datos [2026]

TLDR: RAG permite que una IA responda preguntas usando TUS documentos, no solo su conocimiento general. Funciona convirtiendo tus documentos en "embeddings" (vectores numéricos), buscando los más relevantes para cada pregunta, y dándoselos al LLM como contexto. Es como darle a ChatGPT un libro de referencia antes de cada respuesta.

Tabla de Contenidos

  1. ¿Qué es RAG y por qué importa?
  2. Cómo funciona RAG (explicación visual)
  3. Componentes de un sistema RAG
  4. Tutorial: Construir RAG desde cero
  5. Herramientas no-code para RAG
  6. Mejores prácticas
  7. Casos de uso empresarial
  8. Preguntas frecuentes


¿Qué es RAG y por qué importa? {#que-es-rag}

RAG (Retrieval Augmented Generation) es una técnica que combina:

  • Retrieval: Buscar información relevante en tus documentos
  • Augmented: Añadir esa información al prompt
  • Generation: Generar una respuesta basada en ese contexto

El problema que resuelve RAG

Los LLMs tienen dos limitaciones críticas:

  1. Conocimiento desactualizado: GPT-4 no sabe qué pasó después de su fecha de corte
  2. No conocen TUS datos: No saben sobre tu empresa, productos, o documentos internos

Soluciones alternativas y por qué RAG es mejor

SoluciónProsContras
Fine-tuningConocimiento "internalizado"Caro, no actualizable, alucinaciones
Prompt largoSimpleLímite de contexto, caro por token
RAGActualizable, preciso, económicoComplejidad inicial

Ejemplo real

Sin RAG:

code
1Usuario: ¿Cuál es la política de devoluciones de mi empresa?
2ChatGPT: No tengo acceso a información específica de tu empresa...

Con RAG:

code
1Usuario: ¿Cuál es la política de devoluciones de mi empresa?
2Sistema RAG: [Busca en documentos] → [Encuentra política_devoluciones.pdf]
3ChatGPT + contexto: Según vuestra política, las devoluciones se aceptan
4en 30 días con el ticket original. Para productos electrónicos...


Cómo funciona RAG (explicación visual) {#como-funciona}

El flujo completo

code
1┌─────────────────────────────────────────────────────────────┐
2│ FASE DE INDEXACIÓN │
3│ (se hace una vez) │
4├─────────────────────────────────────────────────────────────┤
5│ │
6│ Documentos → Chunking → Embeddings → DB │
7│ (PDFs, docs) (dividir) (vectores) Vector │
8│ │
9│ 📄📄📄 → [chunk1] → [0.1, 0.3, → 🗄️ │
10│ [chunk2] 0.7, ...] │
11│ [chunk3] │
12└─────────────────────────────────────────────────────────────┘
13 
14┌─────────────────────────────────────────────────────────────┐
15│ FASE DE CONSULTA │
16│ (cada pregunta) │
17├─────────────────────────────────────────────────────────────┤
18│ │
19│ Pregunta → Embedding → Búsqueda → Contexto → LLM │
20│ similitud relevante │
21│ │
22│ "¿Política → [0.2, 0.4, → 🔍 Top 3 → [chunk → 💬│
23│ devolución?" 0.6, ...] matches relevante] │
24│ │
25└─────────────────────────────────────────────────────────────┘

Explicación de cada paso

1. Chunking (dividir documentos)

code
1Documento de 50 páginas
2
3[Chunk 1: párrafos 1-5]
4[Chunk 2: párrafos 6-10]
5[Chunk 3: párrafos 11-15]
6...

Típicamente 500-1000 tokens por chunk

2. Embeddings (convertir a vectores)

code
1"La política de devoluciones permite 30 días"
2
3[0.023, -0.156, 0.789, 0.234, ..., 0.567]
4(1536 dimensiones para OpenAI ada-002)

3. Vector Database (almacenar)

code
1ID: chunk_001
2Vector: [0.023, -0.156, ...]
3Metadata: {source: "politicas.pdf", page: 12}
4Texto: "La política de devoluciones..."

4. Búsqueda por similitud

code
1Pregunta: "¿Cómo devuelvo un producto?"
2Vector pregunta: [0.018, -0.142, ...]
3
4Buscar vectores más similares (cosine similarity)
5
6Top 3: chunk_001 (0.92), chunk_047 (0.87), chunk_023 (0.85)

5. Generación con contexto

code
1Prompt final al LLM:
2"Basándote en el siguiente contexto, responde la pregunta.
3 
4CONTEXTO:
5[chunk_001: La política de devoluciones permite 30 días...]
6[chunk_047: Para iniciar una devolución, contacte a...]
7[chunk_023: Los productos electrónicos tienen garantía...]
8 
9PREGUNTA: ¿Cómo devuelvo un producto?
10 
11RESPUESTA:"


Componentes de un sistema RAG {#componentes}

1. Document Loaders

Función: Cargar documentos de diferentes formatos.

FormatoHerramientas
PDFPyPDF2, pdfplumber, Unstructured
Wordpython-docx
Excelpandas, openpyxl
WebBeautifulSoup, Playwright
NotionNotion API
ConfluenceAtlassian API

2. Text Splitters (Chunkers)

Función: Dividir documentos en fragmentos manejables.

EstrategiaCuándo usar
Por caracteresDocumentos simples
Por tokensControl preciso
Por párrafosDocumentos estructurados
RecursivoTextos variados
SemánticoMáxima calidad
Parámetros clave:
  • chunk_size: Tamaño del fragmento (500-1500 tokens típico)
  • chunk_overlap: Solapamiento entre chunks (50-200 tokens)

3. Embedding Models

Función: Convertir texto a vectores numéricos.

ModeloDimensionesCalidadCosto
OpenAI ada-0021536Muy buena$0.0001/1K tokens
OpenAI text-embedding-3-large3072Excelente$0.00013/1K
Cohere embed-v31024Muy buena$0.0001/1K
Sentence Transformers (local)384-768BuenaGratis
BGE (local)1024Muy buenaGratis

4. Vector Databases

Función: Almacenar y buscar vectores eficientemente.

DatabaseTipoMejor para
PineconeCloudProducción, escala
WeaviateCloud/SelfHíbrido keyword+vector
ChromaLocal/CloudDesarrollo, prototipos
QdrantSelf-hostedControl total
pgvectorPostgreSQL ext.Si ya usas Postgres
SupabaseCloudDevelopers Next.js

5. LLM para generación

Función: Generar respuesta final usando el contexto.

ModeloContextoMejor para
GPT-4o128KCalidad máxima
Claude 3.5200KContextos largos
GPT-4o-mini128KBalance costo/calidad
Llama 3 70B8KSelf-hosted
Mixtral 8x7B32KOpen source

Tutorial: Construir RAG desde cero {#tutorial}

Stack recomendado para este tutorial

  • Lenguaje: Python
  • Framework: LangChain
  • Embeddings: OpenAI
  • Vector DB: Chroma (local, sin config)
  • LLM: GPT-4o-mini

Paso 1: Instalar dependencias

bash
1pip install langchain langchain-openai chromadb pypdf

Paso 2: Configurar entorno

python
1import os
2os.environ["OPENAI_API_KEY"] = "tu-api-key"

Paso 3: Cargar documentos

python
1from langchain_community.document_loaders import PyPDFLoader
2from langchain_community.document_loaders import DirectoryLoader
3 
4# Cargar un PDF
5loader = PyPDFLoader("documentos/manual_empresa.pdf")
6documents = loader.load()
7 
8# O cargar todos los PDFs de una carpeta
9loader = DirectoryLoader(
10 "documentos/",
11 glob="**/*.pdf",
12 loader_cls=PyPDFLoader
13)
14documents = loader.load()
15 
16print(f"Cargados {len(documents)} documentos")

Paso 4: Dividir en chunks

python
1from langchain.text_splitter import RecursiveCharacterTextSplitter
2 
3text_splitter = RecursiveCharacterTextSplitter(
4 chunk_size=1000,
5 chunk_overlap=200,
6 length_function=len,
7 separators=["\n\n", "\n", " ", ""]
8)
9 
10chunks = text_splitter.split_documents(documents)
11print(f"Creados {len(chunks)} chunks")

Paso 5: Crear embeddings y almacenar

python
1from langchain_openai import OpenAIEmbeddings
2from langchain_community.vectorstores import Chroma
3 
4# Crear modelo de embeddings
5embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
6 
7# Crear vector store y almacenar
8vectorstore = Chroma.from_documents(
9 documents=chunks,
10 embedding=embeddings,
11 persist_directory="./chroma_db"
12)
13 
14print("Vector store creado y persistido")

Paso 6: Crear el retriever

python
1# Configurar retriever
2retriever = vectorstore.as_retriever(
3 search_type="similarity",
4 search_kwargs={"k": 4} # Retornar top 4 chunks
5)
6 
7# Probar búsqueda
8docs = retriever.invoke("política de devoluciones")
9for doc in docs:
10 print(f"Score: {doc.metadata.get('score', 'N/A')}")
11 print(f"Contenido: {doc.page_content[:200]}...")
12 print("---")

Paso 7: Crear la cadena RAG

python
1from langchain_openai import ChatOpenAI
2from langchain.chains import RetrievalQA
3from langchain.prompts import PromptTemplate
4 
5# Modelo LLM
6llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
7 
8# Prompt personalizado
9template = """Usa el siguiente contexto para responder la pregunta.
10Si no encuentras la respuesta en el contexto, di "No encontré información sobre esto en los documentos".
11 
12Contexto:
13{context}
14 
15Pregunta: {question}
16 
17Respuesta útil:"""
18 
19prompt = PromptTemplate(
20 template=template,
21 input_variables=["context", "question"]
22)
23 
24# Crear cadena RAG
25qa_chain = RetrievalQA.from_chain_type(
26 llm=llm,
27 chain_type="stuff",
28 retriever=retriever,
29 chain_type_kwargs={"prompt": prompt},
30 return_source_documents=True
31)

Paso 8: Usar el sistema

python
1def ask(question):
2 result = qa_chain.invoke({"query": question})
3 
4 print(f"Pregunta: {question}")
5 print(f"Respuesta: {result['result']}")
6 print("\nFuentes:")
7 for doc in result['source_documents']:
8 print(f"- {doc.metadata.get('source', 'Unknown')}")
9 print("---\n")
10 
11# Ejemplos de uso
12ask("¿Cuál es la política de devoluciones?")
13ask("¿Cuántos días de vacaciones tengo?")
14ask("¿Cómo solicito un reembolso?")

Código completo

python
1# rag_system.py
2import os
3from langchain_community.document_loaders import DirectoryLoader, PyPDFLoader
4from langchain.text_splitter import RecursiveCharacterTextSplitter
5from langchain_openai import OpenAIEmbeddings, ChatOpenAI
6from langchain_community.vectorstores import Chroma
7from langchain.chains import RetrievalQA
8from langchain.prompts import PromptTemplate
9 
10class RAGSystem:
11 def __init__(self, docs_path="./documentos", db_path="./chroma_db"):
12 self.docs_path = docs_path
13 self.db_path = db_path
14 self.embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
15 self.llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
16 self.vectorstore = None
17 self.qa_chain = None
18 
19 def index_documents(self):
20 """Indexar todos los documentos"""
21 # Cargar
22 loader = DirectoryLoader(
23 self.docs_path,
24 glob="**/*.pdf",
25 loader_cls=PyPDFLoader
26 )
27 documents = loader.load()
28 
29 # Dividir
30 splitter = RecursiveCharacterTextSplitter(
31 chunk_size=1000,
32 chunk_overlap=200
33 )
34 chunks = splitter.split_documents(documents)
35 
36 # Almacenar
37 self.vectorstore = Chroma.from_documents(
38 documents=chunks,
39 embedding=self.embeddings,
40 persist_directory=self.db_path
41 )
42 
43 print(f"Indexados {len(chunks)} chunks de {len(documents)} documentos")
44 
45 def load_existing(self):
46 """Cargar base de datos existente"""
47 self.vectorstore = Chroma(
48 persist_directory=self.db_path,
49 embedding_function=self.embeddings
50 )
51 
52 def setup_qa_chain(self):
53 """Configurar cadena de QA"""
54 template = """Responde la pregunta basándote en el contexto.
55 Si no hay información relevante, indícalo.
56 
57 Contexto: {context}
58 Pregunta: {question}
59 Respuesta:"""
60 
61 prompt = PromptTemplate(
62 template=template,
63 input_variables=["context", "question"]
64 )
65 
66 self.qa_chain = RetrievalQA.from_chain_type(
67 llm=self.llm,
68 retriever=self.vectorstore.as_retriever(search_kwargs={"k": 4}),
69 chain_type_kwargs={"prompt": prompt},
70 return_source_documents=True
71 )
72 
73 def ask(self, question):
74 """Hacer una pregunta"""
75 result = self.qa_chain.invoke({"query": question})
76 return {
77 "answer": result["result"],
78 "sources": [doc.metadata for doc in result["source_documents"]]
79 }
80 
81# Uso
82if __name__ == "__main__":
83 rag = RAGSystem()
84 rag.index_documents() # Primera vez
85 # rag.load_existing() # Siguientes veces
86 rag.setup_qa_chain()
87 
88 response = rag.ask("¿Cuál es el proceso de onboarding?")
89 print(response["answer"])


Herramientas no-code para RAG {#herramientas-nocode}

Para quienes no quieren programar

HerramientaDificultadPrecioMejor para
ChatGPT Custom GPTsMuy fácil$20/mesUso personal
Dante AIFácil$52/mesChatbots web
CustomGPTFácil$89/mesEmpresas
VoiceflowMedia$50/mesChatbots avanzados
Stack AIMediaCustomEnterprise

CustomGPT de OpenAI (más simple)

  1. Ve a chat.openai.com → GPTs → Create
  2. Sube tus documentos (PDFs, docs)
  3. Escribe instrucciones
  4. Publica o usa en privado

Limitaciones:

  • Máximo 20 archivos
  • 512MB por archivo
  • Solo funciona en ChatGPT


Mejores prácticas {#mejores-practicas}

1. Chunking inteligente

python
1# Malo: chunks de tamaño fijo sin contexto
2chunks = text.split(1000)
3 
4# Bueno: chunks semánticos con solapamiento
5splitter = RecursiveCharacterTextSplitter(
6 chunk_size=1000,
7 chunk_overlap=200,
8 separators=["\n\n", "\n", ". ", " "]
9)

2. Metadata enriquecida

python
1# Añadir metadata útil a cada chunk
2for chunk in chunks:
3 chunk.metadata["source_file"] = filename
4 chunk.metadata["page_number"] = page
5 chunk.metadata["section"] = section_title
6 chunk.metadata["date_indexed"] = datetime.now()

3. Hybrid Search

Combinar búsqueda semántica + keywords:

python
1from langchain.retrievers import EnsembleRetriever
2from langchain_community.retrievers import BM25Retriever
3 
4# BM25 para keywords
5bm25_retriever = BM25Retriever.from_documents(chunks)
6 
7# Vector para semántica
8vector_retriever = vectorstore.as_retriever()
9 
10# Combinar
11ensemble = EnsembleRetriever(
12 retrievers=[bm25_retriever, vector_retriever],
13 weights=[0.4, 0.6]
14)

4. Reranking

Reordenar resultados con un modelo más preciso:

python
1from langchain.retrievers import ContextualCompressionRetriever
2from langchain_cohere import CohereRerank
3 
4reranker = CohereRerank(model="rerank-english-v3.0")
5compression_retriever = ContextualCompressionRetriever(
6 base_compressor=reranker,
7 base_retriever=retriever
8)

5. Evaluación

python
1# Métricas clave para RAG
2- Relevancia del retrieval (¿encontró los chunks correctos?)
3- Fidelidad de la respuesta (¿es fiel al contexto?)
4- Cobertura (¿respondió todo lo preguntado?)
5- Latencia (¿tiempo de respuesta aceptable?)


Casos de uso empresarial {#casos-uso}

1. Soporte al cliente

Documentos: FAQs, manuales, políticas Beneficio: 70% consultas resueltas automáticamente

2. Onboarding de empleados

Documentos: Handbook, procesos, organigramas Beneficio: Nuevos empleados productivos más rápido

3. Legal/Compliance

Documentos: Contratos, regulaciones, precedentes Beneficio: Búsqueda de cláusulas en segundos

4. Ventas/Preventa

Documentos: Fichas de producto, casos de éxito, pricing Beneficio: Respuestas precisas a prospects

5. Investigación

Documentos: Papers, informes, notas Beneficio: Síntesis de conocimiento acumulado


Preguntas frecuentes {#faq}

¿RAG o Fine-tuning?

RAG cuando:

  • Datos cambian frecuentemente
  • Necesitas citar fuentes
  • Quieres actualizar sin re-entrenar
  • Presupuesto limitado

Fine-tuning cuando:

  • Necesitas cambiar el "estilo" del modelo
  • Datos muy estables
  • Casos muy específicos
  • Tienes recursos para entrenar

¿Cuántos documentos puede manejar RAG?

Prácticamente ilimitados si:

  • Usas vector database escalable (Pinecone, Weaviate)
  • Chunking eficiente
  • Indexación por lotes

Sistemas de producción manejan millones de documentos.

¿Qué pasa si el documento no tiene la respuesta?

Buena práctica: Instruir al modelo para que lo diga:

code
1"Si no encuentras la información en el contexto proporcionado,
2responde: 'No encontré información sobre esto en los documentos disponibles.
3¿Podrías reformular la pregunta o indicar en qué documento podría estar?'"


Conclusión

RAG es la forma más práctica de dar a las IAs acceso a tus datos privados. Con las herramientas actuales, puedes construir un sistema funcional en horas, no semanas.

Tu plan de acción:

  1. Hoy: Prueba Custom GPT de OpenAI con 2-3 documentos
  2. Esta semana: Si necesitas más control, sigue el tutorial Python
  3. Este mes: Evalúa herramientas enterprise si es para producción

Recursos relacionados:

Posts Relacionados

JS

Javier Santos Criado

Consultor de IA y Automatización | Fundador de Javadex

Experto en implementación de soluciones de Inteligencia Artificial para empresas. Especializado en automatización con n8n, integración de LLMs, y desarrollo de agentes IA.

¿Quieres más contenido de IA?

Explora nuestras comparativas y guías