Looking for the proactive policy-based system added in PR #1828? See Context Compaction Policy. This page documents the reactive
CompactionConfig system used inside Agent(context=...).Quick Start
1
Agent-Centric Quick Start
2
Simple Usage
3
With Configuration
Anti-Thrashing Protection
Prevents endless compaction cycles in long-running agents by tracking savings effectiveness and giving up when returns diminish.1
Default Protection
2
Custom Thresholds
How Anti-Thrashing Works
- Savings Tracking: Each compaction calculates
(original_tokens - compacted_tokens) / original_tokens * 100 - Streak Counter: Increments when savings <
min_savings_pct, resets on good savings - Circuit Breaker: Stops compaction when
streak >= max_consecutive_low_savings - Reset Trigger: New messages arriving resets the protection state
Configuration Options
Note: Values < 1.0 for
min_savings_pct are auto-scaled (e.g., 0.15 becomes 15.0).
Iterative Summarisation
Builds upon previous summaries instead of starting fresh, preserving context across multiple compaction cycles.1
Enable Iterative Mode
2
Disable for Fresh Summaries
Iterative vs Fresh Summaries
Tool-Result Pruning
Deduplicates and truncates verbose tool outputs before summarization, significantly reducing token waste.1
Default Pruning
2
Custom Tool Pruning
Custom Tool Pruner
Focused Summarisation
Biases summarization toward specific topics using thefocus_topic parameter, preserving relevant content while compacting the rest.
1
Research Agent with Focus
2
Async Compaction with Focus
How Focus Topic Works
- Content Matching: Text matching the focus topic is preserved verbatim
- LLM Emphasis: When using LLM summarization, adds
Focus especially on: {focus_topic}. - Structured Paths: Marks focused content with
*FOCUS*markers in structured summaries
Focus Topic Use Cases
Pluggable Protocols
Inject custom implementations for tool pruning, message formatting, and summary building through protocol interfaces.- Tool Result Pruner
- Message Formatter
- Summary Builder
Anti-Injection Framing
Prevents models from treating compacted summaries as active instructions by prepending safety framing.Default Anti-Injection Prefix
Custom Anti-Injection Framing
Summarize
Replace old messages with a summary:Smart
Intelligently select which messages to keep:LLM-Powered Summarization
LLM_SUMMARIZE uses the agent’s own LLM to summarise older turns, preserving identifiers, file paths, URLs, error messages, and the user’s intent verbatim.Fallback behavior: If the LLM call fails, fallback to naive summarization. If invoked from a sync context that’s already inside an event loop, it also falls back to naive — async callers (achat) get full LLM summarization.
Intelligent Conversation Compaction
New structured summarization that preserves conversation continuity:Compactor API
CLI Usage
Structured Summary Template
Organizes compacted content into clear sections instead of flat text.Template Structure
The structured template categorizes messages into six sections:- Active Task - Current user objective
- Completed Actions - Finished operations
- In Progress - Ongoing work
- Pending Questions - Unanswered queries
- Relevant Files / Paths - Mentioned file references
- Remaining Work - Planned future actions
Before/After Example
Before (Flat Summary):Disable Structured Template
Iterative Updates Across Multiple Compactions
Preserves context from previous compactions so long-running agents don’t lose early context.How Iterative Updates Work
- First compaction: Creates initial structured summary
- Second compaction: Merges previous summary with new content
- Subsequent compactions: Continue preserving essential context
Disable Iterative Updates
In-Loop Compaction (Two-Tier)
In-loop compaction runs between tool iterations inside a single turn, so tool results never accumulate unbounded and blow past the context window mid-run.max_iter times; the hook fires each iteration and does nothing while the conversation stays below threshold. Above threshold it applies up to two tiers in order.
The Two Tiers
Cleared tool results are replaced with this exact placeholder:
Custom Thresholds
The in-loop knobs are passed viallm= extra settings on the Agent.
Disable (Restore Prior Behaviour)
in_loop_compaction=False, compaction runs only once before the turn — the pre-#2995 behaviour.
When the active model changes mid-run (auth failover, model failover), the cached loop compactor is rebuilt automatically so the token budget and tokeniser stay aligned with the new provider’s window. Nothing to configure.
New CompactionConfig Fields
These extend the reactiveCompactionConfig — same class, new fields.
Accurate Token Counting
Every threshold decision above usesestimate_tokens(), which now uses tiktoken when it is available offline, otherwise the character heuristic.
- Tiktoken downloads its BPE vocab from the network on first use.
- To stay offline-safe (CI, air-gapped hosts), the accurate path is probed once in a short-lived, timeout-bounded daemon thread. If the tokeniser is not locally cached, the code permanently falls back to the
len//4heuristic — never blocks. count_message_tokens()now includes thetool_callspayload (function name + arguments), which the old heuristic silently dropped.- For guaranteed-accurate counts,
pip install tiktokenand run once with the model set onCompactionConfig(model=...)to warm the cache.
clear_tool_results() API
- Only mutates entries with
role == "tool". - Rewrites their
contentstring toplaceholder, leaving all other fields intact. - Assistant
tool_callsmessages are never touched, so the model still sees the call structure (name, args, id) needed for coherent tool loops. - Preserves the last
keep_recenttool results.
When To Tune
Configuration Options
Strategies Available
ExecutionConfig Options
CompactionConfig Options
Note:
min_savings_pct values < 1.0 are auto-scaled (e.g., 0.15 becomes 15.0).
Two Ways to Configure Compaction
Choose Your Configuration
Inspecting Results
The newCompactionResult provides detailed metrics about compaction operations and their effectiveness.
New CompactionResult Fields
Monitoring Compaction Health
User Interaction Flow
Real-world example showing how the new features work together in a long research session:How This Helps Long Research Sessions
- Hours 1-2: Agent builds initial knowledge about distributed systems
- Hours 3-4: Tool pruning keeps large documentation snippets manageable
- Hours 5-6: Focus topic preserves critical Raft algorithm details
- Hours 7+: Anti-thrashing prevents compaction overhead when context stabilizes
Best Practices
How do I tune anti-thrashing for my workload?
How do I tune anti-thrashing for my workload?
Adjust thresholds based on your agent’s usage pattern:For cost-sensitive workloads:For quality-focused workloads:Monitor
result.was_skipped_due_to_low_savings to see if protection is triggering.When should I write a custom ToolResultPrunerProtocol?
When should I write a custom ToolResultPrunerProtocol?
Write a custom tool pruner when:
- Your tools generate domain-specific outputs that need special handling
- Default size limits don’t match your tool output patterns
- You need to preserve specific data types (IDs, timestamps, etc.)
Iterative summaries vs. fresh summaries — which do I want?
Iterative summaries vs. fresh summaries — which do I want?
Use iterative summaries (default) when:
- Agent runs for hours/days with context continuity
- Research sessions with building knowledge
- Project management with evolving requirements
- Frequent topic switches in conversations
- Agent handles independent requests
- You prefer simpler mental models
What does focus_topic actually do?
What does focus_topic actually do?
Focus topic preserves content in three ways:
- Exact matches are preserved verbatim with
*FOCUS*markers - LLM summarization gets explicit instructions:
"Focus especially on: {focus_topic}." - Structured summaries emphasize focused content in relevant sections
- Long research sessions (“machine learning optimization”)
- Debugging sessions (“authentication errors”)
- Feature development (“payment integration”)
System-only overflow no longer hangs
System-only overflow no longer hangs
Since PR #1980,
_truncate() exits cleanly when only system messages remain over budget — previously this could loop indefinitely. The trade-off: when your system prompt alone exceeds target_tokens, post-compaction count may stay over target rather than dropping system messages.Best practices for long-running agents
Best practices for long-running agents
- Keep
enable_iterative_summary=True(default) for context preservation - Use
focus_topicwhen discussing specific technical areas - Monitor
result.tool_results_prunedto track tool output efficiency - Set appropriate
min_savings_pctbased on your cost tolerance - Use structured templates for better organization
- Test topic changes to verify anti-injection works properly
Hooks
BEFORE_COMPACTIONandAFTER_COMPACTIONhook events now fire consistently around every compaction (both sync and async). See Hooks.
Persistence
When the agent is bound to asession_id, a successful in-run compaction now writes its summary to the session automatically as a compaction checkpoint. On the next run, resume replays that summary plus the retained tail instead of the full raw transcript.
This is fully backward compatible — sessions without a checkpoint resume from raw messages exactly as before. See Compacted Session Resume for the persistence details.
Policy vs. CompactionConfig — which should I use?
ContextCompactionPolicy is the proactive gate that runs before LLM calls. CompactionConfig runs after when compaction is actually needed. Both are compatible —execution.context_compaction is the proactive gate, Agent(context=...) runs after.
Related
Serialization
Intelligent compaction vs. plain summarize
See Intelligent Conversation Compaction for detailed usage.
Zero Performance Impact
Compaction uses lazy loading:Memory Management
Long-term memory storage and retrieval
Agent Configuration
Complete agent configuration options
Context Budgeter
Model context-window limits that drive in-loop thresholds

