Aquí tienes la traducción al español (Latinoamérica), manteniendo el formato, la estructura y todos los fragmentos de código intactos.
Pregúntale a Claude sobre tu empresa, tus notas o tus archivos, y se quedará en blanco. Nunca los ha visto. Solo conoce lo que aprendió durante su entrenamiento, y tu contenido no fue parte de eso.
Un sistema RAG soluciona esto. En lugar de responder de memoria, Claude primero busca en tus documentos, toma las partes relevantes y responde basándose en lo que realmente encontró. Tus datos como fuente, sin adivinanzas.
Por qué es mejor que solo pegar archivos en el chat:
Escala. Toda tu base de conocimiento no cabe en un solo chat. RAG almacena todo y solo extrae lo que necesita cada pregunta.
Es más económico. Pegar un archivo significa que Claude relee el documento completo en cada pregunta. RAG lo lee una vez y luego obtiene solo la parte relevante. En lugar de enviar un manual de 10,000 tokens cada vez, podría enviar 500 tokens de la sección exacta que necesitas. Las configuraciones reales reducen el uso de tokens en un 80% o más.
Es más preciso. Si le das al modelo un muro de texto enorme, pierde los detalles del medio. Si le das unos pocos fragmentos precisos, las respuestas son más acertadas.
Se mantiene actualizado. Actualiza tus archivos una vez y el sistema usa la versión nueva. Sin tener que volver a pegar nada.
Al final de esta guía, tendrás uno funcionando con tus propios archivos, paso a paso, sin necesidad de un doctorado.
Lo que vas a necesitar
Antes de tocar cualquier código, aquí está la lista completa. La buena noticia: esta versión solo necesita una clave API, y todo lo demás corre gratis en tu propia máquina.
1. Python 3.9 o superior. Para verificar si lo tienes, abre tu terminal (Terminal en Mac, Símbolo del sistema en Windows) y escribe python --version. Si ves algo como 3.11, estás listo. Si no, descárgalo de python.org y ejecuta el instalador. En Windows, marca la casilla "Añadir Python al PATH" durante la instalación, de lo contrario los comandos de abajo no funcionarán.
2. Una clave API de Claude, más un saldo pequeño de crédito. Esta es la única clave y el único dinero que necesita toda la guía. Aquí está la ruta exacta, clic por clic:
Ve a platform.claude.com, e inicia sesión (o regístrate) allí.
La API necesita un saldo positivo para funcionar, así que primero agrega fondos. Cuando se te solicite, elige si los créditos son para ti o para una empresa, y luego llegarás a la pantalla de pago. Selecciona la opción $5 "Empezando". Eso es suficiente: todo lo demás en esta guía es gratis y local, así que Claude es lo único que cuesta dinero, y cada pregunta te cuesta una fracción de centavo. Los créditos vencen un año después de la compra.
Después de pagar, llegarás al panel de tu Consola. Deberías ver tu saldo (por ejemplo, $5.00) en la parte superior izquierda bajo "Créditos de la organización".
Ahora obtén la clave. Haz clic en Obtener clave API (arriba a la derecha), luego en Crear clave. Ponle cualquier nombre que quieras (por ejemplo, mi-clave-rag) y deja el espacio de trabajo como Predeterminado. Haz clic en crear, luego copia la cadena que te muestra. Empieza con sk-ant- y solo la ves una vez, así que pégala en un lugar seguro por un momento.
Esa es toda la configuración.
Paso 1: Agrega tu clave y carga tus archivos
1. Crea la carpeta del proyecto. Crea una nueva carpeta en tu Escritorio y nómbrala rag-project. Todo va aquí.
2. Abre tu terminal. En Mac: Cmd+Espacio, escribe Terminal, presiona Enter. En Windows: Botón de Inicio, escribe cmd, presiona Enter.
3. Apunta la terminal a tu carpeta. Escribe cd y un espacio, luego arrastra la carpeta rag-project a la ventana de la terminal y presiona Enter. Todos los comandos de abajo se ejecutan desde dentro de esta carpeta.
1cd Desktop/rag-project
4. Instala las herramientas. Pega esto en tu terminal y presiona Enter (la primera ejecución puede tomar un minuto):
1pip install anthropic chromadb sentence-transformers pypdf python-dotenv
Si obtienes pip: command not found, usa pip3 en lugar de pip. Cuando la terminal muestre una línea nueva sin errores en rojo, está listo.
5. Crea tu archivo de código. Dentro de rag-project, crea un archivo vacío con el nombre exacto rag.py. Ábrelo en cualquier editor de texto.
6. Crea tu archivo de clave. En la misma carpeta, crea un archivo con el nombre exacto .env (empieza con un punto, sin nombre antes). Pega esto dentro, con la clave real que creaste durante la configuración después del =, sin espacios, sin comillas:
1ANTHROPIC_API_KEY=sk-ant-pega-tu-clave-real-aqui
Mantener la clave en .env en lugar de en tu código significa que no se filtrará si compartes el script o lo subes a GitHub.
7. Carga la clave. Pon esto al inicio de rag.py:
1import os2from dotenv import load_dotenv34load_dotenv() # lee tu archivo .env5api_key = os.getenv("ANTHROPIC_API_KEY")
8. Crea tu base de conocimiento. Dentro de rag-project, crea una carpeta llamada documents. Coloca allí cualquier archivo .txt, .md o .pdf: tus notas, un documento de producto, resúmenes de reuniones, lo que sea.
8.1. Si aún no tienes archivos, usa este archivo de prueba. Crea notes.txt dentro de la carpeta documents y pega esto:
Project Northstar es nuestra herramienta interna para rastrear comentarios de clientes. Se lanzó en marzo de 2026 y es mantenida por el equipo de plataforma. La ingeniera líder es Dana Reyes. Los comentarios se revisan cada viernes. Northstar reemplazó el antiguo sistema de hojas de cálculo que usamos hasta 2025.
Al final, le preguntarás a Claude sobre Northstar y lo verás responder desde este mismo archivo.
9. Agrega el código que lee tus archivos. Debajo del código del paso 7, en rag.py:
1from pathlib import Path2from pypdf import PdfReader34def load_documents(folder="documents"):5 docs = []6 for file in Path(folder).iterdir():7 if file.suffix in [".txt", ".md"]:8 text = file.read_text(encoding="utf-8")9 docs.append({"source": file.name, "text": text})10 elif file.suffix == ".pdf":11 reader = PdfReader(str(file))12 text = "\n".join(page.extract_text() or "" for page in reader.pages)13 docs.append({"source": file.name, "text": text})14 return docs1516documents = load_documents()17print(f"Se cargó(aron) {len(documents)} documento(s).")
10. Ejecútalo. Guarda rag.py, luego en tu terminal:
1python rag.py
Deberías ver:
Se cargó(aron) 1 documento(s).
Si ves "Se cargó(aron) 0 documento(s)", la carpeta documents está vacía o en el lugar equivocado. Debe estar directamente dentro de rag-project, al lado de rag.py.
Paso 2: Divide tus archivos en fragmentos
Ahora mismo cada archivo es un gran bloque de texto. Antes de poder buscarlo, necesitamos dividirlo en piezas más pequeñas llamadas fragmentos. Aquí está el porqué: cuando alguien hace una pregunta, el sistema encuentra los fragmentos que coinciden y envía solo esos a Claude. Si tus fragmentos son documentos enteros de 50 páginas, envías demasiado. Si son oraciones individuales, pierden contexto. Los párrafos pequeños son el punto óptimo.
1. Agrega el código de división. Debajo del código del paso 10, en rag.py:
1def chunk_text(text, chunk_size=500, overlap=100):2 words = text.split()3 chunks = []4 start = 05 while start < len(words):6 end = start + chunk_size7 chunk = " ".join(words[start:end])8 chunks.append(chunk)9 start = end - overlap # retrocede un poco para que los fragmentos se superpongan10 return chunks
Dos números para entender aquí, en términos simples:
- chunk_size=500 significa que cada fragmento tiene aproximadamente 500 palabras. Suficientemente grande para contener una idea completa, lo suficientemente pequeño para ser preciso.
- overlap=100 significa que cada fragmento repite las últimas 100 palabras del anterior. Esto importa porque una respuesta podría estar justo en la línea donde se encuentran dos fragmentos. Sin superposición, una oración dividida por la mitad podría perderse. La superposición asegura que ninguna idea se pierda en la grieta.
2. Convierte cada documento en fragmentos. Agrega esto debajo:
1all_chunks = []2for doc in documents:3 for chunk in chunk_text(doc["text"]):4 all_chunks.append({"source": doc["source"], "text": chunk})56print(f"Se crearon {len(all_chunks)} fragmento(s) a partir de {len(documents)} documento(s).")
Observa que cada fragmento lleva su source (el nombre del archivo del que proviene). Lo mantenemos adjunto durante todo el proceso, para que cuando Claude responda más tarde, pueda decirte de qué archivo provino la respuesta.
3. Ejecútalo. Guarda rag.py, luego en tu terminal:
1python rag.py
Deberías ver algo como:
Se cargó(aron) 1 documento(s).
Se crearon 1 fragmento(s) a partir de 1 documento(s).
El archivo de prueba pequeño se convierte en un solo fragmento porque es corto. Los documentos reales producirán muchos. Si colocaste un PDF largo en la carpeta, podrías ver docenas o cientos de fragmentos, que es exactamente lo que quieres.
Paso 3: Convierte tus fragmentos en embeddings
Este es el paso que permite que la computadora busque por significado en lugar de palabras exactas. Cada fragmento se convierte en una lista de números (un embedding) que captura de qué se trata. Los fragmentos con significado similar terminan con números similares. Más tarde, cuando llegue una pregunta, convertimos la pregunta en números también y encontramos las coincidencias más cercanas.
El modelo que hace esto se ejecuta localmente en tu máquina. Se descarga una vez, luego funciona sin conexión y es gratis, y tus archivos nunca salen de tu computadora.
1. Carga el modelo de embeddings. Debajo del código del paso 2, en rag.py:
1from sentence_transformers import SentenceTransformer23print("Cargando el modelo de embeddings (la primera ejecución lo descarga, unos 90 MB)...")4embedder = SentenceTransformer("all-MiniLM-L6-v2")
La primera vez que ejecutes esto, descarga el modelo, así que dale un momento. Cada ejecución posterior es instantánea porque ya está en tu máquina.
2. Convierte cada fragmento en un embedding. Agrega esto debajo:
1chunk_texts = [chunk["text"] for chunk in all_chunks]2embeddings = embedder.encode(chunk_texts)34print(f"Se crearon {len(embeddings)} embedding(s).")5print(f"Cada embedding es una lista de {len(embeddings[0])} números.")
embedder.encode(...) toma tu lista de textos de fragmentos y devuelve un embedding por fragmento. Eso es todo lo que se necesita.
3. Ejecútalo. Guarda rag.py, luego en tu terminal:
1python rag.py
La primera ejecución se detiene mientras se descarga el modelo, luego deberías ver algo como:
Se cargó(aron) 1 documento(s).
Se crearon 1 fragmento(s) a partir de 1 documento(s).
Cargando el modelo de embeddings (la primera ejecución lo descarga, unos 90 MB)...
Se crearon 1 embedding(s).
Cada embedding es una lista de 384 números.
Esa línea de "384 números" es toda la idea hecha visible: tu texto ahora es una fila de números que la computadora puede comparar. No necesitas leer ni entender esos números tú mismo. La base de datos en el siguiente paso maneja toda la comparación por ti.
Si la descarga falla con un error de conexión, solo ejecuta el comando nuevamente. Retoma desde donde se quedó.
Paso 4: Almacena todo en tu base de datos vectorial
Ahora colocamos los fragmentos y sus embeddings en Chroma, tu base de datos local. Esto es lo que hace que la búsqueda sea rápida: en lugar de comparar tu pregunta contra cada fragmento manualmente cada vez, Chroma los almacena listos para usar y hace la coincidencia por ti. Se guarda en una carpeta en tu máquina, por lo que solo lo construyes una vez.
1. Configura la base de datos. Debajo del código del paso 3, en rag.py:
1import chromadb23client = chromadb.PersistentClient(path="chroma_db")4collection = client.get_or_create_collection("my_documents")
PersistentClient(path="chroma_db") le dice a Chroma que guarde en una carpeta llamada chroma_db (la crea automáticamente, justo al lado de tu script). Debido a que se guarda en el disco, tus datos sobreviven después de que el script termina. Una collection es simplemente la caja con nombre donde viven tus fragmentos.
2. Agrega tus fragmentos a la base de datos. Agrega esto debajo:
1collection.add(2 ids=[str(i) for i in range(len(all_chunks))],3 embeddings=[emb.tolist() for emb in embeddings],4 documents=[chunk["text"] for chunk in all_chunks],5 metadatas=[{"source": chunk["source"]} for chunk in all_chunks],6)78print(f"Se almacenaron {collection.count()} fragmento(s) en la base de datos.")
Esto es lo que cada línea le entrega a Chroma, en términos simples: ids le da a cada fragmento una etiqueta única (0, 1, 2...), embeddings son los números del paso 3, documents es el texto real del fragmento, y metadatas lleva el nombre del archivo para que podamos mostrar la fuente más tarde. Chroma mantiene los cuatro vinculados.
3. Ejecútalo. Guarda rag.py, luego en tu terminal:
1python rag.py
Deberías ver:
Se almacenaron 1 fragmento(s) en la base de datos.
Algo que debes saber para después. Cada vez que ejecutas el script ahora, agrega los fragmentos nuevamente, por lo que los recuentos pueden aumentar (1, luego 2, luego 3...) en ejecuciones repetidas. Eso está bien mientras estamos construyendo. Para empezar limpio, elimina la carpeta chroma_db y ejecuta una vez más. En la versión final manejaremos esto correctamente para que no se duplique.
Paso 5: Busca en tus documentos
Esta es la parte de "recuperación" de RAG, la R en el nombre. Tomamos una pregunta, la convertimos en un embedding de la misma manera que hicimos con los fragmentos, y le pedimos a Chroma los fragmentos cuyo significado sea más cercano. Esos fragmentos coincidentes son lo que le entregaremos a Claude en el siguiente paso.
1. Agrega la función de búsqueda. Debajo del código del paso 4, en rag.py:
1def search(question, n_results=3):2 question_embedding = embedder.encode([question])[0]3 results = collection.query(4 query_embeddings=[question_embedding.tolist()],5 n_results=n_results,6 )7 return results
Lo que esto hace, línea por línea en términos simples: convierte la pregunta en números con el mismo modelo que usaste en tus fragmentos (esto es importante, ambos deben hablar el mismo "lenguaje numérico"), luego le pide a Chroma las coincidencias más cercanas. n_results=3 significa "dame los 3 fragmentos más relevantes". Tres es un buen valor predeterminado: suficiente contexto, no tanto como para desperdiciar tokens.
2. Prueba una búsqueda. Agrega esto debajo para probarlo:
1question = "¿Quién dirige Northstar y cuándo se revisan los comentarios?"2results = search(question)34for i, doc in enumerate(results["documents"][0]):5 source = results["metadatas"][0][i]["source"]6 print(f"\n--- Coincidencia {i+1} (de {source}) ---")7 print(doc)
Esto ejecuta una pregunta real contra tu base de datos e imprime los fragmentos que encontró, cada uno con el nombre del archivo del que proviene.
3. Ejecútalo. Guarda rag.py, luego en tu terminal:
1python rag.py
Con el archivo de prueba de Northstar, deberías ver que recupera el fragmento coincidente, algo como:
--- Coincidencia 1 (de notes.txt) ---
Project Northstar es nuestra herramienta interna para rastrear comentarios de clientes. Se lanzó en marzo de 2026 y es mantenida por el equipo de plataforma. La ingeniera líder es Dana Reyes. Los comentarios se revisan cada viernes. Northstar reemplazó el antiguo sistema de hojas de cálculo que usamos hasta 2025.
Observa lo que acaba de pasar: tu pregunta usó las palabras "quién dirige" y "revisan", pero el archivo dice "ingeniera líder" y "revisan cada viernes". Coincidió de todas formas, porque la búsqueda funciona con significado, no con palabras exactas. Ese es el punto central de los embeddings, y es por esto que esto supera a una búsqueda simple de palabras clave (Ctrl+F) a través de tus archivos.
Si tienes más archivos, verás los 3 fragmentos principales de todos ellos, ordenados por qué tan cerca coinciden.
Paso 6: Haz que Claude responda a partir de lo que encontró
Esta es la parte de "generación", la G en RAG. Tomamos los fragmentos del paso 5, se los entregamos a Claude Opus 4.8 junto con la pregunta, y le decimos que responda usando solo ese contexto. Esto es lo que evita que adivine: Claude responde desde tus archivos, no desde su propia memoria, y te dice qué archivo usó.
1. Agrega la función de respuesta. Debajo del código del paso 5, en rag.py:
1import anthropic23claude = anthropic.Anthropic(api_key=api_key)45def answer(question):6 results = search(question)7 chunks = results["documents"][0]8 sources = [m["source"] for m in results["metadatas"][0]]910 context = ""11 for i, chunk in enumerate(chunks):12 context += f"[De {sources[i]}]\n{chunk}\n\n"1314 message = claude.messages.create(15 model="claude-opus-4-8",16 max_tokens=1024,17 system=(18 "Respondes preguntas usando solo el contexto proporcionado. "19 "Si la respuesta no está en el contexto, di que no lo sabes. "20 "Menciona siempre de qué archivo proviene tu respuesta."21 ),22 messages=[23 {24 "role": "user",25 "content": f"Contexto:\n{context}\nPregunta: {question}",26 }27 ],28 )29 return message.content[0].text
Lo que sucede aquí, en términos simples: buscamos los fragmentos relevantes, los unimos en un bloque de context (cada uno etiquetado con su nombre de archivo), luego enviamos ese bloque más la pregunta a Claude. La instrucción system es la parte clave. Le dice a Claude tres cosas: responde solo desde el contexto, admite cuando la respuesta no está ahí, y nombra el archivo fuente. Esas tres reglas son lo que hace que las respuestas sean confiables en lugar de inventadas.
model="claude-opus-4-8" es el nombre exacto del modelo (guiones, no puntos). max_tokens=1024 limita la longitud de la respuesta.
2. Haz una pregunta. Agrega esto debajo:
1question = "¿Quién dirige Northstar y cuándo se revisan los comentarios?"2print(answer(question))
3. Ejecútalo. Guarda rag.py, luego en tu terminal:
1python rag.py
Deberías obtener una respuesta real construida desde tu archivo, algo como:
Dana Reyes es la ingeniera líder que dirige Project Northstar, y los comentarios se revisan cada viernes. (Fuente: notes.txt)
Eso es un sistema RAG completo funcionando. Claude nunca vio este archivo durante su entrenamiento, no puede saber quién es Dana Reyes, sin embargo respondió correctamente y te dijo exactamente de dónde vino la respuesta. Pregúntale algo que no esté en tus archivos y dirá que no lo sabe, en lugar de inventar una respuesta. Ese "no lo sé" es una característica, no una falla: es la diferencia entre una herramienta en la que puedes confiar y una que adivina.
Paso 7: Conviértelo en algo que realmente puedas usar
Ahora mismo tienes que editar el código y volver a ejecutar todo el script cada vez que quieras preguntar algo. Peor aún, cada ejecución vuelve a leer tus archivos y los vuelve a agregar a la base de datos, por lo que los fragmentos se acumulan. Arreglemos ambas cosas: construye la base de datos solo una vez, luego te permite hacer preguntas en un bucle, escribiéndolas directamente en la terminal.
1. Arregla la doble adición. Busca el bloque del paso 4 que agrega fragmentos (la parte de collection.add(...)) y reemplázalo con esta versión, que solo construye la base de datos si está vacía:
1if collection.count() == 0:2 collection.add(3 ids=[str(i) for i in range(len(all_chunks))],4 embeddings=[emb.tolist() for emb in embeddings],5 documents=[chunk["text"] for chunk in all_chunks],6 metadatas=[{"source": chunk["source"]} for chunk in all_chunks],7 )8 print(f"Se almacenaron {collection.count()} fragmento(s) en la base de datos.")9else:10 print(f"La base de datos ya tiene {collection.count()} fragmento(s), omitiendo reconstrucción.")
Ahora el trabajo pesado (leer archivos, crear embeddings, llenar la base de datos) ocurre solo la primera vez. Las ejecuciones posteriores saltan directamente a responder.
2. Agrega el bucle de preguntas. Al final de rag.py, reemplaza la pregunta de prueba única del paso 6 con esto:
1print("\nHaz una pregunta sobre tus documentos (o escribe 'salir' para terminar).\n")23while True:4 question = input("Tú: ")5 if question.lower() in ["salir", "quit", "exit"]:6 break7 print("\nClaude: " + answer(question) + "\n")
input("Tú: ") espera a que escribas una pregunta y presiones Enter. while True lo mantiene funcionando para que puedas hacer todas las que quieras. Escribir salir lo detiene.
3. Ejecútalo. Guarda rag.py, luego en tu terminal:
1python rag.py
Ahora puedes simplemente hablar con tus archivos:
Haz una pregunta sobre tus documentos (o escribe 'salir' para terminar).
Tú: ¿quién es la ingeniera líder de Northstar?
Claude: La ingeniera líder de Project Northstar es Dana Reyes. (Fuente: notes.txt)
Tú: ¿qué reemplazó?
Claude: Northstar reemplazó el antiguo sistema de hojas de cálculo que se usaba hasta 2025. (Fuente: notes.txt)
Tú: salir
Ese es tu sistema RAG terminado. Lee tus archivos una vez, los recuerda y responde preguntas sobre ellos bajo demanda, siempre con la fuente.
Algo que debes saber cuando agregues archivos nuevos. Debido a que la base de datos ahora se construye solo una vez, colocar archivos nuevos en documents no aparecerá automáticamente. Para cargar archivos nuevos, elimina la carpeta chroma_db y ejecuta el script una vez. Se reconstruye desde cero con todo lo que hay en la carpeta.
Opcional: dale una ventana de chat en tu navegador
La terminal funciona, pero si quieres una ventana de chat real, Streamlit agrega una en aproximadamente 20 líneas.
1. Instálalo. En tu terminal:
1pip install streamlit
2. Crea app.py en la misma carpeta y pega esto. Reutiliza la función answer de tu rag.py:
1import streamlit as st2from rag import answer34st.title("Chatea con tus documentos")56if "history" not in st.session_state:7 st.session_state.history = []89question = st.chat_input("Pregunta sobre tus archivos...")1011if question:12 reply = answer(question)13 st.session_state.history.append((question, reply))1415for q, a in st.session_state.history:16 st.chat_message("user").write(q)17 st.chat_message("assistant").write(a)
3. Ejecútalo. En tu terminal (nota: streamlit run, no python):
1streamlit run app.py
Se abre una ventana de chat en tu navegador automáticamente. Escribe una pregunta, obtén una respuesta con su fuente, igual que en la terminal pero más agradable a la vista.
Una nota: para que esto funcione, el bucle de preguntas del paso 7 no debe ejecutarse al importar. Envuelve ese bucle al final de rag.py en if __name__ == "__main__": para que solo se active cuando ejecutes rag.py directamente, no cuando app.py lo importe.
Permitir que responda preguntas generales también
Si quieres que también responda preguntas generales. Ahora mismo el sistema solo responde desde tus archivos, por lo que una pregunta como "¿cuál es la capital de Venezuela?" obtiene "eso no está en los documentos", aunque Claude sepa la respuesta. Si quieres que recurra a su propio conocimiento, abre rag.py, busca el bloque system=(...) del paso 6, y cambia esta línea:
1"Si la respuesta no está en el contexto, di que no sabes. "
para esto:
1"Si la respuesta no está en el contexto, responde desde tu propio conocimiento general pero di que lo estás haciendo. "
Guarda y vuelve a ejecutar. Ahora responde primero desde tus archivos, y recurre al conocimiento general cuando los archivos no lo cubren, indicándote cuál usó.
Resumiendo
Acabas de construir un sistema RAG funcional. Lee tus propios archivos, encuentra las partes que importan y logra que Claude responda a partir de ellas, citando la fuente exacta cada vez. La misma configuración escala desde unas cuantas notas hasta toda tu base de conocimiento.
A partir de aquí, puedes orientarlo hacia donde quieras: tu bóveda de Obsidian, tus documentos de trabajo, tus investigaciones guardadas. Coloca los archivos, reconstruye una vez y empieza a preguntar. Todo lo que aprendiste aquí —los fragmentos, las incrustaciones, la búsqueda, la respuesta— es la misma base detrás de cada herramienta de "chatea con tus documentos" que hayas visto.
Si te fue útil, ve a mi perfil y sígueme. Escribo sobre tecnología, IA y sistemas que realmente funcionan.
Ciao,
[@undefinedKi](https://x.com/@undefinedKi)





