Skip to Content

How do I trace the OpenAI Agents SDK in Python?

Rius traces the OpenAI Agents SDK in Python with one install, one init call and observe wrappers around your entrypoint and tools. Model calls arrive as generations with model, tokens and cost, and the wrappers give the run and its tools their shape. Run one request and open the trace in the console to see the agent span, the model calls and your tool spans.

How it works

The OpenAI Agents SDK drives the OpenAI client underneath, so Rius’s openai integration captures every model call the framework makes. You write no framework-specific code for that part.

The agent loop, tool executions and handoffs run inside the framework, and auto-instrumentation only sees the client calls that come out of it. Wrapping your entrypoint and your tool bodies with observe puts that structure in the trace.

The framework also ships its own tracing, which uploads to the OpenAI platform and is independent of OpenTelemetry. Call set_tracing_disabled(True) if you want Rius to be the single telemetry path. Leaving it on reports to two backends and does not interfere with Rius.

For the full list of supported libraries and frameworks, see Integrations.

Set it up

  1. Install the Rius SDK with the OpenAI extra, next to the Agents SDK. The extra installs the instrumentation, not the library itself.

    pip install "glassflow-rius[openai]" openai-agents
  2. Call rius.init once, as early as possible, and turn off the framework’s own tracing. Set service_name explicitly, because it is how you find your agent later. All other init options are on the installation page.

  3. Wrap each tool body with observe using the TOOL kind, and wrap the function that calls Runner with observe using the AGENT kind.

    import rius from agents import Agent, Runner, function_tool, set_tracing_disabled from rius import SpanKind rius.init(api_key="ri_...", service_name="my-agent") set_tracing_disabled(True) @function_tool @rius.observe(kind=SpanKind.TOOL) def account_status(email: str) -> str: """Fetch a customer's account standing by email.""" return lookup(email) # lookup is your own function support_agent = Agent( name="support_agent", instructions="Answer support questions; check accounts with the tool.", tools=[account_status], model="gpt-5-mini", ) @rius.observe(name="handle-ticket", kind=SpanKind.AGENT) def handle_ticket(ticket: str) -> str: result = Runner.run_sync(support_agent, ticket) return str(result.final_output) print(handle_ticket("Is ana@example.com in good standing?"))
  4. Keep the decorator order on tools exactly as shown: @function_tool outermost, observe on the function body. The framework reads the function signature for its tool schema, and the tool span parents under the run through ambient context.

  5. Use underscores in agent names. A hyphen gets rewritten in the generated handoff tool name, and the framework warns on every run.

  6. Run one request that calls a tool, then open the trace in the console.

To group turns of one conversation, scope each run with rius.session() and reuse your conversation or ticket id.

What you get

Each part of your code lands in the trace like this:

In the frameworkIn the trace
Your entrypoint around Runner.run()The root AGENT span, from your observe wrapper
A model callAn LLM generation with model, tokens, cost and time to first token
A function toolA TOOL span, from your observe wrapper on the body
A handoffNo span of its own

A run that crosses a handoff looks like this:

handle-ticket AGENT 9.8s ├─ Response LLM 2.3s triage decides to hand off ├─ Response LLM 2.8s billing agent decides to call the tool ├─ execute_tool account_status TOOL 0ms └─ Response LLM 4.6s billing agent answers

Things to know when you read it:

  • A handoff shows only as consecutive generations that belong to different agents.
  • Responses API calls are all named Response, so the span name does not say which agent spoke.
  • Streamed runs carry token counts only when usage is enabled on the underlying OpenAI client. The OpenAI integration page explains the include_usage setting that applies here too.

These details were checked against openai-agents 0.22.0. The full guide is on the OpenAI Agents SDK integration page.

When something else fits

  • If handoff boundaries matter to you, add an observe wrapper per agent entry, or use the framework’s RunHooks to open spans at agent boundaries.
  • If your agents run on another framework or client library, the Integrations page lists the setup for each one.
  • This setup is for Python. The OpenAI Agents SDK has no Rius integration in TypeScript.

Still stuck? Get help

Last updated on