Chapter 14 of 14 · Part 4: Give Your Agent Memory

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:

  1. 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.

  2. 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.

  3. 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).

DiagramThree pattern cards arranged side by side. Card 1: "Per-User Memory" — single user icon, one memory store, personalization focus. Card 2: "Project Memory" — code/file icon, one or two memory stores, continuity focus. Card 3: "Team Knowledge" — group icon, shared read-only store plus per-agent write stores, shared wisdom focus. Each card has a brief "What it stores" description and a "Key design principle."

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.

DiagramThree notebook illustrations. (1) Personal client notebook — different colored tabs for each client, pages showing preferences and notes. (2) Project conference room binder — labeled sections for architecture, decisions, status. (3) Company wiki printout — structured table of contents, well-organized sections. Caption: "Each has a different purpose, a different owner, and a different update cadence."

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 prompt field 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 prompt field should explicitly instruct Claude to both read conventions before coding AND write updates when decisions are made
  • Review the /learnings/what-didnt-work.md file 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.

DiagramMemory maintenance calendar. Monthly view with labeled tasks: Week 1 — "Audit /project/ store for outdated entries." Week 2 — "Review version history for unexpected writes." Week 3 — "Check per-user memories for users who've been inactive 30+ days." Week 4 — "Update team knowledge base with any new style/policy changes." Caption: "Memory requires maintenance. Build it into your workflow."

Try it yourself

Try It Yourself

  1. 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.

  2. 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"},
    )
    
  3. 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?

  4. 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 resources array from this chapter.

  5. 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
DiagramThree-store session diagram. Central box: "Session." Three memory store boxes feeding into it with labeled arrows: (1) "Team Knowledge (read_only)" — grey feed arrow. (2) "Project Memory (read_write)" — blue feed arrow with bidirectional (read + write). (3) "User Preferences (read_write)" — green feed arrow bidirectional. Caption: "Three stores, three purposes, three access levels. All within the 8-store limit."

Common pitfalls

Common Pitfalls

  • Not giving memory stores a prompt at session creation. The prompt field (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_only for 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

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 .md files 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 prompt field 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.