Trace the agent loop, do not log it
An agent run is a tree: model call, tool call, model call, retry, sub agent. Logs flatten it. A trace keeps it, with the messages that went into each model call as span attributes.
tracer.startActiveSpan("chat claude-sonnet-5", (span) => { ... });
tracer.startActiveSpan("execute_tool kb.read", (span) => { ... });The GenAI semantic conventions mean your existing backend renders it. The first trace you open for a bad run usually has the bug in it.
ai-agentsobservability
Longer version: the post this came from.