A ready-to-run example is available here!Persistent memory lets an agent keep what it learned — root causes, environment quirks, project decisions, user preferences — in plain Markdown files that are loaded back into the system prompt at the start of every new conversation. The agent maintains the files itself as it works, so it gets better at a project over time. The feature is opt-in and off by default: without it, agents keep the existing
AGENTS.md-based guidance and prompts are unchanged.
Enabling Persistent Memory
Setload_memory=True on the agent’s AgentContext:
- At session start, the conversation reads the
MEMORY.mdindexes from both memory tiers and injects them into the system prompt as a<MEMORY_CONTEXT>block. - The system prompt’s
<MEMORY>section switches to instructions that teach the agent where its memory lives and how to maintain it.
The Two Tiers
Each tier contains:
MEMORY.md— a curated index of durable facts. This is the only file injected into the prompt, so the agent is instructed to keep it small and high-value.- Daily logs (
YYYY-MM-DD.md) — free-form working notes. They are never injected automatically; the agent reads them on demand with its file tools whenMEMORY.mdpoints to them.
.openhands/memory/ to share agent-learned knowledge.
What Gets Injected
At the start of each opted-in conversation, the resolved memory appears in the system prompt like this (user tier first, then project tier):- Size budget: the combined indexes are capped at ~6,000 characters. When the budget is exceeded, whole lines are dropped from the top of each over-budget tier (the oldest content) — partial lines never survive, the tier headers are always kept, and a truncation notice appears under the header of any tier that lost lines. Keep indexes curated.
- Untrusted by design: the injected block is wrapped in
<UNTRUSTED_CONTENT>. Memory files are typically agent-written, but anyone with access to the workspace or repository can edit or commit them (a cloned repo may ship a.openhands/memory/MEMORY.md), so the agent is told they may contain prompt injection, and to treat them as unverified hints, never as authoritative instructions. - Never persisted: the resolved memory text is re-read from disk each session and is excluded from conversation persistence (
base_state.json) and API payloads. - Best-effort: an unreadable memory file logs a warning and the conversation starts normally without it.
How the Agent Maintains Memory
When memory is enabled, the system prompt instructs the agent to:- record durable, broadly useful facts in
MEMORY.mdnear the end of a task (creating the directories and files if missing), and put long detail in daily logs; - merge duplicates, prune stale entries, and keep the indexes concise;
- never record secrets or credentials, and skip facts that are trivially re-discoverable (directory listings, obvious commands);
- keep
AGENTS.mdfor instructions addressed to any agent working in the repository — memory is for what the agent learned itself.
Ready-to-run Example
This example is available on GitHub: examples/01_standalone_sdk/55_persistent_memory.py
examples/01_standalone_sdk/55_persistent_memory.py
The model name should follow the LiteLLM convention:
provider/model_name (e.g., anthropic/claude-sonnet-4-5-20250929, openai/gpt-4o).
The LLM_API_KEY should be the API key for your chosen provider.Next Steps
- Skills - Inject reusable instructions and context into agents
- Context Condenser - Keep long conversations within the context window
- Persistence - Save and restore conversation state across sessions

