Skip to content

Anthropic SDK and Claude Agent SDK

Two packages, one for each way of building with Claude:

You build with Package What is traced
The Anthropic SDK (anthropic, @anthropic-ai/sdk) anosys-sdk-anthropic Every messages call, including streaming, prompt caching and extended thinking
The Claude Agent SDK (claude-agent-sdk, @anthropic-ai/claude-agent-sdk) anosys-sdk-claude-agents Each agent run, its tool calls and subagents, with total tokens and cost

Looking for Claude Code itself? See Claude Code.

Before you start

  1. Create an endpoint of type OpenTelemetry / AI Agents and an API key (Collecting → Integration Options → API → Create New API Key).
  2. Set your keys:
export ANOSYS_API_KEY="your-anosys-key"
export ANTHROPIC_API_KEY="your-anthropic-key"

Anthropic SDK

Install

pip install anosys-sdk-anthropic

Requires Python 3.10+ and anthropic 2.0 or later.

npm install anosys-sdk-anthropic

Initialize once, before creating clients

import anthropic
from anosys_sdk_anthropic import AnosysAnthropicLogger

AnosysAnthropicLogger()

client = anthropic.Anthropic()
message = client.messages.create(
    model="claude-sonnet-5-5",
    max_tokens=1024,
    messages=[{"role": "user", "content": "Hello!"}],
)
import Anthropic from '@anthropic-ai/sdk';
import { AnosysAnthropicLogger } from 'anosys-sdk-anthropic';

new AnosysAnthropicLogger();

const client = new Anthropic();
const message = await client.messages.create({
  model: 'claude-sonnet-5-5',
  max_tokens: 1024,
  messages: [{ role: 'user', content: 'Hello!' }],
});

Result: run it once. The endpoint shows activity within seconds, and each call appears as a span in Trace Timeline.

Options

Python JavaScript Default What it does
get_user_context getUserContext none Function returning {"session_id": ..., "token": ...} to tie calls to a user
capture_content captureContent True False sends metadata, tokens and timing without prompts or responses
use_batch_processor useBatchProcessor False Batch spans before sending (better for high volume)

Already using OpenTelemetry?

The logger attaches to an existing tracer provider. If you pass your own open_telemetry options to a client, build them with get_anthropic_open_telemetry_options() (getAnthropicOpenTelemetryOptions() in JavaScript) so tracing stays on.

What is captured

  • Model, max tokens, stop sequences, stop reason, response ID
  • Input, output and total tokens, plus prompt-cache read and write tokens
  • Whether extended thinking was used
  • System instructions, input and output messages (unless capture_content is off)
  • Duration and errors

Claude Agent SDK

Install

pip install anosys-sdk-claude-agents
npm install anosys-sdk-claude-agents

Initialize

Create the logger before importing query:

import asyncio
from anosys_sdk_claude_agents import AnosysClaudeAgentsLogger

AnosysClaudeAgentsLogger()

from claude_agent_sdk import ClaudeAgentOptions, query

async def main():
    options = ClaudeAgentOptions(allowed_tools=["Bash", "Read"])
    async for message in query(prompt="List the Python files here", options=options):
        print(message)

asyncio.run(main())

ClaudeSDKClient is traced too. If query was imported before the logger, wrap it: query = wrap_query(query).

import { query } from '@anthropic-ai/claude-agent-sdk';
import { AnosysClaudeAgentsLogger, wrapQuery } from 'anosys-sdk-claude-agents';

new AnosysClaudeAgentsLogger();
const tracedQuery = wrapQuery(query);

for await (const message of tracedQuery({
  prompt: 'List the files in this folder',
  options: { allowedTools: ['Bash', 'Read'] },
})) {
  console.log(message);
}

Options

Python JavaScript Default What it does
agent_name agentName "claude_agent" Name shown for the agent in traces
get_user_context getUserContext none Ties runs to a user or session
capture_content captureContent True False drops prompts, results and tool input/output
emit_llm_spans emitLlmSpans False Adds one span per model response, with its own token usage
use_batch_processor useBatchProcessor False Batch spans before sending

What a run looks like

%%{init: {"flowchart": {"curve": "linear"}}}%%
graph TD
    A["Agent run<br/>prompt, result, total tokens, cost"] --> B["Tool: Bash"]
    A --> C["Tool: Read"]
    A --> D["Subagent (Task)"]
    D --> E["Subagent's tool calls"]

Token and cost totals sit on the run. If you turn on emit_llm_spans, the per-response spans also carry usage, so add up one or the other, not both.

Troubleshooting

No data in the console
  • Check ANOSYS_API_KEY is set in the process that runs your code.
  • Create the logger before creating the Anthropic client, or before importing query.
  • In JavaScript, make sure only one version of @opentelemetry/api is installed (npm dedupe).
  • Allow outbound HTTPS to api.anosys.ai.

Next steps