Skip to main content
Atomic Agents is a lightweight, modular Python framework for building agentic AI applications from small, single-purpose components. Every agent is a typed function: a Pydantic input schema in, a Pydantic output schema out, with the LLM call handled by Instructor. Atomic Agents ships its own OpenInference instrumentor, 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

Launch Arize AX

  1. Sign in to your Arize AX account.
  2. From Space Settings, copy your Space ID and API Key. You will set them as ARIZE_SPACE_ID and ARIZE_API_KEY below.

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

  1. Open your Arize AX space and select project atomic-agents-tracing-example.
  2. 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.
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, carrying agent.name, the input and output schemas as JSON, and atomic_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 plus atomic_agents.stream.closed_early when 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
Wrap calls in 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_ID and ARIZE_API_KEY are set in the same shell that runs example.py. Enable OpenTelemetry debug logs with export OTEL_LOG_LEVEL=debug and re-run.
  • ModuleNotFoundError on atomic_agents.observability. Install the extra: pip install "atomic-agents[observability]".
  • Every LLM call appears twice. Both a provider instrumentor and openinference-instrumentation-instructor are 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.
  • 400 from OpenAI mentioning reasoning_effort. gpt-6-luna accepts function tools on Chat Completions only with reasoning_effort set to "none". Keep model_api_parameters={"reasoning_effort": "none"} in AgentConfig, or swap in a model your key can call.

Resources

Atomic Agents observability guide

Atomic Agents GitHub

OpenInference OpenAI Instrumentor