How does Rius read OpenInference agent name attributes?
Rius reads an OpenInference agent through openinference.span.kind set to AGENT, and takes the agent’s name from gen_ai.agent.name and the resource agent attributes. Rius classifies the span as an agent step and files it under the agent name it finds. You can send OpenInference spans straight to the ingest endpoint, with or without the Rius SDK.
How it works
Rius combines the OpenInference span kind with the OpenTelemetry GenAI agent attributes.
- Span kind.
openinference.span.kindwith the valueAGENTclassifies the span as an agent span in trace views and per-kind analytics. Set it, or setgen_ai.operation.nametoinvoke_agent, and Rius derives the other one. - Agent name on the span.
gen_ai.agent.nameon aninvoke_agentspan is the agent being invoked. On anexecute_toolspan it is the agent executing the tool. - Agent name for the process. Rius files a span under the first of these that is set and is not a placeholder such as
unknown_service: the resource’sgen_ai.main_agent.name, the resource’srius.main_agent.name, the resource’sgen_ai.agent.name, the span’sgen_ai.agent.name, andservice.name. - Normalization at ingest. The OpenInference attributes Rius moves onto
gen_ai.*keys are the LLM detail ones:llm.model_name,llm.provider,llm.token_count.*,llm.invocation_parameters,llm.tools.*and the flattenedllm.input_messages.*andllm.output_messages.*. The agent name is not one of them, so send it asgen_ai.agent.nameor as a resource attribute. Nativegen_ai.*keys always win, and normalization only fills gaps. - Span names. Rius does not require it, but the convention is the operation followed by what it acted on, such as
invoke_agent planner, which keeps mixed fleets readable.
The full contract is in the span attribute reference, and the overview of every sender path is in Interoperability.
Set it up
- Wire your OpenInference instrumentor to the Rius ingest endpoint. This is the only setup this question needs, and the OpenInference page covers it in full.
from opentelemetry.sdk.trace import SpanLimits, TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from openinference.instrumentation.openai import OpenAIInstrumentor
# Raise the attribute limit: see step 4 below.
provider = TracerProvider(span_limits=SpanLimits(max_span_attributes=4096))
provider.add_span_processor(
BatchSpanProcessor(
OTLPSpanExporter(
endpoint="https://ingest.eu.console.rius-glassflow.com/v1/traces",
headers={"Authorization": "Bearer <your API key>"},
)
)
)
OpenAIInstrumentor().instrument(tracer_provider=provider)- Name the agent on the resource. Set
gen_ai.main_agent.nameas a resource attribute. If you send nothing else, setservice.name, which Rius uses when no agent attribute is present. - Mark each agent step. The OpenAI instrumentor only emits model call spans, so start the agent span yourself around the agent’s work. Give it
openinference.span.kindofAGENT, setgen_ai.agent.nameto the agent’s name, and name it in the forminvoke_agent planner:
tracer = provider.get_tracer(__name__)
with tracer.start_as_current_span(
"invoke_agent planner",
attributes={"openinference.span.kind": "AGENT", "gen_ai.agent.name": "planner"},
):
run_planner(task) # your agent's own code- Keep the agent attributes from being dropped. OpenInference writes one attribute per message and tool field, and OpenTelemetry keeps only 128 attributes per span by default, dropping the rest without an error. Raise the limit through the environment for any language:
export OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT=4096- Run the agent and open the trace in the console to confirm the span kind and the agent name.
What you get
- Spans with
openinference.span.kindofAGENTare classified as agent spans in trace views and per-kind analytics, and their operation is derived asinvoke_agent. - Each span is filed under the first agent name Rius finds in the order above, so the agent you named is the one you see in the console.
- Agent steps sit in the same trace as the LLM calls under them. Those calls are normalized from the
llm.*attributes, so they get model analytics, token usage and server-side cost like native spans. Cost is a list-price estimate in US dollars. - Tool spans that carry
gen_ai.agent.nameshow which agent executed the tool. - Search and filter on the stored
gen_ai.*keys, such asgen_ai.usage.input_tokens, not on the OpenInference source keys.
For a comparison of every way to send traces, see Trace LLM calls with OpenTelemetry.
When something else fits
- If your app is Python, the Rius SDK ships the same OpenInference instrumentors as integrations and sets the exporter, the attribute limit and privacy controls for you.
- If you want control over agent names directly, send the GenAI attributes from a vanilla OpenTelemetry SDK or an OpenTelemetry Collector instead of relying on OpenInference.
Related
Last updated on