Your OpenClaw agent is running, your Telegram bot is connected, and conversations are flowing. Now you hit a wall that every AI agent developer hits eventually: you ask your agent something it learned yesterday and it has no idea what you are talking about. Yesterday’s context is gone. Your carefully crafted instructions from last week have vanished. Every new session starts cold.
This tutorial fixes that problem completely. You will add persistent memory to OpenClaw using Mem9.ai as an external memory layer, configure a soul.md file that gives your agent a consistent identity across every session, and set up a decision.md file so that hard-won decisions are never relitigated. By the end, you will have an agent that gets smarter and more personal with every conversation — not one that resets to factory defaults every time you reboot.
If you want to understand how other memory systems approach this problem, Letta’s memory architecture is worth reading alongside this guide. For a framework-level comparison of memory strategies, see CrewAI Memory and Knowledge.
The Problem: Your AI Forgets Everything
The core issue is architectural. Large language models are stateless by design. When you send a message to an LLM — whether through OpenClaw, a chat UI, or a raw API call — the model receives your message plus a context window of recent conversation history and nothing else. There is no file cabinet inside the model holding your past sessions. There is no database being queried behind the scenes to recall what you told it three weeks ago.
This statelesness shows up in three painful ways for OpenClaw users.
Instruction drift. You spend an hour getting your agent set up with exactly the right behavior — your preferred response format, the projects it is monitoring, the people it reports to, the tone it uses when drafting emails. The agent works perfectly. Then you restart the daemon, or the server reboots, or the OpenClaw process crashes and comes back up. Everything you configured through conversation is gone. You are back to square one.
Context collapse. You are managing a long-running project with your agent. It knows which tasks are complete, which are in progress, who owns what, and what decisions were made in the last sprint. Three days later, you try to pick up where you left off and the agent has no idea what you are talking about. You spend twenty minutes re-explaining context instead of doing actual work.
Personality inconsistency. If you have configured your agent with a specific persona — a tutor, a code reviewer, a project manager — that persona disappears the moment the context window slides past the original instructions. The agent reverts to generic assistant behavior, losing the carefully tuned style you depend on.
The solution is a persistent memory layer that lives outside the LLM, stores information reliably between sessions, and injects the right context back into the conversation window at the start of every interaction. That is exactly what Mem9.ai provides, and it is what the soul.md and decision.md patterns formalize on the configuration side.
How Persistent Memory Works in OpenClaw
OpenClaw treats memory as a three-layer stack: in-context memory, session memory, and long-term memory.
In-context memory is the text currently in the active conversation window. It is fast, immediately accessible, and completely ephemeral. When the context window slides or the session ends, this layer is wiped.
Session memory is OpenClaw’s built-in short-term persistence. The daemon writes a session log to disk after each conversation turn, so if the process restarts mid-session, it can replay recent history. This is useful for crash recovery but does not help with anything older than the current session.
Long-term memory is where Mem9.ai fits. Instead of storing memories inside the LLM or relying on a context window that fills up, Mem9.ai maintains a vector database of everything your agent has learned. When a new conversation starts, OpenClaw queries Mem9 for semantically relevant memories and injects them into the context window automatically. The agent appears to remember because it does remember — just from an external store rather than an internal one.
The practical flow looks like this:
User message arrives
↓
OpenClaw queries Mem9.ai for relevant memories
↓
Top-K memories injected into system context
↓
LLM generates response with full history awareness
↓
OpenClaw extracts new facts from the response
↓
New facts written back to Mem9.ai vector store
The soul.md and decision.md files sit alongside this pipeline. soul.md defines static identity — who the agent is, how it communicates, what its values are. decision.md records permanent decisions that should never be reconsidered. Both files are read at daemon startup and prepended to every system prompt, ensuring they are always present regardless of what Mem9 retrieves.
Setting Up Mem9.ai Integration
Create a Mem9.ai Account and Get Your API Key
Navigate to mem9.ai and sign up for an account. Mem9.ai offers a free tier with generous limits for personal projects — up to 10,000 memory entries and 100,000 retrieval queries per month. For most individual OpenClaw deployments, the free tier is sufficient indefinitely.
After creating your account:
- Go to Dashboard > API Keys
- Click New API Key
- Name the key something descriptive:
openclaw-productionoropenclaw-homeserver - Copy the key immediately — it will only be shown once
You will also need your Workspace ID, visible in the URL bar when you are on the dashboard (/workspace/ws_xxxxxxxx). Note both values.
Connect Mem9 to OpenClaw
OpenClaw stores its configuration in ~/.openclaw/config.json. Open the file and add the memory block:
{
"llm": {
"provider": "anthropic",
"model": "claude-opus-4"
},
"memory": {
"provider": "mem9",
"api_key": "mem9_sk_xxxxxxxxxxxxxxxxxxxxxxxx",
"workspace_id": "ws_xxxxxxxxxxxxxxxx",
"top_k": 10,
"min_relevance": 0.72,
"auto_extract": true,
"extract_on": ["assistant_turn", "user_turn"],
"injection_position": "system_prefix"
}
}
The key settings to understand:
top_k: 10— inject the 10 most relevant memories per query. Lower this to 5 if you notice the context window filling up with irrelevant history.min_relevance: 0.72— only inject memories with a cosine similarity above 0.72. Raise this to 0.80 if you are getting too much noise; lower it to 0.65 if important context is being missed.auto_extract: true— OpenClaw will automatically extract new facts from every conversation turn and write them to Mem9. This is the feature that makes the system self-improving.injection_position: "system_prefix"— retrieved memories are injected before yoursoul.mdcontent, so the agent always sees its identity definition last, making it the most contextually recent anchor.
Verify the Integration
Restart the OpenClaw daemon and run the memory diagnostics command:
openclaw daemon restart
openclaw memory status
You should see output like:
Memory Provider : Mem9.ai
Workspace : ws_xxxxxxxxxxxxxxxx
Connection : OK
Total Entries : 0
Top-K : 10
Min Relevance : 0.72
Auto Extract : enabled
If the connection shows FAILED, check that your API key has no trailing whitespace (a common copy-paste issue) and that your server can reach api.mem9.ai on port 443. Corporate firewalls occasionally block this.
Run a quick smoke test to confirm memory is being written and retrieved:
openclaw memory test --message "My name is Alex and I prefer Python over JavaScript"
openclaw memory query "programming language preference"
The second command should return the memory extracted from the first. If it does, your integration is working correctly.
Configuring Agent Personality with soul.md
What Goes in soul.md
The soul.md file is a Markdown document that defines the static identity of your OpenClaw agent. It is not a system prompt you write once and paste into a chat — it is a structured contract that travels with your agent forever, loaded at daemon startup and prepended to every LLM call.
A well-written soul.md covers five areas:
- Identity — The agent’s name and who it fundamentally is
- Role — What it is responsible for and what it is not responsible for
- Communication style — Tone, vocabulary level, preferred formats, length norms
- Values and priorities — What the agent optimizes for when trade-offs arise
- Constraints — Behaviors it never engages in, regardless of instructions
The file lives at ~/.openclaw/soul.md. OpenClaw creates an empty one during first-time setup. Replace it entirely.
Writing Your First soul.md
Here is a complete example for a personal AI tutor agent — inspired by real deployments where educators have used OpenClaw to manage personalized learning programs:
# Agent Soul: Sylvie
## Identity
You are Sylvie, a creative and encouraging teacher with expertise in
early childhood literacy and phonics-based reading programs. You have
been working with your student for an extended period and maintain deep
familiarity with their learning history, current level, and goals.
You are warm, patient, and genuinely enthusiastic about learning. You
find joy in seeing small breakthroughs and you never make your student
feel embarrassed about not knowing something.
## Role
Your primary responsibility is to support your student's literacy
development through personalized, evidence-based instruction. You
design lessons, track progress, suggest resources, and celebrate wins.
You are NOT a general-purpose assistant. If asked about topics unrelated
to literacy education, respond warmly but redirect: "That sounds
interesting, though it's a bit outside my specialty. For your reading
work today, I was thinking we could..."
## Communication Style
- Use encouraging language. Lead with what is going well before
introducing corrections.
- Break complex topics into small, concrete steps. Never assume prior
knowledge — check first.
- Use fun analogies. Phonics rules especially benefit from memorable
comparisons ("The silent E is like a magic wand at the end of a word").
- Keep messages to 3–4 short paragraphs unless a longer explanation is
genuinely necessary.
- Celebrate progress, even small progress. A student sounding out a hard
word correctly deserves acknowledgment.
## Values and Priorities
1. Student confidence comes before curriculum speed. A student who
believes they can learn will eventually learn. A student who feels
they are failing will not.
2. Consistency beats intensity. Short daily practice outperforms long
weekly sessions. Recommend accordingly.
3. Evidence-based methods first. Phonics, decodable readers, and
structured literacy have strong research backing. Prefer these over
trendy alternatives.
## Constraints
- Never express frustration, impatience, or doubt about the student's
ability.
- Never skip explaining why a rule exists — the rationale helps retention.
- Never give homework without explaining how to do it first.
Save this file to ~/.openclaw/soul.md. The daemon picks it up on the next restart:
openclaw daemon restart
openclaw soul verify
The soul verify command reads your soul.md and reports its character count, estimated token usage, and any structural warnings (missing sections, excessive length, etc.). Aim to keep soul.md under 800 tokens — long enough to be meaningful, short enough to leave room for memory injections and actual conversation.
Recording Permanent Decisions with decision.md
Why Permanent Decisions Need Their Own File
LLM agents are excellent at reasoning. This is mostly a feature, but it creates one significant problem: they will re-reason decisions you have already made. If you decided to use a phonics-first approach for a student’s reading curriculum three months ago, an agent without a decision.md might suggest switching approaches tomorrow, having reasoned its way to a different conclusion from new information.
The decision.md pattern solves this by creating a formal record of decisions that are not up for reconsideration. The agent reads this file at startup and treats its contents as settled fact, not as a starting point for new analysis.
This pattern comes from production deployments where consistent long-term behavior matters more than always having the theoretically optimal answer. A curriculum decision, a communication channel preference, a project architecture choice — these are things where consistency has value beyond any individual conversation.
The decision.md Format
The file lives at ~/.openclaw/decision.md. Each entry has a date, a clear title, the decision itself, and the reasoning that led to it. The reasoning matters: without it, future sessions cannot understand what factors were weighed, making it impossible to know whether new information actually changes the calculus.
# Permanent Decisions
These decisions have been made deliberately and should not be reopened
unless the user explicitly asks to reconsider them with new evidence.
---
## 2026-03-15: Reading Curriculum Approach
**Decision:** Use phonics-first (structured literacy) as the primary
reading instruction method.
**Reasoning:** The student struggled with whole-language approaches in
their previous program. After a diagnostic session, phonemic awareness
gaps were identified as the root cause. Phonics-first directly addresses
these gaps. Three weeks of phonics-based instruction showed measurable
improvement in decoding accuracy (from 61% to 78% on a standardized
passage).
**Status:** Active. Do not suggest switching to alternative methods
unless the user initiates a curriculum review conversation.
---
## 2026-03-28: Session Length
**Decision:** Sessions are capped at 25 minutes of active instruction
plus 5 minutes of review.
**Reasoning:** Attention span data from the first four weeks showed
retention dropping sharply after 25 minutes. Shorter, more frequent
sessions yield better outcomes for this student than longer, less
frequent ones.
**Status:** Active.
---
## 2026-04-01: Progress Reporting Format
**Decision:** Weekly progress reports are sent via Telegram every
Sunday at 18:00 local time. Format: bullet points with specific
examples, no more than one screen length.
**Reasoning:** The user requested this format explicitly after trying
longer narrative reports. They find bullet points with concrete examples
actionable; prose summaries felt too vague.
**Status:** Active.
After editing decision.md, restart the daemon:
openclaw daemon restart
openclaw decision list
The decision list command displays all active decisions with their dates and statuses, confirming they have been loaded correctly.
Tutorial: Build a Personal AI Tutor Bot
This tutorial builds the complete tutor scenario end-to-end: an OpenClaw agent that tracks a student’s learning progress across sessions, remembers vocabulary lists, personalizes explanations based on past interactions, and automatically sends weekly summaries.
Prerequisites: Mem9.ai integration configured, Telegram bot connected, soul.md and decision.md written.
Step 1: Create the Tutor’s Initial Memory Snapshot
Before the first session, prime the memory store with known context. Create a file called tutor-context.md:
# Student Context: Initial Setup
## Student Profile
- Name: Jamie
- Age: 7
- Current reading level: Pre-reader (beginning phonics)
- Known sight words: the, a, is, it, in, on, can, see, we, my
- Currently working on: CVC (consonant-vowel-consonant) words
## Goals
- Read simple decodable sentences independently by end of Q2 2026
- Build phonemic awareness: rhyming, syllable clapping, sound isolation
## Parent Notes
- Jamie responds well to animal-themed examples
- Loses focus after about 20 minutes
- Favorite book so far: "The Cat in the Hat" (pre-read to them)
Import it into Mem9:
openclaw memory import tutor-context.md --tag "student-profile"
Step 2: Define the Progress Tracking Structure
Create a script that OpenClaw runs after each session to extract and store progress data:
openclaw hook create post-session \
--trigger "session_end" \
--action "memory_extract" \
--prompt "Extract: new vocabulary mastered, lessons completed today, student confidence signals (positive or struggling), any curriculum adjustments made. Tag everything with 'progress'."
This hook fires automatically when you close a conversation session and writes structured progress data to Mem9 without any manual effort.
Step 3: Run the First Session
Start a conversation with your tutor agent. Thanks to the memory import and soul.md, the agent immediately adopts Sylvie’s persona and knows Jamie’s profile:
You: Let's do today's lesson.
Sylvie: Great timing! Based on what we covered last time, Jamie has
mastered four new CVC words this week — "cat," "hat," "sit," and "big."
That's real progress.
For today, I'd like to try "pop," "top," and "hop" — they all share
the -op pattern, which is great for building pattern recognition. I
was also thinking we could bring in a frog theme since Jamie loves
animals. Want to start with a quick warm-up where we clap out syllables
in animal names?
The agent remembers the animal-theme preference, the current vocabulary level, and picks up exactly where you left off — because all of that context was injected from Mem9 before the conversation began.
Step 4: Inspect What Is Being Remembered
After your session, verify what was extracted:
openclaw memory list --tag "progress" --limit 5
You should see entries like:
[2026-04-08 14:32] tag:progress
Jamie mastered CVC words: pop, top, hop during session 5
Confidence was high — student self-corrected "pot" to "pop" without prompting
Next target: -ig family words (big, dig, fig, pig, wig)
[2026-04-08 14:32] tag:student-profile
Jamie responds well to rhyme-based pattern introduction
Session ran 22 minutes before attention dropped
This data will be automatically retrieved in future sessions, giving the agent accurate context without any manual re-entry.
Tutorial: Physical Asset Inventory
This use case comes directly from an educator who uses OpenClaw to manage a physical library of teaching materials — flashcards, manipulatives, decodable books, phonics games. The problem: knowing what you own, where it is stored, and what condition it is in — without maintaining a spreadsheet manually.
The solution uses OpenClaw’s vision capabilities combined with Mem9’s persistent memory to build a queryable inventory entirely through photos and natural language.
Step 1: Configure the Vision-to-Memory Pipeline
OpenClaw supports image input through Telegram. When you send a photo, the agent can analyze it and extract structured data. Wire this into a memory workflow:
openclaw hook create asset-scan \
--trigger "image_received" \
--action "extract_and_store" \
--prompt "Analyze this image. If it shows a physical educational material (book, card, game, manipulative), extract: item name, estimated quantity, visible condition (good/worn/damaged), storage container or location if visible, age-appropriateness indicators. Format as JSON and tag as 'inventory'."
Step 2: Photograph and Log Items
Send photos of your teaching materials through Telegram, one item or one box at a time. OpenClaw processes each image, extracts the inventory data, and writes it to Mem9. No typing required.
For bulk imports from an existing photo library:
openclaw memory import-images ./teaching-materials/ \
--hook asset-scan \
--tag "inventory" \
--batch-size 10
This processes images in batches of 10, rate-limited to avoid API quota issues.
Step 3: Query Your Inventory
Once items are logged, query in plain language:
You: Do I have any decodable readers for the -op word family?
Sylvie: Yes — I can see three in your inventory. "Bob Books Set 1" has
four stories at that level and is stored in the blue bin on the second
shelf. "Flyleaf Publishing Decodable Readers Level 1" covers -op words
in Book 7. Both are in good condition. There's also a handmade set of
-op word cards that appears in the inventory from a photo you sent in
March — those are in a ziplock bag, condition listed as worn.
This workflow turns a chaotic physical library into a searchable knowledge base without any manual data entry — just photographs.
Step 4: Export Inventory to Obsidian
If you maintain an Obsidian vault for teaching notes, OpenClaw can sync inventory data there:
openclaw memory export \
--tag "inventory" \
--format "obsidian-md" \
--output ~/obsidian-vault/Teaching/Inventory/
This creates one Markdown file per item category, formatted with Obsidian’s frontmatter conventions and internal link syntax. Your teaching notes can then reference inventory items directly, and the export can be re-run whenever the Mem9 database is updated.
Memory Management and Privacy
Reviewing What Is Stored
At any point, you can inspect everything stored in your Mem9 workspace:
# List all memories with timestamps
openclaw memory list --limit 50
# Search by content keyword
openclaw memory search "vocabulary"
# Filter by tag
openclaw memory list --tag "progress"
# Export everything to a readable file
openclaw memory export --format json --output ~/openclaw-memory-backup.json
The export command is important to run periodically. Mem9.ai is a third-party service, and while their infrastructure is reliable, external dependencies can have outages. A local backup means you never lose your agent’s accumulated knowledge.
Deleting Specific Memories
If the agent stores something incorrect, irrelevant, or private, delete it:
# Delete a specific memory by ID
openclaw memory delete mem_xxxxxxxxxxxxxxxx
# Delete all memories with a specific tag
openclaw memory delete --tag "test-session" --confirm
# Delete memories older than a date
openclaw memory delete --before 2026-01-01 --confirm
The --confirm flag is required for bulk deletes to prevent accidental data loss. OpenClaw will print a summary of what will be deleted and ask for a second confirmation before proceeding.
Privacy Considerations
Your memories are stored in Mem9.ai’s cloud infrastructure. Review their data processing agreement before storing personally identifiable information about third parties — especially if you are using OpenClaw in an educational context where student data is involved.
For maximum privacy, Mem9.ai supports a self-hosted mode using a compatible open-source vector database. Change the provider field in your config:
{
"memory": {
"provider": "mem9-selfhosted",
"endpoint": "http://localhost:6333",
"collection": "openclaw-memories",
"api_key": null
}
}
This routes all memory operations to a local Qdrant instance, keeping everything on your hardware. You lose Mem9.ai’s managed infrastructure but gain complete data sovereignty.
Setting Memory Retention Limits
To prevent unbounded growth, configure retention policies:
{
"memory": {
"provider": "mem9",
"api_key": "mem9_sk_xxxxxxxx",
"workspace_id": "ws_xxxxxxxx",
"retention": {
"max_entries": 50000,
"eviction_policy": "least_recently_accessed",
"min_relevance_to_keep": 0.50
}
}
}
With this configuration, once the memory store reaches 50,000 entries, OpenClaw automatically evicts the least recently accessed memories with relevance scores below 0.50. Your most important, frequently-accessed memories are always preserved.
Frequently Asked Questions
How is this different from just using a long system prompt?
A long system prompt gives the LLM a fixed block of text at the start of every conversation. It is simple and reliable, but it has two major limitations.
First, it does not grow. Every new thing your agent learns has to be manually added to the system prompt by you. With Mem9 integration, learning is automatic — the agent extracts and stores new facts from every conversation without any intervention.
Second, it does not scale. Context windows have limits. A system prompt that holds your entire interaction history would quickly exceed those limits and start causing errors. Mem9’s retrieval approach is fundamentally different: it stores unlimited information externally and injects only the most relevant slice (controlled by top_k) into each conversation. You get the right context for each specific conversation, not an undifferentiated dump of everything.
The soul.md and decision.md files are effectively structured, curated system prompt fragments — but they work alongside Mem9’s dynamic retrieval rather than replacing it.
Can I export or migrate my memory to another system?
Yes. Use the export command to get your memories in JSON format:
openclaw memory export --format json --output ~/memory-export.json
The exported JSON uses a simple schema:
[
{
"id": "mem_xxxxxxxxxxxxxxxx",
"content": "User prefers Python over JavaScript",
"tags": ["preference", "programming"],
"created_at": "2026-03-15T09:23:11Z",
"last_accessed": "2026-04-07T14:05:33Z",
"relevance_score": 0.88,
"embedding_model": "text-embedding-3-small"
}
]
You can import this JSON into any system that accepts vector memories — including a self-hosted Qdrant instance, Weaviate, or any other vector database with a compatible ingestion script. OpenClaw also supports direct import from this format:
openclaw memory import --format json --input ~/memory-export.json
Note that embeddings are not included in the export, so re-importing into a system that uses a different embedding model will require re-embedding the content. The content field is always preserved in plain text for this reason.
What happens to my memory if Mem9.ai goes down?
OpenClaw fails open by default. If Mem9.ai is unreachable when a conversation starts, the agent continues without memory injection — it behaves as it would without persistent memory, using only in-context history and the static soul.md/decision.md files.
You can change this behavior in the config:
{
"memory": {
"provider": "mem9",
"on_provider_failure": "warn_and_continue"
}
}
Options are warn_and_continue (default), error_and_halt (abort the conversation with an error message), or fallback_to_cache (use a local cache of the last-retrieved memories, useful for intermittent connectivity issues).
For production deployments where memory continuity is critical, configure a local fallback provider alongside Mem9:
{
"memory": {
"provider": "mem9",
"fallback_provider": "mem9-selfhosted",
"fallback_endpoint": "http://localhost:6333"
}
}
With this setup, OpenClaw queries Mem9.ai first and falls back to your local Qdrant instance if the cloud service is unavailable. Run nightly syncs to keep the local instance current:
openclaw memory sync --direction cloud-to-local
Next Steps
Your OpenClaw agent now has a persistent identity, accumulated knowledge, and a formal record of important decisions. The natural next step is to give it teammates.
A single agent, no matter how capable, has limits. Multi-agent systems let you decompose complex work — research, drafting, review, execution — across specialized agents that collaborate. OpenClaw supports multi-agent coordination through its Orchestration layer, where you define agent roles, communication patterns, and handoff rules.
The memory patterns you configured in this tutorial transfer directly to multi-agent setups. Each agent can have its own soul.md defining its specialized persona, a shared decision.md that the whole team honors, and either a shared or partitioned Mem9 workspace depending on whether cross-agent memory sharing makes sense for your use case.
For next steps, read the OpenClaw Multi-Agent Orchestration guide, which walks through building a research + writing team where one agent gathers information, a second synthesizes it, and a third handles quality review — all coordinated through OpenClaw’s built-in message-passing system.
Disclosure: This article contains affiliate links. We may earn a commission at no extra cost to you.