Skip to main content
Conversation summarization helps manage long conversation histories by condensing older messages while preserving important context. This is essential for maintaining context in extended conversations without exceeding token limits or performance constraints.

Overview

The SDK provides two types of summarizers:
  1. LLM Summarizer: Uses an LLM to intelligently summarize conversation history while preserving important context
  2. Sliding Window Summarizer: Keeps only the most recent N conversation runs and discards older messages
Summarizers are integrated with conversation managers and automatically trigger when certain conditions are met (e.g., token threshold for LLM summarizer, or when the number of runs exceeds the window size for sliding window).

LLM Summarizer

The LLM summarizer uses an LLM to create intelligent summaries of conversation history. It triggers when the total token count exceeds a specified threshold, keeping recent messages intact and summarizing older ones.

Configuration

Parameters

  • LLM: The LLM provider to use for summarization (can be different from the agent’s LLM)
  • Instruction: System prompt that defines how the summarizer should summarize conversations
  • TokenThreshold: The token count threshold at which summarization triggers
  • KeepRecentCount: Number of recent conversation runs to keep unsummarized (default: 5)
  • Parameters: Optional LLM parameters (temperature, etc.) for the summarization call

How It Works

  1. When messages are loaded, the summarizer checks whether the context occupancy exceeds TokenThreshold
  2. If it does and there are more than KeepRecentCount runs, messages are grouped into the runs that produced them
  3. It keeps the most recent KeepRecentCount runs intact
  4. Older runs are summarized into a single message using the LLM
  5. The summary replaces the old messages, preserving context while reducing token usage
Summarization is skipped entirely when the thread has KeepRecentCount runs or fewer — there would be nothing left to summarize.

How the token count is measured

TokenThreshold is compared against the run’s context occupancy: the last prompt-token count the provider actually reported, plus an estimate of everything appended since. The estimate is deliberately rough — roughly 4 characters per token, with a flat nominal cost for images and attached files — because it only has to cover the messages added since the last usage report, and is replaced by an exact number as soon as the next one arrives. The estimate runs low on code and structured text, which errs toward summarizing sooner. That is the safe direction: the cost of a needless summary is one extra call, and the cost of a missed one is a rejected request.

Summarization is billed to the run

Producing a summary costs real tokens, and those are added to the run’s usage total — so a run’s reported spend includes the work done to shrink it. They are deliberately not folded into the context-occupancy figure the summarizer keys off. A summarization request is its own instruction plus a flattened transcript, with none of the agent’s tools or system prompt; counting it as context would hand the summarizer a reading of a conversation that isn’t the one it is deciding about.

Sliding Window Summarizer

The sliding window summarizer keeps only the most recent N conversation runs and discards older ones. This is a simple, cost-effective approach that doesn’t require an LLM.

Configuration

Parameters

  • KeepCount: The number of recent conversation runs to retain. Older runs are discarded. Floored at 1, so leaving it unset keeps the run in flight rather than discarding every turn.

How It Works

  1. Messages are grouped into the runs that produced them
  2. If the number of runs exceeds KeepCount, only the most recent KeepCount runs are kept
  3. Older runs are discarded without creating a summary
  4. This approach is simple and cost-effective but loses older context completely
Unlike the LLM summarizer, this one has no token threshold — it trims purely by run count, and needs no model call, so SummaryResult.Usage is nil.
Runs are contiguous blocks. A run id that reappears later starts a new group rather than reopening the earlier one, so a message arriving out of order can’t be filed under an unrelated run and cut the trimming boundary in the wrong place. Adjacent messages with no run id of their own still group together, which is the conservative reading: fewer runs means the keep window covers more, not less.

Using Summarizers with Conversation Managers

To use a summarizer, pass it to the conversation manager using history.WithSummarizer():

Writing your own summarizer

Implement history.HistorySummarizer:
Return nil, nil when no summarization is needed. Otherwise return a SummaryResult:
A summary boundary naming the run still being written is refused and cleared — the summary row is saved but stays inert on reload. Floor your keep window at one run so the boundary always stops short of the most recent.

Reading a summarized thread back

Once a thread has been summarized, the agent’s own history load returns the summary in place of the turns it covers. That is right for the model and wrong for a UI. To render the thread as written, use LoadTranscript — see Reading a thread back.

Complete Example: LLM Summarizer

Here’s a complete example using an LLM summarizer:

Complete Example: Sliding Window Summarizer

Here’s a complete example using a sliding window summarizer: