query() function. Arize AX captures Agent SDK runs and tool calls via the @arizeai/openinference-instrumentation-claude-agent-sdk package.
The Agent SDK runs Claude Code in a subprocess, so the parent Node.js process does not make Anthropic API calls directly. This instrumentor captures SDK-level AGENT spans and TOOL spans through the SDK’s hooks.
Prerequisites
- Node.js 18+
- An Arize AX account (sign up)
- An
ANTHROPIC_API_KEYfrom the Claude Console
Launch Arize AX
- Sign in to your Arize AX account.
- From Space Settings, copy your Space ID and API Key. You will set them as
ARIZE_SPACE_IDandARIZE_API_KEYbelow.
Install
Configure credentials
Setup tracing
The Claude Agent SDK is native ESM. Use the
claudeAgentSDK value returned by manuallyInstrument(...) in your application code so Node receives the patched module namespace.Run Claude Agent SDK JS
npx tsx example.ts. The agent uses the Bash and Glob tools to answer, so the run produces both an AGENT span and child TOOL spans.
Verify in Arize AX
- Open your Arize AX space and select project
claude-agent-sdk-js-tracing-example. - You should see a new trace within ~30 seconds with a
ClaudeAgent.queryAGENT span carrying the prompt as input, the SDK result as output, and session, model, token-count, and cost metadata. The tools the agent invokes appear as child TOOL spans (e.g.Bash,Glob) with their inputs and outputs. - If no traces appear, see Troubleshooting.
Span coverage
The instrumentor emits an AGENT span perquery() call and child TOOL spans for each tool the agent invokes. It does not emit separate LLM spans: the Agent SDK runs Claude Code in a subprocess and makes its model calls there, so an in-process instrumentor like @arizeai/openinference-instrumentation-anthropic never sees them. Model, token-count, and cost detail is captured as attributes on the AGENT span (llm.model_name, llm.token_count.*, llm.cost.total).
Capture LLM spans
If you want per-generationLLM spans in addition to the AGENT span, synthesize them yourself from the assistant messages the SDK streams back — each one carries the model, its output, and token usage. Wrap the run in a parent span so the instrumentor’s AGENT span and your LLM spans share one trace, and read the final token counts from the result message (the per-message usage is a partial, streaming value):
Troubleshooting
- No traces in Arize AX. Confirm
ARIZE_SPACE_IDandARIZE_API_KEYare set in the same shell that runsexample.ts. Enable OpenTelemetry debug logs withexport OTEL_LOG_LEVEL=debugand re-run. - Agent spans missing.
manuallyInstrument(ClaudeAgentSDK)must run beforequery()is called, and your app must use the returnedclaudeAgentSDKnamespace frominstrumentation.ts. claudeexecutable not found. The Agent SDK runs the Claude Code CLI as a subprocess. Install it withnpm install -g @anthropic-ai/claude-code, or point the SDK at an existing binary withCLAUDE_CODE_EXECUTABLE.Cannot assign to read only property 'query'. Upgrade@arizeai/openinference-instrumentation-claude-agent-sdkto a version that supports native ESM namespaces, then use theclaudeAgentSDKreturn value shown above.401from Anthropic. VerifyANTHROPIC_API_KEYis set and valid.- Tool spans expected but not present. TOOL spans only emit when the agent invokes a tool. Grant tools through
options.toolsoroptions.allowedToolsand use a prompt that requires tool use. - Process exits before spans flush. Spans are exported asynchronously; always
await provider.forceFlush()orawait provider.shutdown()before the process exits.