
query() as a trace with nested steps for assistant turns, tool calls (including MCP and sub-agents), session metadata, cost, and tokens.
Choosing an integration path
Openlayer supports three different ways to instrument the Claude Agent SDK. They all land traces in the same Openlayer pipeline; pick the one that fits your stack best.| Path | Setup | When to use it |
|---|---|---|
| 1. Openlayer wrapper (recommended) | One line — trace_claude_agent_sdk() (Python) or a drop-in query import (TypeScript) | You want the richest metadata out of the box (system prompt, resolved agent config, sub-agent definitions, raw assistant messages, full ResultMessage) and the least setup. |
| 2. OpenInference + OTLP | Install openinference-instrumentation-claude-agent-sdk and point its OTLP exporter at Openlayer’s OTel endpoint | You already use OpenTelemetry across your stack and want Claude Agent SDK traces to flow through the same collector. |
| 3. Native Claude Agent SDK OTel (beta) | Set CLAUDE_CODE_ENABLE_TELEMETRY=1 and other OTEL_* env vars on ClaudeAgentOptions.env | You can’t add new dependencies and you’re comfortable with the SDK’s beta-gated telemetry path. Zero code change. |
Path 1 — Openlayer wrapper (recommended)
A single line of setup auto-instruments every call toquery() and ClaudeSDKClient. The wrapper:
- Wraps the agent loop into a root
AGENTstep perquery()call. - Captures each assistant turn as a nested
CHAT_COMPLETIONstep (text, thinking, tokens, model). - Captures each tool invocation as a nested
TOOLstep bracketed by the SDK’sPreToolUse/PostToolUse/PostToolUseFailurehooks. MCP tools are parsed (mcp__server__tool) intomcp_serverandmcp_tool_namemetadata. - Represents sub-agent dispatches (the
Agenttool) as nestedAGENTsteps. The sub-agent’s own assistant turns and tool calls nest underneath viaparent_tool_use_id. - Composes with any hooks you already have — your hooks are appended to, never replaced.
Monitoring
See full Python example
See full TypeScript example
query() call is published to Openlayer with:
- Agent loop with the resolved configuration: model, tools, MCP servers, skills, plugins, permission mode, working directory.
- System prompt and sub-agent definitions (per registered sub-agent: description, prompt, tools, model) captured on the root
AGENTstep. - Assistant turns with text, thinking blocks, prompt/completion tokens, and the raw assistant-message JSON.
- Tool calls with input arguments, output, latency,
tool_use_id, andmcp_server/mcp_tool_namefor MCP tools. - Sub-agent dispatches as nested
AGENTsteps. The sub-agent’s own assistant turns and tool calls nest underneath. - Session metadata (
session_id,num_turns,stop_reason,is_error,model_usagebreakdown,permission_denials) and the fullResultMessageJSON. - Cost (
total_cost_usd) and total tokens.
The Openlayer wrapper composes with hooks you’ve already configured. Hooks you
pass via
ClaudeAgentOptions.hooks are preserved — Openlayer’s hooks are
appended and act only as observers (they always return {}), so your hooks
retain full control over permissionDecision, updatedInput, etc.Multi-stage orchestration
If you make multiplequery() calls that you want to appear as a single trace, wrap them in tracer.create_step(). Each query() becomes a nested AGENT step under your outer step.
Python
Path 2 — OpenInference + OTLP
If you already use OpenTelemetry across your stack, you can use Arize’s OpenInference instrumentation for the Claude Agent SDK and point its OTLP exporter at Openlayer. This path emits spans that follow the OpenInference semantic conventions (e.g.openinference.span.kind=AGENT|LLM|TOOL, llm.input_messages.*, tool.parameters). Openlayer ingests them via its OpenTelemetry endpoint.
Python
Openlayer’s OTel endpoint accepts OTLP HTTP/protobuf at
https://api.openlayer.com/v1/otel/v1/traces. The Authorization header
carries your Openlayer API key, and x-bt-parent routes the trace to the
correct inference pipeline. See the OpenTelemetry integration
page for the full endpoint reference.Path 3 — Native Claude Agent SDK OTel (beta)
The Claude Agent SDK’s bundled Claude Code CLI has built-in OpenTelemetry instrumentation that emitsclaude_code.interaction, claude_code.llm_request, claude_code.tool, and claude_code.tool.execution spans. You can point it directly at Openlayer’s OTel endpoint by setting environment variables — no Openlayer or OpenInference packages required.
claude_code.interaction (one per turn), claude_code.llm_request (one per Claude API call), and claude_code.tool (one per tool invocation, with claude_code.tool.execution as a child).
Bonus: W3C trace context propagation
If your application already starts OpenTelemetry spans before callingquery(), the SDK reads TRACEPARENT and TRACESTATE from the subprocess environment and parents claude_code.interaction under your span automatically — so an agent run appears inside your existing distributed trace.
Comparison: which path produces what
| Openlayer wrapper | OpenInference + OTLP | Native SDK OTel | |
|---|---|---|---|
| Setup | One line | ~10 lines + 4 packages | Env vars only |
| Step type names | AGENT, CHAT_COMPLETION, TOOL (Openlayer’s model) | openinference.span.kind (AGENT, LLM, TOOL) | claude_code.* |
| System prompt captured | ✅ | ⚠️ partial | ⚠️ only with OTEL_LOG_USER_PROMPTS=1 (beta-gated) |
| Sub-agent definitions on AGENT step | ✅ | ❌ | ❌ |
Raw ResultMessage JSON | ✅ | ❌ | ❌ |
MCP server / tool_name parsed | ✅ | ✅ | ✅ |
Sub-agent nesting via parent_tool_use_id | ✅ | ✅ | ✅ (via W3C trace context) |
| Tool inputs/outputs in trace | ✅ | ✅ | ⚠️ off by default — requires OTEL_LOG_TOOL_DETAILS=1 + OTEL_LOG_TOOL_CONTENT=1 |
Cost (total_cost_usd) | ✅ | ✅ | ✅ |
| Stable API | ✅ | ✅ | ⚠️ beta — span names may change |
| Portable to other OTel backends | ❌ | ✅ | ✅ |
Development
In development mode, Openlayer becomes a step in your CI/CD pipeline, and your tests get automatically evaluated after being triggered by some events. Openlayer tests often rely on your AI system’s outputs on a validation dataset. As discussed in the Configuring output generation guide, you have two options:- either provide a way for Openlayer to run your AI system on your datasets, or
- before pushing, generate the model outputs yourself and push them alongside your artifacts.
ANTHROPIC_API_KEY.
If you don’t add the required Anthropic API key, you’ll encounter a “Missing API key” error when Openlayer tries to run your AI system to get its outputs.
