Claw Mart
← Back to Blog
August 3, 20269 min readClaw Mart Team

Understanding AGENTS.md, SOUL.md & MEMORY.md Files

Understanding AGENTS.md, SOUL.md & MEMORY.md Files

Understanding AGENTS.md, SOUL.md & MEMORY.md Files

Most people building their first AI agent hit the same wall: the agent works for about three turns, then starts hallucinating, forgets what it was doing, or loops infinitely burning through API credits like a drunk sailor at a casino. You stare at the terminal, watching tokens evaporate into nothing, and think, "There has to be a better way to configure this thing."

There is. And it comes down to three files you've probably seen referenced but never fully understood: AGENTS.md, SOUL.md, and MEMORY.md.

These aren't just documentation files. In OpenClaw, they're the actual configuration backbone of your agent β€” the blueprints that determine how it thinks, what it remembers, and how it behaves over time. Get them right and you have an agent that's reliable, debuggable, and genuinely useful. Get them wrong (or skip them entirely) and you're back to the "why is my agent calling the same tool seventeen times in a row" nightmare.

Let me break down what each file does, how they work together, and how to actually set them up so your agents stop embarrassing you.

The Three-File Architecture: What Each File Actually Does

Think of building an agent like building a person for a very specific job.

  • AGENTS.md is the job description β€” what the agent does, what tools it has access to, what its boundaries are.
  • SOUL.md is the personality and cognitive architecture β€” how it thinks, reasons, and maintains its internal state.
  • MEMORY.md is the brain's filing system β€” what it remembers, how it stores information, and what gets retrieved when.

They're separate files for a reason. You might want the same "personality" (SOUL) across multiple agents with different toolsets (AGENTS). You might want different memory strategies for a quick-task agent versus a long-running research agent. Separation of concerns isn't just good software engineering here β€” it's what keeps your agents from turning into incoherent mush.

AGENTS.md: The Operational Blueprint

This is where most people start, and honestly where you should start. Your AGENTS.md file defines the practical stuff: what LLM provider to use, what tools the agent can access, token budgets, error handling, and permissions.

Here's a real-world example for a code review agent:

