Adding Logs to the Agent › What to Log

Michael BrenndoerferAugust 6, 20252 min read
AI Agent HandbookAll chapters
Part 12 of 15Observability and Debugging - Peering Inside the Agent
Chapter 33Adding Logs to the Agent › What to Log
Reading section 3 of 10 · What to Log · 2 minSection 3 of 10 · 2 min

Book contents

Section 3 of 10 · 2 min read

Adding Logs to the Agent › What to LogOne section · Sections in this chapter3 / 10 ↓

You don't need to log everything your agent does. Too many logs become noise, making it harder to find useful information. Instead, focus on logging the key decision points and transitions in your agent's flow.

Here are the most valuable things to log:

User Input: Record what the user asked for. This gives you the starting point for tracing through what the agent did.

In[3]:
Code
## Using Claude Sonnet 4.5 for its superior agent reasoning capabilities
import logging
import os

from anthropic import Anthropic

## Set up basic logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


def process_user_query(user_input):
    logger.info(f"Received user query: {user_input}")
    # Process the query...

Tool Decisions: Log when the agent decides to use a tool and which tool it chose. This helps you verify the agent is selecting the right tool for each task.

In[4]:
Code
def decide_tool_usage(query, available_tools):
    # Agent decides which tool to use
    selected_tool = agent_select_tool(query, available_tools)
    logger.info(f"Agent selected tool: {selected_tool} for query: {query}")
    return selected_tool

Tool Calls and Results: Record both the input to each tool and what the tool returned. If a tool fails or returns unexpected data, you'll want to know.

In[5]:
Code
def call_calculator(expression):
    logger.info(f"Calling calculator with expression: {expression}")
    try:
        result = eval(expression)  # Simplified for example
        logger.info(f"Calculator returned: {result}")
        return result
    except Exception as e:
        logger.error(f"Calculator failed: {e}")
        return None

Reasoning Steps: When your agent uses chain-of-thought or other reasoning techniques, log the intermediate thoughts. This lets you follow the agent's logic.

In[6]:
Code
def reason_through_problem(problem):
    logger.info(f"Starting reasoning for problem: {problem}")
    # Agent generates reasoning steps
    steps = generate_reasoning_steps(problem)
    for i, step in enumerate(steps):
        logger.info(f"Reasoning step {i + 1}: {step}")
    return steps

Memory Operations: Log when the agent retrieves information from memory or stores something new. This helps you verify the agent is using its memory correctly.

In[7]:
Code
def retrieve_from_memory(query):
    logger.info(f"Searching memory for: {query}")
    results = memory_search(query)
    logger.info(f"Found {len(results)} relevant items in memory")
    return results

Final Response: Log the agent's final answer to the user. Combined with the initial query log, this gives you the complete input-output pair.

In[8]:
Code
def send_response(response):
    logger.info(f"Sending response to user: {response}")
    return response