AutoGen
Trace agents built with AutoGen
(AgentChat) with Rius: the framework emits its own OpenTelemetry spans for
agents and tools, and the openai integration adds the generations with
tokens and cost. This guide covers the Python framework; the runnable
example behind it lives in
agent-observability-examples .
How coverage works
AutoGen combines both coverage paths:
- Framework spans. AutoGen natively emits
create_agent,invoke_agent, andexecute_toolspans through the global tracer provider, whichrius.init()installs. Agent and tool structure arrives with no wrappers. - Generations. Model calls go through the OpenAI client
(
autogen-ext[openai]), so theopenaiintegration captures them with model, tokens, and cost.
One observe wrapper on the entrypoint groups agent creation and
invocation into a single trace per unit of work.
Do not wrap AutoGen tool functions with observe. The framework executes
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.
Setup
pip install "glassflow-rius[openai]" "autogen-agentchat" "autogen-ext[openai]"import rius
from autogen_agentchat.agents import AssistantAgent
from autogen_ext.models.openai import OpenAIChatCompletionClient
from rius import SpanKind
rius.init(api_key="gf_...", 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)What lands where
| In the framework | In the trace |
|---|---|
| Your entrypoint | The root AGENT span (your observe wrapper) |
| Agent construction | A create_agent <name> span (framework) |
| An agent run | An invoke_agent <name> span (framework) |
| A model call | A ChatCompletion generation with tokens and cost |
| A tool call | An execute_tool <name> span (framework) |
A run that calls a tool looks like this (real trace from the example,
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 search_knowledge_base 0msQuirks
Verified against autogen-agentchat 0.7.5:
- Tool wrappers split traces (see the callout above).
- Framework span statuses arrive UNSET rather than OK on success; the trace status still reads Ok.
- Generation span names are generic (
ChatCompletion).
Sessions
One conversation is one session: scope each run with
rius.session(), reusing your conversation
id.
Verify
Run one request that calls a tool, then open the trace in the console: the
root span, the framework’s invoke_agent and execute_tool spans, and the
ChatCompletion generation with model, tokens, and cost should all be
there.