Skip to Content

How do I trace AutoGen in Python?

Rius traces AutoGen in Python with one install command, one rius.init() call and one observe wrapper on your entrypoint. AutoGen’s own spans give you the agent and tool structure, and the openai integration adds each model call with its model, tokens and cost. Run one request and the full run appears as a single trace in the console.

How it works

AutoGen (AgentChat) combines two ways of getting data into Rius:

  • 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.
  • Model calls. AutoGen sends them through the OpenAI client from autogen-ext[openai], so the openai integration records each one as a generation with model, tokens and cost. Cost is a list-price estimate in US dollars.

With a default init(), every installed integration turns on automatically, so you do not enable anything by hand. The one thing you add is an observe wrapper on your entrypoint. It groups agent creation and invocation into a single trace per unit of work and becomes the root span.

The AutoGen integration is available in Python only. The Integrations page lists which frameworks are covered in each language, and the AutoGen integration page covers this setup in full.

Set it up

  1. Install the SDK with the openai extra, plus AutoGen and its OpenAI extension. The extra installs only the instrumentation, so the AutoGen packages come from you:

    pip install "glassflow-rius[openai]" "autogen-agentchat" "autogen-ext[openai]"
  2. Call rius.init() once, as early as possible, then wrap your entrypoint with observe and the AGENT kind. In this example, lookup stands for your own function that fetches the account:

    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)

    Set service_name explicitly. It is how you find your agent in trace filters and cost breakdowns. The other init() arguments and their environment variables are in Installation and configuration.

  3. Leave your tool functions unwrapped. AutoGen runs tools in a detached context, so an observe wrapper on a tool cannot find the run and splits off as its own single-span trace. The framework’s execute_tool spans already cover every tool.

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

  5. Call handle_ticket once with a request that triggers the tool, then open the trace in the console.

What you get

One run that calls a tool produces a trace shaped like this:

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

Here is where each piece comes from:

In AutoGenIn the trace
Your entrypointThe root AGENT span from your observe wrapper
Agent constructionA create_agent span named after the agent
An agent runAn invoke_agent span named after the agent
A model callA ChatCompletion generation with model, tokens and cost
A tool callAn execute_tool span named after the tool

A correct setup shows the root span, the invoke_agent and execute_tool spans, and the ChatCompletion generation with model, tokens and cost.

Three behaviours are normal, checked against autogen-agentchat 0.7.5:

  • Framework spans arrive with an unset status rather than OK on success, and the trace status still reads Ok.
  • Model-call spans share the generic name ChatCompletion.
  • Tool wrappers split traces, which is why you leave tools unwrapped.

When something else fits

  • If your agents run on a different framework, such as the OpenAI Agents SDK, CrewAI or Pydantic AI, use that framework’s page from the Integrations list instead.
  • If you work in TypeScript, there is no AutoGen integration today. Trace those calls with manual generations.

Still stuck? Get help

Last updated on