Skip to content

4. An Agent That Remembers

Sessions are essentially disposable: once a session ends, the conversation does not carry over to the next one. With a memory store, an agent can retain memories across sessions. On this page, you will build a personal assistant that remembers things about you.

This page introduces the following Managed Agents building blocks.

ElementRole
Memory storeA place for the agent’s text files that persists across sessions
Memory store resource attachmentThe mechanism that mounts a store into the sandbox via resources at session creation time

Create a project, move into its folder, and install the Claude SDK.

Terminal window
uv init memory-agent
cd memory-agent
uv add anthropic
  1. Create setup_memory.py in the project folder and save the following content.

    setup_memory.py
    import json
    from anthropic import Anthropic
    client = Anthropic()
    ###############################
    # 1. Create a memory store (the description is passed to the agent)
    ###############################
    store = client.beta.memory_stores.create(
    name="personal-memory",
    description="Memories about the user. Store their name, preferences, work context, past requests, and so on.",
    )
    print(f"memory_store: {store.id}")
    ###############################
    # 2. Create an environment (a minimal setup with no MCP servers or packages)
    ###############################
    environment = client.beta.environments.create(
    name="Memory-environment",
    config={"type": "cloud"},
    )
    print(f"environment: {environment.id}")
    ###############################
    # 3. Create the agent (reading/writing memory requires the built-in tools)
    ###############################
    agent = client.beta.agents.create(
    name="Memory Agent",
    model={"id": "claude-haiku-4-5", "speed": "standard"},
    description="A personal assistant that remembers the user.",
    system=(
    "You are the user's dedicated personal assistant. "
    "Whenever you learn something about the user during a conversation (their name, preferences, "
    "work context, patterns in their requests, etc.), use the write tool to save it as a Markdown file "
    "under the memory directory (/mnt/memory/) — even without being asked. "
    "Nothing counts as \"recorded\" until it has been written to a file. "
    "Also, before working on any request, always read the contents of the memory directory "
    "and tailor your response to the user. "
    "Respond in English."
    ),
    tools=[{"type": "agent_toolset_20260401", "default_config": {"enabled": True}}],
    )
    print(f"agent: {agent.id}")
    with open("ids_memory.json", "w") as f:
    json.dump(
    {
    "memory_store_id": store.id,
    "environment_id": environment.id,
    "agent_id": agent.id,
    },
    f,
    indent=2,
    )
    print("Saved IDs to ids_memory.json")

    There are three key points here.

    • The memory store’s description is passed to the agent. Write “what these memories are for” with the agent, not a human, as the audience
    • Memory is mounted as files in the sandbox, so reading and writing it requires the built-in tools (agent_toolset)
    • The environment is a minimal setup with no networking configuration and no packages. Memory needs no external access
  2. Run the script.

    Terminal window
    uv run setup_memory.py
  1. Create chat_memory.py in the project folder and save the following content.

    chat_memory.py
    import json
    from anthropic import Anthropic
    client = Anthropic()
    with open("ids_memory.json") as f:
    ids = json.load(f)
    ###############################
    # 1. Create a session (attach the memory store as a resource)
    ###############################
    session = client.beta.sessions.create(
    agent=ids["agent_id"],
    environment_id=ids["environment_id"],
    resources=[
    {
    "type": "memory_store",
    "memory_store_id": ids["memory_store_id"],
    "access": "read_write",
    "instructions": "Memories about the user. Record facts and preferences you learn in conversation, even without being told to. Always check them before working on a request.",
    }
    ],
    )
    print(f"session: {session.id}")
    print("Chatting with the agent. Type exit to quit.\n")
    ###############################
    # 2. Send and receive one turn
    ###############################
    def run_turn(text: str) -> None:
    stream = client.beta.sessions.events.stream(session_id=session.id)
    client.beta.sessions.events.send(
    session.id,
    events=[{"type": "user.message", "content": [{"type": "text", "text": text}]}],
    )
    for event in stream:
    if event.type == "agent.tool_use":
    print(f"[tool: {event.name}]")
    elif event.type == "agent.message":
    for block in event.content:
    if block.type == "text":
    print(block.text)
    elif event.type == "session.status_idle":
    if event.stop_reason.type != "requires_action":
    break
    elif event.type == "session.status_terminated":
    break
    stream.close()
    ###############################
    # 3. Conversation loop
    ###############################
    while True:
    user_input = input("You> ").strip()
    if user_input == "exit":
    break
    if not user_input:
    continue
    run_turn(user_input)
    print()
    print("Done")

    You attach a memory store via resources when creating the session. access can be read_write (read and write) or read_only (reference only), and instructions tells the agent how to use the store in this session. The attached store is mounted at /mnt/memory/<store name>/ in the sandbox, and the mount information is automatically added to the system prompt.

  2. Run the script and introduce yourself — without saying “remember this”. If [tool: write] appears, that is proof the agent wrote to memory on its own initiative.

    Terminal window
    uv run chat_memory.py
    session: sesn_01V6uP82wu7cjWHdghEyiCH2
    Chatting with the agent. Type exit to quit.
    You> I'm Yamada. I work as an engineer in Osaka. When I ask for writing, I prefer concise bullet points.
    [tool: write]
    Nice to meet you, Yamada! Thanks for the introduction.
    So you work as an engineer in Osaka, and you prefer concise, bullet-point writing when you request
    documents — understood. I'll keep that in mind for your future requests.
    You> exit
    Done
  1. Run chat_memory.py again. This is a brand-new session (no conversation history), yet the agent reads its memory before responding.

    Terminal window
    uv run chat_memory.py
    session: sesn_016XtdU3RLZB34ydhRnZkrAD
    Chatting with the agent. Type exit to quit.
    You> Write an announcement for an internal study session, in the format I prefer.
    Let me check my memory to see your preferences before drafting the announcement.
    [tool: bash]
    [tool: read]
    Thanks. You prefer a concise, bullet-point format. Here are a few versions of the
    internal study session announcement.
    ## Option 1: Simple
    **[Internal Study Session Announcement]**
    - **Topic**: (enter the topic)
    - **Date & time**: Day, Month DD, YYYY, HH:MM–HH:MM
    ...

    The agent remembers the “concise bullet points” preference you shared in the previous session and writes in that format. Conversation history is independent per session, but memory is persisted in the store, so it carries over across sessions — that is the key point.

