> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inference.net/llms.txt
> Use this file to discover all available pages before exploring further.

# Claude Agent SDK Traces

> Trace Claude Agent SDK query loops and yielded agent messages.

Use this integration for applications that call the Claude Agent SDK, formerly
the Claude Code SDK. Python can patch `query()` during `setup()` before import.
TypeScript uses an explicit wrapper because ESM namespace bindings cannot be
safely patched in place.

The Claude Agent SDK integration emits an AGENT span for each query loop. To
group those executions under a stable custom ID in the Agents dashboard, wrap
the product-level query with `agentSpan()` / `agent_span()` and use the SDK
wrapper inside it.

If your app shells out to the `claude` binary instead of importing
`@anthropic-ai/claude-agent-sdk` or `claude_agent_sdk`, use
[Claude Code SDK traces](/integrations/traces/claude-code-sdk).

## Install

<CodeGroup>
  <Metadata text="integrations/traces/claude-agent-sdk-install-typescript" />

  ```bash TypeScript theme={"system"}
  bun add @inference/tracing @anthropic-ai/claude-agent-sdk
  ```

  <Metadata text="integrations/traces/claude-agent-sdk-install-python" />

  ```bash Python theme={"system"}
  pip install 'inference-catalyst-tracing[claude-agent-sdk]'
  ```
</CodeGroup>

## TypeScript Wrapped Query

<Metadata text="integrations/traces/claude-agent-sdk-ts" />

```typescript TypeScript theme={"system"}
import { query } from "@anthropic-ai/claude-agent-sdk";
import { setup, wrapClaudeAgentSdkQuery } from "@inference/tracing";

const tracing = await setup({ serviceName: "claude-agent" });
const tracedQuery = wrapClaudeAgentSdkQuery(query);

const stream = tracedQuery({
  prompt:
    "Count the number of files matching *.md under the current directory tree. " +
    "Use the Bash tool. Reply with just the integer.",
  options: {
    maxTurns: 4,
    allowedTools: ["Bash"],
    permissionMode: "bypassPermissions",
  },
});

for await (const message of stream) {
  console.log(message);
}

await tracing.shutdown();
```

## Stable Agent Identity

Use a stable `agent.id` for the logical agent or workflow you operate. The
Claude Agent SDK span remains visible inside the trace, and the outer AGENT span
provides the dashboard grouping key.

<CodeGroup>
  <Metadata text="integrations/traces/claude-agent-sdk-identity-ts" />

  ```typescript TypeScript theme={"system"}
  import { agentSpan } from "@inference/tracing";

  const prompt = "Review the current diff and list risky changes.";

  await agentSpan(
    {
      agentId: "claude-review-agent",
      agentName: "Claude Review Agent",
      spanName: "claude-review.run",
      sessionId: "conversation-pr-review-101",
      role: "code-review",
      system: "anthropic",
    },
    async (span) => {
      span.setInput(prompt);
      const stream = tracedQuery({ prompt, options: { maxTurns: 4 } });
      let output = "";

      for await (const message of stream) {
        output += JSON.stringify(message) + "\n";
      }

      span.setOutput(output.trim());
    },
  );
  ```

  <Metadata text="integrations/traces/claude-agent-sdk-identity-python" />

  ```python Python theme={"system"}
  from inference_catalyst_tracing import agent_span

  prompt = "Review the current diff and list risky changes."

  async def traced_review() -> None:
      options = ClaudeAgentOptions(max_turns=4)

      with agent_span(
          tracing.tracer,
          agent_id="claude-review-agent",
          agent_name="Claude Review Agent",
          span_name="claude-review.run",
          session_id="conversation-pr-review-101",
          agent_role="code-review",
          system="anthropic",
      ) as span:
          span.set_input(prompt)
          output = []
          async for message in query(prompt=prompt, options=options):
              output.append(str(message))
          span.set_output("\n".join(output))
  ```
</CodeGroup>

## Python Query Loop

<Metadata text="integrations/traces/claude-agent-sdk-python" />

```python Python theme={"system"}
import asyncio

from inference_catalyst_tracing import setup

tracing = setup(service_name="claude-agent")

from claude_agent_sdk import ClaudeAgentOptions, query

async def main() -> None:
    options = ClaudeAgentOptions(
        max_turns=4,
        allowed_tools=["Bash"],
        permission_mode="bypassPermissions",
    )
    async for message in query(
        prompt=(
            "Count files matching *.md under the current directory tree. "
            "Use the Bash tool. Reply with just the integer."
        ),
        options=options,
    ):
        print(message)

asyncio.run(main())
tracing.shutdown()
```

## What To Look For

* An AGENT span for the query run
* An outer AGENT span with `agent.id` when you add the stable identity wrapper
* Nested LLM turns from the Claude Agent SDK
* Tool-use and tool-result data when built-in tools are used
* Final assistant output captured on the span
