Skip to content

Trace a run

Every agent run can be recorded as OpenTelemetry spans: one for the run, one per graph node, per model call and per tool call, carrying the task id, step, tool name, tokens in and out, cost, resolution tier and verifier result. Off by default, and off builds nothing.

Terminal window
uv sync --extra tracing
IOS_AGENT_TRACING=otel uv run ios-agent "turn on bold text" # any OTLP backend
IOS_AGENT_TRACING=langsmith uv run ios-agent "turn on bold text" # needs LANGSMITH_API_KEY

otel reads the standard OTEL_EXPORTER_OTLP_* variables, so Phoenix, Langfuse or a collector is one endpoint away. To view traces locally with Phoenix:

Terminal window
uvx --from arize-phoenix phoenix serve # UI and OTLP on http://localhost:6006
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:6006 IOS_AGENT_TRACING=otel \
uv run ios-agent "turn on bold text"

Spans carry counts and names, never prompts, screens or replies, and every span is passed through the session’s redactor on its way out, so a value typed with ios_type_secret cannot reach a trace; a test plants one and reads the exported spans back. Measured over the 22 agent tasks, replayed with tracing off and on, it changed no token and added 0.06 ms per span. See docs/adr/0023, and uv run pytest tests/evals/agent --trace-agent otel to trace an eval run and record each trace id beside its result.