Add Memory

In shortAdd memory to a 10xGraph agent by compiling the graph with InMemoryCheckpointer, so conversation state persists across calls on the same thread.

  • 2 min read
  • 7 sections
  • Updated
  • v0.9.2
  • Markdown

Without a checkpointer, each app.invoke call is independent — the agent starts fresh every time. A checkpointer saves state after each run and restores it when the same thread_id is used again.

This page adds InMemoryCheckpointer so your agent remembers the conversation.

Why thread IDs matter now

Every call to app.invoke takes a config with a thread_id. Once a checkpointer is attached, all calls sharing the same thread_id share the same conversation history:

sequenceDiagram
  participant App as app.invoke(thread_id="abc")
  participant Checkpointer as InMemoryCheckpointer
  participant State as AgentState

  App->>Checkpointer: load state for "abc"
  Checkpointer-->>State: previous context
  App->>State: append new message
  App->>State: run nodes
  App->>Checkpointer: save updated state for "abc"

Without a checkpointer, the “load state” step is skipped and history is lost between calls.

Add InMemoryCheckpointer

InMemoryCheckpointer stores state in memory. It works for development and testing. For production, use PgCheckpointer with a database.

Update your graph to compile with a checkpointer:

Python
from tenxgraph.core.graph import Agent, StateGraph, ToolNode
from tenxgraph.core.state import AgentState, Message
from tenxgraph.storage.checkpointer import InMemoryCheckpointer
from tenxgraph.utils import END

checkpointer = InMemoryCheckpointer()

agent = Agent(
    model="google/gemini-2.5-flash",
    system_prompt=[
        {
            "role": "system",
            "content": "You are a helpful assistant.",
        }
    ],
)

graph = StateGraph(AgentState)
graph.add_node("assistant", agent)
graph.set_entry_point("assistant")
graph.add_edge("assistant", END)

# Pass the checkpointer when compiling
app = graph.compile(checkpointer=checkpointer)

Test multi-turn conversation

Create agent_with_memory.py with the graph above, then add these calls:

Python
THREAD = "memory-demo-1"

# First turn
result = app.invoke(
    {"messages": [Message.text_message("My name is Alex.")]},
    config={"thread_id": THREAD},
)
print(result["messages"][-1].text())

# Second turn — same thread_id, agent remembers
result = app.invoke(
    {"messages": [Message.text_message("What is my name?")]},
    config={"thread_id": THREAD},
)
print(result["messages"][-1].text())

Run it:

Terminal
python agent_with_memory.py

Expected output (exact wording varies):

Text
Nice to meet you, Alex!
Your name is Alex.

The agent remembered “Alex” from the first turn because both calls shared the same thread_id.

Use a different thread

Each thread_id is an independent conversation. Using a different ID gives the agent a fresh start:

Python
# New thread — agent has no memory of "Alex"
result = app.invoke(
    {"messages": [Message.text_message("What is my name?")]},
    config={"thread_id": "memory-demo-2"},
)
print(result["messages"][-1].text())

Expected output:

Text
I don't know your name yet. Could you tell me?

Key imports

Python
from tenxgraph.storage.checkpointer import InMemoryCheckpointer

For production:

Python
from tenxgraph.storage.checkpointer import PgCheckpointer
# Requires: pip install 10xgraph[pg_checkpoint]

What you learned

  • A checkpointer saves and restores AgentState between calls.
  • Conversations are isolated by thread_id.
  • InMemoryCheckpointer is for development; PgCheckpointer is for production.
  • Pass the checkpointer to graph.compile(checkpointer=...).

Next step

Serve the agent over HTTP with Run with the API.

Last updated for v0.9.2Edit this page on GitHubReport an issue