Skip to Content

What does the gen_ai.system_instructions attribute mean in Rius?

In Rius, gen_ai.system_instructions holds the system prompt a model call was given separately from its chat history, as a JSON array of text parts. It belongs on the span for each model call, and Rius counts it as the system prompt when it breaks down a call’s context. Rius reads no older names into it. It is a content attribute, so it is stored for trace inspection and covered by the SDK’s privacy controls.

How it works

  • What it holds. The OpenTelemetry GenAI conventions define it as “the system message or instructions provided to the GenAI model separately from the chat history”, type any, at Development stability and opt-in. Instructions that are part of the chat history belong in gen_ai.input.messages instead. Its registry entry links the definition. The value is a JSON array in which each part has a type of text and a content string.
  • Which spans carry it. The span for each model call (LLM spans). Tool, agent and retrieval spans do not use it.
  • What Rius does with it. Rius counts it as the system prompt in context attribution, which divides a call’s input tokens across the parts of its context. The SDKs send rius.context.sizes from their generation API, a compact record of the byte size of each tool definition and each message part. When that record is absent, as on spans from auto-instrumentation such as the OpenAI or LangChain integrations, Rius estimates the same breakdown from the captured messages, gen_ai.system_instructions and the tool definitions.
  • What it does not do. It does not set cost. Rius computes cost on its own from gen_ai.request.model and the gen_ai.usage.* token counts, and you never send a cost attribute.
  • Older names. Rius reads no older spelling into this key. When an OpenInference producer sends Anthropic’s system parameter, Rius turns it into the leading system message, so it appears in the messages, not in this key.
  • How it is stored. It is kept under the key you send, so search and filter on gen_ai.system_instructions in trace inspection.

Set it up

  1. Emit your spans to Rius with an OpenTelemetry SDK or the Rius SDK. The attribute reference gives the ingest contract, and Trace LLM calls with OpenTelemetry covers the setup for each sender.
  2. On the span for each model call, set gen_ai.request.model and the gen_ai.usage.* token counts, so the call gets a cost.
  3. Set gen_ai.system_instructions to a JSON array of text parts. Use this shape and change only the content:
[ {"type": "text", "content": "You are a support agent for Acme. Answer in two sentences."} ]
  1. Keep the rest of the conversation in gen_ai.input.messages and gen_ai.output.messages, in the GenAI message shape with a role and parts for each message. Rius renders those on the span’s Input / Output tab.
  2. If you export without the Rius SDKs and your agent loops through many turns, raise the OpenTelemetry attribute limit so the span keeps its model, usage and content:
export OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT=4096
  1. Content capture is on by default in the Rius SDKs, so the key is sent as is. To keep prompts out of Rius, turn it off. Content attributes such as this one are covered by the SDK’s privacy controls, and setting RIUS_CAPTURE_CONTENT to false strips this key at export while the rest of the span still flows.

What you get

  • The system prompt is stored with the span, so you can inspect what the model was told for a given call.
  • Context attribution counts the system prompt as its own part of the call’s context, so you can see how much of the input it takes.
  • When your spans carry no rius.context.sizes, the estimate of the context breakdown uses this key, which is why it is worth setting on spans you emit yourself.
  • Cost, token totals and time to first token are unaffected by this key. They come from the model name and token counts. Turning off content capture does not change them either.
  • A filter on gen_ai.system_instructions matches the key as you sent it, because Rius stores it under that name.

When something else fits

  • If your provider takes the system prompt as an ordinary message in the chat history, put it in gen_ai.input.messages with the system role. Use gen_ai.system_instructions only for a system prompt sent separately.
  • If you do not want prompts stored in Rius, turn content capture off. Cost and token analytics still work, and the call’s context breakdown relies on rius.context.sizes from the SDKs because it holds no content.

Still stuck? Get help

Last updated on