Por qué las líneas más antiguas son las que se van
La memoria persistente en OpenHands está desactivada a menos que la solicites. La documentación es explícita: la función es "opt-in y desactivada por defecto", y sin ella "los agentes mantienen la guía existente basada en AGENTS.md y los prompts no cambian". Se habilita estableciendo load_memory en true en el AgentContext del agente.
Una vez activada, existen dos niveles. Un nivel de usuario en ~/.openhands/memory/ que contiene "conocimientos y preferencias que se aplican a todos los proyectos", y un nivel de proyecto en <workspace>/.openhands/memory/ que contiene "conocimientos específicos del repositorio actual". Cada nivel contiene un archivo MEMORY.md, descrito como "un índice curado de datos duraderos. Este es el único archivo que se inyecta en el prompt", además de registros diarios fechados que "nunca se inyectan automáticamente; el agente los lee bajo demanda con sus herramientas de archivos cuando MEMORY.md apunta a ellos".
Esa división es la arquitectura clave, y también es de donde proviene el desalojo de datos:
"Presupuesto de tamaño: los índices combinados están limitados a unos 6,000 caracteres. Cuando se supera el presupuesto, se descartan líneas completas de la parte superior de cada nivel que supere el límite (el contenido más antiguo); las líneas parciales nunca sobreviven, los encabezados de nivel siempre se conservan y aparece un aviso de truncamiento debajo del encabezado de cualquier nivel que haya perdido líneas. Mantén los índices curados".
Léelo despacio, porque ahí se concentran cuatro comportamientos distintos.
El límite se aplica a los índices combinados de ambos niveles, por lo que tus preferencias personales y los datos de tu proyecto compiten por el mismo presupuesto. Un archivo de nivel de usuario muy detallado reduce el espacio disponible para el nivel de proyecto.
Las líneas se descartan desde la parte superior, y la documentación define la parte superior como "el contenido más antiguo". Dado que el agente añade información a medida que aprende, la parte superior del archivo es lo primero que registró. La mayoría de los límites descartan lo más nuevo o fallan al escribir. Este elimina tus cimientos primero.
El descarte se realiza a nivel de línea y de forma limpia ("las líneas parciales nunca sobreviven"), por lo que nunca tendrás una frase a medias que cambie de significado. Un buen diseño que implica que una sola línea larga se mantiene por completo o se elimina del todo.
Y hay una señal: "aparece un aviso de truncamiento debajo del encabezado de cualquier nivel que haya perdido líneas". Nada ocurre en silencio si prestas atención. El problema es que nadie mira un bloque de prompt del sistema inyectado durante una sesión de trabajo normal.
Vale la pena señalar para cualquiera que use múltiples herramientas: 6,000 caracteres es el mismo presupuesto que Devin Desktop documenta para su archivo de reglas globales. Alrededor de seis mil caracteres es el punto donde varios proveedores decidieron de forma independiente que un archivo cargado constantemente deja de valer lo que cuesta, un número útil de interiorizar independientemente de la herramienta que utilices.
Lo que la gente intenta en su lugar
Aumentar el presupuesto. El primer instinto, pero la documentación no lo ofrece como una opción de configuración; el límite se describe como una propiedad de la función. Incluso si fuera ajustable, un bloque más grande cargado constantemente es un peor trato, no uno mejor, por las razones que se analizan en how much memory you should give an AI agent.
Reescribir MEMORY.md a mano cada pocas semanas. Esto funciona y es lo que se pide al decir "mantén los índices curados". También es una tarea tediosa sin un detonante claro, por lo que se hace un par de veces y luego se deja de hacer, y el archivo vuelve a crecer.
Mover todo a AGENTS.md para que nunca se descarte. Tentador, pero interpreta mal la división del trabajo que establece la documentación. El agente tiene instrucciones de "mantener AGENTS.md para instrucciones dirigidas a cualquier agente que trabaje en el repositorio; la memoria es para lo que el agente aprendió por sí mismo". Volcar el historial aprendido en un archivo de instrucciones te da un archivo largo cargado constantemente con un nombre diferente y sin ningún aviso de truncamiento.
Poner los datos importantes en una habilidad (skill) para que se carguen bajo demanda. Un instinto razonable que choca con el mecanismo equivocado, por las razones explicadas en why agent skills aren't memory. Las habilidades responden a "cómo hago esta tarea". Una alternativa arquitectónica rechazada no es una tarea.
Hacer commit de .openhands/memory/ y tratarlo como documentación del equipo. La documentación lo permite explícitamente: "un equipo de proyecto puede incluso hacer commit de .openhands/memory/ para compartir el conocimiento aprendido por el agente", y es realmente útil. Pero empeora el problema del desalojo en lugar de mejorarlo, porque ahora los agentes de varias personas están añadiendo información a un índice compartido contra el mismo límite de 6,000 caracteres.
Hay otra razón por la que ninguna de estas opciones funciona del todo, y es la frase que la gente suele pasar por alto:
"No confiable por diseño: el bloque inyectado está envuelto en<UNTRUSTED_CONTENT>. Los archivos de memoria suelen ser escritos por el agente, pero cualquiera con acceso al espacio de trabajo o al repositorio puede editarlos o hacer commit de ellos (un repositorio clonado puede incluir un.openhands/memory/MEMORY.md), por lo que se le indica al agente que pueden contener inyección de prompts y que debe tratarlos como pistas no verificadas, nunca como instrucciones autoritativas".
Se le indica al agente que trate su propia memoria como pistas no verificadas. Esa es la postura de seguridad correcta (un repositorio clonado realmente puede incluir un archivo de memoria) y resuelve una duda de diseño. Cualquier cosa que deba ser obedecida no puede vivir en la memoria, porque la memoria no es autoritativa por definición. La memoria sirve para aportar un contexto que el agente pueda encontrar útil. Las instrucciones pertenecen a AGENTS.md, donde se dirigen a cualquier agente y se leen como instrucciones.
Así, las dos propiedades documentadas se combinan en una sola regla: el índice de memoria es un archivo de punteros pequeño, no autoritativo y con pérdida de datos en la parte superior. Si lo tratas como algo más, te decepcionará de una de estas dos maneras.
La solución: Mantén el índice como un puntero, no como un almacén
Tres pasos. Los dos primeros toman diez minutos; el tercero es el que evita que el problema vuelva a ocurrir.
Paso 1: Convierte MEMORY.md en un índice de punteros
La documentación ya te indica la estructura prevista: MEMORY.md es "un índice curado de datos duraderos", se le indica al agente que "coloque los detalles largos en los registros diarios" y los registros se leen "bajo demanda con sus herramientas de archivos cuando MEMORY.md apunta a ellos".
Por lo tanto, cada línea del índice debe ser corta y apuntar a algún lugar. Una línea por dato, redactada de manera que el agente sepa tanto qué es cierto como dónde está el detalle. Los párrafos de prosa, los ejemplos de código y las explicaciones largas se trasladan a los archivos de registro fechados, donde se leen solo cuando es necesario y no consumen nada del presupuesto.
Haz esto y el límite de 6,000 caracteres dejará de ser una limitación. Cien punteros de una sola línea caben cómodamente; una docena de párrafos no.
Paso 2: Reordena el índice para que la parte superior sea prescindible
Dado que el desalojo elimina líneas de la parte superior y la parte superior es el contenido más antiguo, el orden cronológico del archivo juega directamente en tu contra. Soluciónalo haciendo que el orden sea semántico en su lugar.
Coloca los datos que lamentarías perder en la parte inferior del índice de cada nivel (aquellos sobre arquitectura, restricciones y decisiones a largo plazo). Coloca las notas operativas transitorias en la parte superior. Ahora, cuando se supere el presupuesto, las líneas que se eliminen serán las que habrías depurado de todos modos.
Luego, reequilibra los niveles. Debido a que el límite es combinado, un archivo ~/.openhands/memory/MEMORY.md inflado y lleno de preferencias personales le está quitando espacio directamente a los datos del proyecto. Mantén el nivel de usuario limitado a preferencias reales entre proyectos y deja espacio libre para el nivel de proyecto.
Mientras estés allí, busca el aviso de truncamiento debajo del encabezado de cada nivel. Si está presente, ya has perdido líneas, y los registros diarios son donde encontrarás lo que decían (lo cual es un buen argumento para realizar el Paso 1 primero).
Paso 3: Separa las tres cosas que actualmente comparten un solo archivo
El índice ahora contiene tres tipos de contenido que requieren destinos diferentes.
Instrucciones: cosas que deben seguirse obligatoriamente. Pertenecen a AGENTS.md, según la propia división de la documentación. No son memoria, y la memoria no es autoritativa.
Detalles operativos aprendidos por el agente: la peculiaridad del entorno, la prueba inestable, el comando que realmente funciona. Pertenecen exactamente a donde están: una línea de puntero en el índice y el detalle en un registro diario. Para esto sirve la función.
Decisiones del proyecto y sus motivos: por qué se rechazó la biblioteca de colas, qué requiere realmente la restricción de cumplimiento, qué se intentó en marzo y no funcionó. No pertenecen a ninguno de los dos. No son instrucciones, por lo que AGENTS.md es incorrecto. No deben perderse ni carecer de autoridad, por lo que el índice de memoria es incorrecto. Y deben poder ser respondidas por cada herramienta que use tu equipo, no solo por aquella que tenga activado load_memory.
Configuración en MemoryLake
MemoryLake es el hogar para esa tercera categoría. Almacena las decisiones y sus motivos fuera de cualquier agente individual, sin un presupuesto de carga constante por el que competir, y responde preguntas sobre ellos a través de MCP o la API. Tu MEMORY.md se mantiene como un índice de punteros corto y OpenHands sigue manteniéndolo exactamente como está documentado; el razonamiento duradero vive en un lugar al que no llega ningún límite de caracteres.
Paso 1: Crea una clave de API
Genera una clave y realiza tu primera solicitud en unos treinta segundos. Haz esto antes del Paso 2 anterior, para tener un lugar donde mover cada decisión a medida que reordenas el índice.

