Skip to Content

What does Rius record when my agent calls AutoGen?

Rius records the agent and tool structure that AutoGen (AgentChat) emits, plus each model call as a generation with model, tokens and cost. The spans for agent creation, agent runs and tool calls come from AutoGen’s own OpenTelemetry output. The model calls come from Rius’s OpenAI integration. The integration is Python only, and it has a few quirks you should know before you read your first trace.

How it works

AutoGen combines two ways of getting coverage, so Rius records two kinds of spans:

  • Framework spans. AutoGen emits create_agent, invoke_agent and execute_tool spans through the global tracer provider, which rius.init() installs. Agent and tool structure arrives without any wrappers.
  • Generations. Model calls go through the OpenAI client from autogen-ext[openai], so the OpenAI integration records each one with its model and token counts. Rius computes the cost from the model and the tokens. You never send a cost value, and the figure is a list-price estimate in US dollars.

One observe wrapper on your entrypoint groups agent creation and invocation into a single trace for each unit of work. Prompt and response content follows the SDK-wide RIUS_CAPTURE_CONTENT setting. Set it to false and content is stripped at export.

The full recipe is on the AutoGen integration page.

Set it up

  1. Install the SDK with the OpenAI extra, together with AutoGen:
pip install "glassflow-rius[openai]" "autogen-agentchat" "autogen-ext[openai]"
  1. Call rius.init() once, then wrap your entrypoint with observe as an AGENT span. Pass the tool as a plain function in the agent’s tools list:
import rius from autogen_agentchat.agents import AssistantAgent from autogen_ext.models.openai import OpenAIChatCompletionClient from rius import SpanKind rius.init(api_key="ri_...", service_name="my-agent") def account_status(email: str) -> str: """Fetch a customer's account standing by email.""" return lookup(email) @rius.observe(name="handle-ticket", kind=SpanKind.AGENT) async def handle_ticket(ticket: str) -> str: agent = AssistantAgent( name="support_agent", model_client=OpenAIChatCompletionClient(model="gpt-5-mini"), tools=[account_status], system_message="Answer support questions; check accounts with the tool.", ) result = await agent.run(task=ticket) return str(result.messages[-1].content)
  1. Do not wrap AutoGen tool functions with observe. AutoGen runs tools in a detached context, so the wrapper’s span cannot find the run and splits off as its own single-span trace. The framework’s execute_tool spans already cover tools.

  2. To group a conversation, scope each run with rius.session() and reuse your conversation id. One conversation is then one session.

  3. Run one request that calls a tool and open the trace in the console. You should see the root span, the invoke_agent and execute_tool spans, and the generation with model, tokens and cost.

What you get

A run that calls a tool looks like this, from a real trace of the example on autogen-agentchat 0.7.5:

handle-ticket AGENT 2.8s ├─ create_agent support_agent 0ms └─ invoke_agent support_agent 2.8s ├─ ChatCompletion LLM 2.6s └─ execute_tool account_status 0ms

Each part of the framework maps to a span:

  • Your entrypoint: the root AGENT span, from your observe wrapper.
  • Agent construction: a create_agent span named for the agent.
  • An agent run: an invoke_agent span named for the agent.
  • A model call: a ChatCompletion generation with model, tokens and cost.
  • A tool call: an execute_tool span named for the tool.

Known limits, verified against autogen-agentchat 0.7.5:

  • Tool wrappers split traces. Leave observe off AutoGen tool functions, as described above.
  • Framework span statuses arrive as unset. AutoGen’s spans are not marked OK on success, but the trace status still reads Ok.
  • Generation names are generic. Every model call is named ChatCompletion, so tell calls apart by their position in the tree.
  • Python only. There is no AutoGen integration for TypeScript today.

When something else fits

If your agent calls models through a client other than the OpenAI client, check the integrations list for the integration that covers that client. For an agent in TypeScript, the same list shows which frameworks have TypeScript support. You can trace those calls yourself with manual generations.

Still stuck? Get help

Last updated on