How do I switch from LangSmith to Rius for the OpenAI Agents SDK?
Rius traces the OpenAI Agents SDK through its OpenAI integration, so you swap LangSmith’s setup for one rius.init() call and a few observe wrappers. Every model call arrives as a generation with model, tokens and cost, and your wrappers give the agent run and its tools their shape. You can run both backends side by side until Rius shows what you need, then remove LangSmith. Rius supports the OpenAI Agents SDK in Python.
How it works
The framework drives the OpenAI client underneath, so the Rius openai integration captures its model calls without framework-specific code. rius.init() turns that on for the whole process. The LangSmith client wrapper wrap_openai has no Rius counterpart, because there is no per-client wrapper to remember.
The agent loop, tool runs and handoffs happen inside the framework, so you add observe wrappers around your entrypoint and your tool bodies. That is the only code you add.
How your LangSmith setup maps over:
LANGSMITH_TRACING,LANGSMITH_API_KEYandLANGSMITH_PROJECTbecomeRIUS_API_KEYplusrius.init(service_name="my-agent"). A LangSmith project corresponds to a Rius agent, named byservice.name.wrap_openai(OpenAI())becomes a plainOpenAI().- LangSmith’s
OpenAIAgentsTracingProcessor, registered withset_trace_processors, goes away. Theobservewrappers replace the run structure it recorded. @traceablebecomes@rius.observe, and@traceable(run_type="tool")becomes@rius.observe(kind=rius.SpanKind.TOOL).- A
thread_idin metadata becomeswith rius.session(thread_id):around the call. It stampssession.idon every span inside it, so you set it once per request.
The OpenAI Agents SDK integration page covers the framework in full, and the LangSmith migration guide has the complete mapping table.
Set it up
-
Install the SDK with the
openaiextra, plus the framework:pip install "glassflow-rius[openai]" openai-agents -
Replace the LangSmith setup in your startup code with
rius.init(). Wrap the entrypoint as anAGENTspan and each tool body as aTOOLspan. Put@function_tooloutermost andobserveon the function body, because the framework reads the function signature for the tool schema. Remove@traceableandwrap_openaifrom this code.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) 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) with rius.session("ticket-1042"): handle_ticket("My invoice shows two charges.") -
Decide about the framework’s own tracing. It uploads to the OpenAI platform, is independent of OpenTelemetry, and is also the path LangSmith’s
OpenAIAgentsTracingProcessorreads from.set_tracing_disabled(True)makes Rius the single telemetry path, so if you compare against LangSmith first, leave that line out until you cut over. Leaving it on does not interfere with Rius. -
Use underscores in agent names. A hyphen gets rewritten in the generated handoff tool name, and the framework warns on every run.
-
Replace
thread_idmetadata withrius.session(), reusing your conversation or ticket id, so every turn of a conversation groups together. -
Run one request that calls a tool and open the trace in the console. Compare it with LangSmith for a few days, then unset
LANGSMITH_TRACING, remove the remaining@traceabledecorators and revoke the LangSmith keys. The Migrate to Rius guide lists the other tools you can move from.
What you get
The trace for one run 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- The root
AGENTspan is your entrypoint wrapper. - Each model call is an
LLMgeneration with model, tokens, cost and time to first token. Cost is a list-price estimate in US dollars that Rius computes from the model and token counts, so you never send it. - Each function tool is a
TOOLspan with the name you gave it. - Conversations group into sessions.
Two behaviours differ from what you may expect. A handoff has no span of its own and shows only as consecutive generations from different agents. Responses API calls are all named Response, so the span name does not say which agent spoke. To mark handoff boundaries, add an observe wrapper per agent entry or use the framework’s RunHooks to open spans at agent boundaries. Streamed runs carry token counts only when usage is enabled on the underlying client; the OpenAI integration page covers the include_usage setting.
The integrations list shows what else attaches automatically if your app uses other libraries.
When something else fits
- Rius has no datasets, experiments, evaluators, feedback queues, Prompt Hub or playground, so keep LangSmith for those and run both backends.
- Existing LangSmith traces stay in LangSmith, because Rius cannot import them and starts from the first span you send.
- Rius is a managed service only, so a self-hosted deployment is not available.