Designing the Agent's Brain (Architecture) › Putting It All Together

Michael BrenndoerferJuly 9, 20252 min read
AI Agent HandbookAll chapters
Part 7 of 15Agent State and Architecture - Putting It All Together
Chapter 19Designing the Agent's Brain (Architecture) › Putting It All Together
Reading section 9 of 14 · Putting It All Together · 2 minSection 9 of 14 · 2 min

Book contents

Section 9 of 14 · 2 min read

Designing the Agent's Brain (Architecture) › Putting It All TogetherOne section · Sections in this chapter9 / 14 ↓

Let's look at a complete example that brings together everything we've discussed:

In[7]:
Code
import os
import anthropic
from typing import Dict, Any, Optional

class PersonalAssistant:
    """A well-structured AI agent with clear architecture"""
    
    def __init__(self, model="claude-sonnet-4-5"):
        # Using Claude Sonnet 4.5 for superior agent reasoning
        self.client = anthropic.Anthropic()
        self.model = model
        
        # Centralized state
        self.state = {
            "conversation_history": [],
            "user_preferences": {},
            "session_data": {}
        }
    
    def run(self, user_input: str) -> str:
        """Main agent loop - orchestrates everything"""
        try:
            # Step 1: Update state with input
            self._add_to_history("user", user_input)
            
            # Step 2: Decide what to do
            action = self._decide_action(user_input)
            
            # Step 3: Execute the action
            response = self._execute_action(action, user_input)
            
            # Step 4: Update state with response
            self._add_to_history("assistant", response)
            
            # Step 5: Return response
            return response
            
        except Exception as e:
            error_msg = f"I encountered an error: {str(e)}"
            self._add_to_history("assistant", error_msg)
            return error_msg
    
    def _add_to_history(self, role: str, content: str):
        """Manage conversation history"""
        self.state["conversation_history"].append({
            "role": role,
            "content": content
        })
    
    def _decide_action(self, user_input: str) -> str:
        """Decide what action to take based on input"""
        # Simple rule-based decisions
        # In a real system, this could be much more sophisticated
        
        if any(word in user_input.lower() for word in ["calculate", "compute", "+"]):
            return "calculate"
        elif "remember" in user_input.lower():
            return "store_preference"
        else:
            return "converse"
    
    def _execute_action(self, action: str, user_input: str) -> str:
        """Execute the decided action"""
        if action == "calculate":
            return self._handle_calculation(user_input)
        elif action == "store_preference":
            return self._store_preference(user_input)
        else:
            return self._converse(user_input)
    
    def _handle_calculation(self, text: str) -> str:
        """Handle math calculations"""
        # Simplified: in reality, you'd parse and evaluate properly
        return "I'd calculate that for you using my calculator tool."
    
    def _store_preference(self, text: str) -> str:
        """Store user preferences"""
        # Simplified: in reality, you'd extract and store the preference
        return "I've stored that preference."
    
    def _converse(self, user_input: str) -> str:
        """Use the language model for conversation"""
        response = self.client.messages.create(
            model=self.model,
            messages=self.state["conversation_history"],
            max_tokens=1024
        )
        return response.content[0].text
    
    def get_state(self) -> Dict[str, Any]:
        """Expose current state for debugging/monitoring"""
        return self.state.copy()

## Usage
assistant = PersonalAssistant()
print(assistant.run("Hello! What can you help me with?"))
print(assistant.run("Remember that I prefer morning meetings"))
print(assistant.run("What did I just tell you?"))
Out[7]:
Console
Hello! I'm Claude, an AI assistant. I can help you with a wide variety of things, including:

- **Answering questions** on many topics (science, history, technology, arts, etc.)
- **Writing and editing** (essays, emails, creative writing, proofreading)
- **Analysis and research** (summarizing information, comparing options, explaining concepts)
- **Problem-solving** (math, logic puzzles, brainstorming solutions)
- **Coding help** (explaining code, debugging, writing scripts in various languages)
- **Planning and organizing** (breaking down projects, creating outlines)
- **Learning support** (explaining difficult topics, tutoring)
- **Creative projects** (brainstorming ideas, worldbuilding, storytelling)
- **General conversation** and much more!

What would you like help with today?
I've stored that preference.
You told me that you prefer morning meetings.

However, I should clarify that I don't actually have the ability to remember information between different conversations. Each time we start a new chat session, I won't have access to what we discussed before, including your preference for morning meetings.

If there are important preferences or context you'd like me to keep in mind, you'll need to remind me at the start of each new conversation. Sorry for any confusion!

This assistant has a clear architecture:

  • The run() method implements the agent loop
  • State is centralized and managed through helper methods
  • Decision logic is separate from execution
  • Each capability (calculate, store, converse) has its own method
  • Error handling keeps the agent robust
  • The state can be inspected for debugging