LangChainLangChain 1.4 · Python 3.10+
0%
1
Curious builder0 XP earned · 300 to level 2
0 daysFinish a lesson to begin
Badge collection0 of 6 unlocked
43 small wins to finish your pathNext lesson

Memory that outlives the conversation

A thread holds one conversation. A store holds facts that last across all of them, saved as JSON documents filed under a namespace and a key.

Ravi told the shop once to leave parcels at the back door. That belongs to Ravi, not to any one conversation, so a new thread next week should still know it.

Putting and getting

Example
from langgraph.store.memory import InMemoryStore

store = InMemoryStore()
store.put(("customers", "ravi"), "delivery", {"note": "leave it at the back door"})

item = store.get(("customers", "ravi"), "delivery")
print(item.key, item.value)
print(store.get(("customers", "mei"), "delivery"))

The namespace is a tuple that works like a folder path, here one folder per customer. The key names a document in it, and the value is a dictionary. Asking for a document that is not there returns None.

Where an agent keeps things
One thread, saved by the checkpointerThe store, across all threadsmessagesthe conversationyour own keysstate_schemacontextpassed per callthe agentcreate_agentcustomers/ravidelivery notecustomers/meiher own documents
Hover or tap a piece to see what it is and which lesson built it.
What survives

Pick one to watch it run, step by step.

A tool with the store

Exampletools.py
from dataclasses import dataclass


@dataclass
class Customer:
    name: str


from langchain.tools import ToolRuntime, tool

ORDERS = {"A17": "shipped on 3 March", "C40": "waiting for stock"}


@tool
def lookup_order(order_id: str, runtime: ToolRuntime[Customer]) -> str:
    """Look up an order's shipping status by its id, such as A17."""
    folder = ("customers", runtime.context.name)
    runtime.store.put(folder, "last_order", {"order_id": order_id})
    note = runtime.store.get(folder, "delivery")
    status = f"{order_id} {ORDERS.get(order_id, 'is not an order we have')}."
    return f"{status} Delivery note: {note.value['note']}." if note else status

runtime.store is the store the agent was given. The tool reads Ravi's delivery note into its answer, and writes which order he asked about last. The agent gets the store, the context from lesson 9 and a checkpointer.

Exampleagent.py
from langchain.agents import create_agent
from langgraph.checkpoint.memory import InMemorySaver
from langgraph.store.memory import InMemoryStore
from shop_model import ShopModel
from tools import Customer, lookup_order

store = InMemoryStore()
store.put(("customers", "ravi"), "delivery", {"note": "leave it at the back door"})
agent = create_agent(ShopModel(), tools=[lookup_order], context_schema=Customer,
                     checkpointer=InMemorySaver(), store=store)
Example
ravi = Customer("ravi")
result = agent.invoke({"messages": [{"role": "user", "content": "Where is A17?"}]},
                      {"configurable": {"thread_id": "monday"}}, context=ravi)
print(result["messages"][-1].text)

The delivery note came out of the store, not out of the conversation, and the tool wrote A17 down as the order Ravi asked about last.

A new thread, the same customer

Example
result = agent.invoke({"messages": [{"role": "user", "content": "And C40?"}]},
                      {"configurable": {"thread_id": "friday"}}, context=ravi)

print(len(result["messages"]))
print(store.get(("customers", "ravi"), "last_order").value)

The Friday thread starts with four messages, none from Monday: the checkpointer keeps threads apart. The store does not. It still has Ravi's note, and the last order is now C40, written during Friday's call.

Try it yourself
  • Invoke as Mei and check that the answer has no delivery note.
  • Print [i.key for i in store.search(("customers", "ravi"))].
  • Create the agent without store= and read the error the tool raises.

This is what real progress feels like.