altaskur
30 ago 2026 · 6 min lectura
Más allá del prompt: RAG y arquitectura de capas para sistemas de IA con memoria
Cómo desarrollar un proyecto de IA sin saturar el prompt, dándole memoria y contexto personalizados a cada respuesta con RAG, embeddings, chunking y una arquitectura de tres capas.
¿Sabrías cómo desarrollar un proyecto de IA sin saturar el prompt y, además, proporcionarle memoria y contexto personalizados para cada respuesta? Para ello, conocerás conceptos como RAG, embeddings y la arquitectura de capas. Te lo explicaré basándome en mi proyecto Atanor Memoriae, un editor de texto con asistente de IA y un sistema PKM que utilizo a diario.
Si estás empezando a desarrollar con IA, uno de los principales problemas es la limitación de la ventana de contexto. Aunque los modelos frontera como Claude o ChatGPT son grandes, no siempre tendremos acceso a ellos ni disfrutaremos de una reducción de costes; además, cuanto más amplia sea la sesión, más se degradará el rendimiento del modelo. En este proyecto, trabajaremos con modelos locales, lo que nos obligará a manejar contextos ajustados y a aprender a optimizar las llamadas a los LLMs.
Primer problema: la gestión de la memoria
Seguramente habrás pensado en inyectar la información que necesitas en cada mensaje, pero esta opción presenta varios problemas: se desaprovecha la capacidad del modelo con datos deterministas, se incrementa el contexto innecesariamente, se aumentan los costes y se degrada el rendimiento.
RAG (Retrieval-Augmented Generation)
Imagina que estás cocinando una cena de tres platos. ¿Sabrías decirme el paso a paso exacto de cada uno sin mirar las recetas? Lo más normal sería consultar en tu recetario cada una de las recetas conforme vayas necesitándola. Incluso podrías rescatar partes; por ejemplo, sé hacer un arroz, ¿pero cuánta agua necesito para el arroz?
Esta es la esencia de RAG (Retrieval-Augmented Generation). Cuando haces una pregunta, el sistema de recuperación (Retrieval) consulta fragmentos de información relevantes, los extrae y los envía al modelo de lenguaje (LLM). De esta manera, nuestro modelo podrá responder con precisión, adaptando su prompt según la necesidad específica.
Sin embargo, para que este sistema funcione, no basta con “guardar textos”. Necesitamos un proceso de transformación de datos que pase por varias etapas:
Embeddings y el problema del Chunking
Para que la IA pueda buscar en nuestro “recetario”, primero debemos convertir el texto en algo que la máquina pueda comparar matemáticamente. Aquí entran los Embeddings, la búsqueda vectorizada.
Un embedding representa la información semántica en un espacio vectorial. No significa que el modelo “entienda” el significado como un humano, sino que coloca conceptos similares en posiciones cercanas dentro de un espacio multidimensional. Por ejemplo, un filete de carne podría estar cerca de la “proteína” y lejos de la “verdura”. Una de las métricas más habituales para medir esta cercanía es la similitud coseno, que compara el ángulo entre dos vectores: cuanto más alineados están, mayor es su similitud.
Pero hay un paso previo crítico: el Chunking. No podemos convertir un libro entero en un solo vector, porque perderíamos precisión. Debemos dividir la información en fragmentos pequeños (chunks). El tamaño de estos fragmentos es un equilibrio delicado: si son muy grandes, el modelo recibe ruido innecesario; si son muy pequeños, el fragmento puede perder la relación lógica con el resto del texto.
¿Dónde se guarda y cómo se recupera?
Los embeddings y los metadatos necesarios para recuperarlos pueden almacenarse en una base de datos vectorial. Actualmente, utilizo PostgreSQL con pgvector para sistemas que ya cuentan con esa base de datos, y Qdrant, que es una de mis opciones favoritas por su rendimiento y por estar construida en Rust.
En la arquitectura de Atanor Memoriae, utilizamos un enfoque híbrido: Qdrant se encarga de la búsqueda vectorial, mientras que SQLite gestiona el estado y los metadatos del sistema.
Arquitectura de Capas: Gestionando el “Context Budget”
La clave no es conseguir que el modelo tenga acceso a toda nuestra información, sino decidir qué información merece entrar en cada llamada. Para solucionar el problema de la saturación, gestiono el prompt en tres capas distintas, cada una con una estabilidad y función diferente.
La Capa de Identidad es la más estable: aquí vive la configuración fija, esas normas de comportamiento, tono y preferencias del autor que definen cómo habla el LLM. Es como la voz que nunca cambia, y debe estar siempre presente en cada interacción.
Luego está la Capa de Memoria/RAG, que es completamente variable. Aquí van los fragmentos recuperados por los embeddings, pero aquí viene lo interesante: para no saturar al modelo, aplicamos un proceso de refinamiento que funciona en tres pasos. Primero, los Filtros de Metadatos actúan como guardianes, filtrando por criterios duros antes de buscar por similitud. Imagina que solo quieres documentos del Proyecto A o notas de este año; es una regla de ingeniería básica: utiliza filtros deterministas cuando tienes información determinista. Después viene el Scoring y Re-ranking, donde combinamos diferentes señales de relevancia —similitud, recencia, prioridad— y volvemos a ordenar los resultados antes de construir el contexto final. Y finalmente, el Context Budget nos obliga a ser implacables: recortamos o eliminamos los fragmentos más lejanos para asegurar que el contenido quepa en la ventana de tokens del modelo seleccionado.
Por último, la Capa de Historial es volátil, pero crucial. Se mantienen las últimas interacciones para que el sistema no pierda el hilo de la conversación actual. Sin ella, estaríamos condenados a recordar solo lo que cabe en un prompt, sin contexto de lo que acaba de pasar.
Resumen del flujo
El usuario pregunta por recetas de arroz con pollo; la pregunta se vectoriza y el sistema busca los fragmentos más cercanos. A partir de ahí, se filtran por metadatos, se re-ordenan por relevancia y se seleccionan los mejores para que quepan en el presupuesto de tokens. Finalmente, se inyectan junto con la identidad y el historial en el prompt.
Nota: Si ningún resultado supera el umbral de relevancia, el sistema puede decidir no inyectar memoria y dejar que el modelo responda únicamente con su conocimiento disponible o solicite más información.
Limitaciones y el siguiente paso
Este método tiene costes: el filtrado y el re-ranking suponen una carga computacional y, a veces, la pérdida de relaciones lógicas complejas. Por ejemplo, si tienes una nota que dice “El proyecto A depende del componente B, pero solo si el usuario X lo activa”, un vector podría recuperar “Proyecto A” y “Componente B” por separado, pero perder la condición lógica (“si el usuario X lo activa”), ya que el vector entiende proximidad, no lógica estructural.
Lo interesante sería complementar la búsqueda vectorial con un Grafo de Conocimiento (GraphRAG), donde las entidades y sus relaciones se representan explícitamente mediante nodos y aristas. No fue el objetivo de este tutorial, pero es una evolución clave. No todo problema necesita la arquitectura más sofisticada disponible; el objetivo aquí ha sido aprender los conceptos base y cómo equilibrar la potencia de la búsqueda semántica con la necesidad de mantener un contexto saludable.
En conclusión, la arquitectura de capas en Atanor Memoriae permite que la IA no solo tenga acceso a más datos, sino a los datos correctos en el momento justo. Al filtrar, re-ordenar y estructurar la información, logramos reducir el ruido y aumentar la probabilidad de que el modelo reciba la información relevante para generar una respuesta adecuada.
Ahora te pregunto, ¿Dónde implementarías este sistema? ¿Qué problemas has visto en la gestión de contextos de tus propios proyectos?