Skip to main content
A span kind is the category of operation a span represents. OpenTelemetry has its own span kinds for network calls (SERVER, CLIENT, PRODUCER, …). OpenInference adds an AI-specific set: LLM, Tool, Agent, Chain, Retriever, and more. Span kind is what drives the span-kind icons in the Phoenix UI. It’s also how Phoenix knows which attributes to expect — an LLM span gets a different visual treatment from a tool span.

Setting the Span Kind

Span kind is set via the openinference.span.kind attribute. The value is ALL CAPS"TOOL", not "Tool". Casing matters: the canonical OpenInference Python enum is OpenInferenceSpanKindValues.TOOL = "TOOL".
Phoenix UI behavior: span-kind icons in Phoenix trace tree come directly from the openinference.span.kind attribute. A span without that attribute renders with a blank icon. Auto-instrumentors set this for you — set it explicitly on every manual span.

The Eleven Span Kinds

OpenInference defines eleven span-kind values. The first four (LLM, Chain, Agent, Tool) are the ones you’ll encounter most often:

Common Attributes Across All Kinds

These attributes apply to every span kind. Auto-instrumentors set them automatically; set them yourself on every manual span:
Phoenix UI behavior: Phoenix reads the trace-level input and output from the root span’s input.value and output.value. If your root span doesn’t set them, the trace list view shows those columns as blank even if child spans have data.

Per-Kind Attributes

The four most-used kinds have a richer attribute set. The full list lives in the OpenInference semantic conventions — the tables below are a summary.

LLM

A call to a large language model.

TOOL

A call to an external tool, API, or function on behalf of an LLM.
Tool calls are one of the clearest cases where you must instrument manually when making an LLM calls directly, instead of via a framework. When you call OpenAI directly, the auto-instrumentor traces the model’s request for a tool call — but the actual execution of the tool function happens in your Python code, where the instrumentor can’t see it. Wrap the function in a tool span yourself.

AGENT

A span that encompasses calls to LLMs and tools — typically the top-level wrapper for an agent loop.

CHAIN

A starting point or a link between different application steps. Use a chain span to group pre/post-processing logic that doesn’t fit any of the more specific kinds. Chain spans use only the common attributes — input.value, output.value, metadata, session.id, etc.

Other Kinds

The remaining seven span kinds — RETRIEVER, EMBEDDING, RERANKER, GUARDRAIL, EVALUATOR, PROMPT, UNKNOWN — each have their own attribute schemas. Consult the canonical source for the full per-kind attribute list.

Multimodal Message Content

Inputs and outputs in modern AI applications aren’t always plain text. OpenInference defines a message_content attribute family for multimodal content: For audio specifically, OpenInference exposes a separate set of attributes — audio.url, audio.mime_type, audio.transcript — see the canonical source.

How a Trace Tree Uses Span Kinds

A typical agent trace nests span kinds inside each other:
Each level has its own kind, its own attributes, and its own rendering in the Phoenix UI. The combination is what makes agent behavior legible. Trace in Phoenix from the OpenAI Agents SDK example, showing agent, chain, tool, and LLM spans nested together

Next step

You know what attributes go on a span. Next, the three ways to actually emit spans — auto, manual, and hybrid:

Next: Instrumentation Approaches