Context Optimizer

Strategies for reducing context size when approaching model limits

Reduce context size automatically before models hit token limits — preventing overflow errors and cutting costs.

python
from praisonaiagents import Agent, ManagerConfig

agent = Agent(
    instructions="You are helpful.",
    context=ManagerConfig(
        auto_compact=True,
        compact_threshold=0.8,
        strategy="smart",
    ),
)
response = agent.chat("Hello!")

The user keeps chatting; the optimizer compacts context automatically when usage nears the model limit.

Which Strategy Should I Pick?

Diagram

Yes

No

Yes

No

Yes

No

Yes

No

Yes

No

Context over budget?

Need full audit trail?

non_destructive

Tool-heavy session?

prune_tools or smart

Long multi-hour chat?

conversation

Need LLM summarisation?

summarize or llm_compress

Simple trim OK?

truncate or sliding_window

smart — recommended default

How It Works

Diagram
ContextOptimizerAgentUserContextOptimizerAgentUserRequestProcessResultResponse

Quick Start

  1. Simple Usage
    python
    from praisonaiagents import Agent, ManagerConfig
    
    agent = Agent(
        instructions="You are helpful.",
        context=ManagerConfig(
            auto_compact=True,
            compact_threshold=0.8,
            strategy="smart",
        ),
    )
    agent.chat("Hello!")
  2. With Configuration
    python
    from praisonaiagents import Agent, ManagerConfig, get_optimizer, OptimizerStrategy
    
    agent = Agent(
        context=ManagerConfig(strategy="truncate", compact_threshold=0.7),
    )
    
    messages = [{"role": "user", "content": "Hello"}]
    optimizer = get_optimizer(OptimizerStrategy.SMART)
    optimized, stats = optimizer.optimize(messages, target_tokens=50000)
    print(f"Saved {stats.tokens_saved} tokens")

Optimisation Strategies

Diagram

truncate

sliding_window

prune_tools

summarize

non_destructive

smart

llm_compress

conversation

Messages

Strategy

Remove Oldest

Keep Recent N

Truncate Tool Outputs

LLM Summary

Tag & Exclude

Smart 4-Step

LLM-Driven Compression

Intelligent Compaction

Optimized

Smart Strategy Flow (Default)

Diagram

Yes

Yes

No

Yes

No

Yes

No

Over Budget?

Step 1: Summarize Tool Outputs

Under Budget?

Done

Step 2: Truncate Tool Outputs

Under Budget?

Step 3: Sliding Window

Under Budget?

Step 4: Summarize Conversation

Low-Level API

python
from praisonaiagents import get_optimizer, OptimizerStrategy

# Get an optimizer
optimizer = get_optimizer(OptimizerStrategy.SMART)

# Optimize messages to target token count
messages = [...]  # Your conversation history
optimized, stats = optimizer.optimize(messages, target_tokens=50000)

print(f"Reduced from {len(messages)} to {len(optimized)} messages")
print(f"Saved {stats.tokens_saved} tokens")

Strategy Reference

Truncate

Removes oldest messages first, preserving system prompt and recent context.

python
from praisonaiagents import TruncateOptimizer

optimizer = TruncateOptimizer()
result, stats = optimizer.optimize(messages, target_tokens=10000)

Best for: Simple cases where old context is not important.

Sliding Window

Keeps the N most recent messages within a token window.

python
from praisonaiagents import SlidingWindowOptimizer

optimizer = SlidingWindowOptimizer()
result, stats = optimizer.optimize(messages, target_tokens=10000)

Best for: Conversations where recent context matters most.

Prune Tools

Truncates old tool outputs while preserving recent ones.

python
from praisonaiagents import PruneToolsOptimizer

optimizer = PruneToolsOptimizer(
    protect_recent=5,  # Keep last 5 tool outputs intact
    max_output_tokens=500,  # Truncate older outputs to 500 tokens
)
result, stats = optimizer.optimize(messages, target_tokens=10000)

Best for: Tool-heavy conversations with large outputs.

Summarize

Uses LLM to create a summary of older conversation.

python
from praisonaiagents import SummarizeOptimizer

optimizer = SummarizeOptimizer(
    keep_recent=4,  # Keep last 4 turns intact
    model="gpt-4o-mini",
)
result, stats = optimizer.optimize(messages, target_tokens=10000)

Best for: Long conversations where context continuity matters.

Conversation

Conversation-aware compaction that preserves topic, goals, decisions, and action items across long sessions.

python
from praisonaiagents import Agent, ManagerConfig

agent = Agent(
    name="Planner",
    instructions="Help plan products over multi-hour sessions.",
    context=ManagerConfig(
        auto_compact=True,
        strategy="conversation",
        conversation_compaction=True,
        conversation_analyzer_strategy="hybrid",
        conversation_min_compaction_ratio=0.3,
    ),
)

Low-level class usage:

python
from praisonaiagents import ConversationOptimizer

optimizer = ConversationOptimizer(
    analyzer_strategy="hybrid",
    preserve_recent=5,
    min_compaction_ratio=0.3,
)
result, stats = optimizer.optimize(messages, target_tokens=4000)

