Short-Term Conversation Memory › Solution 2: Conversation Summarization

Michael BrenndoerferJuly 1, 20252 min read
AI Agent HandbookAll chapters
Part 6 of 15Memory and Retrieval - How Agents Remember
Chapter 15Short-Term Conversation Memory › Solution 2: Conversation Summarization
Reading section 10 of 15 · Solution 2: Conversation Summarization · 2 minSection 10 of 15 · 2 min

Book contents

Section 10 of 15 · 2 min read

Short-Term Conversation Memory › Solution 2: Conversation SummarizationOne section · Sections in this chapter10 / 15 ↓

A more sophisticated approach: periodically summarize old messages and replace them with the summary. This preserves important information while reducing token count.

In[14]:
Code
class ConversationalAgentWithSummary:
    """Agent with conversation summarization."""
    
    def __init__(self, summarize_after: int = 20):
        self.client = Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY"))
        self.conversation_history = []
        self.summarize_after = summarize_after
    
    def _summarize_history(self, messages: list) -> str:
        """Create a summary of conversation history."""
        # Format the conversation
        conversation_text = "\n".join([
            f"{msg['role'].title()}: {msg['content']}"
            for msg in messages
        ])
        
        # Ask the model to summarize
        response = self.client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=500,
            messages=[{
                "role": "user",
                "content": f"""Summarize this conversation, preserving key facts, 
                decisions, and context that might be referenced later:
                
                {conversation_text}
                
                Provide a concise summary in 2-3 paragraphs."""
            }]
        )
        
        return response.content[0].text
    
    def chat(self, user_message: str) -> str:
        """Chat with automatic summarization."""
        # Add user message
        self.conversation_history.append({
            "role": "user",
            "content": user_message
        })
        
        # Check if we should summarize
        if len(self.conversation_history) > self.summarize_after:
            # Take first half of messages to summarize
            to_summarize = self.conversation_history[:self.summarize_after // 2]
            keep_recent = self.conversation_history[self.summarize_after // 2:]
            
            # Create summary
            summary = self._summarize_history(to_summarize)
            
            # Replace old messages with summary
            self.conversation_history = [
                {
                    "role": "user",
                    "content": f"[Previous conversation summary: {summary}]"
                }
            ] + keep_recent
        
        # Get response
        response = self.client.messages.create(
            model="claude-sonnet-4-5",
            max_tokens=1024,
            messages=self.conversation_history
        )
        
        assistant_message = response.content[0].text
        
        # Add response
        self.conversation_history.append({
            "role": "assistant",
            "content": assistant_message
        })
        
        return assistant_message

This approach:

  • Keeps recent messages in full detail
  • Summarizes older messages to preserve important context
  • Reduces token count while maintaining continuity

The tradeoff: summarization costs an extra API call, and some details might be lost in the summary.