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.
The CompositeBackend call
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.
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}."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)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.
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.
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")[monday] you: I love museums and I never do boat trips. Please remember that. [monday] read: [] [monday] agent: Got it—museums are a must and boat trips are a no‑go. I’ve saved those preferences for future travel plans. [friday] you: Suggest two sights for my first day in Paris. [friday] read: ['/memories/preferences.md'] [friday] agent: Visit the Louvre Museum (2,000 ₹) and explore Montmartre on a free walking tour. Both fit your love of museums and avoid boat trips. [friday] you: Suggest two sights for my first day in Paris. [friday] read: [] [friday] agent: Eiffel Tower summit (₹3,100) and Louvre Museum (₹2,000) are great first‑day sights. Both offer iconic views and art for a memorable start.
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.mdfirst, 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/... | |
|---|---|---|
| Backend | StateBackend | StoreBackend |
| Seen on another thread | No | Yes |
| Good for | Drafts, offloaded results | Preferences, 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.
/memories/, it may save nothing, or save everything. Name the file and the kind of fact in the system prompt.Related
- Previous: StoreBackend: files shared across threads
- Next: Memory: AGENTS.md loaded with memory=
- Reference: Backends: CompositeBackend
- Run Friday's question on a new agent with a fresh
InMemoryStoreand 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.mdon Monday and try to read it on Friday.
Slow is fine. Stopping is the only problem.