Agent Tracing and Observability: Debugging Every Decision
Master built-in tracing in the OpenAI Agents SDK to debug, visualize, and monitor agent workflows. Learn to create traces, spans, and custom processors for production observability.
Published on • September 6, 2026
AI Assistant

When an agent makes a decision, you need to understand why. The OpenAI Agents SDK includes built-in tracing that collects a comprehensive record of events during an agent run: LLM generations, tool calls, handoffs, guardrails, and custom events. Using the Traces dashboard, you can debug, visualize, and monitor your workflows during development and in production.
In this tutorial, you will learn how tracing works in the Agents SDK, how to create custom traces and spans, and how to configure tracing processors for production observability.
How Tracing Works
Tracing is enabled by default. Every Runner.run() call automatically creates a trace that captures the full execution flow.
Traces and Spans
- Traces represent a single end-to-end operation of a workflow, composed of nested Spans
- Spans represent operations with start and end times, containing specific data about what happened
A typical trace hierarchy:
trace("Agent workflow")
├── task_span()
│ ├── turn_span()
│ │ ├── agent_span()
│ │ ├── generation_span() # LLM call
│ │ ├── function_span() # Tool call
│ │ ├── guardrail_span() # Input/output validation
│ │ └── handoff_span() # Agent delegation
Default Tracing
The SDK automatically traces:
Runner.run()→ wrapped in atrace()- Each runner invocation →
task_span() - Each model turn →
turn_span() - Each agent execution →
agent_span() - LLM generations →
generation_span() - Function tool calls →
function_span() - Guardrails →
guardrail_span() - Handoffs →
handoff_span() - Audio transcription →
transcription_span() - Audio speech →
speech_span()
Custom Traces
For multi-step workflows, wrap the entire operation in a trace() context manager:
from agents import Agent, Runner, trace
async def main():
agent = Agent(name="Joke generator", instructions="Tell funny jokes.")
with trace("Joke workflow"):
first_result = await Runner.run(agent, "Tell me a joke")
second_result = await Runner.run(
agent, f"Rate this joke: {first_result.final_output}"
)
print(f"Joke: {first_result.final_output}")
print(f"Rating: {second_result.final_output}")
Both Runner.run calls become part of one overall trace, making it easy to follow the complete workflow.
Creating Custom Spans
Use custom_span() to track specific operations:
from agents import trace, custom_span
async def process_data(data):
with trace("Data processing"):
# Custom span for data validation
with custom_span("validate_data", {"input_size": len(data)}):
validated = validate(data)
# Custom span for transformation
with custom_span("transform", {"records": len(validated)}):
transformed = transform(validated)
# Custom span for storage
with custom_span("store", {"records": len(transformed)}):
await store(transformed)
Disabling Tracing
You can disable tracing at three levels:
# Globally via environment variable
import os
os.environ["OPENAI_AGENTS_DISABLE_TRACING"] = "1"
# Globally via code
from agents import set_tracing_disabled
set_tracing_disabled(True)
# Per-run via RunConfig
from agents import RunConfig, Runner
result = await Runner.run(
agent,
"Hello",
run_config=RunConfig(tracing_disabled=True),
)
Compact Trace Hierarchy
For a more compact hierarchy, disable automatic task and turn spans:
from agents import RunConfig, Runner
result = await Runner.run(
agent,
"Hello",
run_config=RunConfig(tracing={
"include_task_and_turn_spans": False
}),
)
Agent, generation, function, guardrail, handoff, and custom spans are still recorded.
Sensitive Data
The generation_span() captures LLM inputs/outputs, and function_span() captures tool call data. Disable sensitive data capture:
from agents import RunConfig
result = await Runner.run(
agent,
"Hello",
run_config=RunConfig(trace_include_sensitive_data=False),
)
Or via environment variable:
export OPENAI_AGENTS_TRACE_INCLUDE_SENSITIVE_DATA=false
Custom Tracing Processors
By default, the SDK exports traces to the OpenAI backend. For custom or additional destinations, use processors:
Adding a Processor
from agents import add_trace_processor
# Add a secondary processor (keeps OpenAI backend)
add_trace_processor(my_custom_processor)
Replacing Processors
from agents import set_trace_processors
# Replace the default processor entirely
set_trace_processors([my_custom_processor])
Ecosystem Integrations
The Agents SDK integrates with popular observability platforms:
| Platform | Integration |
|---|---|
| Weights & Biases | W&B Weave |
| Arize Phoenix | Phoenix |
| MLflow | MLflow Tracing |
| LangSmith | LangSmith |
| Langfuse | Langfuse |
| Datadog | Datadog LLM Observability |
| Pydantic Logfire | Logfire |
| Braintrust | Braintrust |
Long-Running Workers
The default BatchTraceProcessor exports traces in batches. For long-running workers like Celery or FastAPI background tasks, call flush_traces() for immediate delivery:
from agents import Runner, flush_traces, trace
@celery_app.task
def run_agent_task(prompt: str):
try:
with trace("celery_task"):
result = Runner.run_sync(agent, prompt)
return result.final_output
finally:
flush_traces()
Tracing with Non-OpenAI Models
When using non-OpenAI models, provide an OpenAI API key for the tracing exporter:
from agents import set_tracing_export_api_key, Agent
set_tracing_export_api_key("sk-your-key")
agent = Agent(
name="Assistant",
model=AnyLLMModel(
model="your-provider/your-model-name",
api_key="your-api-key",
),
)
Production Monitoring
With tracing enabled, monitor your agents in production:
- Error rates: Track failed tool calls and guardrail violations
- Latency: Identify slow LLM generations and tool executions
- Token usage: Monitor costs per workflow
- Handoff patterns: Understand agent delegation flows
- Tool selection: Verify agents pick the right tools
The Traces dashboard provides real-time visibility into every decision your agents make.
Next Steps
- Explore the Tracing API Reference for the complete tracing interface
- Read about Testing to understand how tracing integrates with agent evaluation
- Browse the ecosystem integrations for connecting to your observability stack
Tracing is the foundation of agent observability. By understanding every decision your agents make, you can debug issues faster, optimize costs, and build trust with your users.