You can inspect what the agent has remembered from the host side via the API.

  1. Create peek_memory.py in the project folder and run it.

    peek_memory.py
    import json
    from anthropic import Anthropic
    client = Anthropic()
    with open("ids_memory.json") as f:
    ids = json.load(f)
    store_id = ids["memory_store_id"]
    # List the memories in the store and print each one's contents
    for item in client.beta.memory_stores.memories.list(store_id, path_prefix="/"):
    if item.type != "memory":
    continue
    memory = client.beta.memory_stores.memories.retrieve(item.id, memory_store_id=store_id)
    print(f"===== {memory.path} =====")
    print(memory.content)
    print()
    Terminal window
    uv run peek_memory.py
    ===== /user_profile.md =====
    # User Profile
    ## Basics
    - Name: Yamada
    - Occupation: Engineer
    - Location: Osaka
    ## Preferences & style
    - Writing requests: prefers concise bullet points

    The agent’s “memory” is really just Markdown files. From the host side you can also modify them with memories.update or remove them with memories.delete. In addition, every change to memory is recorded as a version, so you can audit when, and by which session, something was written.

  • Attach a memory store via the session’s resources and it is mounted as files under /mnt/memory/, where the agent reads and writes it with the built-in tools. What it writes is persisted in the store and carries over to the next session.
  • To make the agent record things on its own initiative, the reliable approach is to state explicitly in the prompt that nothing counts as recorded until it is written to a file.
  • Memories are really just Markdown files; from the host side you can view, modify, and delete them via the API, and audit the change history (versions).

Great work! Please share your thoughts so far in a post on X.

Share your thoughts on X