Skip to main content
Normally, a managed deep agent’s conversational memory is scoped to a thread or session. Durable memory is optional knowledge that an agent can retain across threads, sessions, and deployments. Managed Deep Agents do not have durable memory by default. Durable memory is backed by the Context Hub and comes in two independent layers. Enable the layer you need.
Managed Deep Agents is in public beta on LangSmith Cloud and Bring Your Own Cloud (BYOC). Use version 0.10 of the Managed Deep Agents CLI and SDK for BYOC.
Memory layers require managed-deepagents>=0.8.0. Earlier versions declare a single deployment-shared scope instead.
To enable durable memory, put a memory declaration at the project root:
For the full project layout, see Project structure.

Choose a layer

A layer names whose memory the agent reads and writes. Each enabled layer mounts its own read/write tree in the agent filesystem. Most agents need one layer. One mount means one hot file in every model call, and no routing decision on each save. Choose by asking whose knowledge the agent keeps. Use agent memory alone when every caller benefits from the same knowledge: a support agent that learns an escalation path, a research agent that learns which sources your team trusts, a build agent that learns a repository’s conventions. Use user memory alone when the agent serves many people and adapts to each one: an assistant that learns a person’s office, their preferred answer format, or the product area they work on. User memory requires a deployment that authenticates callers as people. Declare both when the agent keeps both kinds of knowledge: a team assistant that learns shared conventions and each person’s preferences. The agent picks a mount on every save, guided by the runtime. To review that choice before a write is stored, see Require approval before a memory write. To mount one layer at a time instead, see Select layers for each run.
Agent memory is readable by every caller. On a deployment that serves more than one person, a caller-specific detail saved to /memories/agent/ is exposed to all of them.The runtime tells the agent not to save private or caller-specific information there. That instruction is guidance, and nothing enforces it.Declaring user memory alongside it gives the agent somewhere correct to put such a detail. Agent memory alone leaves it nowhere to go. Only a deployment that mounts user memory alone avoids the exposure outright. Where agent memory has to mount, require approval before a memory write.
Omitting a layer disables it. Removing the memory declaration turns durable memory off for the whole agent. Turning memory off deletes nothing. The Context Hub repositories behind each layer keep their contents, and the agent can no longer read or write them. Declaring the layer again mounts the same repositories, with everything stored before still in place. The runtime never copies content between layers. Use durable memory for knowledge the agent should learn while it runs and reuse later. For always-on behavior, use instructions instead. For task-specific procedures, use skills instead. User memory is stored in an opaque Context Hub repository keyed on the caller’s authenticated principal, so one person cannot reach another person’s memory.
User memory prerequisite: user memory mounts only for a caller the deployment authenticates as a person. A LangSmith API key authenticates a service, so the default identity provider never mounts user memory. To authenticate signed-in end users, configure Supabase. Runs that arrive through a connected Slack workspace resolve to the linked person and satisfy this requirement.Agent memory has no identity requirement. Skip this prerequisite if you enable only the agent layer.

Enable memory

1

Add the memory declaration

Export a named memory declaration that enables the layer you want. This example enables agent memory, which works without identity configuration:
memory.py
To give each person their own memory instead, declare the user layer and confirm your deployment authenticates callers as people:
memory.py
Each layer uses its default access unless a factory selects layers for the run.
2

Guide what to remember (Optional)

The agent decides what to remember based on prompting. To make the policy explicit, add guidance like the following to instructions.md and adapt it to your application:
instructions.md is always read-only. The agent never updates it. Deploys sync project-owned instructions and skills, but do not overwrite durable content already stored in Context Hub.

Control access to a layer

Declaring a layer makes it available. Whether the agent reaches it on a given run is a second decision, made once at the start of that run:
  1. The runtime resolves the caller. User memory stops here unless the caller is an authenticated person.
  2. The agent factory selects the layers for that run, or the project’s declaration applies when no factory selects them.
  3. Layers that pass mount at their paths, and their hot memory loads.
When nothing selects layers for a run, Managed Deep Agents applies these defaults: Agent memory is deployment-shared, so it is available by default. User memory is personal, so it mounts by default only where the conversation is already private to one person. A Slack channel, a group DM, and a direct API run all fall outside that. The runtime cannot determine from the outside whether such a run is private, so it denies user memory there. Personal memory never reaches a shared conversation unless the deployment opts in.

Select layers for each run

To decide per run, export an agent factory and pass memory to the definition it returns. The factory receives the runtime, so it can read the application context the caller sent, or the channel the run arrived on. For the factory itself, see Select configuration per run. A direct API run is denied user memory by default, because the runtime cannot determine whether the run is private. Your application has that information. It knows which end user it acts for, and whether that person asked the agent to remember them. Send that decision in the run’s context field, then read it in the factory. This example mounts user memory when the caller sets remember to true, and agent memory otherwise:
agent.py
The caller supplies that context when it creates the run, so a “remember me” setting in your product becomes a field on the run:
A factory selection overrides the project’s memory declaration for that run. The table above applies only to runs where no factory selected the layers. One rule survives the override: user memory mounts only for an authenticated person. A user layer selected for a service principal does not mount. Configure Supabase or your own backend before any run reaches user memory. Pass memory=None to give a run no durable memory. Omit memory to keep what the project declares. Agent Server calls the factory to inspect the graph as well as to run it, so keep the selection a pure function of the runtime it receives. See Keep the factory repeatable.

