Giving Your Agent Long-Term Memory¶
Our agent is efficient, but it's still... a bit forgetful. Every time we interact with it, it's a completely new, isolated execution. The agent has no memory of what we talked about just a moment ago. For a single task, that's fine. But for a real chatbot, that's a deal-breaker.
Note that here we are not talking about a single execution where as per previous code, langgraph state with all previous prompts is updated and passed for all subsequent inferences but only for that single execution.
Let's fix that and give our agent a proper memory.
Introducing Checkpointers¶
In LangGraph, the mechanism for giving a graph memory across multiple runs is called a checkpointer.
What is a Checkpointer?
A checkpointer is a component that automatically saves the state of your graph after an execution and loads it back in before the next one. It's the key to building conversational applications.
The simplest kind of checkpointer is the MemorySaver
. It holds the conversation state in your computer's RAM.
How MemorySaver
Works¶
When you attach a MemorySaver
to your graph, the invoke
/stream
process changes slightly:
- You provide a unique ID for your conversation (called a
thread_id
). - LangGraph asks the
MemorySaver
: "Do you have any saved history forthread_id
?" - If yes, it loads that state and starts the graph execution from there.
- The graph runs as usual, adding new messages to the state.
- At the end of the run, LangGraph tells the
MemorySaver
: "Here is the final, updated state forthread_id
. Please save it."
This simple save/load cycle ensures that context is passed between turns, creating a continuous conversation.
In-Memory vs. Persistent Memory¶
In-Memory: MemorySaver
MemorySaver
stores conversation history in a variable inside your running Python script. It's perfect for learning and for applications where memory only needs to last for a single session. If you restart your script, the memory is gone.
Persistent: SqliteSaver
, PostgresSaver
For production applications, you'd use a persistent checkpointer like SqliteSaver
. It saves the state to a database file (or a full-fledged database like Postgres). This means you can stop your application, restart it days later, and the agent will remember the conversation perfectly.
Implementing MemorySaver
¶
Adding memory to our streamlined agent is surprisingly simple. We only need to change how we compile and call the graph. The agent's elegant logic, using the pre-built ToolNode
and tools_condition
, remains exactly the same.
Here is the complete code. Notice the two key additions: the MemorySaver
and the config
dictionary used when calling the graph.
Running the Code and Seeing the Result¶
When you run this script, you'll see the magic of the checkpointer in action.
Success! In the second interaction, the agent correctly recalled the name from the first. It didn't need to search or guess; the information was present in the conversation state that was automatically loaded by the MemorySaver
. The only thing connecting the two separate .stream()
calls was the config
dictionary pointing to the same conversation thread.
And just like that, our smart and efficient agent is no longer forgetful! It's now a true conversationalist, ready to build upon past interactions.
without MemorySaver
Without Checkpointer, agent won't know the previous conversations across the two different graph runs as in the example. Go ahead and give it a try by updating agent code like below where we can compile the graph without the checkpointer