Agents That Remember: Memory Stores and Dreaming in Claude Managed Agents
Sessions are isolated by default — agents forget everything when they close. This lesson shows how to wire persistent memory onto your agents and use Dreaming to consolidate and improve what they remember over time.
This lesson is original educational writing based on this video by Claude (published May 23, 2026). All credit for the original content goes to the creators.
1. The isolation problem
When you create a session in Claude Managed Agents today, it starts with no knowledge of any previous session. Tell it something, close the session, open a new one — it has no idea what you just said. This is by design for many use cases, but it becomes a real limitation for agents that are supposed to learn, adapt, and improve over time.
In the workshop that this lesson is based on, engineer Kevin demonstrates this directly: he creates a session, tells it information about a conference talk, then creates a second session and asks what it knows. The second session has nothing. “That’s effectively the base case today.”
The fix is three composable primitives:
2. Memory stores
A memory store is a persistent, file-system-like store that you attach to a session. Under the hood it’s mounted as an actual filesystem: the agent can use bash, grep, and file tools to navigate it — a powerful interface that makes memory search efficient without requiring a vector database.
Creating a store
anthropic managed-agents memory-stores create \
--name "cwc-memory" \
--description "Conference notes and session follow-ups"
You’ll get back a memory store ID. You can inspect its contents (and manually add or edit entries) in the console at any time.
Attaching it to a session
When you create a session, pass the memory store configuration:
import anthropic
client = anthropic.Anthropic()
memory_config = {
"memory_store_id": "ms_abc123",
# Steer what the agent focuses on
"prompt": "Remember key insights, speaker names, resource links, and follow-up actions.",
# Optional: "read_only" to prevent the agent from writing
"access": "read_write",
}
session = client.beta.managed_agents.sessions.create(
agent_id="ag_xyz",
environment_id="env_xyz",
memory_stores=[memory_config],
title="Post-conference digest session",
)
What happens next
When the session receives a user message, the agent first checks memory: “Is there anything relevant I should know for this conversation?” It uses grep and file reads against the mounted store. If relevant context exists, it incorporates it. If new information worth keeping appears, it writes it — typically as a new file or appending to an existing one.
The second session in the demo retrieves the conference notes that the first session wrote, including timestamps and resource URLs it had extracted. That’s the working memory pattern.
Check your understanding
3 questions · your answers are saved in this browser only
-
1. Why is the memory store mounted as a filesystem rather than offered as a key-value API?
-
2. What does the `access: "read_only"` parameter do when attaching a memory store?
-
3. Dreaming is non-destructive. What does this mean specifically?
3. The memory growth problem
Once you have agents writing to a shared memory store across many sessions, a new problem emerges: unbounded growth. Agents tend to dump information rather than curate it. Over time:
- The same event gets recorded in ten slightly different ways
- Outdated information sits next to current information with no distinction
- The store becomes too large to efficiently search
- Important facts get buried under noise
This is the problem Dreaming solves.
4. Dreaming: a multi-agent memory improvement harness
Dreaming is an asynchronous batch job you launch against a memory store and a list of session transcripts. Under the hood it runs a multi-agent harness:
- An orchestrator assigns each session transcript to a sub-agent
- Each sub-agent reads its transcript and the current memory store, then identifies new facts, corrections, and conflicts
- The orchestrator collects results and produces a consolidated, deduplicated output memory store
The job writes to a new output memory store — your original is never modified. You can see exactly what changed in the console diff view before deciding whether to adopt the output.
Launching a dream
dream = client.beta.managed_agents.dreams.create(
model="claude-opus-4-8", # or sonnet-4-6 for lower cost
input_memory_store_id="ms_abc123",
session_ids=[
"sess_001", "sess_002", "sess_003",
# ... can scale to hundreds
],
# Optional: steer the dreaming harness
instructions="Focus on adding exact timestamps, speaker names, and URL references. "
"Organize memories by topic into subdirectories.",
)
print(f"Dream job started: {dream.id}")
What changes
In the workshop demo, after dreaming over three sessions, the output memory store had:
- An index file with slugs pointing to related memory files — enabling efficient future navigation
- An event logistics file with the full conference schedule (synthesized from mentions across multiple sessions)
- Richer session notes with added metadata: specific dates, names, session URLs
- All deduplicated: three sessions mentioning the same keynote collapsed into one entry
5. Human review in the loop
One of Dreaming’s underrated features: the output memory store is visible in the console before you adopt it. You can read the diff, check whether the harness hallucinated anything, manually edit entries, and only then wire the output into future sessions.
This is the right place for human review in memory-augmented agent systems — not in every session interaction, but in the periodic consolidation step where quality matters most.
Retiring the old store
Once you’re satisfied with the dream output:
# Point new sessions at the improved memory store
session = client.beta.managed_agents.sessions.create(
agent_id="ag_xyz",
environment_id="env_xyz",
memory_stores=[{"memory_store_id": dream.output_memory_store_id}],
)
# Optionally retire the original to keep your store list manageable
client.beta.managed_agents.memory_stores.retire("ms_abc123")
Retiring doesn’t delete the old store or affect any sessions that used it — it just removes it from your active list.
Build it yourself
Follow these exact steps to reproduce it yourself · estimated time: ~60 minutes
Prerequisites
- An Anthropic API key with Claude Managed Agents access
- Python 3.10+
- A use case with at least two sessions that should share context (e.g. a research agent, a support agent, a personal assistant)
Build a research assistant that remembers what it’s already learned across sessions.
Step 1 — Install and configure
pip install anthropic
export ANTHROPIC_API_KEY="sk-ant-..."Step 2 — Bootstrap the memory store and agent
import anthropic
client = anthropic.Anthropic()
# Create the agent
agent = client.beta.managed_agents.agents.create(
name="research-assistant",
model="claude-sonnet-4-6",
system_prompt=(
"You are a research assistant. When you learn new facts, save them to your "
"memory store. When asked a question, always check memory first before "
"searching the web. Organize memory files by topic."
),
)
# Create the environment
env = client.beta.managed_agents.environments.create(
name="research-env",
networking={"allowed_domains": ["*"]},
)
# Create a memory store
memory = client.beta.managed_agents.memory_stores.create(
name="research-memory",
description="Long-term research notes organized by topic",
)
print(f"Agent: {agent.id}, Env: {env.id}, Memory: {memory.id}")Step 3 — Session 1: teach it something
session_1 = client.beta.managed_agents.sessions.create(
agent_id=agent.id,
environment_id=env.id,
memory_stores=[{
"memory_store_id": memory.id,
"prompt": "Save key facts, sources, and open questions. Organize by topic.",
}],
title="Initial research: transformer attention mechanisms",
)
# Send the research brief
client.beta.managed_agents.sessions.messages.create(
session_id=session_1.id,
content="I've been reading about transformer attention. Key points: "
"self-attention allows tokens to attend to all other tokens in the sequence. "
"Scaled dot-product attention uses Q, K, V matrices. "
"Flash attention (Dao et al. 2022) makes this memory-efficient. "
"Reference paper: arxiv.org/abs/2205.14135",
)Let the session run, then close it.
Step 4 — Session 2: test recall
session_2 = client.beta.managed_agents.sessions.create(
agent_id=agent.id,
environment_id=env.id,
memory_stores=[{"memory_store_id": memory.id}],
title="Follow-up: attention efficiency",
)
client.beta.managed_agents.sessions.messages.create(
session_id=session_2.id,
content="What do you know about efficient attention implementations?",
)The agent should find the Flash Attention note from Session 1 without being told it exists.
Step 5 — Run a dreaming job after several sessions
import time
dream = client.beta.managed_agents.dreams.create(
model="claude-sonnet-4-6",
input_memory_store_id=memory.id,
session_ids=[session_1.id, session_2.id],
)
# Poll for completion
while True:
status = client.beta.managed_agents.dreams.retrieve(dream.id)
if status.status in ("completed", "failed"):
break
time.sleep(10)
print(f"Dream complete. Output store: {status.output_memory_store_id}")
print("Review the diff in the console before adopting.")What to iterate on
- Memory organization: If the agent dumps everything in one flat file, add to the memory prompt: “Use subdirectories:
/topics/,/sources/,/open-questions/” - Dreaming frequency: Start with dreaming after every 10 sessions; adjust based on memory quality
- Read-only reference: Once you have a good baseline memory, attach it as
read_onlyand have agents use a separate writable store for new notes
Where to go next
- Ship Your First Managed Agent — the Agent, Environment, Session primitives that memory attaches to
- Watch the original workshop to see the CLI and console UI live
- Anthropic’s Claude Managed Agents docs cover memory store endpoints in full