13 KiB
Memory
LangGraph supports two types of memory essential for building conversational agents:
- Short-term memory: Tracks the ongoing conversation by maintaining message history within a session.
- Long-term memory: Stores user-specific or application-level data across sessions.
This guide demonstrates how to use both memory types with agents in LangGraph. For a deeper understanding of memory concepts, refer to the LangGraph memory documentation.
!!! note "Terminology"
In LangGraph:
- *Short-term memory* is also referred to as **thread-level memory**.
- *Long-term memory* is also called **cross-thread memory**.
A [thread](../concepts/persistence.md#threads) represents a sequence of related runs
grouped by the same `thread_id`.
Short-term memory
Short-term memory enables agents to track multi-turn conversations. To use it, you must:
- Provide a
checkpointerwhen creating the agent. Thecheckpointerenables persistence of the agent's state. - Supply a
thread_idin the config when running the agent. Thethread_idis a unique identifier for the conversation session.
from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import InMemorySaver
# highlight-next-line
checkpointer = InMemorySaver() # (1)!
def get_weather(city: str) -> str:
"""Get weather for a given city."""
return f"It's always sunny in {city}!"
agent = create_react_agent(
model="anthropic:claude-3-7-sonnet-latest",
tools=[get_weather],
# highlight-next-line
checkpointer=checkpointer # (2)!
)
# Run the agent
config = {
"configurable": {
# highlight-next-line
"thread_id": "1" # (3)!
}
}
sf_response = agent.invoke(
{"messages": [{"role": "user", "content": "what is the weather in sf"}]},
# highlight-next-line
config
)
# Continue the conversation using the same thread_id
ny_response = agent.invoke(
{"messages": [{"role": "user", "content": "what about new york?"}]},
# highlight-next-line
config # (4)!
)
- The
InMemorySaveris a checkpointer that stores the agent's state in memory. In a production setting, you would typically use a database or other persistent storage. Please review the checkpointer documentation for more options. If you're deploying with LangGraph Platform, the platform will provide a production-ready checkpointer for you. - The
checkpointeris passed to the agent. This enables the agent to persist its state across invocations. Please note that - A unique
thread_idis provided in the config. This ID is used to identify the conversation session. The value is controlled by the user and can be any string. - The agent will continue the conversation using the same
thread_id. This will allow the agent to infer that the user is asking specifically about the weather in New York.
When the agent is invoked the second time with the same thread_id, the original message history from the first conversation is automatically included, allowing the agent to infer that the user is asking specifically about the weather in New York.
!!! Note "LangGraph Platform providers a production-ready checkpointer"
If you're using [LangGraph Platform](./deployment.md), during deployment your checkpointer will be automatically configured to use a production-ready database.
Message history summarization
Long conversations can exceed the LLM's context window. To handle this, you can summarize older messages by specifying a [pre_model_hook][langgraph.prebuilt.chat_agent_executor.create_react_agent], such as the prebuilt SummarizationNode:
from langchain_anthropic import ChatAnthropic
from langmem.short_term import SummarizationNode
from langchain_core.messages.utils import count_tokens_approximately
from langgraph.prebuilt import create_react_agent
from langgraph.prebuilt.chat_agent_executor import AgentState
from langgraph.checkpoint.memory import InMemorySaver
from typing import Any
model = ChatAnthropic(model="claude-3-7-sonnet-latest")
summarization_node = SummarizationNode( # (1)!
token_counter=count_tokens_approximately,
model=model,
max_tokens=384,
max_summary_tokens=128,
output_messages_key="llm_input_messages",
)
class State(AgentState):
# NOTE: we're adding this key to keep track of previous summary information
# to make sure we're not summarizing on every LLM call
# highlight-next-line
context: dict[str, Any] # (2)!
checkpointer = InMemorySaver() # (3)!
agent = create_react_agent(
model=model,
tools=tools,
# highlight-next-line
pre_model_hook=summarization_node, # (4)!
# highlight-next-line
state_schema=State, # (5)!
checkpointer=checkpointer,
)
- The
InMemorySaveris a checkpointer that stores the agent's state in memory. In a production setting, you would typically use a database or other persistent storage. Please review the checkpointer documentation for more options. If you're deploying with LangGraph Platform, the platform will provide a production-ready checkpointer for you. - The
contextkey is added to the agent's state. The key contains book-keeping information for the summarization node. It is used to keep track of the last summary information and ensure that the agent doesn't summarize on every LLM call, which can be inefficient. - The
checkpointeris passed to the agent. This enables the agent to persist its state across invocations. - The
pre_model_hookis set to theSummarizationNode. This node will summarize the message history before sending it to the LLM. The summarization node will automatically handle the summarization process and update the agent's state with the new summary. You can replace this with a custom implementation if you prefer. Please see the [create_react_agent][langgraph.prebuilt.chat_agent_executor.create_react_agent] API reference for more details. - The
state_schemais set to theStateclass, which is the custom state that contains an extracontextkey.
To learn more about using pre_model_hook for managing message history, see this how-to guide
Long-term memory
Use long-term memory to store user-specific or application-specific data across conversations. This is useful for applications like chatbots, where you want to remember user preferences or other information.
To use long-term memory, you need to:
- Configure a store to persist data across invocations.
- Use the [
get_store][langgraph.config.get_store] function to access the store from within tools or prompts.
Reading
from langgraph.config import get_store
from langgraph.prebuilt import create_react_agent
from langgraph.store.memory import InMemoryStore
# highlight-next-line
store = InMemoryStore() # (1)!
# highlight-next-line
store.put( # (2)!
("users",), # (3)!
"user_123", # (4)!
{
"name": "John Smith",
"language": "English",
} # (5)!
)
def get_user_info(config: RunnableConfig) -> str:
"""Look up user info."""
# Same as that provided to `create_react_agent`
# highlight-next-line
store = get_store() # (6)!
user_id = config.get("configurable", {}).get("user_id")
# highlight-next-line
user_info = store.get(("users",), user_id) # (7)!
return str(user_info.value) if user_info else "Unknown user"
agent = create_react_agent(
model="anthropic:claude-3-7-sonnet-latest",
tools=[get_user_info],
# highlight-next-line
store=store # (8)!
)
# Run the agent
agent.invoke(
{"messages": [{"role": "user", "content": "look up user information"}]},
# highlight-next-line
config={"configurable": {"user_id": "user_123"}}
)
- The
InMemoryStoreis a store that stores data in memory. In a production setting, you would typically use a database or other persistent storage. Please review the store documentation for more options. If you're deploying with LangGraph Platform, the platform will provide a production-ready store for you. - For this example, we write some sample data to the store using the
putmethod. Please see the [BaseStore.put][langgraph.store.base.BaseStore.put] API reference for more details. - The first argument is the namespace. This is used to group related data together. In this case, we are using the
usersnamespace to group user data. - A key within the namespace. This example uses a user ID for the key.
- The data that we want to store for the given user.
- The
get_storefunction is used to access the store. You can call it from anywhere in your code, including tools and prompts. This function returns the store that was passed to the agent when it was created. - The
getmethod is used to retrieve data from the store. The first argument is the namespace, and the second argument is the key. This will return aStoreValueobject, which contains the value and metadata about the value. - The
storeis passed to the agent. This enables the agent to access the store when running tools. You can also use theget_storefunction to access the store from anywhere in your code.
Writing
from typing_extensions import TypedDict
from langgraph.config import get_store
from langgraph.prebuilt import create_react_agent
from langgraph.store.memory import InMemoryStore
store = InMemoryStore() # (1)!
class UserInfo(TypedDict): # (2)!
name: str
def save_user_info(user_info: UserInfo, config: RunnableConfig) -> str: # (3)!
"""Save user info."""
# Same as that provided to `create_react_agent`
# highlight-next-line
store = get_store() # (4)!
user_id = config.get("configurable", {}).get("user_id")
# highlight-next-line
store.put(("users",), user_id, user_info) # (5)!
return "Successfully saved user info."
agent = create_react_agent(
model="anthropic:claude-3-7-sonnet-latest",
tools=[save_user_info],
# highlight-next-line
store=store
)
# Run the agent
agent.invoke(
{"messages": [{"role": "user", "content": "My name is John Smith"}]},
# highlight-next-line
config={"configurable": {"user_id": "user_123"}} # (6)!
)
# You can access the store directly to get the value
store.get(("users",), "user_123").value
- The
InMemoryStoreis a store that stores data in memory. In a production setting, you would typically use a database or other persistent storage. Please review the store documentation for more options. If you're deploying with LangGraph Platform, the platform will provide a production-ready store for you. - The
UserInfoclass is aTypedDictthat defines the structure of the user information. The LLM will use this to format the response according to the schema. - The
save_user_infofunction is a tool that allows an agent to update user information. This could be useful for a chat application where the user wants to update their profile information. - The
get_storefunction is used to access the store. You can call it from anywhere in your code, including tools and prompts. This function returns the store that was passed to the agent when it was created. - The
putmethod is used to store data in the store. The first argument is the namespace, and the second argument is the key. This will store the user information in the store. - The
user_idis passed in the config. This is used to identify the user whose information is being updated.
Prebuilt memory tools
LangMem is a LangChain-maintained library that offers tools for managing long-term memories in your agent. See the LangMem documentation for usage examples.