Search⌘ K
AI Features

Debugging the Agent Transcript

Explore how to instrument and debug agent loops in Claude AI architecture by implementing structured logging at key iteration points. Learn to read detailed turn-level logs and message arrays to identify and fix issues in tool calls and stop reasons, improving your system's reliability and transparency.

The loop from the previous lessons works, but when it breaks, there is nothing to inspect. The messages array changes on every iteration, tool calls come and go, and errors surface only as wrong output or silent None returns. Without visibility into what happened between the first API call and the final answer, debugging is guesswork.

In this lesson, we instrument the loop with structured logging that prints state at each decision point. We then use that output to trace a failing run and identify the exact turn where it went wrong.

By the end of this lesson, we will have:

  • A logging helper that formats message-array turns in human-readable form

  • Turn-level log output for every API call, stop reason, tool call, and tool result

  • A failing transcript annotated to show where and why it breaks

  • A methodology for reading agent transcripts that applies to any loop

What to log and why

A loop produces four types of events worth capturing, each at a different moment in the iteration:

Event

When It Fires

What to Capture

API call

Before client.messages.create()

Turn count, message count, input token estimate

Stop reason

After the response arrives

stop_reason, response id, output token count

Tool dispatch

Before each tool function runs

Tool name, input arguments

Tool result

After each tool function returns

Tool name, result string (truncated if long)

These four points cover the full life cycle of one iteration. Any failure in the loop, wrong stop reason handling, missing tool result, ID mismatch, or truncation will be visible in at least one of these log lines.

The logging helper

Rather than scattering print() calls throughout the loop, we write one helper that formats any event as a consistent, scannable line:

import json
def log(event: str, **kwargs) -> None:
parts = [f"[{event}]"]
for key, value in kwargs.items():
if isinstance(value, (dict, list)):
parts.append(f"{key}={json.dumps(value, default=str)[:120]}")
else:
parts.append(f"{key}={value}")
print(" ".join(parts))
A minimal logging helper. It formats an event name and key-value pairs into a single scannable line, truncating long values to keep output readable.
  • Line 1: ...