Skip to main content
OpenAI Agents JS is OpenAI’s TypeScript framework for building agents — instructions, tools, handoffs, guardrails, and the run function that drives them. Arize AX captures every Agents JS run — agent invocations, tool calls, handoffs, guardrails, and the underlying LLM calls — via the @arizeai/openinference-instrumentation-openai-agents package, which registers as a first-class TracingProcessor against the SDK.

Prerequisites

Launch Arize AX

  1. Sign in to your Arize AX account.
  2. From Space Settings, copy your Space ID and API Key. You will set them as ARIZE_SPACE_ID and ARIZE_API_KEY below.

Install

Configure credentials

Setup tracing

The instrumentor implements the Agents SDK’s first-class TracingProcessor interface rather than monkey-patching imports, so manuallyInstrument(agents) must receive the same @openai/agents namespace your application code imports. Pass exclusiveProcessor: false to the constructor to run alongside the SDK’s default OpenAI tracing exporter instead of replacing it.

Run OpenAI Agents JS

Expected output

Verify in Arize AX

  1. Open your Arize AX space and select project openai-agents-js-tracing-example.
  2. You should see a new trace within ~30 seconds with this shape: an Agent workflow root span (AGENT) wraps an Assistant agent span (AGENT) and a response LLM child span (model gpt-5.5) with the prompt, response, and token usage attached. Tool, handoff, and guardrail spans appear when the agent invokes them.
  3. If no traces appear, see Troubleshooting.

Check from the skill, CLI, or SDK

Confirm spans are actually reaching your Arize AX project. Use whichever fits your workflow — the skill and CLI work for any framework; the SDK check is shown for each language.
Install the Arize Skills plugin and let your coding agent check for you:
Then prompt your agent:
Use the arize-trace skill to export and analyze recent traces from my project. Confirm spans are arriving, and summarize any errors or latency issues.

Span filter

The basic setup above exports every span the tracer provider receives. That’s fine for a standalone Node script — nothing else is emitting through the provider. In Next.js / Vercel / NestJS / any runtime that ships its own OpenTelemetry auto-instrumentation, those instrumentations emit POST / GET spans for every fetch, every page render, every API route, and the Agents SDK spans nest under those HTTP roots inside your AX project. A single chat turn can balloon into 30+ unrelated infra spans. OpenInference-tagged spans all carry an openinference.span.kind attribute that the @arizeai/openinference-instrumentation-openai-agents processor sets — checking for it is enough to drop non-OpenInference spans. Swap SimpleSpanProcessor in instrumentation.ts for a filtering subclass:
This is the same predicate @arizeai/openinference-vercel exports as isOpenInferenceSpan — inlined here so a non-Vercel app doesn’t have to depend on a Vercel-specific package. The trade-off: filtering removes the HTTP root spans, which orphans the surviving Agents SDK spans on the Traces tab (no parent to anchor them) — they remain visible on the Spans tab. If you also need a clean trace tree on the Traces tab, swap the filter for a span processor that promotes the SDK’s top-level Agent workflow span to root by clearing its parent ID:
Wire it in by replacing the SimpleSpanProcessor (or OpenInferenceFilteringSpanProcessor) in instrumentation.ts:
The recipe needs two additional dependencies: npm install @arizeai/openinference-core lru-cache.

Troubleshooting

  • No traces in Arize AX. Confirm ARIZE_SPACE_ID and ARIZE_API_KEY are set in the same shell that runs example.ts. Enable OpenTelemetry debug logs with export OTEL_LOG_LEVEL=debug and re-run.
  • Agents spans missing. instrumentation.manuallyInstrument(agents) must run before Agent is constructed or run is called. Make sure import { provider } from "./instrumentation" is the first import in your entry point, and that the same @openai/agents namespace passed to manuallyInstrument(...) is the one your application code imports.
  • 401 from OpenAI. Verify OPENAI_API_KEY is set and has access to the default model. Swap model: "gpt-5.5" for a model your key can call.
  • Spans still going to the default OpenAI tracing exporter. The instrumentor registers exclusively by default. If you need to keep the SDK’s built-in exporter alongside Arize AX, pass new OpenAIAgentsInstrumentation({ tracerProvider: provider, exclusiveProcessor: false }).
  • Process exits before spans flush. Spans are exported asynchronously (more so when you swap in the RootAwareOpenInferenceProcessor below, which batches); always await provider.forceFlush() (or provider.shutdown()) before the process exits to avoid losing trailing spans.
  • Tool / handoff / guardrail spans expected but not present. These spans only emit when the agent actually invokes the corresponding feature. The minimal example above has none — add tools, handoffs, or inputGuardrails to the Agent constructor to see them.
  • AX project is full of GET /, POST /api/chat, or other infra spans. Your runtime’s auto-OTel (Next.js, Vercel, NestJS, …) is piping HTTP / fetch / page-render spans through the global provider. See Span filter above for the OpenInferenceFilteringSpanProcessor recipe (and the RootAwareOpenInferenceProcessor if you also need a clean trace tree on the Traces tab). In Next.js apps an additional defence is to skip provider.register() entirely and pass the provider directly to new OpenAIAgentsInstrumentation({ tracerProvider }) — the instrumentor resolves its tracer off the provider you hand it, so global registration isn’t needed.
  • Agents SDK spans orphaned on the Traces tab. Expected when the OpenInferenceFilteringSpanProcessor is the only processor — see Span filter for the RootAwareOpenInferenceProcessor recipe that promotes Agent workflow to root.

Resources

OpenAI Agents JS Documentation

OpenInference OpenAI Agents Instrumentor (JS/TS)

OpenAI Agents JS GitHub