If you’ve ever built a chatbot, you’ve probably noticed how quickly things fall apart when it forgets what you just said. Short-term memory is the key to keeping conversations flowing naturally, and LangGraph makes it straightforward to implement. In this post, we’ll explore how LangGraph handles short-term memory using thread-scoped checkpoints, and I’ll walk you through practical examples to show it in action.
By the end, you’ll see how to build a simple chatbot, add memory to it, retrieve conversation states, and even manage long histories with trimming and summarization techniques. Let’s dive in!
What Is Short-Term Memory in LangGraph?
LangGraph manages short-term memory as part of an agent’s state, persisting it through thread-scoped checkpoints. This state typically includes the conversation history — human inputs and AI responses — along with any other relevant data, like uploaded files or generated outputs. By storing this state in the graph, the agent can maintain full context within a single conversation thread, while keeping different threads isolated from each other.
Let’s start with a basic example and build from there.
A Simple Chatbot Without Memory
First, let’s create a chatbot that doesn’t remember anything. This will help us see the problem memory solves.
from langchain_groq import ChatGroq
from langchain.prompts import ChatPromptTemplate,MessagesPlaceholder
from langgraph.graph import StateGraph,START,END
from langgraph.graph.message import AnyMessage,add_messages
from typing import Annotated,List
from typing_extensions import TypedDict
class State(TypedDict):
messages:Annotated[List[AnyMessage],add_messages]
llm = ChatGroq(model="llama-3.3-70b-versatile",api_key="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")
prompt_template = ChatPromptTemplate.from_messages(
[
("system", "{system_message}"),
MessagesPlaceholder("messages")
]
)
llm_model = prompt_template | llm
graph_builder=StateGraph(State)
def ChatNode(state:State)->State:
system_message="You are an assistant"
state["messages"]=llm_model.invoke({"system_message":system_message,"messages":state["messages"]})
return state
graph_builder.add_node("chatnode",ChatNode)
graph_builder.add_edge(START,"chatnode")
graph_builder.add_edge("chatnode",END)
graph=graph_builder.compile()
# First input
input_state={"messages":["My name is sajith"]}
response_state=graph.invoke(input_state)
for message in response_state["messages"]:
message.pretty_print()
# Second input
input_state={"messages":["Who am i?"]}
response_state=graph.invoke(input_state)
for message in response_state["messages"]:
message.pretty_print()
Output:
================================ Human Message =================================
My name is Sajith
================================== Ai Message ==================================
Hello Sajith, it's nice to meet you. Is there something I can help you with or would you like to chat?
================================ Human Message =================================
Who am I?
================================== Ai Message ==================================
Unfortunately, I don't have any information about you, so I'm not sure who you are...
Notice how the bot forgets my name between the two inputs. Each invocation starts fresh, with no memory of prior messages. That’s fine for one-off responses, but terrible for a conversation. Let’s fix that.
Adding Short-Term Memory with Checkpoints
To give our chatbot memory, we’ll use LangGraph’s MemorySaver checkpointer and a thread_id to persist state across invocations. Here’s the updated code:
from langgraph.checkpoint.memory import MemorySaver
# Same imports and setup as before...
graph_builder = StateGraph(State)
def ChatNode(state: State) -> State:
system_message = "You are an assistant"
state["messages"] = llm_model.invoke({"system_message": system_message, "messages": state["messages"]})
return state
graph_builder.add_node("chatnode", ChatNode)
graph_builder.add_edge(START, "chatnode")
graph_builder.add_edge("chatnode", END)
graph = graph_builder.compile(checkpointer=MemorySaver())
config={"configurable":{"thread_id":1}}
# First Input
input_state={"messages":["My name is sajith"]}
response_state=graph.invoke(input_state,config=config)
for message in response_state["messages"]:
message.pretty_print()
# Second Input
input_state={"messages":["Who am i?"]}
response_state=graph.invoke(input_state,config=config)
for message in response_state["messages"]:
message.pretty_print()
Output:
================================ Human Message =================================
My name is Sajith
================================== Ai Message ==================================
Hello Sajith, it's nice to meet you. Is there something I can help you with or would you like to chat?
================================ Human Message =================================
My name is Sajith
================================== Ai Message ==================================
Hello Sajith, it's nice to meet you. Is there something I can help you with or would you like to chat?
================================ Human Message =================================
Who am I?
================================== Ai Message ==================================
You are Sajith, the person I'm having a conversation with. If you'd like to share more about yourself, I'm all ears! What do you do, or what are your interests, Sajith?
Now the bot remembers my name! The MemorySaver persists the state, and the thread_id ensures all interactions stay within the same conversation thread. Each new input appends to the existing message history, giving the LLM full context.
Peeking Into the State
LangGraph lets you inspect the conversation state at any point using the thread_id. Here’s how to get the current state snapshot:
config = {"configurable": {"thread_id": 1}}
state = graph.get_state(config=config)
print(state)
Or fetch a specific state using a checkpoint_id:
config = {"configurable": {"thread_id": 1,"checkpoint_id":"1eff1b93-8255-698c-8004-bc52982a4a1d"}}
state = graph.get_state(config)
print(state)
Output:
StateSnapshot(
values={'messages':
[HumanMessage(content='My name is sajith', additional_kwargs={}, response_metadata={}, id='a504dce7-b478-4c1c-a6cd-426d0447b6c1'),
AIMessage(content="Hello Sajith, it's nice to meet you. Is there something I can help you with or would you like to chat?", additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 28, 'prompt_tokens': 45, 'total_tokens': 73, 'completion_time': 0.101818182, 'prompt_time': 0.0047757, 'queue_time': 0.233790742, 'total_time': 0.106593882}, 'model_name': 'llama-3.3-70b-versatile', 'system_fingerprint': 'fp_2ca0059abb', 'finish_reason': 'stop', 'logprobs': None}, id='run-4ee5966e-8d52-43b7-893c-05f5162181ca-0', usage_metadata={'input_tokens': 45, 'output_tokens': 28, 'total_tokens': 73}),
HumanMessage(content='Who am i?', additional_kwargs={}, response_metadata={}, id='22804775-6822-420a-bf33-e2a1b5a8e80d'),
AIMessage(content="You are Sajith, the person I'm having a conversation with. If you'd like to share more about yourself, I'm all ears! What do you do, or what are your interests, Sajith?", additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 46, 'prompt_tokens': 86, 'total_tokens': 132, 'completion_time': 0.167272727, 'prompt_time': 0.00620371, 'queue_time': 0.233534108, 'total_time': 0.173476437}, 'model_name': 'llama-3.3-70b-versatile', 'system_fingerprint': 'fp_2ca0059abb', 'finish_reason': 'stop', 'logprobs': None}, id='run-619f4f89-25d0-4641-b86d-3f2b26269cbf-0', usage_metadata={'input_tokens': 86, 'output_tokens': 46, 'total_tokens': 132})
]},
next=(),
config={'configurable': {'thread_id': 1, 'checkpoint_ns': '', 'checkpoint_id': '1eff1b93-8255-698c-8004-bc52982a4a1d'}},
metadata={'source': 'loop', 'writes': {'chatnode': {'messages': AIMessage(content="You are Sajith, the person I'm having a conversation with. If you'd like to share more about yourself, I'm all ears! What do you do, or what are your interests, Sajith?", additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 46, 'prompt_tokens': 86, 'total_tokens': 132, 'completion_time': 0.167272727, 'prompt_time': 0.00620371, 'queue_time': 0.233534108, 'total_time': 0.173476437}, 'model_name': 'llama-3.3-70b-versatile', 'system_fingerprint': 'fp_2ca0059abb', 'finish_reason': 'stop', 'logprobs': None}, id='run-619f4f89-25d0-4641-b86d-3f2b26269cbf-0', usage_metadata={'input_tokens': 86, 'output_tokens': 46, 'total_tokens': 132})}}, 'thread_id': 1, 'step': 4, 'parents': {}},
created_at='2025-02-23T07:38:48.499019+00:00',
parent_config={'configurable': {'thread_id': 1, 'checkpoint_ns': '', 'checkpoint_id': '1eff1b93-7a2a-6554-8003-2b5dfd35edf7'}},
tasks=())
You can also retrieve the entire state history for a thread_id .This code will return all the snapshots (6 snapshots till now) with the checkpoint_id of each snapshot:
config = {"configurable": {"thread_id": 1}}
state_history = graph.get_state_history(config)
for state in state_history:
print(state)
Output:
StateSnapshot(
values={'messages':
[HumanMessage(content='My name is sajith', additional_kwargs={}, response_metadata={}, id='a504dce7-b478-4c1c-a6cd-426d0447b6c1'),
AIMessage(content="Hello Sajith, it's nice to meet you. Is there something I can help you with or would you like to chat?", additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 28, 'prompt_tokens': 45, 'total_tokens': 73, 'completion_time': 0.101818182, 'prompt_time': 0.0047757, 'queue_time': 0.233790742, 'total_time': 0.106593882}, 'model_name': 'llama-3.3-70b-versatile', 'system_fingerprint': 'fp_2ca0059abb', 'finish_reason': 'stop', 'logprobs': None}, id='run-4ee5966e-8d52-43b7-893c-05f5162181ca-0', usage_metadata={'input_tokens': 45, 'output_tokens': 28, 'total_tokens': 73}),
HumanMessage(content='Who am i?', additional_kwargs={}, response_metadata={}, id='22804775-6822-420a-bf33-e2a1b5a8e80d'),
AIMessage(content="You are Sajith, the person I'm having a conversation with. If you'd like to share more about yourself, I'm all ears! What do you do, or what are your interests, Sajith?", additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 46, 'prompt_tokens': 86, 'total_tokens': 132, 'completion_time': 0.167272727, 'prompt_time': 0.00620371, 'queue_time': 0.233534108, 'total_time': 0.173476437}, 'model_name': 'llama-3.3-70b-versatile', 'system_fingerprint': 'fp_2ca0059abb', 'finish_reason': 'stop', 'logprobs': None}, id='run-619f4f89-25d0-4641-b86d-3f2b26269cbf-0', usage_metadata={'input_tokens': 86, 'output_tokens': 46, 'total_tokens': 132})
]},
next=(),
config={'configurable': {'thread_id': 1, 'checkpoint_ns': '', 'checkpoint_id': '1eff1b93-8255-698c-8004-bc52982a4a1d'}},
metadata={'source': 'loop', 'writes': {'chatnode': {'messages': AIMessage(content="You are Sajith, the person I'm having a conversation with. If you'd like to share more about yourself, I'm all ears! What do you do, or what are your interests, Sajith?", additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 46, 'prompt_tokens': 86, 'total_tokens': 132, 'completion_time': 0.167272727, 'prompt_time': 0.00620371, 'queue_time': 0.233534108, 'total_time': 0.173476437}, 'model_name': 'llama-3.3-70b-versatile', 'system_fingerprint': 'fp_2ca0059abb', 'finish_reason': 'stop', 'logprobs': None}, id='run-619f4f89-25d0-4641-b86d-3f2b26269cbf-0', usage_metadata={'input_tokens': 86, 'output_tokens': 46, 'total_tokens': 132})}}, 'thread_id': 1, 'step': 4, 'parents': {}},
created_at='2025-02-23T07:38:48.499019+00:00',
parent_config={'configurable': {'thread_id': 1, 'checkpoint_ns': '', 'checkpoint_id': '1eff1b93-7a2a-6554-8003-2b5dfd35edf7'}},
tasks=())
StateSnapshot(
values={'messages':
[HumanMessage(content='My name is sajith', additional_kwargs={}, response_metadata={}, id='fb2530a6-23a9-49b9-aa05-05ee3d6033b5'),
AIMessage(content="Hello Sajith, it's nice to meet you. Is there something I can help you with or would you like to chat?", additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 28, 'prompt_tokens': 45, 'total_tokens': 73, 'completion_time': 0.101818182, 'prompt_time': 0.005301916, 'queue_time': 0.23472177200000002, 'total_time': 0.107120098}, 'model_name': 'llama-3.3-70b-versatile', 'system_fingerprint': 'fp_0a4b7a8df3', 'finish_reason': 'stop', 'logprobs': None}, id='run-9bd34581-f421-4ba4-8e4f-4a8ebe7dc0b2-0', usage_metadata={'input_tokens': 45, 'output_tokens': 28, 'total_tokens': 73}),
HumanMessage(content='Who am i?', additional_kwargs={}, response_metadata={}, id='609a20d0-f3b6-45b5-8e41-ae3c0d5ef87f')
]},
next=('chatnode',),
config={'configurable': {'thread_id': 1, 'checkpoint_ns': '', 'checkpoint_id': '1eff3ff0-f18a-60bb-8003-0206ca59dd82'}},
metadata={'source': 'loop', 'writes': None, 'thread_id': 1, 'step': 3, 'parents': {}},
created_at='2025-02-26T05:03:46.725660+00:00',
parent_config={'configurable': {'thread_id': 1, 'checkpoint_ns': '', 'checkpoint_id': '1eff3ff0-f17a-6dec-8002-a34664ba3775'}},
tasks=(PregelTask(id='c674df80-862b-a0af-9be3-0e7b687fab82', name='chatnode', path=('__pregel_pull', 'chatnode'), error=None, interrupts=(), state=None, result={'messages': AIMessage(content="You are Sajith, the person I'm currently chatting with. If you'd like to share more about yourself, I'm all ears! What do you do, or what are your interests?", additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 41, 'prompt_tokens': 86, 'total_tokens': 127, 'completion_time': 0.149090909, 'prompt_time': 0.006059721, 'queue_time': 0.232343247, 'total_time': 0.15515063}, 'model_name': 'llama-3.3-70b-versatile', 'system_fingerprint': 'fp_5f849c5a0b', 'finish_reason': 'stop', 'logprobs': None}, id='run-1c6fa3f7-cc6a-4481-83de-98423bdbdb49-0', usage_metadata={'input_tokens': 86, 'output_tokens': 41, 'total_tokens': 127})}),))
....
StateSnapshot(
values={'messages':
[HumanMessage(content='My name is sajith', additional_kwargs={}, response_metadata={}, id='fb2530a6-23a9-49b9-aa05-05ee3d6033b5')
]},
next=('chatnode',),
config={'configurable': {'thread_id': 1, 'checkpoint_ns': '', 'checkpoint_id': '1eff3ff0-e021-6e1b-8000-f334729d7d33'}},
metadata={'source': 'loop', 'writes': None, 'thread_id': 1, 'step': 0, 'parents': {}},
created_at='2025-02-26T05:03:44.900445+00:00',
parent_config={'configurable': {'thread_id': 1, 'checkpoint_ns': '', 'checkpoint_id': '1eff3ff0-e01d-6340-bfff-9f60f86089c9'}},
tasks=(PregelTask(id='7643d589-07fc-af50-26da-056cf318eca4', name='chatnode', path=('__pregel_pull', 'chatnode'), error=None, interrupts=(), state=None, result={'messages': AIMessage(content="Hello Sajith, it's nice to meet you. Is there something I can help you with or would you like to chat?", additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 28, 'prompt_tokens': 45, 'total_tokens': 73, 'completion_time': 0.101818182, 'prompt_time': 0.005301916, 'queue_time': 0.23472177200000002, 'total_time': 0.107120098}, 'model_name': 'llama-3.3-70b-versatile', 'system_fingerprint': 'fp_0a4b7a8df3', 'finish_reason': 'stop', 'logprobs': None}, id='run-9bd34581-f421-4ba4-8e4f-4a8ebe7dc0b2-0', usage_metadata={'input_tokens': 45, 'output_tokens': 28, 'total_tokens': 73})}),))
StateSnapshot(
values={'messages':
[]}, StateSnapshot(
values={'messages':
[HumanMessage(content='My name is sajith', additional_kwargs={}, response_metadata={}, id='fb2530a6-23a9-49b9-aa05-05ee3d6033b5')
]},
next=('chatnode',),
config={'configurable': {'thread_id': 1, 'checkpoint_ns': '', 'checkpoint_id': '1eff3ff0-e021-6e1b-8000-f334729d7d33'}},
metadata={'source': 'loop', 'writes': None, 'thread_id': 1, 'step': 0, 'parents': {}},
created_at='2025-02-26T05:03:44.900445+00:00',
parent_config={'configurable': {'thread_id': 1, 'checkpoint_ns': '', 'checkpoint_id': '1eff3ff0-e01d-6340-bfff-9f60f86089c9'}},
tasks=(PregelTask(id='7643d589-07fc-af50-26da-056cf318eca4', name='chatnode', path=('__pregel_pull', 'chatnode'), error=None, interrupts=(), state=None, result={'messages': AIMessage(content="Hello Sajith, it's nice to meet you. Is there something I can help you with or would you like to chat?", additional_kwargs={}, response_metadata={'token_usage': {'completion_tokens': 28, 'prompt_tokens': 45, 'total_tokens': 73, 'completion_time': 0.101818182, 'prompt_time': 0.005301916, 'queue_time': 0.23472177200000002, 'total_time': 0.107120098}, 'model_name': 'llama-3.3-70b-versatile', 'system_fingerprint': 'fp_0a4b7a8df3', 'finish_reason': 'stop', 'logprobs': None}, id='run-9bd34581-f421-4ba4-8e4f-4a8ebe7dc0b2-0', usage_metadata={'input_tokens': 45, 'output_tokens': 28, 'total_tokens': 73})}),))
next=('__start__',),
config={'configurable': {'thread_id': 1, 'checkpoint_ns': '', 'checkpoint_id': '1eff3ff0-e01d-6340-bfff-9f60f86089c9'}},
metadata={'source': 'input', 'writes': {'__start__': {'messages': ['My name is sajith']}}, 'thread_id': 1, 'step': -1, 'parents': {}},
created_at='2025-02-26T05:03:44.898532+00:00',
parent_config=None,
tasks=(PregelTask(id='09ab64cc-a528-2dab-e307-f2fdba458043', name='__start__', path=('__pregel_pull', '__start__'), error=None, interrupts=(), state=None, result={'messages': ['My name is sajith']}),))
Updating the State
But what if you want to tweak the state — say, to add or correct information? LangGraph’s update_state method lets you modify the state directly. Here’s an example where we update the state to include a new piece of info:
from langchain_core.messages import HumanMessage
# After initial invokes
config = {"configurable": {"thread_id": 1}}
graph.update_state(config, {"messages": [HumanMessage(content="I am a software engineer")]})
# Test the updated state
input_state = {"messages": ["What do I do?"]}
response_state = graph.invoke(input_state, config=config)
for message in response_state["messages"]:
message.pretty_print()
Output:
================================ Human Message =================================
My name is Sajith
================================== Ai Message ==================================
Hello Sajith, it's nice to meet you. Is there something I can help you with or would you like to chat?
================================ Human Message =================================
Who am I?
================================== Ai Message ==================================
You are Sajith, the person I'm having a conversation with. If you'd like to share more about yourself, I'm all ears! What do you do, or what are your interests, Sajith?
================================ Human Message =================================
I am a software engineer
================================ Human Message =================================
What do I do?
================================== Ai Message ==================================
You’re a software engineer, Sajith! That’s what you told me. Do you work on anything specific, like web development or AI?
With graph.update_state, we injected “I am a software engineer” into the conversation history without running a full node. The next invocation picks up this updated state, and the bot responds with the new context in mind.
Modifying State at a Checkpoint
You can also update the state at a specific checkpoint using the checkpoint_id and continue execution from there. Let’s walk through an example where we update a message “I am a software engineer” to “I live in Kerala”
config = {"configurable":{"thread_id":1}}
# Get all checkpoints
all_checkpoints = []
for state in graph.get_state_history(config):
all_checkpoints.append(state)
# find the index of checkpoint to restore to
index = 0
selected_index = 0
for state in graph.get_state_history(config):
index += 1
if state.values["messages"] != [] and state.values["messages"][-1].content == "I am a software engineer":
selected_index = index
# update the message at the selected checkpoint
old_config = all_checkpoints[selected_index].config
graph.update_state(old_config, {"messages": [HumanMessage(content="I live in kerala")]})
# Test the updated state
input_state = {"messages": ["Where do i live?"]}
response_state = graph.invoke(input_state, config=config)
for message in response_state["messages"]:
message.pretty_print()
Output:
================================ Human Message =================================
My name is Sajith
================================== Ai Message ==================================
Hello Sajith, it's nice to meet you. Is there something I can help you with or would you like to chat?
================================ Human Message =================================
Who am I?
================================== Ai Message ==================================
You are Sajith, the person I'm having a conversation with. If you'd like to share more about yourself, I'm all ears! What do you do, or what are your interests, Sajith?
================================ Human Message =================================
I live in kerala
================================ Human Message =================================
Where do i live?
================================== Ai Message ==================================
You live in Kerala, a beautiful state in India known for its stunning natural landscapes, rich culture, and delicious cuisine. Is that correct, Sajith?
We replaced “I am a software engineer” with “I live in kerala” in the conversation history using graph.update_state by specifying the checkpoint_id.
Managing Long Conversations
As conversations grow, the message history can balloon beyond an LLM’s context window, causing errors. LangGraph offers two main strategies to handle this: trimming messages and summarizing conversations.

