Chapter 8: Conversation Managers — Controlling Context Windows¶
← Back to Table of Contents | ← Previous: Session Persistence
Conversation managers control how the conversation history is managed — truncation, summarization, or no management at all. This is different from session persistence (which stores history) — conversation managers decide what's in the context window when the LLM is called.
agents:
assistant:
model: default
conversation_manager:
type: strands.agent:SlidingWindowConversationManager
params:
window_size: 40
should_truncate_results: false
system_prompt: "You are a helpful assistant."
Built-in Conversation Managers¶
These come from strands-agents directly:
| Class | What It Does |
|---|---|
strands.agent:SlidingWindowConversationManager |
Keeps the last N messages in context |
strands.agent:SummarizingConversationManager |
Summarizes older messages to save context |
strands.agent:NullConversationManager |
No management — keeps entire history |
Using Them¶
# Fixed-window approach
conversation_manager:
type: strands.agent:SlidingWindowConversationManager
params:
window_size: 20
# Summarization approach
conversation_manager:
type: strands.agent:SummarizingConversationManager
params:
summary_ratio: 0.3
preserve_recent_messages: 10
# No management (pass everything)
conversation_manager:
type: strands.agent:NullConversationManager
Custom Conversation Managers¶
Write your own by subclassing strands.agent.conversation_manager.ConversationManager:
conversation_manager:
type: ./managers.py:MySmartManager
params:
strategy: semantic_relevance
What the Model Is Sent: context:¶
A conversation manager decides what an agent keeps. context: shapes only the
copy of that conversation each model call is sent: the agent's own messages, the
chat a client stores and the history written back for it stay exactly as they
were.
Clearing old tool results¶
An agent working through many tool calls resends every earlier result on every
model turn. clear_tool_results replaces the older ones once the input grows:
agents:
analyst:
mcp: [warehouse]
context:
clear_tool_results:
trigger: 60000 # estimated input tokens before anything is cleared
keep_last: 3 # results of the 3 most recent turns always stay
min_chars: 1500 # shorter results always stay
keep_tools: [warehouse___get_schema]
| Key | Default | Meaning |
|---|---|---|
trigger |
(required) | Estimated input tokens (system prompt plus messages, four characters a token) above which results are cleared before a model call. The structuredContent strands keeps beside an MCP tool's result isn't counted, since no model is sent it. |
keep_last |
3 |
How many of the most recent turns keep their results; at least 1. A turn is every result of one model response, so a batch of parallel calls stays or goes together, and the newest batch, which the model has not read yet, is always sent whole. |
min_chars |
1500 |
Results shorter than this many characters always stay. |
keep_tools |
[] |
Tools whose results always stay. |
A cleared result keeps its call and reads:
Result cleared (warehouse___run_query, queryExecutionId=8f3c, tableId=sales): call it again to see it.
It names the tool and up to ten key=value pairs found in the result's JSON for
keys ending in id, Id or ID, so the model can call again for the data it
needs. A cleared result also loses its structuredContent. A delegate's
result, another agent's report, is never cleared: it cannot be fetched again
without rerunning that agent. The rewrite depends on nothing but
the messages and leaves a cleared result as it is, so the result reads the same
on every later call and a cached prompt prefix survives.
Calls to tools an agent does not have¶
Every agent, with or without context:, turns a toolUse for a tool it does not
have into a text note on the copy its model is sent:
Earlier step (analyze_sql, a tool you don't have): asked {"input": "revenue in 2024"}; returned Revenue in 2024 was $42M.
Such calls reach an agent through a transcript it did not write: the chat, when
the workflow changed between turns, or a history.group shared with an agent
whose tools differ. A model shown a call it cannot make tends to make it anyway.
A delegate (a name without ___) keeps up to 2,000 characters of input and its
whole result; an MCP tool (<target>___<tool>) keeps 500 characters of input
and a 500-character excerpt of its result, with its full length noted. Calls to
tools the agent has are left alone, and so is every call the agent makes itself
during the invocation: only the messages it held at its first model call are
rewritten. A tool name it gets wrong therefore reaches its model as the call
and its error, which is what lets it correct the name.
Tips & Tricks
- Conversation managers are per-agent. Different agents in the same config can use different strategies.
- For orchestration coordinators that do a lot of delegating,
SlidingWindowConversationManagerwith a generouswindow_sizeprevents context overflow from long delegate tool results.- Unlike session managers, there's no "global" conversation manager — set it on each agent that needs one.