Configuration Options:

OptionTypeDefaultDescription
llm_analyze_fnOptional[callable]NoneLLM function for conversation analysis. If None, falls back to rule-based analysis.
min_compaction_ratiofloat0.3Minimum compression ratio to attempt compaction. Below this, falls back to SmartOptimizer.
analyzer_strategystr"hybrid"One of "hybrid", "rule_based", "keyword".
preserve_recentint5Number of recent messages to keep intact.
llm_summarize_fnOptional[callable]NoneLLM function for summarization.
Diagram

Conversation Optimizer

No

Yes

error

📨 Messages

Compaction Ratio Meaningful?

🤖 SmartOptimizer Fallback

🧠 HybridAnalyzer

📝 ConversationContext

✅ Compacted Messages

Diagram
Context OptimizerAgentUserContext OptimizerAgentUserRequestProcess requestResultResponse

Best for: Multi-hour planning, iterative development, long support sessions where topic/goal continuity matters more than literal message history.

See Intelligent Conversation Compaction for the full conceptual deep-dive.

LLM Context Compressor

Advanced LLM-driven compression with session lineage and head/tail protection.

python
from praisonaiagents import LLMContextCompressorOptimizer

optimizer = LLMContextCompressorOptimizer(
    llm_client=agent.llm,
    auxiliary_model="gpt-4o-mini",
    protect_last_n_tokens=20_000,
    summary_target_tokens=750,
    enable_session_tracking=True,
)
result, stats = optimizer.optimize(messages, target_tokens=10000)

Best for: Long conversations requiring intelligent summarization with audit trails.

See LLM Context Compression for detailed usage.

Non-Destructive

Tags messages for exclusion without deleting them (enables undo).

python
from praisonaiagents import NonDestructiveOptimizer

optimizer = NonDestructiveOptimizer()
result, stats = optimizer.optimize(messages, target_tokens=10000)

# Messages are tagged with 'excluded': True
# Use get_effective_history() to filter

Best for: When you need to preserve full history for audit/undo.

Smart (Recommended)

Combines all strategies intelligently based on content analysis.

python
from praisonaiagents import SmartOptimizer

optimizer = SmartOptimizer()
result, stats = optimizer.optimize(messages, target_tokens=10000)

Order of operations (Smart Strategy):

  1. Summarize tool outputs – Uses LLM to intelligently summarize large tool outputs (preserves key info)
  2. Truncate tool outputs – Fallback truncation for remaining large outputs
  3. Sliding window – Remove oldest messages
  4. Summarize conversation – LLM summary of older conversation if still over limit

Factory Function

python
from praisonaiagents import get_optimizer, OptimizerStrategy

# Available strategies
strategies = [
    OptimizerStrategy.TRUNCATE,
    OptimizerStrategy.SLIDING_WINDOW,
    OptimizerStrategy.PRUNE_TOOLS,
    OptimizerStrategy.SUMMARIZE,
    OptimizerStrategy.NON_DESTRUCTIVE,
    OptimizerStrategy.SMART,
    OptimizerStrategy.CONVERSATION,
]

for strategy in strategies:
    optimizer = get_optimizer(strategy)
    result, stats = optimizer.optimize(messages, target_tokens=10000)
    print(f"{strategy.value}: {len(result)} messages")

Optimization Result

python
from praisonaiagents import OptimizationResult

# stats returned from optimize()
stats: OptimizationResult
print(f"Original tokens: {stats.original_tokens}")
print(f"Optimized tokens: {stats.optimized_tokens}")
print(f"Tokens saved: {stats.tokens_saved}")
print(f"Strategy used: {stats.strategy_used}")
print(f"Messages removed: {stats.messages_removed}")
print(f"Tool outputs pruned: {stats.tool_outputs_pruned}")
print(f"Tool outputs summarized: {stats.tool_outputs_summarized}")
print(f"Tokens saved by summarization: {stats.tokens_saved_by_summarization}")
print(f"Tokens saved by truncation: {stats.tokens_saved_by_truncation}")

Tool Call Preservation

The optimizer preserves tool_call/tool_result pairs to maintain API validity:

python
# These pairs are kept together or removed together
{"role": "assistant", "tool_calls": [{"id": "call_123", ...}]}
{"role": "tool", "tool_call_id": "call_123", "content": "..."}

CLI Usage

bash
# Set optimization strategy
praisonai chat --context-strategy smart

# Set trigger threshold
praisonai chat --context-threshold 0.8

# Manual optimization in session
/context compact

Configuration

yaml
# config.yaml
context:
  auto_compact: true
  compact_threshold: 0.8
  strategy: smart

Best Practices

Start with smart

smart combines summarisation, tool pruning, sliding window, and conversation summarisation — use it unless you have a specific reason not to.

Set compact_threshold below 1.0

Trigger compaction at 0.7–0.8 so optimisation runs before the model hard-fails on context overflow.

Use conversation for long sessions

Multi-hour planning or support threads benefit from conversation strategy — it preserves topics, goals, and decisions.

Preserve tool_call pairs

All strategies keep tool_calls and matching tool results together so API message history stays valid.

Related