query() function or the ClaudeSDKClient class. Arize AX captures every Agent SDK run — agent invocations and the tool calls they make — via the openinference-instrumentation-claude-agent-sdk package.
Use this if you are building an application with the Claude Agents SDK. This page uses the OpenInference
ClaudeAgentSDKInstrumentor to emit standard agent and tool spans into your application’s project — the right choice when the SDK is part of an app you’re instrumenting. If you instead want to trace Claude Code CLI (or SDK) sessions — the coding tool’s activity, tool usage, and token costs — via a plugin you enable through a settings file with no in-code instrumentor, use Claude Code instead.Prerequisites
- Python 3.10+
- Node.js and the Claude Code CLI (
npm install -g @anthropic-ai/claude-code), which the Agent SDK runs as a subprocess - 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
Instrument the Agent SDK with
ClaudeAgentSDKInstrumentor. If your app serves the SDK from a web framework (FastAPI, Flask, etc.), do not rely on web-server instrumentation like FastAPIInstrumentor for agent observability — it records HTTP requests, not the SDK’s agent and tool spans. Add ClaudeAgentSDKInstrumentor alongside any transport instrumentation you keep.Run the Claude Agent SDK
The instrumentor traces both entry points:query()— one AGENT span per call, for one-off tasks.ClaudeSDKClient— one AGENT span per response turn (eachreceive_response()iteration), for multi-turn conversations that keep session context.
- query()
- ClaudeSDKClient
Verify in Arize AX
- Open your Arize AX space and select project
claude-agent-sdk-tracing-example. - Within ~30 seconds you should see a new trace with an AGENT root span (
ClaudeAgentSDK.queryorClaudeAgentSDK.ClaudeSDKClient.receive_response) carrying the prompt as input, the SDK result as output, andsession.id,llm.model_name, and token-count metadata. Any tools the agent invokes appear as child TOOL spans with their inputs and outputs. - If no traces appear, see Troubleshooting.
Span coverage
The instrumentor emits AGENT spans (one perquery() call or ClaudeSDKClient response turn) and child TOOL spans for each tool the agent invokes. It does not emit separate LLM spans: the Agent SDK runs the Claude Code binary as a subprocess and makes its model calls there, so an in-process instrumentor like AnthropicInstrumentor 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 AssistantMessage objects the SDK streams back — each one carries the model and its output. Start the LLM span while the assistant message streams (so it nests under the AGENT span) and set the token counts from the final ResultMessage, whose usage holds the accurate totals (the per-AssistantMessage usage is a partial, streaming value):
Troubleshooting
- No traces in Arize AX. Confirm
ARIZE_SPACE_IDandARIZE_API_KEYare set in the same shell that runs your script. Enable OpenTelemetry debug logs withexport OTEL_LOG_LEVEL=debugand re-run. - Agent spans missing.
ClaudeAgentSDKInstrumentor().instrument(...)must run beforequery()orClaudeSDKClientis called. Make sureinstrumentation.pyis the first import in your entry point. 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.401from Anthropic. VerifyANTHROPIC_API_KEYis set and valid.- Tool spans expected but not present. TOOL spans only emit when the agent actually invokes a tool. Grant tools via
ClaudeAgentOptions(allowed_tools=[...])and give a prompt that requires them.