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.
¿Qué es RAG y por qué importa?
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:
- Conocimiento desactualizado: GPT-4 no sabe qué pasó después de su fecha de corte
- No conocen TUS datos: No saben sobre tu empresa, productos, o documentos internos
Soluciones alternativas y por qué RAG es mejor
| Solución | Pros | Contras |
|---|---|---|
| Fine-tuning | Conocimiento "internalizado" | Caro, no actualizable, alucinaciones |
| Prompt largo | Simple | Límite de contexto, caro por token |
| RAG | Actualizable, preciso, económico | Complejidad inicial |
Ejemplo real
Sin RAG:
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:
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 aceptan4en 30 días con el ticket original. Para productos electrónicos...
Cómo funciona RAG (explicación visual)
El flujo completo
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)
1Documento de 50 páginas2 ↓3[Chunk 1: párrafos 1-5]4[Chunk 2: párrafos 6-10]5[Chunk 3: párrafos 11-15]6...
2. Embeddings (convertir a vectores)
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)
1ID: chunk_0012Vector: [0.023, -0.156, ...]3Metadata: {source: "politicas.pdf", page: 12}4Texto: "La política de devoluciones..."
4. Búsqueda por similitud
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
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
1. Document Loaders
Función: Cargar documentos de diferentes formatos.
| Formato | Herramientas |
|---|---|
| PyPDF2, pdfplumber, Unstructured | |
| Word | python-docx |
| Excel | pandas, openpyxl |
| Web | BeautifulSoup, Playwright |
| Notion | Notion API |
| Confluence | Atlassian API |
2. Text Splitters (Chunkers)
Función: Dividir documentos en fragmentos manejables.
| Estrategia | Cuándo usar |
|---|---|
| Por caracteres | Documentos simples |
| Por tokens | Control preciso |
| Por párrafos | Documentos estructurados |
| Recursivo | Textos variados |
| Semántico | Máxima calidad |
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.
| Modelo | Dimensiones | Calidad | Costo |
|---|---|---|---|
| OpenAI ada-002 | 1536 | Muy buena | $0.0001/1K tokens |
| OpenAI text-embedding-3-large | 3072 | Excelente | $0.00013/1K |
| Cohere embed-v3 | 1024 | Muy buena | $0.0001/1K |
| Sentence Transformers (local) | 384-768 | Buena | Gratis |
| BGE (local) | 1024 | Muy buena | Gratis |
4. Vector Databases
Función: Almacenar y buscar vectores eficientemente.
| Database | Tipo | Mejor para |
|---|---|---|
| Pinecone | Cloud | Producción, escala |
| Weaviate | Cloud/Self | Híbrido keyword+vector |
| Chroma | Local/Cloud | Desarrollo, prototipos |
| Qdrant | Self-hosted | Control total |
| pgvector | PostgreSQL ext. | Si ya usas Postgres |
| Supabase | Cloud | Developers Next.js |
5. LLM para generación
Función: Generar respuesta final usando el contexto.
| Modelo | Contexto | Mejor para |
|---|---|---|
| GPT-4o | 128K | Calidad máxima |
| Claude 3.5 | 200K | Contextos largos |
| GPT-4o-mini | 128K | Balance costo/calidad |
| Llama 3 70B | 8K | Self-hosted |
| Mixtral 8x7B | 32K | Open source |
Si quieres ejecutar Llama 3 o Mixtral en local para tu pipeline RAG, necesitas una GPU con al menos 12 GB de VRAM o un equipo con 32 GB+ de RAM. Un mini PC con 32 GB como el Minisforum UM890 Pro puede correr modelos de 7B-13B con Ollama sin problemas, y si necesitas modelos más grandes, un Mac Mini M4 con memoria unificada es la opción más eficiente por vatio.
Tutorial: Construir RAG desde cero
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
1pip install langchain langchain-openai chromadb pypdf
Paso 2: Configurar entorno
1import os2os.environ["OPENAI_API_KEY"] = "tu-api-key"
Paso 3: Cargar documentos
1from langchain_community.document_loaders import PyPDFLoader2from langchain_community.document_loaders import DirectoryLoader3 4# Cargar un PDF5loader = PyPDFLoader("documentos/manual_empresa.pdf")6documents = loader.load()7 8# O cargar todos los PDFs de una carpeta9loader = DirectoryLoader(10 "documentos/",11 glob="**/*.pdf",12 loader_cls=PyPDFLoader13)14documents = loader.load()15 16print(f"Cargados {len(documents)} documentos")
Paso 4: Dividir en chunks
1from langchain.text_splitter import RecursiveCharacterTextSplitter2 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
1from langchain_openai import OpenAIEmbeddings2from langchain_community.vectorstores import Chroma3 4# Crear modelo de embeddings5embeddings = OpenAIEmbeddings(model="text-embedding-3-small")6 7# Crear vector store y almacenar8vectorstore = 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
1# Configurar retriever2retriever = vectorstore.as_retriever(3 search_type="similarity",4 search_kwargs={"k": 4} # Retornar top 4 chunks5)6 7# Probar búsqueda8docs = 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
1from langchain_openai import ChatOpenAI2from langchain.chains import RetrievalQA3from langchain.prompts import PromptTemplate4 5# Modelo LLM6llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)7 8# Prompt personalizado9template = """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 RAG25qa_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=True31)
Paso 8: Usar el sistema
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 uso12ask("¿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
1# rag_system.py2import os3from langchain_community.document_loaders import DirectoryLoader, PyPDFLoader4from langchain.text_splitter import RecursiveCharacterTextSplitter5from langchain_openai import OpenAIEmbeddings, ChatOpenAI6from langchain_community.vectorstores import Chroma7from langchain.chains import RetrievalQA8from langchain.prompts import PromptTemplate9 10class RAGSystem:11 def __init__(self, docs_path="./documentos", db_path="./chroma_db"):12 self.docs_path = docs_path13 self.db_path = db_path14 self.embeddings = OpenAIEmbeddings(model="text-embedding-3-small")15 self.llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)16 self.vectorstore = None17 self.qa_chain = None18 19 def index_documents(self):20 """Indexar todos los documentos"""21 # Cargar22 loader = DirectoryLoader(23 self.docs_path,24 glob="**/*.pdf",25 loader_cls=PyPDFLoader26 )27 documents = loader.load()28 29 # Dividir30 splitter = RecursiveCharacterTextSplitter(31 chunk_size=1000,32 chunk_overlap=20033 )34 chunks = splitter.split_documents(documents)35 36 # Almacenar37 self.vectorstore = Chroma.from_documents(38 documents=chunks,39 embedding=self.embeddings,40 persist_directory=self.db_path41 )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.embeddings50 )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=True71 )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# Uso82if __name__ == "__main__":83 rag = RAGSystem()84 rag.index_documents() # Primera vez85 # rag.load_existing() # Siguientes veces86 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
Para quienes no quieren programar
| Herramienta | Dificultad | Precio | Mejor para |
|---|---|---|---|
| ChatGPT Custom GPTs | Muy fácil | $20/mes | Uso personal |
| Dante AI | Fácil | $52/mes | Chatbots web |
| CustomGPT | Fácil | $89/mes | Empresas |
| Voiceflow | Media | $50/mes | Chatbots avanzados |
| Stack AI | Media | Custom | Enterprise |
CustomGPT de OpenAI (más simple)
- Ve a chat.openai.com → GPTs → Create
- Sube tus documentos (PDFs, docs)
- Escribe instrucciones
- Publica o usa en privado
Limitaciones:
- Máximo 20 archivos
- 512MB por archivo
- Solo funciona en ChatGPT
Mejores prácticas
1. Chunking inteligente
1# Malo: chunks de tamaño fijo sin contexto2chunks = text.split(1000)3 4# Bueno: chunks semánticos con solapamiento5splitter = RecursiveCharacterTextSplitter(6 chunk_size=1000,7 chunk_overlap=200,8 separators=["\n\n", "\n", ". ", " "]9)
2. Metadata enriquecida
1# Añadir metadata útil a cada chunk2for chunk in chunks:3 chunk.metadata["source_file"] = filename4 chunk.metadata["page_number"] = page5 chunk.metadata["section"] = section_title6 chunk.metadata["date_indexed"] = datetime.now()
3. Hybrid Search
Combinar búsqueda semántica + keywords:
1from langchain.retrievers import EnsembleRetriever2from langchain_community.retrievers import BM25Retriever3 4# BM25 para keywords5bm25_retriever = BM25Retriever.from_documents(chunks)6 7# Vector para semántica8vector_retriever = vectorstore.as_retriever()9 10# Combinar11ensemble = EnsembleRetriever(12 retrievers=[bm25_retriever, vector_retriever],13 weights=[0.4, 0.6]14)
4. Reranking
Reordenar resultados con un modelo más preciso:
1from langchain.retrievers import ContextualCompressionRetriever2from langchain_cohere import CohereRerank3 4reranker = CohereRerank(model="rerank-english-v3.0")5compression_retriever = ContextualCompressionRetriever(6 base_compressor=reranker,7 base_retriever=retriever8)
5. Evaluación
1# Métricas clave para RAG2- 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
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
¿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:
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:
- Hoy: Prueba Custom GPT de OpenAI con 2-3 documentos
- Esta semana: Si necesitas más control, sigue el tutorial Python
- Este mes: Evalúa herramientas enterprise si es para producción
Recursos relacionados:
¿Listo para poner tu proyecto en producción?
Si estás siguiendo este tutorial, necesitas un servidor donde desplegarlo. Yo uso Hostinger para mis proyectos porque el panel es intuitivo, los VPS van con SSD NVMe, y a 4,99€/mes no hay nada comparable en relación calidad-precio.
* Enlace de afiliado. Si contratas a través de este enlace, nos ayudas a mantener este contenido gratuito.
Posts Relacionados
Consultoría IA en San Sebastián (Donostia): Agentes, Automatización y Modelos Privados para Empresas [2026]
Guía completa de servicios de inteligencia artificial en San Sebastián: agentes IA, automatización, modelos privados y consultoría para empresas vascas en 2026.
Kit Digital 2026 para IA: Cómo Solicitar Hasta 12.000€ para tu PYME Paso a Paso
Tutorial paso a paso para solicitar el Kit Digital 2026 con soluciones de IA. Requisitos, cuantías por segmento (hasta 12.000€), agentes digitalizadores y errores que rechazan tu solicitud.
Formación en Claude Code para Empresas en España: Proveedores, Precios y Qué Esperar [2026]
Guía de formación en Claude Code para empresas españolas: proveedores, precios (desde 4.000€), programas in-company, duración y resultados esperados.
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.
Lleva tu proyecto a producción
Hosting web desde 2,99€/mes o VPS con SSD NVMe desde 4,99€/mes. Panel intuitivo, IP dedicada y soporte 24/7 en español.
¿Quieres más contenido de IA?
Explora nuestras comparativas y guías