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 (version 2.11.0 and later). 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.

Install

Install exactly one LLM instrumentor for the provider SDK your Instructor client wraps (openinference-instrumentation-openai, openinference-instrumentation-anthropic, openinference-instrumentation-litellm, …). Installing both a provider instrumentor and openinference-instrumentation-instructor produces two layers of LLM spans.

Setup

Set your API keys as environment variables:
Register Phoenix with auto-instrumentation. The Atomic Agents instrumentor is discovered through the openinference_instrumentor entry point, so no extra code is needed:
To activate the instrumentor by hand (for example with your own TracerProvider), use AtomicAgentsInstrumentor().instrument(tracer_provider=tracer_provider) from atomic_agents.observability. It accepts an OpenInference TraceConfig 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 is a root span on its own, so wrap a unit of work in a parent span to see one trace per turn:

Observe

The trace in Phoenix looks like this:
Agent spans carry agent.name (Class[InputSchema, OutputSchema]), 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. Tool spans carry tool.name, tool.description, tool.parameters (the input JSON schema) and the tool’s input and output. Streaming runs (run_stream, run_async_stream) record the final response, or the last partial plus atomic_agents.stream.closed_early when the consumer stops early. 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.

Resources