AtomicAgentsInstrumentor. It emits an agent span for every AtomicAgent run and a tool span for every BaseTool run, including tools generated from MCP servers. LLM spans come from the provider instrumentor you already use and nest under the agent span.
Prerequisites
- Python 3.10+
- An Arize AX account (sign up)
- An
OPENAI_API_KEYfrom the OpenAI Platform
Launch Arize AX
- Sign in to your Arize AX account.
- From Space Settings, copy your Space ID and API Key. You will set them as
ARIZE_SPACE_IDandARIZE_API_KEYbelow.
Install
The
observability extra installs the OpenInference dependencies the instrumentor needs. Install exactly one LLM instrumentor, for the provider SDK your Instructor client wraps (openinference-instrumentation-openai, openinference-instrumentation-anthropic, openinference-instrumentation-litellm, and so on). Adding openinference-instrumentation-instructor as well produces two layers of LLM spans for every call.Configure credentials
Setup tracing
AtomicAgentsInstrumentor().instrument() also accepts an OpenInference TraceConfig through config= for masking inputs and outputs.
Run Atomic Agents
Atomic Agents has no built-in tool-calling loop: your code calls an agent, then a tool, then another agent. Each call would otherwise be a root span of its own, so the example wraps the turn in a chain span to get one trace per question:Expected output
Verify in Arize AX
- Open your Arize AX space and select project
atomic-agents-tracing-example. - Open the newest trace. The chain span wraps both agent runs and the tool call, with each agent’s LLM call nested under it:
Check from the skill, CLI, or SDK
Confirm spans are actually reaching your Arize AX project. Use whichever fits your workflow — the skill and CLI work for any framework; the SDK check is shown for each language.- Arize skill (agent)
- AX CLI
- SDK
Install the Arize Skills plugin and let your coding agent check for you:Then prompt your agent:
Use the arize-trace skill to export and analyze recent traces from my project. Confirm spans are arriving, and summarize any errors or latency issues.
What Arize AX captures
- Agent spans named
AtomicAgent[InputSchema, OutputSchema].run, carryingagent.name, the input and output schemas as JSON, andatomic_agents.*attributes for the model, the Instructor mode, the schema names, the history size entering the turn, the registered context providers, and a hash of the static system prompt sections - Agent spans for sync, async, and streaming runs. Streaming runs (
run_stream,run_async_stream) record the final response, or the last partial response plusatomic_agents.stream.closed_earlywhen the consumer stops early - Tool spans carrying
tool.name,tool.description,tool.parameters(the input JSON schema), and the tool’s input and output - LLM spans from the provider instrumentor, with prompts, responses, and token counts, nested under the agent span that made the call
using_session, using_user, or using_metadata from openinference.instrumentation to group spans by conversation or user. To redact agent and tool payloads, set OPENINFERENCE_HIDE_INPUTS=true and OPENINFERENCE_HIDE_OUTPUTS=true.
Troubleshooting
- No traces in Arize AX. Confirm
ARIZE_SPACE_IDandARIZE_API_KEYare set in the same shell that runsexample.py. Enable OpenTelemetry debug logs withexport OTEL_LOG_LEVEL=debugand re-run. ModuleNotFoundErroronatomic_agents.observability. Install the extra:pip install "atomic-agents[observability]".- Every LLM call appears twice. Both a provider instrumentor and
openinference-instrumentation-instructorare active. Keep only the provider instrumentor. - Agent, tool, and LLM spans land in separate traces. Your code calls each component directly, so each call starts its own trace. Wrap the unit of work in a parent span, as in Run Atomic Agents.
400from OpenAI mentioningreasoning_effort.gpt-6-lunaaccepts function tools on Chat Completions only withreasoning_effortset to"none". Keepmodel_api_parameters={"reasoning_effort": "none"}inAgentConfig, or swap in a model your key can call.