What you will be able to do
- Create a managed memory store and write entries with the correct actor_id, path and description
- Retrieve memory by listing or by natural-language search, and give an agent memory through tools
- Choose an actor_id strategy and enforce isolation at the right boundary
- Configure a Lakebase-backed LangGraph memory store for a Databricks App, and recognize the legacy Unity Catalog memory store
1.The memory data model: stores and entries
Managed agent memory gives an agent long-term memory that lasts across conversations. Databricks stores it in Lakebase and handles the storage, indexing and search, so you don't operate a database. The feature is in Beta and works with agents built on any framework. It has two levels.
A memory store is the workspace-scoped container for an agent's memories. Creating one provisions its Lakebase storage, and you refer to it by its display_name. That name must be 3 to 56 characters, start with a lowercase letter, end with a letter or number, and contain only lowercase letters, numbers and hyphens.
A memory entry is a single piece of content. It has free-form text content, a short description that is used for retrieval, and three fields that organize it:
- actor_id (required): whose memory this is, such as an end user or another agent.
- session_id (optional): the session the memory was captured from, kept for provenance. Leave it unset for memory that isn't tied to a session.
- path (required): a filesystem-like path inside the actor, such as /preferences/response-style.md.
Checkpoint 1 of 8· Match them up
Match each memory entry field to its purpose
Tap a term, then the definition that fits it.
actor_id partitions entries by owner and path organizes them within that owner. session_id records provenance, and description helps search find the entry.
“actor_id (required): who the memory belongs to, such as an end user or another agent.”Source: docs.databricks.com
Sources1
2.Saving and recalling memory
The AgentKit SDK (pip install databricks-agentbricks, authenticated with a WorkspaceClient) wraps the REST API under /api/2.0/agents/memory-stores. The example below follows a support agent. It creates a store, saves a preference once it learns something durable about a user, and recalls that preference in a later conversation.
memory_store = client.memory_stores.create("support-agent-memory")memory_store.add( actor_id="user-123", path="/preferences/communication.md", content="Prefers email over phone. Timezone: PST. Enterprise subscription.", description="User 123 communication preferences",)There are two ways to retrieve memory, and both are scoped to one actor. List returns an actor's entries, optionally filtered by session_id or a path prefix, which is useful for browsing or rendering an index of what the agent knows. Search takes a natural-language query and returns the most relevant entries, ranked by a full-text (BM25) relevance score.
Checkpoint 2 of 8· Fill the gap
Which store operation does the memory tool call to recall relevant facts from a natural-language query?
results = memory_store. ? (actor_id=actor_id, query=query, limit=10)search takes a natural-language query and returns ranked entries. list browses an actor's entries by session_id or path prefix, and add writes an entry.
Source: docs.databricks.comCheckpoint 3 of 8· Exam question
A platform team wants multiple agents across different projects to share durable, long-term knowledge about company policies, and they need Unity Catalog to enforce access control and lineage on that knowledge. Which persistence approach satisfies these requirements?
Correct answer: A — A managed agent memory store, since it is a Unity Catalog securable object that inherits standard governance, access control, and lineage like any other Unity Catalog asset.
- A. A managed agent memory store is a Unity Catalog securable, so it inherits the same governance, access control, and lineage as other Unity Catalog assets, letting multiple agents and projects share governed, durable knowledge.
- B. A self-managed Lakebase database gives the team a Postgres instance to manage themselves; tables created there do not automatically pick up Unity Catalog lineage tracking, since self-managed memory requires the team to handle governance.
- C. A LangGraph checkpointer persists state per conversation thread for a single agent's session continuity; it is not designed to share organizational knowledge across unrelated agents and projects.
- D. The `user_client` scope isolates entries to an individual end user rather than sharing them, so scoping the store this way would prevent other agents and projects from accessing the shared company knowledge.
Sources1
3.Letting the agent decide when to remember
Your application decides when the API gets called. To let the agent choose when to save and recall, wrap the store's operations as tools and explain in the system prompt when to use them. In the OpenAI Agents SDK, the documented pattern binds actor_id when the tools are *built*, so the model only ever supplies the query, path and content:
def make_memory_tools(memory_store, actor_id: str):
@function_tool
def search_memory(query: str) -> str:
"""Search long-term memory for relevant facts about the user."""
results = memory_store.search(actor_id=actor_id, query=query, limit=10)
return "\n\n".join(f"{r.memory.path}: {r.memory.content}" for r in results) or "No memory found."
@function_tool
def save_memory(path: str, content: str, description: str = "") -> str:
"""Save a durable, long-term memory about the user."""
memory_store.add(actor_id=actor_id, path=path, content=content, description=description)
return f"Saved memory at {path}"
return [search_memory, save_memory]The same pattern works with the Claude Agent SDK and other frameworks: expose search and add as that framework's tool type.
Checkpoint 4 of 8· Check yourself
A reviewer suggests adding an actor_id parameter to save_memory so the model can 'save notes for the right person'. What does the documentation say?
Choosing whose memory to read or write is the application's job, based on verified identity. A model-supplied actor_id could read or overwrite someone else's memory.
“Set the actor_id in trusted application code from the verified end-user identity. Never let the model choose whose memory to read or write.”Source: docs.databricks.com
Sources1
4.Partitioning with actor_id, isolating with stores
Every list and search is scoped to a single actor_id, which makes the value you choose a design decision:
| Strategy | actor_id value | Example |
|---|---|---|
| Private memory for each user | The verified end-user identity | A support agent remembers one user's communication preferences and past tickets |
| Shared memory for a group | A fixed key such as a team, project or organization ID | A team agent remembers a shared glossary of company terms |
| Split by something else | A value you build, such as {tenant}:{user} | A multi-tenant app keeps each customer's users isolated |
If your strategy depends on an end-user identity, reject any request that arrives without one. Do not fall back to a shared actor_id.
actor_id separates memories, but it does not control access. Memory stores are workspace-scoped, so any principal that can reach a store can read and write every entry for every actor. The security boundary is the store. For strict isolation between tenants or users, create one store per boundary. To let your agent's service principal use a store, grant access with memory_store.grant_permission(principal_id).
Checkpoint 5 of 8· Check yourself
A SaaS vendor must guarantee that tenant A's principals can never read tenant B's agent memories. What should they configure?
actor_id and path only organize entries. Anyone who can reach a store can read every entry in it, so strict isolation requires one store per tenant.
“For strict isolation between tenants or users, create a separate memory store per boundary.”Source: docs.databricks.com
Checkpoint 6 of 8· Exam question
An agent built with LangGraph needs to maintain conversation context for follow-up questions within a single chat session, using a thread ID, and the state must survive across serving replicas rather than living only in process memory. Which configuration meets this need?
Correct answer: D — Configure LangGraph's built-in checkpointing to persist thread state to a Lakebase Postgres instance, so session context durably survives across serving instances.
- A. Keeping checkpoint state only in local process memory means each replica has its own copy, so a follow-up request routed to a different replica would lose the earlier conversation context, failing the durability requirement.
- B. Managed memory entries are intended for long-term, cross-conversation knowledge rather than efficient per-turn short-term session state, so writing the full transcript as a single entry each turn is not the documented pattern for thread-based continuity.
- C. Direct Vector Access lets an application manually read and write vectors for similarity search; it has no connection to persisting thread-scoped conversational state for a LangGraph agent.
- D. LangGraph's checkpointer backed by Lakebase durably stores thread state in a managed Postgres database, so conversation context for a given thread ID is available regardless of which serving replica handles the next request.
5.Configuring a Lakebase store for a LangGraph agent on Apps
Not every agent uses the managed memory API. An agent deployed on Databricks Apps can connect to a Lakebase instance directly through AsyncDatabricksStore from databricks_langchain. That setup needs two pieces of configuration. First, the app needs a database resource in databricks.yml with the CAN_CONNECT_AND_CREATE permission:
resources:
apps:
my_agent:
resources:
- name: 'memory_database'
database:
instance_name: '<lakebase-instance-name>'
database_name: 'postgres'
permission: 'CAN_CONNECT_AND_CREATE'Second, the store's tables have to exist before the first request. Initialize them locally before you deploy:
import asyncio
from databricks_langchain import AsyncDatabricksStore
async def setup_memory():
async with AsyncDatabricksStore(
instance_name='your-lakebase-instance',
embedding_endpoint='databricks-gte-large-en',
embedding_dims=1024,
) as store:
await store.setup()
asyncio.run(setup_memory())The first means the memory tables were never initialized. Run await store.setup() locally before deploying. The second means the app lacks Lakebase permissions. Add the database resource in databricks.yml with permission: 'CAN_CONNECT_AND_CREATE'.
Checkpoint 7 of 8· Check yourself
Where should the memory tables for an AsyncDatabricksStore be created, and when?
The missing-table error is fixed by initializing the tables locally with store.setup() before you deploy. The database permission is a separate requirement.
“Run await store.setup() locally before deploying to create required tables”Source: docs.databricks.com
Sources2
6.Recognizing the legacy Unity Catalog memory store
You may still see an earlier managed memory store in documentation and in existing code. It was a Unity Catalog securable, and it is being turned down, so don't build new agents on it. The things that tell it apart are its three-level name, its scope field, and its access model based on UC privileges:
| Aspect | Managed agent memory (current) | Managed agent memory (legacy) |
|---|---|---|
| Store identity | Workspace-scoped, addressed by display_name | Unity Catalog securable with a three-level name, e.g. main.default.support_agent_memory |
| REST path | /api/2.0/agents/memory-stores | /api/2.1/unity-catalog/memory-stores |
| Partition field | actor_id | scope |
| Granting access | grant_permission(principal_id) | CREATE MEMORY STORE, READ MEMORY STORE, WRITE MEMORY STORE, MANAGE privileges |
Checkpoint 8 of 8· Check yourself
A design doc for a new agent says: 'Grant CREATE MEMORY STORE on main.default, then create the store with catalog_name and schema_name.' What is wrong with it?
Schema-level privileges and catalog/schema names belong to the legacy UC-governed store. The current store is workspace-scoped and addressed by display_name.
“This is an earlier version of the managed agent memory store and will be turned down soon.”Source: docs.databricks.com
Sources3
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.Setting actor_id to each user's ID stops users and principals from reading each other's memories.Why is that wrong?
actor_id only partitions entries. The store is the security boundary, and anyone who can reach it can read every actor's entries, so strict isolation needs separate stores.
Covered in Partitioning with actor_id, isolating with stores
2.The model should pass actor_id to the memory tools so it can save notes for whoever it is talking to.Why is that wrong?
actor_id comes from trusted application code and the verified end-user identity. The model never chooses whose memory to read or write.
Covered in Letting the agent decide when to remember
3.Creating an agent memory store requires the CREATE MEMORY STORE privilege on a Unity Catalog schema.Why is that wrong?
That privilege belongs to the legacy UC-governed store, which is being turned down. The current managed memory store is workspace-scoped and addressed by display_name.
Covered in Recognizing the legacy Unity Catalog memory store
Practise it for real
Give a support agent per-user long-term memory backed by a managed memory store
1.Run pip install databricks-agentbricks on Python 3.10 or above, then build an AgentKitClient from a WorkspaceClient.
Why: The AgentKit SDK is the Databricks Python client for the agent memory APIs and authenticates with your workspace credentials.
You should see: The client is created without an authentication error.
2.Call client.memory_stores.create("support-agent-memory").
Why: Creating the store provisions its Lakebase storage, and the display_name must follow the naming rules.
You should see: A memory store named support-agent-memory exists in the workspace.
3.Call memory_store.add with actor_id="user-123", path="/preferences/communication.md", plus content and a description.
Why: actor_id partitions the entry by user, path organizes it, and description improves retrieval.
You should see: The entry is stored for user-123.
4.Call memory_store.search(actor_id="user-123", query="communication preferences", limit=10).
Why: Search is how a later conversation recalls the preference, scoped to that actor.
You should see: The results include the /preferences/communication.md entry.
5.Call memory_store.grant_permission(principal_id) with your agent's service principal ID.
Why: The store is the security boundary, and the agent's principal needs explicit access to it.
You should see: The deployed agent can read and write the store.
Stuck? Get a nudge
If search for a different actor_id returns nothing, that is expected: every list and search is scoped to one actor.
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.
“A memory store is the workspace-scoped container for an agent's memories.”
↩︎ The memory data model: stores and entries“A memory store's display_name must be 3 to 56 characters, start with a lowercase letter, end with a letter or number”
↩︎ The memory data model: stores and entries“Search returns the most relevant entries ranked by a full-text (BM25) relevance score.”
↩︎ Saving and recalling memory“List entries for an actor, optionally filtered by session_id or a path prefix.”
↩︎ Saving and recalling memory“wrap the client operations as tools and instruct the agent on when to use them in its system prompt”
↩︎ Letting the agent decide when to remember“any principal that can reach a store can read and write every entry across all actors”
↩︎ Partitioning with actor_id, isolating with stores“If your strategy depends on an end-user identity, reject requests that don't carry one rather than falling back to a shared actor_id.”
↩︎ Partitioning with actor_id, isolating with stores“The store, not the actor, is the security boundary.”
↩︎ Exam trap 1“Never let the model choose whose memory to read or write.”
↩︎ Exam trap 2“An entry is uniquely identified by the combination of actor_id, session_id, and path.”
↩︎ Prediction“actor_id (required): who the memory belongs to, such as an end user or another agent.”
↩︎ Checkpoint“Set the actor_id in trusted application code from the verified end-user identity. Never let the model choose whose memory to read or write.”
↩︎ Checkpoint“For strict isolation between tenants or users, create a separate memory store per boundary.”
↩︎ Checkpoint - 2.
“Ensure you pass a consistent user_id in custom_inputs for each user”
↩︎ Partitioning with actor_id, isolating with stores“Run await store.setup() locally before deploying to create required tables”
↩︎ Configuring a Lakebase store for a LangGraph agent on Apps“Add a database resource in databricks.yml with permission: 'CAN_CONNECT_AND_CREATE'”
↩︎ Configuring a Lakebase store for a LangGraph agent on Apps - 3.
“A memory store is a Unity Catalog securable that acts as a container for memory entries.”
↩︎ Recognizing the legacy Unity Catalog memory store“This is an earlier version of the managed agent memory store and will be turned down soon.”
↩︎ Checkpoint
Also cited
“Managed agent memory (legacy): the earlier managed memory store, governed by Unity Catalog.”
↩︎ Exam trap 3