Deep AgentsDeep Agents 0.7 · Python 3.11+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
28 small wins to finish your pathNext lesson →

CompositeBackend: long-term memory in /memories/

CompositeBackend is a backend that routes each file path to a different backend by its prefix, so the agent can keep scratch files for one thread and long-term memory under /memories/ in one file system.

Last updated: 29 Sep, 2026 · Deep Agents 0.7

The video mentions the composite backend at the end of the backends section and leaves it to explore; this lesson follows the docs. The idea: most files are scratch work for one conversation, but a few facts, like what the traveller likes, should be there next week. A composite backend keeps both, by path.

CompositeBackend sends paths under /memories/ to a StoreBackend, kept across threads, and every other path to a StateBackend, kept only for that thread.
Two backends, one file system

The CompositeBackend call

python
CompositeBackend(
    default=StateBackend(),                                   # any path not listed below
    routes={"/memories/": StoreBackend(namespace=...)},        # this prefix goes to the store
)

The planner with long-term memory

Start trip.py with search_travel, the catalog tool from Tools: a travel search the agent can call. Everything below goes in the same file, under it.

python
from langchain.tools import tool

CATALOG = {
    "paris": {
        "flight": ["Return flight Delhi to Paris: 42,000 rupees"],
        "hotel": ["Seine Budget Inn, Latin Quarter: 5,200 rupees a night",
                  "Hotel Lumiere, Montmartre: 7,500 rupees a night",
                  "Le Grand Opera Hotel: 16,000 rupees a night"],
        "sight": ["Eiffel Tower summit: 3,100 rupees", "Louvre Museum: 2,000 rupees",
                  "Seine river cruise: 1,500 rupees", "Versailles day trip: 2,600 rupees",
                  "Montmartre walking tour: free"],
        "food": ["Cafe breakfast and bistro dinner: 3,000 rupees a day"],
    },
}


@tool
def search_travel(city: str, kind: str) -> str:
    """Search the travel catalog. kind is "flight", "hotel", "sight" or "food". Prices are in rupees."""
    entries = CATALOG.get(city.lower(), {}).get(kind)
    return "\n".join(entries) if entries else f"The catalog has no {kind} entries for {city}."
python
from deepagents import create_deep_agent
from langchain.chat_models import init_chat_model

model = init_chat_model("groq:openai/gpt-oss-120b", temperature=0, max_retries=6)
python
from deepagents.backends import CompositeBackend, StateBackend, StoreBackend
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.store.memory import InMemoryStore

def make_agent():
    return create_deep_agent(
        model=model,
        tools=[search_travel],
        backend=CompositeBackend(
            default=StateBackend(),                                    # any other path: this thread only
            routes={"/memories/": StoreBackend(namespace=lambda rt: ("traveller",))},   # kept for every thread
        ),
        store=InMemoryStore(),
        checkpointer=InMemorySaver(),
        system_prompt="You are a travel planner. When the traveller states a preference, save it to /memories/preferences.md. "
                      "Before suggesting anything, read /memories/preferences.md if it exists. "
                      "Use only prices from search_travel. Reply in two short sentences.",
    )

make_agent builds the planner with a fresh store each time it is called. The prompt tells the agent what to remember and where, and to read the file before it suggests anything. The store starts empty; the agent creates the file itself.

A helper that asks on a thread and shows the files read

ask sends one message on a named thread, prints every file the agent opened with read_file, then prints the reply.

python
def ask(text, thread_id):
    result = agent.invoke({"messages": [{"role": "user", "content": text}]}, config={"configurable": {"thread_id": thread_id}})
    print(f"[{thread_id}] you:  ", text)
    files_read = [c["args"].get("file_path") for m in result["messages"] for c in getattr(m, "tool_calls", []) if c["name"] == "read_file"]
    print(f"[{thread_id}] read: ", files_read)
    print(f"[{thread_id}] agent:", result["messages"][-1].text)

A preference on Monday, a plan on Friday

Monday and Friday run on one agent. The last question runs on a new agent with a new, empty store, to show what Friday looks like without the memory.

ExampleAPI keytrip.py, continued
agent = make_agent()
ask("I love museums and I never do boat trips. Please remember that.", "monday")
ask("Suggest two sights for my first day in Paris.", "friday")

agent = make_agent()                  # a new store: nothing was remembered
ask("Suggest two sights for my first day in Paris.", "friday")

What Friday's run shows

  • Monday: the traveller stated two preferences and the agent said it saved them.
  • Friday is a different thread with an empty conversation. The agent read /memories/preferences.md first, as its prompt says, and found Monday's file: the composite backend had sent it to the store.
  • The suggestion follows the memory: museums and free walks, no boat trip, even though the Seine cruise is one of the cheapest sights.
  • The new agent had an empty store, found no preferences file, and suggested sights without them.

Scratch files vs /memories/ files

Any other path/memories/...
BackendStateBackendStoreBackend
Seen on another threadNoYes
Good forDrafts, offloaded resultsPreferences, facts to keep

Where this pattern fits

  • Personal assistants that learn preferences over time.
  • Agents that improve their own instructions, which the memory lesson builds on.
  • Separating what may be deleted after a run from what must be kept.
Watch out. The agent decides what to save. If the prompt does not say which facts belong in /memories/, it may save nothing, or save everything. Name the file and the kind of fact in the system prompt.
Try it yourself
  • Run Friday's question on a new agent with a fresh InMemoryStore and compare the suggestion.
  • Tell the agent on a third thread "I changed my mind, I like boat trips now." and ask Friday's question again.
  • Save a scratch file /notes/today.md on Monday and try to read it on Friday.

Slow is fine. Stopping is the only problem.