> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inference.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Attributes And Span Kinds

> Reference for the OpenInference attribute constants and span-kind enum exported by the Catalyst tracing SDKs.

Both Catalyst tracing SDKs export the OpenInference attribute keys and span
kinds they emit. Use them when you author manual spans, when you need to
filter on a specific attribute from the CLI, or when you want to understand
what each span in the trace tree should carry.

`Attr` is not a whitelist. A span is an ordinary OpenTelemetry span, so you can
set any key you like with `setAttribute` (see
[custom attributes](/integrations/traces/manual-spans#adding-custom-attributes)).
The keys below are the ones the dashboard *understands*: set `Attr.MODEL_NAME`
(`llm.model_name`) and it shows the model and computes cost; set
`Attr.SESSION_ID` (`session.id`) and it groups the conversation. `Attr` just
spares you from typing, and mistyping, the wire keys by hand.

The wire-format values are byte-identical to the upstream
[OpenInference](https://github.com/Arize-ai/openinference) semantic conventions,
so OpenInference-aware viewers render Catalyst spans without configuration.

<CodeGroup>
  <Metadata text="integrations/traces/attributes-import" />

  ```typescript TypeScript theme={"system"}
  import { Attr, SpanKindValues } from "@inference/tracing";
  ```

  <Metadata text="integrations/traces/attributes-import" />

  ```python Python theme={"system"}
  from inference_catalyst_tracing import Attr, SpanKindValues
  ```
</CodeGroup>

## Span Kinds

`SpanKindValues` is the canonical set of values for the
`openinference.span.kind` attribute. Pick the kind that best describes the
work the span wraps.

| Kind        | Constant                   | Use For                                                                      | Required Attributes       | Common Optional Attributes                                                                                                      |
| ----------- | -------------------------- | ---------------------------------------------------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `AGENT`     | `SpanKindValues.AGENT`     | The outer span around an agent run                                           | `SPAN_KIND`, `AGENT_ID`   | `AGENT_NAME`, `AGENT_ROLE`, `SESSION_ID`, `USER_ID`, `SYSTEM`, `INPUT_VALUE`, `OUTPUT_VALUE`, `MODEL_NAME`, token counts        |
| `LLM`       | `SpanKindValues.LLM`       | One LLM call (chat, completion, embedding-as-LLM)                            | `SPAN_KIND`, `MODEL_NAME` | `SYSTEM`, `LLM_SYSTEM`, `LLM_PROVIDER`, `INVOCATION_PARAMETERS`, `STREAMING`, `FINISH_REASON`, message attributes, token counts |
| `TOOL`      | `SpanKindValues.TOOL`      | A tool invocation by an agent                                                | `SPAN_KIND`, `TOOL_NAME`  | `TOOL_CALL_ID`, `INPUT_VALUE`, `OUTPUT_VALUE`, `INPUT_MIME_TYPE`, `OUTPUT_MIME_TYPE`                                            |
| `CHAIN`     | `SpanKindValues.CHAIN`     | A chain step that is not itself an LLM call (router, postprocessor, planner) | `SPAN_KIND`               | `INPUT_VALUE`, `OUTPUT_VALUE`, free-form attributes                                                                             |
| `RETRIEVER` | `SpanKindValues.RETRIEVER` | A vector-search or document-lookup call                                      | `SPAN_KIND`               | `INPUT_VALUE` (the query), `OUTPUT_VALUE` (the results)                                                                         |
| `EMBEDDING` | `SpanKindValues.EMBEDDING` | An embedding-model call your code makes directly                             | `SPAN_KIND`, `MODEL_NAME` | `INPUT_VALUE`, token counts                                                                                                     |

The patched provider SDKs emit `LLM`-kind spans automatically with all required
and most optional attributes filled in. You only need to author `LLM` spans
manually if you are wrapping an SDK Catalyst does not patch.

## Attribute Constants

All attributes are exported on the `Attr` object. The constant name is the
left-hand column; the wire-format key in the right-hand column is what
actually goes on the span.

### Span Identity

| Constant          | Wire key                  | On                                          |
| ----------------- | ------------------------- | ------------------------------------------- |
| `Attr.SPAN_KIND`  | `openinference.span.kind` | Every span                                  |
| `Attr.SESSION_ID` | `session.id`              | Any span, used for conversation grouping    |
| `Attr.USER_ID`    | `user.id`                 | Any span, used for filtering traces by user |

### Agent Identity

Set on `AGENT` spans, copied onto child `LLM`/`TOOL` spans by the per-SDK
patchers and by `agentSpan()` / `agent_span()` when the child is created in
the active context.

| Constant          | Wire key     | Purpose                                                   |
| ----------------- | ------------ | --------------------------------------------------------- |
| `Attr.AGENT_ID`   | `agent.id`   | Stable identifier for grouping in the Agents dashboard    |
| `Attr.AGENT_NAME` | `agent.name` | Human-readable label                                      |
| `Attr.AGENT_ROLE` | `agent.role` | Role in a multi-agent workflow (e.g. `triage`, `refunds`) |

### Inputs And Outputs

| Constant                | Wire key           | Notes                                             |
| ----------------------- | ------------------ | ------------------------------------------------- |
| `Attr.INPUT_VALUE`      | `input.value`      | Stringified input. JSON-encode structured values. |
| `Attr.OUTPUT_VALUE`     | `output.value`     | Stringified output.                               |
| `Attr.INPUT_MIME_TYPE`  | `input.mime_type`  | Typically `"application/json"` or `"text/plain"`. |
| `Attr.OUTPUT_MIME_TYPE` | `output.mime_type` | Same.                                             |

### Model And Provider

Set on `LLM` and `EMBEDDING` spans. Also useful on `AGENT` spans to declare the
provider the agent runs on.

| Constant                     | Wire key                    | Notes                                                            |
| ---------------------------- | --------------------------- | ---------------------------------------------------------------- |
| `Attr.MODEL_NAME`            | `llm.model_name`            | Prefer the model the API echoed back.                            |
| `Attr.SYSTEM`                | `gen_ai.system`             | Provider identifier on AGENT spans (`"openai"`, `"anthropic"`).  |
| `Attr.LLM_SYSTEM`            | `llm.system`                | Provider identifier on LLM spans.                                |
| `Attr.LLM_PROVIDER`          | `llm.provider`              | Alternate provider identifier on LLM spans.                      |
| `Attr.INVOCATION_PARAMETERS` | `llm.invocation_parameters` | JSON of the request parameters (temperature, max\_tokens, etc.). |
| `Attr.STREAMING`             | `llm.streaming`             | Boolean. Did the call stream.                                    |
| `Attr.FINISH_REASON`         | `llm.finish_reason`         | Provider finish reason.                                          |

### Token Usage

| Constant                                | Wire key                                       |
| --------------------------------------- | ---------------------------------------------- |
| `Attr.TOKEN_COUNT_PROMPT`               | `llm.token_count.prompt`                       |
| `Attr.TOKEN_COUNT_COMPLETION`           | `llm.token_count.completion`                   |
| `Attr.TOKEN_COUNT_TOTAL`                | `llm.token_count.total`                        |
| `Attr.TOKEN_COUNT_PROMPT_CACHE_WRITE`   | `llm.token_count.prompt_details.cache_write`   |
| `Attr.TOKEN_COUNT_PROMPT_CACHE_READ`    | `llm.token_count.prompt_details.cache_read`    |
| `Attr.TOKEN_COUNT_COMPLETION_REASONING` | `llm.token_count.completion_details.reasoning` |

The per-SDK patchers fill these in automatically when the provider returns
usage. For manual spans, use the helpers on the
[span handle](/integrations/traces/handle-api):

* TypeScript: `span.recordTokens({ prompt, completion, total })` to pass the
  counts directly.
* Python: `span.record_tokens(prompt=..., completion=..., total=...)` for
  manual counts, or `span.record_usage(response.usage)` to let the SDK
  normalize an OpenAI- or Anthropic-shaped usage object (including cache
  fields).

### Tools

Set on `TOOL` spans. Also set on `LLM` spans by the provider patchers when the
LLM emits a `tool_use` block, so the dashboard can show the tool the model
asked for.

| Constant                     | Wire key                |
| ---------------------------- | ----------------------- |
| `Attr.TOOL_NAME`             | `tool.name`             |
| `Attr.TOOL_CALL_ID`          | `tool_call.id`          |
| `Attr.AGENT_TOOL_CALL_COUNT` | `agent.tool_call_count` |
| `Attr.AGENT_LLM_CALL_COUNT`  | `agent.llm_call_count`  |

### Messages

`LLM` spans emit per-message attributes for each input and output message. The
keys are indexed and machine-generated. Use the `OpenInferenceAttribute`
helper to compose them rather than hand-rolling the strings.

<Metadata text="integrations/traces/attributes-messages-ts" />

```typescript TypeScript theme={"system"}
import { OpenInferenceAttribute } from "@inference/tracing";

const prefix = OpenInferenceAttribute.inputMessagePrefix(0);
span.setAttribute(OpenInferenceAttribute.role(prefix), "user");
span.setAttribute(OpenInferenceAttribute.content(prefix), "Hello");
```

The wire keys take the form `llm.input_messages.0.message.role`,
`llm.input_messages.0.message.content`, `llm.output_messages.0.message.role`,
and so on. For tool-call messages, the helper also generates
`...tool_calls.0.tool_call.function.name`,
`...tool_calls.0.tool_call.function.arguments`, and
`...tool_calls.0.tool_call.id`.

You rarely need to author these by hand; the per-SDK patchers emit them.
This block is here so the keys are searchable when you are debugging captured
output.

## Using Attributes From The CLI

The same attribute keys are filterable from `inf trace` and `inf span`:

<Metadata text="integrations/traces/attributes-cli" />

```bash theme={"system"}
# Find all TOOL spans for one tool name
inf span list --kind TOOL --metadata "tool.name=lookup_order"

# Find traces from one conversation
inf trace list --metadata "session.id=conversation-ticket-123"

# Find all traces for one user
inf trace list --metadata "user.id=user_8675309"

# Find expensive LLM spans, sorted by cost
inf span list --kind LLM --filter "cost_total>0.05" --sort cost_total --order desc
```

See [`inf span`](/cli/spans) and [`inf trace`](/cli/traces) for the full
filter syntax.

## Next Steps

<CardGroup cols={2}>
  <Card title="Handle API reference" icon="book" href="/integrations/traces/handle-api">
    The typed methods on `agentSpan` / `manual_span` handles that write these attributes for you.
  </Card>

  <Card title="Manual spans" icon="pen-nib" href="/integrations/traces/manual-spans">
    Author TOOL, CHAIN, and RETRIEVER spans inside your agent loop.
  </Card>

  <Card title="Agent identity" icon="fingerprint" href="/integrations/traces/agent-identity">
    Pick stable `agent.id` and `session.id` values for the Agents dashboard.
  </Card>

  <Card title="CLI span reference" icon="terminal" href="/cli/spans">
    Filter, search, and inspect spans by attribute from the terminal.
  </Card>
</CardGroup>
