Chapter 14: Memory Patterns That Actually Work
By the end of this chapter, you will know three proven memory architecture patterns — per-user memory, project memory, and team knowledge — and understand how to design memory structures that scale cleanly.
The Big Idea
Knowing the six memory tools is necessary but not sufficient. The question of how to structure what gets remembered is where most memory implementations succeed or fail.
A well-designed memory architecture makes your agent smarter over time. A poorly designed one creates noise — the agent reads stale information, writes redundant content, or confuses context from different users and projects.
The difference comes down to three decisions:
What to remember. Not everything worth knowing should be written to memory. Agent memory works best for preferences, conventions, and learned context that genuinely applies across future sessions. Ephemeral facts, raw research, and session-specific calculations belong in the session's event log, not in persistent memory.
How to structure it. Small, focused documents organized by clear path conventions work better than large, sprawling ones. The path structure is your information architecture.
When to read vs. when to write. The agent reads before starting work and writes when it learns something worth keeping. Your job is to make the boundaries of "worth keeping" clear through system prompt guidance and memory store descriptions.
This chapter covers three patterns that work in practice: per-user memory (for agents serving individual users), project memory (for agents working on evolving codebases or ongoing projects), and team knowledge (for shared organizational knowledge bases that all agents in a team can read).
The Analogy
Think of the three patterns like three different types of notebooks.
Per-user memory is like the notes a personal assistant keeps about each client — their preferences, communication style, running priorities, and things not to mention. Every page is about one person.
Project memory is like the project notebook that lives in the conference room — architecture decisions, why we chose this framework, what we tried that didn't work, current status, open questions. Anyone who joins the project picks it up and gets context immediately.
Team knowledge is like the company wiki — the shared, curated knowledge that everyone benefits from and senior team members maintain. It doesn't change based on individual sessions; it evolves as a deliberate knowledge-building practice.
Each notebook serves a different purpose. You wouldn't combine them into one document. You shouldn't combine them in memory either.
How It Actually Works
Pattern 1: Per-User Memory
Per-user memory keeps individual preferences, history, and context specific to each user of your agent. The memory store is scoped to a single user and attached to their sessions.
The structure:
/preferences/
/preferences/communication-style.md ← how they like responses formatted
/preferences/technical-level.md ← how technical to be
/preferences/timezone-and-schedule.md ← scheduling context
/history/
/history/recent-topics.md ← topics from recent sessions
/history/ongoing-projects.md ← projects they've mentioned
/user/
/user/profile.md ← name, role, goals
/user/notes.md ← anything the agent needs to remember
How to implement it:
Create one memory store per user and attach it at session creation:
# Creating the per-user store (do this once per user)
store = client.beta.memory_stores.create(
name=f"User: {user_id}",
description="Preferences and context for this user.",
)
user_store_map[user_id] = store.id
# Attaching at session creation (every time this user starts a session)
session = client.beta.sessions.create(
agent=agent.id,
environment_id=environment.id,
resources=[
{
"type": "memory_store",
"memory_store_id": user_store_map[user_id],
"access": "read_write",
"prompt": "User preferences, history, and personal context. Check before responding to ensure you're adapted to this user.",
}
],
)
What the agent writes automatically: After sessions, Claude will write memories about what it learned: the user prefers concise responses, the user works on a Python backend project, the user doesn't like jargon. These accumulate over time, making each subsequent session more personalized.
Design principles for per-user memory:
- Keep preferences separate from history — they have different update cadences
- Use specific paths (
/preferences/communication-style.md) rather than vague ones (/misc.md) - The
promptfield at session creation is your instruction to Claude about what the store contains and when to consult it
Pattern 2: Project Memory
Project memory keeps the evolving context of a specific project — decisions, conventions, status, what was tried and why. A single project memory store is shared across all sessions working on that project.
The structure:
/architecture/
/architecture/overview.md ← high-level structure
/architecture/decisions.md ← ADRs (architecture decision records)
/architecture/patterns.md ← coding patterns we use
/conventions/
/conventions/code-style.md ← formatting, naming, imports
/conventions/testing.md ← test framework, coverage expectations
/conventions/git.md ← branch naming, commit messages
/status/
/status/current-focus.md ← what's being worked on now
/status/known-issues.md ← bugs and limitations
/status/completed-milestones.md ← what's done
/learnings/
/learnings/what-didnt-work.md ← approaches tried and abandoned + why
How to implement it:
# Create the project store (once per project)
project_store = client.beta.memory_stores.create(
name=f"Project: {project_name}",
description="Architecture decisions, conventions, and status for this project.",
)
# Seed initial conventions from your existing documentation
client.beta.memory_stores.memories.write(
memory_store_id=project_store.id,
path="/conventions/code-style.md",
content="Use 2-space indentation. No trailing whitespace. Files end with a newline.",
precondition={"type": "not_exists"}, # Don't overwrite if already seeded
)
# Attach to coding sessions (every session working on this project)
session = client.beta.sessions.create(
agent=agent.id,
environment_id=environment.id,
resources=[
{
"type": "memory_store",
"memory_store_id": project_store.id,
"access": "read_write",
"prompt": "Project conventions, architecture decisions, and current status. Check conventions before writing any code. Update status when completing milestones.",
}
],
)
The key difference from per-user memory: The project memory is shared across sessions and potentially across users. If multiple developers are using the same agent on the same project, they share this memory store.
Design principles for project memory:
- Seed the memory with existing conventions and documentation before running any sessions
- Use
precondition: {"type": "not_exists"}when seeding to avoid overwriting later updates - The
promptfield should explicitly instruct Claude to both read conventions before coding AND write updates when decisions are made - Review the
/learnings/what-didnt-work.mdfile regularly — this is the most valuable memory file for avoiding repeated mistakes
Pattern 3: Team Knowledge
Team knowledge is a shared, read-only knowledge base that many agents consult but only administrators update. It's the equivalent of a company wiki or a style guide that all agents benefit from.
The structure:
/company/
/company/overview.md ← who we are, what we do
/company/style-guide.md ← brand voice, writing standards
/company/glossary.md ← terminology and definitions
/products/
/products/product-a/overview.md ← product descriptions
/products/product-b/overview.md
/policies/
/policies/data-handling.md ← what data can be shared
/policies/communication.md ← external communication guidelines
How to implement it:
# Create the shared knowledge store (once per organization)
team_store = client.beta.memory_stores.create(
name="Team Knowledge Base",
description="Shared organizational knowledge — style guides, product context, policies.",
)
# Populate with knowledge base content
client.beta.memory_stores.memories.write(
memory_store_id=team_store.id,
path="/company/style-guide.md",
content="...",
)
# Attach as READ-ONLY to all agent sessions
session = client.beta.sessions.create(
agent=agent.id,
environment_id=environment.id,
resources=[
{
"type": "memory_store",
"memory_store_id": team_store.id,
"access": "read_only", # Agents can read but never modify
"prompt": "Organizational knowledge including style guide, product context, and policies. Consult before producing any external-facing content.",
}
],
)
The key design choice: read_only access. The team knowledge base is updated by administrators via the API, not by agent sessions. Attaching it as read_only ensures no agent session — regardless of what it does — can modify the shared knowledge base.
Combining with other patterns:
In practice, a production agent often uses two or three stores together:
session = client.beta.sessions.create(
agent=agent.id,
environment_id=environment.id,
resources=[
{
"type": "memory_store",
"memory_store_id": team_store.id, # Shared knowledge — read only
"access": "read_only",
"prompt": "Organizational style guide and policies.",
},
{
"type": "memory_store",
"memory_store_id": project_store.id, # Project conventions — read/write
"access": "read_write",
"prompt": "Project conventions and architecture decisions.",
},
{
"type": "memory_store",
"memory_store_id": user_store_map[user_id], # User preferences — read/write
"access": "read_write",
"prompt": "This user's preferences and history.",
},
],
)
This is within the 8 memory stores per session limit. Each store serves a distinct purpose, has appropriate access control, and has a prompt that clearly tells Claude what the store contains and when to use it.
Memory Maintenance
Memory is not a "set it and forget it" system. Plan for maintenance:
Regular audits: After every 20–30 sessions, list all memories in your stores and check what's been written. Look for:
- Outdated information (conventions that changed)
- Contradictory entries (two memories that say different things)
- Overly verbose entries (a 40 KB file when 4 KB would do)
- Missing entries (a topic that came up repeatedly but was never documented)
Version review for anomalies: If an agent starts behaving unexpectedly, check recent memory version history. A modified entry from a recent session may contain incorrect information that's now shaping behavior.
Redacting sensitive content: If a session accidentally wrote an API key, credential, or PII to a memory, use memory_versions.redact to expunge the content from the version history while preserving the audit trail.
Seeding from existing documentation: The best memory systems start with your existing documentation — style guides, architecture docs, product context. Write Python scripts to import these into memory stores as structured, path-organized files before running any sessions.
Try It Yourself
Design your memory architecture on paper. For your intended use case: which of the three patterns apply? What paths would you use for each store? What would you seed before the first session? Write it out before writing any code.
Seed a project memory store with existing documentation:
project_store = client.beta.memory_stores.create( name="My Project", description="Conventions and decisions for my project.", ) # Write your existing style guide client.beta.memory_stores.memories.write( memory_store_id=project_store.id, path="/conventions/code-style.md", content=""" ## Code Style Conventions - Use 2-space indentation - Prefer descriptive variable names - Write JSDoc comments for all public functions - No trailing whitespace """, precondition={"type": "not_exists"}, )Run a session with the memory store and observe what gets written. Send a coding task to a session with the project store attached. After the session, list all memories:
page = client.beta.memory_stores.memories.list(project_store.id, path_prefix="/") for memory in page.data: print(f"{memory.path} — {memory.size_bytes} bytes")Were any new memories written? What paths did Claude choose?
Build the multi-store session pattern. If you have both a project store and (if you have per-user use case) a user store, attach both to a single session using the combined
resourcesarray from this chapter.Simulate a memory audit. Run three to five sessions on the same project store. Then audit:
- List all memories by path
- Read each one and check for accuracy
- Look at version history for any files with multiple versions
- Identify anything that should be updated or deleted
Common Pitfalls
Not giving memory stores a
promptat session creation. Thepromptfield (up to 4,096 characters) tells Claude what the store contains and how to use it. Without it, Claude may not know when to consult which store. Always write a clear, specific prompt that names the store's purpose and gives guidance on when to read vs. write.Using a single massive store for everything. Separate stores for separate concerns. User preferences should not mix with project conventions. Project conventions should not mix with team knowledge. When mixed, the agent's memory lookups become ambiguous and maintenance becomes difficult.
Never seeding memory before the first session. Don't wait for the agent to build up memory from scratch. Seed it with your existing documentation, conventions, and context. A well-seeded memory store produces much better results from session one than an empty store that slowly accumulates entries.
Giving agents write access to the team knowledge base. The team knowledge base should be
read_onlyfor all agent sessions. Updates should come from humans via the API. If an agent writes to the team knowledge base based on something a user said in one session, it can corrupt the shared knowledge for all future users and agents.Building memory-dependent workflows without a maintenance plan. Memory accumulates errors over time. Outdated information, incorrect conclusions from past sessions, and contradictory entries will shape future agent behavior unless you actively curate the memory store. Schedule regular audits from day one.
Toolkit
Memory Architecture Design Canvas — A visual planning template for designing memory structures before implementation. Sections for: store names, path conventions, what gets seeded vs. what Claude writes, access levels, and maintenance schedule.
Memory Seeding Script Template — A Python script template for seeding memory stores from existing Markdown documentation. Reads all
.mdfiles from a directory and writes them to specified paths in a memory store using safe preconditions.
Chapter Recap
- Three proven memory patterns: per-user (personalization across sessions for a specific user), project (evolving context for a specific codebase or project), team knowledge (shared, read-only organizational wisdom for all agents).
- Design memory as many small, focused documents organized by clear path conventions. Use the
promptfield at session creation to tell Claude what each store contains and when to use it. - Combine patterns in a single session (up to 8 stores) with appropriate access levels. Seed stores from existing documentation before running sessions. Audit and maintain memory regularly — it accumulates errors without active curation.