Paso 2: Sube tus primeras memorias
Revisa el índice actual y los registros diarios a los que apunta. Cada entrada que sea una decisión en lugar de una observación se registra con lo que se eligió, lo que se rechazó y por qué. Los documentos de soporte y los archivos van al mismo lugar.

Paso 3: Conecta tu IA y agentes
Dale acceso a OpenHands, Claude, Codex y tus otros agentes a través de MCP o la API. Cuando alguno de ellos necesite saber por qué el proyecto es como es, la respuesta llegará con su razonamiento adjunto en lugar de competir por espacio en un prompt del sistema.

Qué cambia esto en la práctica
El primer cambio es que el desalojo deja de importar. Un índice de punteros ordenado con el contenido prescindible en la parte superior solo pierde lo que habrías depurado de todos modos, y el detalle detrás de cada puntero sigue estando en un archivo de registro que el agente puede abrir.
El segundo es que la función de memoria logra ser buena en su trabajo real. Registrar que las pruebas de integración necesitan una variable de entorno específica es exactamente lo que debería hacer un almacén mantenido por un agente, y lo hace bien cuando no se le pide además que sea el registro de decisiones del equipo.
El tercero es que el enfoque de contenido no confiable deja de ser un problema. Una vez que no hay nada estructural en la memoria, el hecho de que el agente la trate como pistas no verificadas es simplemente correcto, y las cosas que sí deben ser autoritativas están en AGENTS.md, donde se leen como instrucciones.
El cuarto es que hacer commit de .openhands/memory/ se vuelve seguro a escala de equipo. Que varios agentes añadan líneas de punteros contra un presupuesto de 6,000 caracteres es sostenible de una manera en que varios agentes añadiendo párrafos no lo es. Y cuando dos entradas realmente no coinciden, tienes un lugar donde resolverlo en lugar de dejar que el azar alfabético o cronológico decida, el problema que memory conflict detection existe para detectar.
Buenas prácticas para la memoria persistente de OpenHands
Una línea, un dato, un puntero. El índice está documentado como un índice curado. Cualquier cosa más larga que una línea pertenece a un registro diario al que apunte el índice.
Ordena por importancia, no por tiempo. El desalojo elimina líneas de la parte superior. Coloca allí lo que puedas permitirte perder.
Presupuesta los dos niveles entre sí. El límite es combinado, por lo que un nivel de usuario muy detallado reduce silenciosamente tu nivel de proyecto.
Busca el aviso de truncamiento. Aparece debajo del encabezado de cualquier nivel que haya perdido líneas. Es la única señal que recibes, y es confiable si prestas atención.
Nunca pongas credenciales en la memoria. Las propias instrucciones del agente dicen que nunca se deben registrar secretos ni credenciales. No contradigas eso agregándolas tú mismo, y realiza auditorías periódicamente; auditing what your AI remembers cubre este hábito.
Omite cualquier cosa que sea trivialmente redescubrible. Las instrucciones de mantenimiento lo dicen claramente: los listados de directorios y los comandos obvios consumen presupuesto y no enseñan nada.
Mantén las instrucciones completamente fuera de la memoria. La memoria está documentada como pistas no verificadas. Si debe ser obedecida, va en AGENTS.md.
Recuerda que la memoria se vuelve a leer, no se almacena en la sesión. Las especificaciones señalan que el texto resuelto se excluye de la persistencia de la conversación y de las cargas útiles de la API, y se vuelve a leer del disco en cada sesión, por lo que editar el archivo a mano surte efecto en la siguiente conversación.
Conclusión
OpenHands documenta su memoria persistente con precisión: opt-in y desactivada por defecto, dos niveles, solo se inyecta MEMORY.md, un límite combinado de unos 6,000 caracteres, líneas completas descartadas de la parte superior de un nivel que supere el presupuesto con un aviso de truncamiento debajo del encabezado, y todo el bloque envuelto en un marcador de contenido no confiable que se le indica al agente que trate como pistas no verificadas en lugar de instrucciones autoritativas. Cada una de esas decisiones es razonable. Juntas describen un archivo de punteros pequeño, con pérdida de datos y de carácter consultivo, lo cual es algo realmente útil y no un lugar para guardar el razonamiento de tu proyecto.
Mantén el índice limitado a punteros de una sola línea, ordénalo de modo que la parte superior sea lo que puedes permitirte perder y separa los tres tipos de contenido que actualmente lo comparten. Las instrucciones van a AGENTS.md. Las observaciones se quedan en la memoria y sus registros, que es para lo que se creó la función. Las decisiones y sus motivos van a un lugar sin presupuesto de caracteres ni caducidad, porque esas son las que seguirás necesitando en un año; y, como sostiene keeping less in agent memory, un archivo más pequeño cargado constantemente es mejor en todos los aspectos una vez que el resto tiene un hogar.