Skip to Content

What does the openinference.span.kind attribute mean in Rius?

In Rius, the openinference.span.kind attribute sets a span’s kind, such as LLM, TOOL or AGENT, which Rius uses to classify the span in trace views and per-kind analytics. You can set it directly, or set gen_ai.operation.name and let Rius derive the kind from it. The value is stored on the span exactly as sent.

How it works

The attribute holds one of these values: AGENT, LLM, TOOL, RETRIEVER, EMBEDDING or CHAIN. The SDKs also emit RERANKER for reranking steps (Python 1.1.0, TypeScript 1.2.0). Any span can carry it.

Rius treats it as one half of a pair with gen_ai.operation.name. Set either one and Rius derives the other:

  • chat, text_completion and generate_content are LLM.
  • invoke_agent and create_agent are AGENT.
  • execute_tool is TOOL.
  • embeddings is EMBEDDING.
  • retrieval is RETRIEVER.
  • invoke_workflow and plan are CHAIN.

A CHAIN span gets no operation in return, because the OpenTelemetry GenAI conventions define none for a generic step. The Rius SDKs set both attributes on the spans they emit.

The kind also decides what counts as an LLM call in the console and in alerts. A span whose kind is LLM, set directly or derived from an operation, is an LLM call. A span with neither a kind nor an operation counts when it carries gen_ai.request.model. Agent, tool, retrieval and embedding spans are not LLM calls even when they carry a model, though their cost still appears in the per-model breakdown and the cost totals.

Rius has no reranker category yet. In trace views and kind filters, a reranking span shows as LLM when it carries gen_ai.request.model, and as Other when it does not.

The SDK also makes this visible in how you write code. A bare observe makes a CHAIN span named after the function. Passing kind=SpanKind.TOOL makes an execute_tool span named after the tool, AGENT makes an invoke_agent span named after the agent, and RETRIEVER makes a retrieval span.

Older and other names. Some producers use their own keys, and Rius turns them into the same kinds at ingest:

  • OpenLLMetry and Traceloop: the decorator kinds (workflow, task, agent, tool) in traceloop.span.kind and the provider span’s llm.request.type become the span taxonomy.
  • Laminar: lmnr.span.type becomes LLM or TOOL.
  • Vercel AI SDK (v5, v6): ai.operationId becomes the taxonomy.

Native keys always win, and normalization only fills gaps.

Set it up

  1. Decide the kind of each span. If you emit spans without the Rius SDK, set openinference.span.kind on every span you create: LLM for model calls, TOOL for tool executions, AGENT for agent runs, RETRIEVER for lookups, EMBEDDING for embedding calls and CHAIN for generic steps.
  2. Or set gen_ai.operation.name instead, for example chat, execute_tool or invoke_agent, and Rius derives the kind. Name spans the way the GenAI conventions ask, the operation followed by what it acted on, such as execute_tool get_weather.
  3. For a model call, also send gen_ai.request.model and the gen_ai.usage.* token counts. Rius computes cost from them. Never send a cost attribute.
  4. Send the spans to the OTLP/HTTP endpoint with your API key:
POST https://ingest.eu.console.rius-glassflow.com/v1/traces Authorization: Bearer <your API key> Content-Type: application/x-protobuf
  1. If you use the Rius SDK and trace a tool function yourself, give it the TOOL kind. A bare observe makes a CHAIN span, which the Tool kind filter and the Tool Loop alert never see.

The full list of attributes and the sender-specific setup are on Span attribute reference. For the wider picture of sending traces from OpenTelemetry, see Trace LLM calls with OpenTelemetry.

What you get

  • Each span is classified, so trace views and per-kind analytics group your model calls, tools, agents and retrievals correctly.
  • In the Spans tab, the All kinds menu filters by kind, for example to show only tool spans.
  • LLM calls are counted consistently in the console and in alerts.
  • Tool Loop counts only spans of kind TOOL, so setting the right kind makes tool spans visible to that alert.
  • The kind is stored as sent, so you can search and filter on openinference.span.kind itself.
  • Senders that use Traceloop, Laminar or Vercel AI SDK keys get a kind without setting this attribute.

When something else fits

  • If your spans already follow the OpenTelemetry GenAI conventions, set gen_ai.operation.name alone and let Rius derive the kind.
  • If you need a reranker category in kind filters, note that Rius shows reranking spans as LLM or Other for now.

Still stuck? Get help

Last updated on