Memory that outlives the conversation
A thread remembers one conversation. Some things should be remembered across all of them, like a customer's name.
The checkpointer saves the state of a thread. Start a new thread and none of it comes with you, which is right for a conversation and wrong for everything you know about the person having it.
So there is a second place to put things. A store is a plain key and value box that sits beside the graph rather than inside any one thread.
A state with something to say and something to recall
from typing_extensions import TypedDict
class State(TypedDict):
said: str
known: strA node that can reach the store
A node can ask LangGraph for more than the state. Add a second argument and the store arrives on it.
from langgraph.runtime import Runtime
def remember(state, runtime: Runtime):
place = ("users", "asha")
if state["said"]:
runtime.store.put(place, "name", {"value": state["said"]})
found = runtime.store.get(place, "name")
return {"known": found.value["value"] if found else "nobody"}Ask for a second argument, typed as Runtime, and LangGraph passes one in. Nothing else about the node changes. The tuple is a namespace, grouping related values the way folders group files, and one per user is the usual shape. put writes a value under a key and get reads it back.
Give the graph a store
from langgraph.graph import StateGraph, START
from langgraph.store.memory import InMemoryStore
builder = StateGraph(State)
builder.add_node("remember", remember)
builder.add_edge(START, "remember")
graph = builder.compile(store=InMemoryStore())The store is given to compile, beside the checkpointer and completely separate from it. A graph can have either, both, or neither.
Two runs that share nothing
print(graph.invoke({"said": "Asha", "known": ""})["known"])
print(graph.invoke({"said": "", "known": ""})["known"])There is no checkpointer here and no thread id, so by everything in lesson 20 the second run should know nothing at all. It knows the name, because the name went into the store rather than into the state.
Which memory is which
| Checkpointer | Store | |
|---|---|---|
| Holds | The state of one thread | Anything you choose to put in it |
| Scope | One conversation | Across every conversation |
| Written by | LangGraph, after every step | You, from inside a node |
| Good for | The messages so far | Names, preferences, facts learned |
Most real agents use both. The checkpointer keeps the thread going, and the store holds the handful of things worth knowing next week.
InMemoryStore disappears with your program, exactly like InMemorySaver. There is a Postgres backed one for real use, and the same put and get calls work against it unchanged.- Change the namespace to
("users", "ravi")on the second run and see what it knows. - Store a second key, such as a preferred language, and read both back.
- Give the graph a checkpointer and a thread id as well, and confirm both kinds of memory work together.
You understood something today that you didn't yesterday.