Trimming Messages
Let’s trim the message list to keep only the last few entries. You can use a custom reducer function to filter messages based on the state information or you can use RemoveMessage to remove message from state when using add_messages as the reducer.
from langgraph.graph.message import RemoveMessage
# Same imports and setup as before...
def filter_node(state: State) -> State:
# Keep only the last 2 messages
state["messages"] = [RemoveMessage(id=m.id) for m in state["messages"][:-2]]
return state
graph_builder = StateGraph(State)
graph_builder.add_node("filternode", filter_node)
graph_builder.add_node("chatnode", ChatNode)
graph_builder.add_edge(START, "filternode")
graph_builder.add_edge("filternode", "chatnode")
graph_builder.add_edge("chatnode", END)
graph = graph_builder.compile(checkpointer=MemorySaver())
Now, older messages are pruned, keeping the context manageable. Alternatively, you can use trim_messages from LangChain to trim based on token count:
from langchain_core.messages import trim_messages
# Same imports and setup as before...
graph_builder = StateGraph(State)
def chat_node(state: State) -> State:
system_message = "You are an assistant"
trimmed_messages = trim_messages(
state["messages"],
strategy="last",
token_counter=llm,
max_tokens=100,
start_on="human",
end_on=("human", "tool"),
include_system=True
)
state["messages"] = llm_model.invoke({"system_message": system_message, "messages": trimmed_messages})
return state
graph_builder.add_node("chatnode", ChatNode)
graph_builder.add_edge(START, "chatnode")
graph_builder.add_edge("chatnode", END)
graph = graph_builder.compile(checkpointer=MemorySaver())
This ensures the context stays within a token limit, preserving the most relevant parts.
Summarizing Conversations
For a smarter approach, you can summarize the conversation and use that summary as context. Here’s an example:
from langchain_groq import ChatGroq
from langchain.prompts import ChatPromptTemplate,MessagesPlaceholder
from langgraph.graph import StateGraph,START,END
from langgraph.graph.message import AnyMessage,add_messages,RemoveMessage
from langchain_core.messages import HumanMessage
from langgraph.checkpoint.memory import MemorySaver
from typing import Annotated,List,Literal
from typing_extensions import TypedDict
class State(TypedDict):
messages:Annotated[List[AnyMessage],add_messages]
summary: str
llm = ChatGroq(model="llama-3.3-70b-versatile",api_key="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")
prompt_template = ChatPromptTemplate.from_messages(
[
("system", "{system_message}"),
MessagesPlaceholder("messages")
]
)
llm_model = prompt_template | llm
graph_builder=StateGraph(State)
def chat_node(state:State)->State:
system_message="You are an assistant"
summary = state.get("summary", "")
if summary:
system_message += f"Summary of conversation earlier: {summary}"
state["messages"]=llm_model.invoke({"system_message":system_message,"messages":state["messages"]})
return state
def summarize_conversation(state: State):
system_message="You are an chat summarizer"
summary = state.get("summary", "")
if summary:
summary_message = (
f"This is summary of the conversation to date: {summary}\n\n"
"Extend the summary by taking into account the new messages above:"
)
else:
summary_message = "Create a summary of the conversation above:"
response=llm_model.invoke({"system_message":system_message,"messages":state["messages"]+[HumanMessage(content=summary_message)]})
# We now need to delete messages that we no longer want to show up # delete all message except last 2
delete_messages = [RemoveMessage(id=m.id) for m in state["messages"][:-2]]
return {"summary": response.content, "messages": delete_messages}
def should_continue(state: State) -> Literal["summarize", END]:
"""Return the next node to execute."""
messages = state["messages"]
# If there are more than six messages, then we summarize the conversation
if len(messages) > 6:
return "summarize"
return END
graph_builder.add_node("chatnode",chat_node)
graph_builder.add_node("summarize",summarize_conversation)
graph_builder.add_edge(START,"chatnode")
graph_builder.add_conditional_edges("chatnode",should_continue)
graph_builder.add_edge("summarize",END)
graph=graph_builder.compile(checkpointer=MemorySaver())
config={"configurable":{"thread_id":1}}
input_state={"messages":["My name is sajith"]}
response_state=graph.invoke(input_state,config=config)
for message in response_state["messages"]:
message.pretty_print()
In this setup, the chatbot summarizes the conversation when it exceeds six messages, storing the summary and remove older messages. The summary is then injected into the system prompt, keeping the agent informed without overwhelming the context window.
Example Interaction:
Input: "My name is Sajith"
Output: "Hello Sajith, it's nice to meet you..."
Input: "I am a software engineer"
Output: "That’s great, Sajith! What type of projects do you work on?"
...
[After several messages]
Summary: "Sajith is a software engineer living in Kerala, working at Ideenkreise Tech..."
Wrapping Up
LangGraph’s approach to short-term memory is both elegant and practical. With thread-scoped checkpoints, you can maintain conversation context effortlessly. Using trimming or summarization you can handle even lengthy chats.