Your First AI Agent

Core Build - Memory, Tools, and Persistence

Transform your basic agent into a production-ready assistant with conversation memory, tool use, and state persistence

Core Build: Production-Ready Agent

Transform your basic Q&A agent into a conversational assistant that remembers context, uses tools, and persists conversations.

What We're Building

Enhancements:

  • 🧠 Conversation Memory: Multi-turn context awareness
  • 🔧 Tool Integration: Web search, calculator, file access
  • 💾 State Persistence: Save/load conversations
  • 🎯 Error Handling: Graceful failures and recovery

Architecture Overview

# Enhanced agent architecture
class Agent:
    def __init__(self):
        self.messages = []      # Conversation memory
        self.tools = []         # Available tools
        self.system_prompt = "" # Behavior definition

    def run(self, user_input):
        self.messages.append({"role": "user", "content": user_input})
        response = self.decide_and_act()
        return response

Key Insight: Agent state (messages, tools, prompts) must persist across turns for coherent conversations.

Part 1: Conversation Memory

Why Memory Matters

Without memory, agents can't:

  • Answer follow-up questions ("What about the previous point?")
  • Maintain context ("As I mentioned earlier...")
  • Build on prior information ("Adding to your analysis...")

Message History Pattern

Store Message History

self.messages = []  # Initialize empty

# Each turn adds messages
self.messages.append({"role": "user", "content": input})
self.messages.append({"role": "assistant", "content": response})

Pass History to API

response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    messages=self.messages  # ← Full conversation history
)

Claude sees entire conversation, not just current message.

Test Multi-Turn Context

You: My research topic is AI agents.
Agent: Great! I can help with AI agent research.

You: What are the key papers?
Agent: For AI agents, key papers include... [uses context]

Memory Management

Token Limits: Long conversations exceed context windows. Implement truncation or summarization.

Strategies:

  • Sliding Window: Keep last N messages
  • Summarization: Compress old messages
  • Importance Scoring: Retain key messages, discard filler
# Sliding window example
if len(self.messages) > 20:
    self.messages = self.messages[-20:]  # Keep last 20

Part 2: Tool Integration

Tool Use Concepts

Tools extend agent capabilities beyond text generation:

  • Web Search: Current information, fact-checking
  • Calculator: Precise computations
  • File Access: Read/write data

Anthropic Tool Use API

Define Tool Schema

tools = [{
    "name": "web_search",
    "description": "Search the web for current information",
    "input_schema": {
        "type": "object",
        "properties": {
            "query": {"type": "string"}
        }
    }
}]

Agent Requests Tool

response = client.messages.create(
    model="claude-3-5-sonnet-20241022",
    messages=messages,
    tools=tools  # ← Agent can request these
)

Claude returns tool use request in response.

Execute Tool

if response.stop_reason == "tool_use":
    tool_name = response.content[0].name
    tool_input = response.content[0].input
    result = execute_tool(tool_name, tool_input)

Return Result to Agent

messages.append({
    "role": "user",
    "content": [{
        "type": "tool_result",
        "tool_use_id": response.content[0].id,
        "content": result
    }]
})

Agent processes tool result in next turn.

Tool Implementation Examples

Pattern: Safe math evaluation

def calculator(expression):
    # Safe eval with restricted operations
    result = safe_eval(expression)
    return str(result)

Agent Usage:

You: What's the NPV of $100k yearly for 5 years at 7% discount?
Agent: [Requests calculator with NPV formula]
[Tool returns: 410,019.75]
Agent: The NPV is $410,019.75

Pattern: Sandboxed file operations

def read_file(path):
    # Restrict to safe directory
    safe_path = validate_path(path)
    with open(safe_path, 'r') as f:
        return f.read()

Agent Usage:

You: Summarize notes.txt
Agent: [Requests read_file("notes.txt")]
[Tool returns file contents]
Agent: Here's a summary... [analyzes content]

Tool Use Loop

# Agentic loop with tools
while not task_complete:
    response = client.messages.create(...)

    if response.stop_reason == "tool_use":
        result = execute_tool(response.content[0])
        messages.append(tool_result(result))
        continue  # Agent processes result

    elif response.stop_reason == "end_turn":
        return response.content[0].text

Key Insight: Agents can chain multiple tool calls to accomplish complex tasks. The loop continues until agent decides task is complete.

Part 3: Conversation Persistence

Why Persistence Matters

Users expect agents to:

  • Remember previous conversations
  • Continue where they left off
  • Build knowledge over time

Save/Load Pattern

Save Conversation

import json

def save_conversation(messages, filename):
    with open(filename, 'w') as f:
        json.dump(messages, f)

When to save:

  • After each turn (auto-save)
  • On explicit user command
  • Before program exit

Load Conversation

def load_conversation(filename):
    with open(filename, 'r') as f:
        return json.load(f)

When to load:

  • On agent startup
  • When user requests history
  • To resume interrupted tasks

Conversation Management

# List conversations
conversations = list_saved_conversations()

# Load specific conversation
messages = load_conversation("2024-01-15_research.json")

# Resume with context
agent.messages = messages
agent.run("Let's continue...")

File Organization

Recommended structure:

conversations/
├── 2024-01-15_research.json
├── 2024-01-16_coding.json
└── 2024-01-17_business.json

Filename pattern: {date}_{topic}.json

Part 4: Error Handling

Common Failure Points

Graceful Degradation

# Error handling pattern
try:
    result = execute_tool(tool_name, tool_input)
except ToolError as e:
    result = f"Tool failed: {str(e)}"
    # Agent adapts to failure in next turn

Testing Your Enhanced Agent

Test Memory

You: I'm researching platform economics.
Agent: I'll help with platform economics research.

You: What about network effects?
Agent: For platform economics, network effects... [uses context]

Verify: Agent references previous topic.

Test Tool Use

You: What's 15% of $2.4 million?
Agent: [Uses calculator]
Agent: 15% of $2.4M is $360,000

You: Search for recent platform economics papers
Agent: [Uses web_search]
Agent: Recent papers include... [lists results]

Verify: Correct tool selection and usage.

Test Persistence

Session 1:

You: Let's discuss AI safety.
[Conversation continues...]
You: save this as ai_safety.json
Agent: Conversation saved.
[Exit]

Session 2:

You: load ai_safety.json
Agent: Loaded previous conversation.

You: What were we discussing?
Agent: We were discussing AI safety... [recalls context]

Verify: Context preserved across sessions.

Success Criteria

Your enhanced agent should:

  • Multi-Turn Context: Answer follow-up questions correctly
  • Tool Selection: Choose appropriate tools for tasks
  • Tool Execution: Successfully execute web search, calculator, file access
  • Persistence: Save and load conversations accurately
  • Error Recovery: Handle failures gracefully

What You've Built

Core Agent Features:

  • 🧠 Conversation memory (full message history)
  • 🔧 Tool use (web search, calculator, files)
  • 💾 Conversation persistence (save/load)
  • 🎯 Error handling (graceful failures)

Missing Enhancements:

  • Domain-specific tools and prompts
  • Advanced reasoning patterns
  • Proactive suggestions
  • Multi-agent collaboration

Next Step: Domain Applications chapter shows how to specialize this agent for Economics, Software, or Business domains.

Key Takeaways

  1. Memory: Message history enables multi-turn conversations
  2. Tools: External capabilities extend agent beyond text
  3. Persistence: Save/load enables long-term context
  4. Error Handling: Graceful failures improve reliability
  5. Agentic Loop: Perceive → Decide → Act pattern handles complexity

Complete Code: Full implementation with all features available in curriculum GitHub repository. These snippets show patterns only.