Skip to Content

What does the gen_ai.tool.call.id attribute mean in Rius?

In Rius, gen_ai.tool.call.id holds the id of the model’s tool call that a tool execution span answers. It belongs on execute_tool spans, and Rius stores it with the span under that key. If you send Laminar spans, Rius fills it from Laminar’s own tool call id key.

How it works

When a model decides to call a tool, the provider gives that call an id. The span that runs the tool carries the same id in gen_ai.tool.call.id, so you can tell which model request the execution answers.

  • Which spans carry it: execute_tool spans, the span for each tool run. Tools called over MCP are execute_tool spans like any other, so the same attribute applies. Model-call spans do not carry it as an attribute. The ids of the calls the model made sit inside their message content instead (see the example below).
  • What it holds: a string, the id of the model’s tool call. The OpenTelemetry GenAI conventions define it, at Development stability, as the tool call identifier supplied by the model or provider, and ask you to set it only when one was supplied. Its registry entry links to the upstream definition. It is not the tool’s name. The tool’s own name goes in gen_ai.tool.name, and gen_ai.tool.type holds function, extension, datastore and similar values.
  • How Rius stores it: as sent, under gen_ai.tool.call.id. Search and filter on that key in trace inspection.
  • Older names: the key is current and not deprecated. The one other spelling Rius reads is Laminar’s lmnr.association.properties.metadata.tool_call_id. At ingest Rius moves it onto gen_ai.tool.call.id and removes the Laminar key. A gen_ai.tool.call.id you send yourself always wins, because normalization fills gaps and never overwrites. After ingest, filter on gen_ai.tool.call.id, because a filter on the Laminar key matches nothing.

Two neighbouring tool keys behave differently, gen_ai.tool.call.arguments and gen_ai.tool.call.result. Rius moves those to input.value and output.value, so a tool’s input and output render like any other span’s. The call id is not moved. The span attribute reference lists all of them.

Set it up

  1. Create one execute_tool span for each tool run. Name it the way the GenAI conventions ask, the operation followed by what it acted on, such as execute_tool calculator.
  2. Set the tool attributes on that span. Copy the call id from the model’s tool call, the same id the provider returned. Do not make one up: if the provider gave no id, leave the key off. Replace the values below with your own tool’s:
gen_ai.operation.name: execute_tool gen_ai.tool.name: calculator gen_ai.tool.type: function gen_ai.tool.call.id: call_1
  1. Keep the id consistent with the message content if you also send it. In the GenAI message shape, the assistant message holds a tool_call part with an id, and the tool message holds a tool_call_response part with the same id:
[ {"role": "user", "parts": [{"type": "text", "content": "What is 2+2?"}]}, { "role": "assistant", "parts": [ {"type": "tool_call", "id": "call_1", "name": "calculator", "arguments": "{\"expr\": \"2+2\"}"} ] }, { "role": "tool", "parts": [{"type": "tool_call_response", "id": "call_1", "response": "4"}] } ]
  1. Send the spans to Rius over OTLP/HTTP. Trace LLM calls with OpenTelemetry covers the exporter setup for each sender.

If your spans come from Laminar, you do not need to rename anything. Rius reads the tool call id from Laminar’s key and stores it under gen_ai.tool.call.id.

What you get

  • Each tool execution span records which model tool call it answers, under one stable key you can search and filter on.
  • Tool spans from Laminar and from native GenAI instrumentation end up under the same key, so mixed fleets read alike.
  • The tool’s name, type, input and output sit beside the call id on the same span, so a tool run reads as one unit in trace inspection.
  • No extra setup for MCP tools. They are execute_tool spans and take the same attribute.

When something else fits

  • If you only need to know which tool ran, gen_ai.tool.name is the key to use. The call id adds the link to the model’s request, not the tool’s identity.
  • If you need to group traces by conversation or by end user, set session.id and user.id instead. The span attribute reference explains both.
  • If a span is not a tool execution, such as a model call or a retrieval, leave the call id off and use the attributes listed for that span type.

Still stuck? Get help

Last updated on