Migrate from an allow policy

A layer could previously carry an allow(context) policy that returned a boolean. That callback is deprecated as of managed-deepagents 0.9.0. A policy declared in memory.py or memory.ts still runs, so an existing project keeps working. Selecting layers in a factory replaces it. Memory selected in a factory rejects the callback:
A policy that raises fails the run rather than denying the mount. Catch exceptions inside a policy you still run, and return false, so that an unavailable datastore denies user memory and the run continues.
Neither a factory selection nor an allow policy widens access past the caller the runtime authenticated. Neither mounts memory for a service principal, and neither reaches another person’s memory.

Test memory access

When a user layer is mounted, a verified Studio user receives it: the runtime skips that layer’s policy for them. The local mda dev principal resolves the same way. Studio is therefore not a place to test a user-layer policy. A factory that omits the user layer, or a project that never declares it, leaves Studio without user memory. An agent layer has no such bypass. Its policy runs for every caller, a verified Studio user included. Agent Server also calls the factory to inspect the graph, and those calls carry no run context. A selection that reads context takes its fallback branch there. Native Node additionally requires Agent Server to pass run context to the graph factory. Exercise a selection or a policy from a real caller against a deployment: a Slack message, or your own application sending its own context.

Require approval before a memory write

A policy decides whether a layer mounts. It does not decide what the agent writes to a layer that did mount. When a person should see a change before it is saved, pause the tool call instead. This matters wherever agent memory mounts on a deployment with many callers. The runtime tells the agent not to save caller-specific information there, and nothing enforces it. An approval card names the target path. A reviewer sees which mount the write is headed for, and can correct or reject it before anything is stored. Add a FilesystemPermission rule in mode="interrupt" over the memory mounts:
agent.py
The agent calls write_file under /memories/, the run pauses before the tool runs, and Slack or Studio renders an approval card naming the path it was headed for. The reviewer can approve, edit, reject, or respond. In Slack the card offers only approve and reject. Nothing is written until they approve. paths decides which writes pause. /memories/** covers both mounts. To pause only on writes to user memory, set paths=["/memories/user/**"].
Unlike create_deep_agent, define_deep_agent needs no checkpointer argument. The managed runtime supplies one.
Interrupt-mode rules merge with any interrupt_on you pass and resume the same way. For the resume flow, see Human-in-the-loop. For rule structure and path matching, see Permissions. Add "read" to operations to pause on read_file, ls, glob, and grep as well. Expect this to interrupt often: the agent lists a mount before it reads from one, so the first approval a reviewer sees is usually ls rather than a file. Automatic hot-memory loading is not covered. AGENTS.md is injected into every model call without a tool call, so no rule matches that load. Tool calls that read or write the hot file still match the same path rules as cold files.

Identify the person behind user memory

User memory is keyed on the authenticated principal for the run, not on anything the caller passes in. Where that principal comes from depends on how the run started: Each person’s memory lives in a separate Context Hub repository derived from the deployment and the principal. Two deployments therefore never share a person’s memory, even for the same person in the same Slack workspace. Agent memory is the layer to use for knowledge that should reach everyone on one deployment.

How the agent uses memory

Each mount holds hot memory and cold memory: Keep hot memory compact because it consumes context on every run. The runtime does not tier memory. Authored instructions and skills decide what to remember and which file to write. Without that guidance, a model may keep appending to AGENTS.md, and every later call pays for it. To keep detailed material out of every model call, name the cold files to write, such as procedures, decision logs, and research notes, and tell the agent to link to them from AGENTS.md. The agent reads and updates memory with the built-in read_file, edit_file, and write_file tools. A hot file that does not exist yet stays empty until the first write. Writes to other locations, including elsewhere under /memories/, are not durable.
Agent memory is shared by every caller of the deployment, and every caller can influence it. Store only knowledge that every caller may read and modify. Never store personal or customer-private data, credentials, API keys, tokens, or other secrets there.Treat memory as untrusted input: content saved by one caller is loaded for later callers and must not grant authority, change tool permissions, or bypass approvals. Keep those controls in the agent definition. Do not enable agent memory when callers should not influence one another.

Test memory

Studio is the way to exercise memory without a Slack workspace. A verified Studio user receives every declared layer, so a layer that appears to do nothing there is usually not declared at all. Check memory.py or memory.ts first. Where Studio writes depends on what you are running:
  • A deployment: memory goes to Context Hub, keyed on your logged-in LangSmith user.
  • mda dev: memory stays on disk under .mda/__contexthub__, keyed on the langsmith-dev Agent Auth principal that the CLI resolves from your personal LangSmith API key.
Local memory and deployed memory are separate stores, so a fact you teach the agent under mda dev does not appear after you deploy. Access decisions are the exception. See Test memory access. For more information, see Local development.

Deployment

When you run mda deploy, Managed Deep Agents enables the layers declared in the project and backs them with Context Hub. Deploys do not overwrite durable content already stored in Context Hub. For how memory relates to deploy-owned instructions and skills in Context Hub, see Context Hub.

When to use memory

See also