

Architecture overview
High-level flow:- User input → short-term messages (working memory) → LLM node produces a reply.
- A summarization node compresses older messages after a threshold and stores that compressed text in the graph state.
- For generation, the LLM prompt is built from the stored summary plus recent messages (not the entire history).
State design
In LangGraph the graph state is the single shared memory object passed between nodes. The state defines what every node reads, writes, and routes on, so its shape is a primary architectural decision. A compact ChatState schema (using TypedDict) looks like:
This schema gives a balanced memory architecture: short-term context for immediacy, compressed long-term memory for historical facts, and control logic (the counter) to determine when to compress.
Summarization node
The summarization node compresses themessages into a concise summary and updates the state. Typical responsibilities:
- Build a summarization prompt that preserves facts, decisions, deadlines, and requested actions.
- Invoke a model to produce a summary.
- Merge the new summary with the existing summary (optionally), trim
messages, and reset or adjust counters.
- The system instruction defines the summarization objective (preserve facts/decisions).
- Save the model’s output to
state["summary"]. - Trim
state["messages"](or keep the last N messages) to avoid unbounded token growth. - Reset or adjust
turn_countafter compression.
Injecting compressed memory back into prompts
When generating replies, include thesummary as part of the system-level context and then append the recent messages. This hybrid prompt keeps long-term facts available while maintaining immediacy.
Counters: a control lever for routing and summarization
A simple integer in state can drive a lot of behavior. Useturn_count to:
- Trigger summarization after N turns.
- Limit retries or loop iterations.
- Influence router/evaluator branching.
- Initialize the counter when a conversation starts.
- Increment after each user+assistant exchange.
- Use
should_summarizein routing logic to decide when to call the summarization node. - Reset or archive the counter as part of the summary operation.

When to summarize
Summarization has a cost. Choose triggers that balance currency and efficiency. Two common strategies:- Time-based: after a fixed number of turns (e.g., 4–6).
- Event-based: when a significant event occurs (topic shift, long message, new decision, etc.).
Typical pattern:
- Increment
turn_countafter each exchange. - If
should_summarizeis true, route to the summarization node. - Persist the updated summary, reset the counter, and continue.
Conversation flow
After several exchanges, trigger summarization. Older messages are compressed intosummary; recent messages are kept in messages. The next LLM prompt uses this cleaned-up state, so the model sees a compact, focused context instead of the entire conversation history.

Production considerations and extensions
- Keep the last 1–3 messages verbatim for conversational continuity when appropriate.
- Persist summaries in an external store (document DB, vector DB) for retrieval and audit trails.
- Generate structured summaries (bullet points, actions, deadlines, named entities) to make downstream reasoning easier.
- Combine time-based and event-based triggers for robust behavior.
- Tune the summarization prompt to preserve facts, decisions, and action items.
- Use observability tools (LangGraph Studio / LangSmith) to inspect state evolution and verify critical facts are retained.
Always test by printing or inspecting the state after each node to ensure summaries preserve key facts and that retained recent messages provide the necessary context for correct responses.
Why this pattern matters
Treat summarization as a first-class architectural component. By modeling memory explicitly in the graph state and using counter-driven routing, you can move from a simple prompt-based bot to a structured, long-running conversational system that scales gracefully and maintains high-quality responses.