agent:
  name: code_reviewer
  description: "Reviews pull requests for bugs, style, and security issues"
  
  llm:
    provider: openai
    model: gpt-4o
    max_tokens: 50000  # Hard budget ceiling
    
  tools:
    - name: read_file
      permissions:
        allow_paths:
          - ./src/**
          - ./tests/**
        deny_paths:
          - ./.env
          - ./secrets/**
          
    - name: run_tests
      command: pytest {test_path} --tb=short
      require_approval: false
      
    - name: post_review_comment
      require_approval: true
      approval:
        method: human
        timeout: 300
        
  error_handling:
    retry:
      max_attempts: 3
      backoff: exponential
    on_tool_error:
      action: report_to_agent
    on_timeout:
      action: checkpoint_and_resume

A few things worth noting here.

The max_tokens: 50000 line is your financial seatbelt. Without it, your agent can burn through unlimited tokens. I've heard stories of people racking up $50+ bills in under 20 minutes because their agent got stuck in a reasoning loop. OpenClaw enforces this as a hard ceiling β€” once you hit it, the agent terminates and reports what it accomplished. No surprises on your bill.

The permissions system is genuinely important. Look at the deny_paths on read_file. Without this, your code review agent could happily read your .env file and potentially leak secrets in its output. The require_approval: true on post_review_comment means the agent pauses and asks you before actually posting anything. It can do all the analysis it wants automatically, but the moment it tries to take an action with real consequences, you get a checkpoint.

Error handling isn't optional β€” it's what separates a toy from a tool. The report_to_agent action on tool errors is particularly clever. Instead of crashing silently (the thing that drives everyone insane), OpenClaw feeds the error back to the agent as context. The agent sees "Tool 'read_file' failed: Permission denied" and can reason about it β€” maybe it needs to check permissions first, or try a different path. Self-healing behavior, configured in five lines of YAML.

You can also run local models without changing your agent logic:

agent:
  llm:
    provider: ollama
    model: llama3:8b
    base_url: http://localhost:11434
    capabilities:
      function_calling: false
      json_mode: true

OpenClaw detects that your local model doesn't support native function calling and automatically switches to ReAct-style prompting. Same agent config, same tools, different execution strategy under the hood. You don't have to rewrite anything. This is one of those things that seems small until you've spent four hours trying to hack function calling support into a local Mistral model through some other framework's abstraction layer.

SOUL.md: The Personality and Cognitive Layer

This is the file most people skip and then wonder why their agent feels "off." The SOUL.md file defines how your agent thinks β€” its reasoning approach, its personality, its internal state tracking.

soul:
  identity:
    role: "Senior code reviewer with 10 years of experience"
    communication_style: "Direct and specific. Always cite line numbers."
    principles:
      - "Security issues are always high priority"
      - "Suggest improvements, don't just criticize"
      - "When uncertain, say so explicitly"
      
  reasoning:
    chain_of_thought: true
    confidence_tracking: true
    
  state:
    enabled: true
    expose:
      - reasoning_chain
      - tool_calls
      - context_window_usage
      - confidence_scores

The identity section does more than you'd think. It's not just cosmetic flavor text. When you tell an agent it's a "senior code reviewer with 10 years of experience," you're priming the LLM's behavior in meaningful ways. It'll be more thorough, more likely to catch edge cases, more opinionated about code quality. The principles list acts as a behavioral guardrail β€” these get injected into the system prompt and guide decision-making at every step.

But the real magic here is the state exposure. Look at what happens when you enable it:

print(agent.soul.current_state())

# Output:
# {
#   "step": 5,
#   "thinking": "Need to check file permissions before writing",
#   "tool_queue": ["check_permissions", "write_file"],
#   "tokens_used": 12405,
#   "confidence": 0.87
# }

You can see exactly what the agent is doing at any moment. No more "thinking..." black box. No more wondering whether it's stuck or working. You get the reasoning chain, the tool queue, the token count, and a confidence score. If confidence drops below a threshold, you can intervene. If the tool queue looks wrong, you can correct course before the agent wastes tokens.

This is the answer to the "I can't debug what the agent is actually doing" problem that plagues virtually every other framework. When your agent does something weird at step 12 of a 20-step task, you can go back to the state at step 11 and see exactly what reasoning led to the bad decision. That's not a nice-to-have β€” that's the difference between "I'll figure it out eventually" and "I found and fixed the issue in five minutes."

You can also add checkpointing:

soul:
  checkpointing:
    enabled: true
    frequency: every_5_steps
    on_crash:
      action: resume_from_last_checkpoint

Agent crashes at step 17? It picks up from the checkpoint at step 15 instead of starting over from scratch. When you're dealing with long-running tasks β€” multi-file code reviews, research synthesis, data processing pipelines β€” this saves enormous amounts of time and money.

MEMORY.md: The Context Retention System

This is the file that solves the "my agent forgets everything after 10 turns" problem. And it's the one that requires the most thought to configure well.

memory:
  working:
    type: sliding_window
    size: 4000_tokens
    
  episodic:
    type: vector
    embedding_model: text-embedding-3-small
    top_k: 5
    decay: 0.95
    
  semantic:
    type: knowledge_graph
    relation_extraction: true
    persistent: true
    storage: ./memory/semantic.db

Here's the key insight: not all memories are equal, and they shouldn't be stored the same way.

Working memory is the agent's immediate context β€” the last few messages, the current task, the file it's looking at right now. This is a sliding window that always stays in the prompt. Keep it small (4,000 tokens is a good starting point) so you don't waste context window space on information the agent doesn't currently need.

Episodic memory is where past interactions get stored as vector embeddings and retrieved by similarity. When the agent is reviewing database.py at turn 15, episodic memory can retrieve that "you flagged a similar SQL pattern as problematic in auth.py back at turn 3." The agent didn't keep that in its working context for 12 turns β€” it was stored, embedded, and retrieved when relevant. The decay: 0.95 means older memories gradually become less relevant, which prevents ancient context from overriding recent information.

Semantic memory is the most powerful layer β€” it extracts structured facts and stores them in a knowledge graph. Things like "this project uses FastAPI," "tests are required for all endpoints," "the user prefers descriptive variable names." These aren't conversation snippets β€” they're extracted truths that persist across sessions. The persistent: true flag means they survive between runs, so your agent actually gets smarter over time as it learns about your project.

Here's what this looks like in practice during a long code review:

Turn 1: Agent reviews auth.py, finds a SQL injection risk. Working memory holds the current file, semantic memory stores "Project has SQL injection vulnerabilities in auth module."

Turn 8: Agent reviews utils.py, finds nothing major. Working memory has rotated β€” auth.py details are gone from the prompt.

Turn 15: Agent reviews database.py, which has similar SQL patterns. Episodic memory retrieves the auth.py review by similarity. Semantic memory provides the fact "Project has SQL injection vulnerabilities." The agent connects the dots: "This uses the same vulnerable pattern I found in auth.py."

Without tiered memory, by turn 15 the agent would have zero context about what happened at turn 1. The context window would be stuffed with intermediate turns that aren't relevant. The agent would review database.py in complete isolation, missing the pattern entirely.

How the Three Files Work Together

The real power is in the interaction between these three files. Here's the flow:

  1. AGENTS.md defines what tools are available and sets operational boundaries
  2. SOUL.md defines how the agent reasons about using those tools and tracks its own state
  3. MEMORY.md ensures the agent has the right context to make good decisions at each step

When the agent encounters a new task:

  • AGENTS.md says "you can use these tools, within these permissions, up to this token budget"
  • SOUL.md says "think step-by-step, track your confidence, and if a security issue appears, prioritize it"
  • MEMORY.md says "here's what you know from previous interactions that's relevant to this task"

They're three separate concerns that compose into a coherent agent. Change the memory strategy without touching the toolset. Swap the personality without reconfiguring permissions. Test a different LLM provider without rebuilding your memory architecture.

An Observability Sidebar

One more piece worth mentioning: OpenClaw gives you built-in telemetry that actually makes sense.

observability:
  metrics:
    enabled: true
    export:
      - prometheus
      - json_file
  tracing:
    enabled: true
    provider: jaeger

This gets you structured data on every session β€” total cost, tokens consumed per phase, tool call success rates, average latency. When you're trying to optimize an agent (or justify its cost to a manager), having actual numbers instead of vibes is invaluable.

{
  "session_id": "abc-123",
  "total_cost": 0.47,
  "tokens": {"input": 8234, "output": 1891},
  "tools_used": {
    "read_file": {"calls": 5, "success_rate": 1.0, "avg_latency_ms": 45},
    "search": {"calls": 2, "success_rate": 0.5, "avg_latency_ms": 320}
  },
  "task_success": true
}

You can see that search has a 50% success rate and is slow. Time to fix or replace that tool. Without metrics, you'd never know β€” you'd just feel like the agent was "kind of slow sometimes."

Getting Started Without the Pain

Here's my honest recommendation: don't try to write all three files from scratch on your first agent. The interplay between AGENTS.md, SOUL.md, and MEMORY.md configurations is nuanced, and there are non-obvious gotchas β€” like setting your working memory window too large and starving episodic retrieval of context space, or configuring error handling that conflicts with your approval workflows.

If you don't want to fumble through all of this manually, Felix's OpenClaw Starter Pack on Claw Mart is the fastest way I've found to get productive. It's $29 and includes pre-configured skills with all three files already set up and tuned β€” working memory sizes that actually make sense, episodic retrieval that's properly calibrated, tool permissions that won't leave your filesystem exposed. I spent two days tweaking memory decay rates before I found it. Could've saved myself the weekend.

The starter pack gives you working examples you can read, modify, and learn from β€” which is a far better starting point than staring at a blank YAML file trying to figure out whether your embedding model should use top_k: 3 or top_k: 10.

What To Do Next

  1. Start with AGENTS.md. Define one agent, two or three tools, and a token budget. Get it running.
  2. Add SOUL.md when you want to debug behavior or shape personality. Enable state exposure immediately β€” you'll thank yourself.
  3. Add MEMORY.md when conversations go beyond five or six turns or when you need cross-session persistence.
  4. Turn on observability once you're running regularly. The data will tell you what to optimize.

The three-file pattern isn't complicated β€” it's just unfamiliar. Once you've configured one agent this way, every subsequent agent takes about ten minutes to set up. And unlike the "throw everything into one giant prompt and pray" approach, you'll actually be able to maintain, debug, and improve it over time.

That's the whole point. Agents that you can understand, control, and trust. Three files. Let's go.

Claw Mart Daily

Get one AI agent tip every morning

Free daily tips to make your OpenClaw agent smarter. No spam, unsubscribe anytime.

More From the Blog