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

npm install @openai/agents zod \
  @arizeai/openinference-instrumentation-openai-agents \
  @arizeai/openinference-semantic-conventions \
  @opentelemetry/exporter-trace-otlp-proto \
  @opentelemetry/resources \
  @opentelemetry/sdk-trace-base \
  @opentelemetry/sdk-trace-node \
  @opentelemetry/semantic-conventions

Configure credentials

export ARIZE_SPACE_ID="<your-space-id>"
export ARIZE_API_KEY="<your-api-key>"
export ARIZE_PROJECT_NAME="openai-agents-js-tracing-example"
export OPENAI_API_KEY="<your-openai-api-key>"

Setup tracing

// instrumentation.ts
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
import { resourceFromAttributes } from "@opentelemetry/resources";
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
import {
  SEMRESATTRS_PROJECT_NAME,
} from "@arizeai/openinference-semantic-conventions";
import {
  OpenAIAgentsInstrumentation,
} from "@arizeai/openinference-instrumentation-openai-agents";
import * as agents from "@openai/agents";

const projectName =
  process.env.ARIZE_PROJECT_NAME ?? "openai-agents-js-tracing-example";

export const provider = new NodeTracerProvider({
  resource: resourceFromAttributes({
    [ATTR_SERVICE_NAME]: projectName,
    [SEMRESATTRS_PROJECT_NAME]: projectName,
  }),
  spanProcessors: [
    new BatchSpanProcessor(
      new OTLPTraceExporter({
        url: "https://otlp.arize.com/v1/traces",
        headers: {
          "arize-space-id": process.env.ARIZE_SPACE_ID ?? "",
          "arize-api-key": process.env.ARIZE_API_KEY ?? "",
        },
      }),
    ),
  ],
});

provider.register();

const instrumentation = new OpenAIAgentsInstrumentation({
  tracerProvider: provider,
});
instrumentation.manuallyInstrument(agents);

console.log("Arize AX tracing initialized for OpenAI Agents JS.");
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

// example.ts

// Importing instrumentation first ensures tracing is set up before the
// Agents SDK is used.
import { provider } from "./instrumentation";

import { Agent, run } from "@openai/agents";

// The agent reads OPENAI_API_KEY from the environment.
const agent = new Agent({
  name: "Assistant",
  instructions: "You are a concise factual assistant.",
  model: "gpt-5",
});

const result = await run(
  agent,
  "Why is the ocean salty? Answer in two sentences.",
);

console.log(result.finalOutput);

// Flush any pending spans before the process exits.
await provider.forceFlush();

Expected output

Arize AX tracing initialized for OpenAI Agents JS.
The ocean is salty because rivers continuously dissolve mineral salts from rocks and soil and carry them to the sea, where they accumulate over millions of years. Water leaves the ocean through evaporation but the salts remain, steadily concentrating until reaching today's roughly 3.5% salinity.

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) 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.

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" 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. BatchSpanProcessor batches spans before export; 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.

Resources

OpenAI Agents JS Documentation

OpenInference OpenAI Agents Instrumentor (JS/TS)

OpenAI Agents JS GitHub