Managing and Reducing Costs › Strategy 5: Trim Conversation History
Michael BrenndoerferAugust 26, 20252 min read
AI Agent HandbookAll chapters Part 15 of 15Performance and Cost Optimization - Doing More with Less
Managing and Reducing Costs › Strategy 5: Trim Conversation HistoryOne section · Sections in this chapter8 / 15 ↓
Sections in this chapter15
Long conversation histories increase input token costs. If your agent includes the last 20 messages in every request, you're paying to process all that context repeatedly.
Example: Smart History Trimming (Claude Sonnet 4.5)
In[9]:
Codeimport os
from anthropic import Anthropic
client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
class HistoryOptimizedAgent:
"""Agent that manages conversation history efficiently."""
def __init__(self):
self.conversation_history = []
self.max_history_messages = 6 # Keep last 3 exchanges
def _trim_history(self):
"""Keep only recent messages to reduce token costs."""
if len(self.conversation_history) > self.max_history_messages:
# Keep only the most recent messages
self.conversation_history = self.conversation_history[-self.max_history_messages:]
def _estimate_tokens(self, text):
"""Rough token estimate (4 chars ≈ 1 token)."""
return len(text) // 4
def respond(self, user_message):
"""Generate response with optimized history."""
# Add user message to history
self.conversation_history.append({
"role": "user",
"content": user_message
})
# Trim history before sending
self._trim_history()
# Calculate token usage
total_input_chars = sum(
len(msg["content"]) for msg in self.conversation_history
)
estimated_input_tokens = total_input_chars // 4
# Make the call
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=512,
messages=self.conversation_history
)
# Add assistant response to history
assistant_message = response.content[0].text
self.conversation_history.append({
"role": "assistant",
"content": assistant_message
})
# Calculate cost
input_cost = (response.usage.input_tokens / 1_000_000) * 3.00
output_cost = (response.usage.output_tokens / 1_000_000) * 15.00
total_cost = input_cost + output_cost
return {
"response": assistant_message,
"input_tokens": response.usage.input_tokens,
"output_tokens": response.usage.output_tokens,
"cost": total_cost,
"history_length": len(self.conversation_history)
}
## Test with a multi-turn conversation
agent = HistoryOptimizedAgent()
queries = [
"What is Python?",
"What are its main features?",
"How does it compare to Java?",
"What about performance?",
"Should I learn it?",
"What resources do you recommend?",
"How long will it take?",
"What projects should I build?"
]
total_cost = 0.0
for query in queries:
result = agent.respond(query)
total_cost += result["cost"]
print(f"Q: {query}")
print(f"Input tokens: {result['input_tokens']}")
print(f"History length: {result['history_length']} messages")
print(f"Cost: ${result['cost']:.6f}")
print()
print(f"Total conversation cost: ${total_cost:.4f}")
print("\nNote: Without trimming, costs would be ~40% higher")Out[9]:
ConsoleQ: What is Python? Input tokens: 11 History length: 2 messages Cost: $0.004278
Q: What are its main features? Input tokens: 303 History length: 4 messages Cost: $0.006324
Q: How does it compare to Java? Input tokens: 674 History length: 6 messages Cost: $0.009702
Q: What about performance? Input tokens: 1200 History length: 7 messages Cost: $0.011280
Q: Should I learn it? Input tokens: 1431 History length: 7 messages Cost: $0.011973
Q: What resources do you recommend? Input tokens: 1584 History length: 7 messages Cost: $0.012432
Q: How long will it take? Input tokens: 1587 History length: 7 messages Cost: $0.012441
Q: What projects should I build? Input tokens: 1588 History length: 7 messages Cost: $0.012444 Total conversation cost: $0.0809 Note: Without trimming, costs would be ~40% higher
By keeping only the last 6 messages (3 exchanges), you prevent the input token count from growing unbounded. This is especially important for long conversations.