OpenInference spans and traces
Agentic metrics evaluate OpenInference telemetry — not free-form prompt / output strings. This page shows the shapes Aegis expects so you can prepare payloads for metrics such as Tool Selection Correctness (tool_select).
Contents
Span vs trace
| Concept | Shape | Typical use |
|---|---|---|
| Span | One object (dictionary) for a single operation — usually an LLM call | Span-level metrics (e.g. tool_select) |
| Trace | Ordered list of spans that share a trace_id, linked by parent_id | Trace-level metrics (not yet documented) |
A real agent run is almost always a trace: a root AGENT wrapper, nested AGENT / LLM / TOOL (and sometimes CHAIN, RETRIEVER, …) children. Span-level metrics take one of those spans (typically an LLM span that advertised tools and emitted tool calls). Trace-level metrics take the full list.
Use an OpenInference-compatible exporter (OpenTelemetry + OpenInference semantic conventions). Aegis reads flattened attribute keys such as llm.input_messages.0.message.role, not only nested JSON blobs under input.value / output.value.
What Aegis reads
Identity and timing live on the span object; semantic payload lives under attributes.
Top-level / context
name— span display namecontext.span_id,context.trace_idparent_id— parent span id (nullfor the root)start_time,end_time— used for duration on trace-level metricsstatus.status_code— e.g.OK
Common attributes
openinference.span.kind— semantic kind:AGENT,LLM,TOOL, …llm.input_messages.{i}.message.role/.content— conversation for LLM spansllm.tools.{n}.tool.json_schema— advertised tool catalogue (OpenAI function-definition shape; string or object)llm.output_messages.{m}.message.tool_calls.{c}.tool_call.(id|function.name|function.arguments)— tools the model requestedllm.token_count.prompt/.completion/.total— token usage when present- For
TOOLspans:tool.name, optionaltool.call.id(orgen_ai.tool.call.id), plusinput.value/output.value
Example LLM span
Minimal shape sufficient for tool-selection evaluation. Real exporter spans include more fields (resource, events, full token/invocation metadata); those are fine to keep.
{
"name": "response",
"context": {
"trace_id": "0x3c25552ecfec75f0dfa5baad5a544c4c",
"span_id": "0x64e5562a83068b87"
},
"parent_id": "0x083b5fc1127d658a",
"start_time": "2026-07-08T11:07:57.729073Z",
"end_time": "2026-07-08T11:07:59.573356Z",
"status": { "status_code": "OK" },
"attributes": {
"openinference.span.kind": "LLM",
"llm.model_name": "gpt-4.1-2025-04-14",
"llm.token_count.prompt": 113,
"llm.token_count.completion": 59,
"llm.token_count.total": 172,
"llm.input_messages.0.message.role": "system",
"llm.input_messages.0.message.content": "You complete tasks by running shell commands with the Bash tool.",
"llm.input_messages.1.message.role": "user",
"llm.input_messages.1.message.content": "Use the Bash tool to run these two commands:\n1. `printf 'hello' | wc -c`\n2. `printf 'world' | wc -c`",
"llm.tools.0.tool.json_schema": {
"type": "function",
"function": {
"name": "bash",
"description": "Run a shell command.",
"parameters": {
"type": "object",
"properties": { "command": { "type": "string" } },
"required": ["command"]
}
}
},
"llm.output_messages.0.message.role": "assistant",
"llm.output_messages.0.message.tool_calls.0.tool_call.id": "call_wn595Y17jc1yKPnucs5jrjG7",
"llm.output_messages.0.message.tool_calls.0.tool_call.function.name": "bash",
"llm.output_messages.0.message.tool_calls.0.tool_call.function.arguments": {
"command": "printf 'hello' | wc -c"
},
"llm.output_messages.0.message.tool_calls.1.tool_call.id": "call_6tj5lKELXQ4wpWBaZ6HUaRMV",
"llm.output_messages.0.message.tool_calls.1.tool_call.function.name": "bash",
"llm.output_messages.0.message.tool_calls.1.tool_call.function.arguments": {
"command": "printf 'world' | wc -c"
}
}
}
Example TOOL span
Tool execution spans sit under the agent (or the LLM that invoked them). Trace-level metrics use them to join call ids, inputs, and results.
{
"name": "bash",
"context": {
"trace_id": "0x3c25552ecfec75f0dfa5baad5a544c4c",
"span_id": "0x6c9868e6283f0ed1"
},
"parent_id": "0x083b5fc1127d658a",
"start_time": "2026-07-08T11:07:59.574350Z",
"end_time": "2026-07-08T11:07:59.589819Z",
"status": { "status_code": "OK" },
"attributes": {
"openinference.span.kind": "TOOL",
"tool.name": "bash",
"tool.call.id": "call_wn595Y17jc1yKPnucs5jrjG7",
"input.value": { "command": "printf 'hello' | wc -c" },
"output.value": " 5\n"
}
}
Example trace
A trace is an array of spans in chronological (or exporter) order, sharing one trace_id. Hierarchy is expressed with parent_id. The sketch below mirrors a typical agent-with-tools run: root agent → child agent → LLM that requests tools → TOOL executions → follow-up LLM that returns the final text.
[
{
"name": "Agent workflow",
"context": {
"trace_id": "0x3c25552ecfec75f0dfa5baad5a544c4c",
"span_id": "0x145e3c64b3b99a77"
},
"parent_id": null,
"start_time": "2026-07-08T11:07:57.725353Z",
"end_time": "2026-07-08T11:08:00.333260Z",
"status": { "status_code": "OK" },
"attributes": { "openinference.span.kind": "AGENT" }
},
{
"name": "Bash Agent",
"context": {
"trace_id": "0x3c25552ecfec75f0dfa5baad5a544c4c",
"span_id": "0x083b5fc1127d658a"
},
"parent_id": "0x145e3c64b3b99a77",
"start_time": "2026-07-08T11:07:57.725590Z",
"end_time": "2026-07-08T11:08:00.332983Z",
"status": { "status_code": "OK" },
"attributes": { "openinference.span.kind": "AGENT" }
},
{
"name": "response",
"context": {
"trace_id": "0x3c25552ecfec75f0dfa5baad5a544c4c",
"span_id": "0x64e5562a83068b87"
},
"parent_id": "0x083b5fc1127d658a",
"start_time": "2026-07-08T11:07:57.729073Z",
"end_time": "2026-07-08T11:07:59.573356Z",
"status": { "status_code": "OK" },
"attributes": {
"openinference.span.kind": "LLM",
"llm.input_messages.0.message.role": "system",
"llm.input_messages.0.message.content": "You complete tasks by running shell commands with the Bash tool.",
"llm.input_messages.1.message.role": "user",
"llm.input_messages.1.message.content": "Run two bash commands and return both counts.",
"llm.tools.0.tool.json_schema": {
"type": "function",
"function": { "name": "bash", "parameters": { "type": "object" } }
},
"llm.output_messages.0.message.tool_calls.0.tool_call.id": "call_a",
"llm.output_messages.0.message.tool_calls.0.tool_call.function.name": "bash",
"llm.output_messages.0.message.tool_calls.1.tool_call.id": "call_b",
"llm.output_messages.0.message.tool_calls.1.tool_call.function.name": "bash",
"llm.token_count.total": 172
}
},
{
"name": "bash",
"context": {
"trace_id": "0x3c25552ecfec75f0dfa5baad5a544c4c",
"span_id": "0x6c9868e6283f0ed1"
},
"parent_id": "0x083b5fc1127d658a",
"start_time": "2026-07-08T11:07:59.574350Z",
"end_time": "2026-07-08T11:07:59.589819Z",
"status": { "status_code": "OK" },
"attributes": {
"openinference.span.kind": "TOOL",
"tool.name": "bash",
"tool.call.id": "call_a",
"input.value": { "command": "printf 'hello' | wc -c" },
"output.value": "5\n"
}
},
{
"name": "bash",
"context": {
"trace_id": "0x3c25552ecfec75f0dfa5baad5a544c4c",
"span_id": "0xaaaaaaaaaaaaaaaa"
},
"parent_id": "0x083b5fc1127d658a",
"start_time": "2026-07-08T11:07:59.590000Z",
"end_time": "2026-07-08T11:07:59.600000Z",
"status": { "status_code": "OK" },
"attributes": {
"openinference.span.kind": "TOOL",
"tool.name": "bash",
"tool.call.id": "call_b",
"input.value": { "command": "printf 'world' | wc -c" },
"output.value": "5\n"
}
},
{
"name": "response",
"context": {
"trace_id": "0x3c25552ecfec75f0dfa5baad5a544c4c",
"span_id": "0xbbbbbbbbbbbbbbbb"
},
"parent_id": "0x083b5fc1127d658a",
"start_time": "2026-07-08T11:07:59.610000Z",
"end_time": "2026-07-08T11:08:00.300000Z",
"status": { "status_code": "OK" },
"attributes": {
"openinference.span.kind": "LLM",
"llm.input_messages.0.message.role": "system",
"llm.input_messages.0.message.content": "You complete tasks by running shell commands with the Bash tool.",
"llm.input_messages.1.message.role": "user",
"llm.input_messages.1.message.content": "Run two bash commands and return both counts.",
"llm.output_messages.0.message.role": "assistant",
"llm.output_messages.0.message.contents.0.message_content.type": "text",
"llm.output_messages.0.message.contents.0.message_content.text": "5\n5",
"llm.token_count.total": 200
}
}
]
For a span-level metric, pass one LLM object from a list like this (not the whole array). For a trace-level metric, pass the entire array.