CertSafari
    Databricks Certified Context Engineer Associate· Lessons

    Domain 4 · Lesson 27/45

    Configure managed agent memory: AgentKit, actor_id and Lakebase fixes

    Configure persistent agent memory across sessions using Lakebase-backed durable store.

    13 min read
    2.25% of exam
    4 sources
    Published 3 Oct 2026
    Docs as of 30 Sep 2026

    What you will be able to do

    • Create a memory store, save an entry and recall it with the AgentKit SDK or the REST API
    • Wire memory into an agent as tools while keeping actor_id under application control
    • Choose an actor_id strategy and know that the store, not the actor, is the security boundary
    • Recognize the legacy Unity Catalog memory API and diagnose common Lakebase memory failures

    1.Create a store, save a memory, recall it

    Setting up managed agent memory takes three operations: create a store, save an entry once the agent learns something durable, and search for it in a later conversation. You can use either of two clients. The AgentKit SDK is the Databricks Python client for agent APIs. It needs Python 3.10 or above, ships in the databricks-agentbricks package, and authenticates through the Databricks SDK's WorkspaceClient. The REST API lives under /api/2.0/agents/memory-stores and works from any language, authenticated with an OAuth token from the Databricks CLI.

    Install the AgentKit SDKbash
    pip install databricks-agentbricks

    Note the two names. The package you install is databricks-agentbricks, but the Python module you import from is databricks_agentkit. The client setup uses two imports: from databricks.sdk import WorkspaceClient and from databricks_agentkit import AgentKitClient. Then client = AgentKitClient(WorkspaceClient()) builds the client.

    With the SDK, client.memory_stores.create("support-agent-memory") creates the store, and Databricks provisions its Lakebase storage. memory_store.add(...) saves an entry with an actor_id (whose memory it is), a path (where it sits under that actor), content, and a description that improves retrieval. A later conversation recalls the entry with a natural-language search scoped to the same actor. Over REST, the same steps are a POST to /memory-stores, a POST to /memory-stores/{name}/entries, and a POST to /entries:search.

    Checkpoint 1 of 8· Put it in order

    Put the steps for giving a support agent persistent memory with the AgentKit SDK in order

    1. 1.Install the databricks-agentbricks package
    2. 2.Save the user's preference with memory_store.add
    3. 3.Create a memory store with client.memory_stores.create
    4. 4.Recall it in a later conversation with memory_store.search

    Checkpoint 2 of 8· Fill the gap

    Which method recalls the user's memories with a natural-language query in a later conversation?

    results = memory_store. ? (actor_id="user-123", query="communication preferences", limit=10)

    Sources1

    2.Let the agent decide when to remember

    For the agent itself to decide when to save and when to recall, wrap the store's operations as tools and use the system prompt to tell the agent when to call them. The documentation's example does this for the OpenAI Agents SDK. The same pattern works with the Claude Agent SDK and other frameworks: you wrap search and add as whatever tool type the framework uses.

    What to save is the hand-off between session and memory. As a session accumulates, the agent (or your application) distills the durable facts out of it and writes them to memory. Memory is for facts that should still matter in a future, unrelated conversation, such as a user's stable preferences, a past decision, or an ongoing project. The session is later cleared or ages out, while the memory persists.

    Memory search and save exposed as OpenAI Agents SDK tools, with actor_id bound outside the modelpython
    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]

    Checkpoint 3 of 8· Check yourself

    You want the agent to decide for itself when to save and recall memory. What does the documentation say to do?

    Sources12

    3.Partitioning with actor_id, isolating with stores

    Inside a store, actor_id separates one subject's memories from another's. Every list and search is scoped to a single actor_id, so the value you choose decides what the agent remembers and who shares it:

    - Private per-user memory: set actor_id to the verified end-user identity, for example a support agent that remembers one user's past tickets. - Shared group memory: set it to a fixed team, project or organization key, for example a team agent's glossary of company terms. - Custom split: build it from your own values, such as {tenant}:{user}, so each customer's users stay isolated from one another.

    Always set actor_id in application code from trusted caller context. If your strategy depends on an end-user identity and a request arrives without one, reject the request. Do not fall back to a shared actor_id.

    Managed memory stores are workspace-scoped. Any principal that can reach a store can read and write every entry in it, for every actor. The security boundary is the store, not the actor. For strict isolation between tenants or users, create a separate memory store for each boundary. To let another principal use a store, such as your agent's service principal, grant it access with memory_store.grant_permission(principal_id). The grant is made on a particular store, so with one store per boundary you grant each principal access only to the store it should use.

    Checkpoint 4 of 8· Check yourself

    A multi-tenant SaaS needs a guarantee that no tenant's agent memory can ever be read under another tenant's credentials. Which configuration meets that requirement?

    Checkpoint 5 of 8· Exam question

    An agent stores each user's long-term memory in a shared Lakebase table, and the team must ensure that one user's application connection can never read or modify another user's memory rows through the Data API. Which Lakebase feature should be configured to enforce this?

    Sources1

    4.Recognizing the legacy memory store

    Older material describes a different store, managed agent memory (legacy), which was governed by Unity Catalog. Its stores are Unity Catalog securables with three-level names (catalog.schema.memory_store_name), served from /api/2.1/unity-catalog/memory-stores. They are controlled by privileges such as CREATE MEMORY STORE, READ MEMORY STORE and WRITE MEMORY STORE. Entries are partitioned by a scope parameter instead of actor_id, and each entry's path must start with /memories/. Databricks says this API will be turned down soon and should not be used for new agents. Build new long-term memory on the current managed agent memory, served from /api/2.0/agents/memory-stores.

    Checkpoint 6 of 8· Check yourself

    A team is starting a new agent and finds a tutorial that creates a memory store with catalog_name and schema_name and passes ?scope=user-123. What should they do?

    Sources3

    5.When Lakebase-backed memory doesn't persist

    Some agents connect to a Lakebase instance directly instead of using the managed store. A LangGraph agent on Databricks Apps using AsyncDatabricksStore is one example. These agents have to set up their own wiring, and the failures that show up come from three places: tables that were never created, resource configuration, and how user identity is passed in.

    Common Lakebase memory errors for agents on Databricks Apps
    SymptomCauseFix
    relation 'store' does not existMemory tables not initializedRun await store.setup() locally before deploying
    Unable to resolve … instance (the Lakebase instance)Wrong instance name or configurationLAKEBASE_INSTANCE_NAME must use value (not valueFrom) in app.yaml and match instance_name in databricks.yml
    permission denied for table storeMissing Lakebase permissionsAdd a database resource in databricks.yml with permission CAN_CONNECT_AND_CREATE
    Memory not persisting across conversationsDifferent user_id per requestPass a consistent user_id in custom_inputs for each user
    Create the memory tables in Lakebase before the first deploypython
    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())

    Checkpoint 7 of 8· Fill the gap

    Which permission lets the app connect to the Lakebase database and create the memory tables it needs?

    resources:
      apps:
        my_agent:
          resources:
            - name: 'memory_database'
              database:
                instance_name: '<lakebase-instance-name>'
                database_name: 'postgres'
                permission: ' ? '

    The last row in the table is the easiest to misread. If memory saves without errors but is never there in the next conversation, storage is usually fine. The likely problem is that each request carries a different user_id, so every conversation reads and writes a different partition. A related symptom is an agent that replies "Memory not available". That points to a request with no custom_inputs.user_id at all. This is the same rule as with managed stores: the identity that keys memory must be stable and must come from the application.

    Checkpoint 8 of 8· Exam question

    A team wants agent memory writes to be governed under the same permissions and audit model already used for the rest of their Databricks data estate, without standing up a separate access-control system just for the memory store. Which Lakebase characteristic supports this goal?

    Sources4

    Exam traps

    Each one states something that sounds right. Open it to see what is actually true.

    1. 1.Since the agent decides when to save and recall, it can also pass in the actor_id to read or write.Why is that wrong?

      actor_id must come from trusted application code, built from the verified end-user identity. The model must never choose it.

      Covered in Let the agent decide when to remember

    2. 2.Giving each tenant its own actor_id in a shared memory store keeps tenants securely isolated.Why is that wrong?

      actor_id only partitions recall. Any principal that can reach the store can read every actor's entries, so strict isolation requires a separate store per boundary.

      Covered in Partitioning with actor_id, isolating with stores

    3. 3.If memory doesn't carry across conversations, the Lakebase store must be losing writes.Why is that wrong?

      The documented cause is a different user_id on each request. Pass a consistent user_id in custom_inputs for each user.

      Covered in When Lakebase-backed memory doesn't persist

    Practise it for real

    Give a support agent cross-session memory using a managed memory store and the AgentKit SDK

    1. 1.Run pip install databricks-agentbricks in a Python 3.10+ environment that has Databricks credentials configured

      Why: The AgentKit SDK is the Python client for the memory-store API and authenticates through WorkspaceClient. The package name is databricks-agentbricks, but the module you import is databricks_agentkit

      You should see: from databricks_agentkit import AgentKitClient runs without errors

    2. 2.Run from databricks.sdk import WorkspaceClient and from databricks_agentkit import AgentKitClient, then create client = AgentKitClient(WorkspaceClient()) and call memory_store = client.memory_stores.create("support-agent-memory")

      Why: Creating the store provisions its Lakebase storage automatically, so you don't run a database yourself

      You should see: A memory store object you can call add and search on

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

      Why: actor_id says whose memory this is, path organizes it under that actor, and description improves retrieval

      You should see: The entry is stored under actor user-123

    4. 4.In a new Python session, call memory_store.search(actor_id="user-123", query="communication preferences", limit=10)

      Why: A separate session simulates a later, unrelated conversation recalling durable memory

      You should see: The communication-preferences entry comes back among the results

    5. 5.Repeat the search with actor_id="user-456"

      Why: Every list and search is scoped to a single actor_id

      You should see: The user-123 entry does not appear

    Stuck? Get a nudge

    If the search for user-456 returns nothing, partitioning is working. Remember that this is not access control: anyone with access to the store can still read every actor's entries.

    Sources

    Every claim above is drawn from one of these pages, quoted as it was written on the date shown.

    1. 1.
      “The clients call the REST API under /api/2.0/agents/memory-stores.”
      ↩︎ Create a store, save a memory, recall it
      “distributed in the databricks-agentbricks package”
      ↩︎ Create a store, save a memory, recall it
      “wrap the client operations as tools and instruct the agent on when to use them in its system prompt.”
      ↩︎ Let the agent decide when to remember
      “Every list and search is scoped to a single actor_id”
      ↩︎ Partitioning with actor_id, isolating with stores
      “reject requests that don't carry one rather than falling back to a shared actor_id.”
      ↩︎ Partitioning with actor_id, isolating with stores
      “grant it access with the store's grant-permission operation”
      ↩︎ Partitioning with actor_id, isolating with stores
      “Never let the model choose whose memory to read or write.”
      ↩︎ Exam trap 1
      “The store, not the actor, is the security boundary.”
      ↩︎ Exam trap 2
      “they create a memory store, save a user's preference, and recall it in a later conversation.”
      ↩︎ Checkpoint
      “actor_id separates memories, but it is not an access control.”
      ↩︎ Prediction
      “For strict isolation between tenants or users, create a separate memory store per boundary.”
      ↩︎ Checkpoint
    2. 2.
      “an agent (or your application) distills the durable facts out of it and writes them to memory.”
      ↩︎ Let the agent decide when to remember
    3. 3.
      “A memory store is a Unity Catalog securable that acts as a container for memory entries.”
      ↩︎ Recognizing the legacy memory store
      “path is a soft path within that scope that must start with /memories/”
      ↩︎ Recognizing the legacy memory store
      “the legacy managed agent memory, which will be turned down soon. Don't build new agents on it.”
      ↩︎ Checkpoint
    4. 4.
      “Run await store.setup() locally before deploying to create required tables”
      ↩︎ When Lakebase-backed memory doesn't persist
      “Pass custom_inputs.user_id in the request payload”
      ↩︎ When Lakebase-backed memory doesn't persist
      “Ensure you pass a consistent user_id in custom_inputs for each user”
      ↩︎ Exam trap 3

    Ready to test yourself?

    Practise Databricks Certified Context Engineer Associate in quiz mode.

    Spotted a mistake, or was something unclear? Tell us.