Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
Important
This feature is in Beta. Workspace admins can control access to this feature from the Previews page. See Manage Azure Databricks previews.
Managed agent memory gives your agents long-term memory across conversations. Azure Databricks runs the infrastructure and isolates each scope's memories, so you don't have to manage storage or partitioning yourself.
With managed memory, your agents can:
- Remember user preferences, past decisions, and accumulated context across conversations.
- Secure that knowledge with Unity Catalog governance.
- Share memory across agents and projects.
- Improve their accuracy and efficiency over time.
Requirements
- A Databricks workspace with Unity Catalog enabled.
- The
CREATE MEMORY STOREprivilege on the parent schema to create memory stores.
How managed memory works
Managed memory has two levels:
- A memory store is a Unity Catalog securable that acts as a container for memory entries. A memory store inherits the same governance, access control, and lineage as any other Unity Catalog asset.
- A memory entry is an individual piece of content stored inside a memory store. Each entry is identified by a scope and a path. The scope determines whose memories an entry belongs to, and the path organizes entries within a scope, similar to a file path (for example,
/memories/preferences.md).
Scope
Scope is how you make a memory private to one user or shared across a group. Your application sets a scope on every read and write, and a search only returns entries with a matching scope. Pick the strategy that matches what your agent needs to remember:
- Private memory for each user: Set the scope to the verified end-user identity. Each user gets their own partition and only sees their own entries. The value
user_clientresolves the end-user's ID for you.- Example: A support agent remembers one user's communication preferences and past tickets.
- Shared memory for a group: Set the scope to a fixed key you choose, such as an organization, team, or project ID. Every user reads and writes the same memories.
- Example: A team agent remembers a shared glossary of company terms and internal policies.
- Memory split by something else: Build the scope from your own values, such as a tenant ID or a
user_id:projectcomposite.- Example: A multi-tenant app keeps each customer's memory separate, or a single user's memory is isolated per project.
A single agent can combine strategies in one conversation. For example, it can read a user's private memory and a shared team memory in the same request.
Set the scope in your application code, from trusted caller context that the request can't tamper with: the verified end-user identity from the OBO token for per-user memory, or a trusted tenant, team, or project key for shared memory. Never let the model choose it. If your scope strategy depends on an end-user identity, reject requests that don't have one rather than falling back to a shared scope. The managed-memory skill guides you through this setup.
Scope separates memories, but it doesn't grant access to the store. A caller still needs the READ MEMORY STORE or WRITE MEMORY STORE privilege to open it. See Memory access control.
Warning
Scope is the isolation boundary between users, but it is not an access control. The app service principal can read every scope, so protect its credential accordingly.
What the agent saves and recalls
Managed memory provides the memory store and the APIs for reading and writing entries. Your application controls what the agent saves, when it retrieves memory, and how it uses the results.
Define this behavior in the agent's system prompt: instruct the agent on what durable information to save and when to retrieve it. The managed-memory skill and templates keep this system prompt in a constant named MEMORY_INSTRUCTIONS. Scope is configured separately in trusted application code and is never chosen by the model.
Match the wording to your scope strategy. The following is an example for the per-user strategy:
You have durable, cross-session memory about whoever (or whatever) this conversation is scoped to. Use it deliberately, not by reflex.
Recall whenever the answer is about the user or calls for personalized information — anything that might draw on preferences, decisions, or workflows they've shared before — and you don't already have it from this conversation; also list once before saving, to find the right existing topic. Don't tell the user you don't know their preferences without checking — list_memories first. Skip memory only when the answer truly doesn't depend on who's asking (general knowledge, math, coding) or you already have what you need. A `[has_contents]` entry has a body to get_memory; one without is fully captured by its description. Open a memory with get_memory before you state its specifics, and never assert a fact that isn't stored — if nothing relevant is stored, just answer without it. Don't re-list what you've already seen this turn.
Save only what will still matter in a future, unrelated conversation — a stable preference, fact, decision, or ongoing project the user actually stated or decided. Don't save your own suggestions or guesses, passing chatter, secrets, or anything scoped to this chat ("for now", a one-off label).
- Write each memory so it stands on its own out of context, under one broad, stable /memories/... topic per subject with the specifics inside it.
- Check the list first and update_memory an existing topic instead of minting a near-duplicate.
- For a very broad question that touches many memories, summarize from the list's descriptions; reserve get_memory for the specific entry you actually need.
- If the user's info changes or contradicts what's stored, update or replace it rather than keeping both — but don't rewrite a memory that already says the same thing.
- delete_memory what's stale.
- Briefly tell the user whenever you save, update, or delete.
Get started with managed memory skills
The easiest way to add managed memory to an agent is the managed-memory Claude Code skill. The skill handles all the setup for you and works with both the OpenAI Agents SDK and LangGraph.
Get the skill into your project one of two ways:
Start from a template
The skill ships inside the Databricks app templates. Scaffold a new agent from one of the agent templates, find the skill under .claude/skills/managed-memory/.
Clone the templates repository:
git clone https://github.com/databricks/app-templates.gitBrowse the
app-templates, select an agent template to start from. For example, to use the OpenAI Agents SDK template:cd app-templates/agent-openai-agents-sdkNote
For "advanced" app templates, after you deploy, you must grant the app service principal Lakebase Postgres privileges otherwise session setup will return a
502error.Once the skill is in your project, describe what you want and your coding assistant takes care of the rest:
Tip
Add Databricks managed long-term memory to my agent.
Add the skill to an existing project
If you already have an agent project, add the skill to it.
Create the skills directory if it doesn't exist:
mkdir -p .claude/skills/managed-memoryDownload the
SKILL.mdfile from themanaged-memoryskill directory and save it to.claude/skills/managed-memory/.Once the skill is in your project, describe what you want and your coding assistant takes care of the rest:
Tip
Add Databricks managed long-term memory to my agent.
Create and use a memory store manually
This section shows how to create and use a memory store without the managed-memory Claude Code skill.
The following example sets up managed memory for a customer support agent that stores a user's preferences and retrieves them in a later conversation.
Generate an OAuth token using the Databricks CLI to call the APIs:
databricks auth login --host ${DATABRICKS_HOST} databricks auth tokenCreate a memory store to hold your agent's memories:
curl -X POST "https://${DATABRICKS_HOST}/api/2.1/unity-catalog/memory-stores" \ -H "Authorization: Bearer ${DATABRICKS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "name": "support_agent_memory", "catalog_name": "main", "schema_name": "default", "description": "Long-term memory for the customer support agent" }'Write a memory entry after the agent learns something about a user. The
scopepartitions the entry to a single user. Use thecontentsfield for the full memory text and thedescriptionas a short summary that improves retrieval:curl -X POST \ "https://${DATABRICKS_HOST}/api/2.1/unity-catalog/memory-stores/main.default.support_agent_memory/entries?scope=user-123" \ -H "Authorization: Bearer ${DATABRICKS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "path": "/memories/preferences.md", "contents": "Prefers email communication. Timezone: PST. Has an Enterprise subscription.", "description": "User 123 communication preferences and account details" }'Search memory entries for that user in a later conversation to retrieve what the agent learned:
curl -X POST \ "https://${DATABRICKS_HOST}/api/2.1/unity-catalog/memory-stores/main.default.support_agent_memory/entries:search" \ -H "Authorization: Bearer ${DATABRICKS_TOKEN}" \ -H "Content-Type: application/json" \ -d '{ "scope": "user-123", "query": "communication preferences" }'
For the full REST API, including endpoints, request fields, and response fields, see Memory API reference.
Add memory to an agent with conversations
The REST workflow above calls the memory store and entry APIs directly. When you build an agent on a Azure Databricks model serving endpoint, connect a memory store to a conversation with the OpenAI-compatible client in the databricks-openai SDK instead.
A conversation is OpenAI-compatible conversation state — the running history of messages and tool calls — backed by a memory store and pinned to a single scope. Reuse the same conversation across requests to give the agent memory of earlier turns.
Bind an existing memory store and a scope to a new conversation.
memory_store.nameis the three-level name of the store, andscopepartitions the conversation's state, typically by end user:from databricks.sdk import WorkspaceClient from databricks_openai import DatabricksOpenAI workspace_client = WorkspaceClient() user_id = str(workspace_client.current_user.me().id) client = DatabricksOpenAI(workspace_client=workspace_client, use_ai_gateway=True) conversation = client.conversations.create( extra_body={ "memory_store": {"name": "main.default.support_agent_memory"}, "scope": {"kind": "user", "value": user_id}, }, )Pass the conversation ID to
responses.create. The agent reads and writes the conversation's state in the bound memory store under that scope:response = client.responses.create( model="databricks-gpt-5-2", conversation=conversation.id, input=[{"type": "message", "role": "user", "content": "What is the average NYC taxi price?"}], stream=True, ) for event in response: if event.type == "response.output_text.delta": print(event.delta, end="", flush=True)Reuse the same conversation ID on later requests so the agent remembers earlier turns. Do not create a new conversation per turn:
followup = client.responses.create( model="databricks-gpt-5-2", conversation=conversation.id, input=[{"type": "message", "role": "user", "content": "Restate the average taxi price you found, and how it was calculated."}], stream=True, ) for event in followup: if event.type == "response.output_text.delta": print(event.delta, end="", flush=True)
For the conversation endpoints and request fields, see Conversation APIs.
Memory access control
Memory stores are Unity Catalog securables. The following privileges control access:
| Privilege | Applies to | Description |
|---|---|---|
CREATE MEMORY STORE |
Parent schema | Create new memory stores under a schema. |
READ MEMORY STORE |
Memory store | Read a memory store's metadata and its entries. |
WRITE MEMORY STORE |
Memory store | Create, update, and delete memory entries in a store. |
MANAGE |
Memory store | Update or delete the memory store itself. Grant permissions to other users. |
USE SCHEMA |
Parent schema | List memory stores in a schema. |
Implement short-term memory
The memory entry APIs provide long-term memory as tools for your agent to use. To give your agent managed short-term memory in a session, Databricks recommends binding your memory store to a conversation. You can also:
- Keep your agent framework's session memory, such as the OpenAI
session=parameter or a LangGraph checkpointer. - Use self-managed agent memory for the conversation history store.
Security recommendations
Azure Databricks provides the governed store, encryption, isolation primitives, and audit trail. As the app developer, Databricks recommends the following:
- Use the per-user scope default (
user_client) unless you have a deliberate reason to partition differently (for example, per-project or per-account memory). - Grant least privilege: only your agent's service principal needs
WRITE MEMORY STORE. GrantREAD MEMORY STOREnarrowly, and avoid broad grants to human users or large groups. - Protect the app service principal credential: it is the key to the store's data plane. Treat it like any high-value service credential — use short-lived tokens, avoid logging it, and add SSRF defenses to your app.
Limitations
- Memory entries provide long-term memory only. For the difference between short-term and long-term memory, see Short-term and long-term memory.
- Memory stores and entries are created and managed through the Unity Catalog REST API only; there is no Python SDK for these APIs. To use a memory store from an agent, connect it to a conversation with the OpenAI-compatible client. See Add memory to an agent with conversations.