Message Management in LangGraph

Handle conversation history with message trimming and summarization to prevent context window overflow.

Advanced · 16 min read

Managing Message History

As conversations grow, history fills the context window and costs increase. LangGraph gives full control over state to implement trimming, summarization, or custom memory strategies.

from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
from langchain_core.messages import BaseMessage, SystemMessage, trim_messages
import operator

llm = ChatOpenAI(model="gpt-4o-mini")

class ConversationState(TypedDict):
    messages: Annotated[list[BaseMessage], operator.add]
    summary: str

def summarize_if_long(state: ConversationState) -> ConversationState:
    if len(state["messages"]) < 10:
        return state
    summary_prompt = [
        SystemMessage(content="Summarize this conversation concisely."),
        *state["messages"][:-4],
    ]
    summary = llm.invoke(summary_prompt).content
    return {
        "messages": [SystemMessage(content=f"Prior summary: {summary}"), *state["messages"][-4:]],
        "summary": summary,
    }

def chat_node(state: ConversationState) -> ConversationState:
    trimmed = trim_messages(state["messages"], strategy="last", max_tokens=2000, token_counter=llm)
    return {"messages": [llm.invoke(trimmed)], "summary": state.get("summary", "")}

builder = StateGraph(ConversationState)
builder.add_node("summarize", summarize_if_long)
builder.add_node("chat", chat_node)
builder.set_entry_point("summarize")
builder.add_edge("summarize", "chat")
builder.add_edge("chat", END)
graph = builder.compile()

Part of the LangChain, LangGraph & Vector DBs series on Tekivex. Browse all tutorials or explore our open-source products.