Agent frameworks

Anthropic

Track Anthropic SDK calls from Python or TypeScript

Language support

Setup option Python TypeScript
Voxmith skill ✓ ✓
Voxmith SDK ✓ ✓
OpenTelemetry Automatic Manual

Choose a setup method

Method Use it when
Voxmith skill You want your coding agent to inspect the app, make the change, and verify it.
Voxmith SDK You want explicit control over the interaction boundaries and fields.
OpenTelemetry The framework already emits useful spans or you operate an OTel pipeline.

Start with one method for a call path. Combining SDK tracking with framework OpenTelemetry on the same call can create duplicate interactions.

Recommended. Choose this path when you want your coding agent to inspect the project, select a supported transport, make the smallest instrumentation change, send a test event, and verify that it reached Voxmith.

Install the skill once in your coding-agent environment:

npx skills add Voxmith/skills --skill voxmith

Run the framework-specific prompt below from the application root. Review the resulting diff before deploying it.

Use the voxmith skill to add Voxmith analytics to this Anthropic application.
Org ID: your-org-id
Instrument the real messages.create() path and verify one fresh interaction.

Manual setup: Voxmith SDK

pip install voxmith
import voxmith
from anthropic import Anthropic

voxmith.init("your-org-id")
client = Anthropic()
interaction = voxmith.begin(user_id="u-42", agent_name="anthropic-support", input=prompt)
try:
    response = client.messages.create(model="claude-sonnet-4-5", max_tokens=512,
                                      messages=[{"role": "user", "content": prompt}])
    interaction.end(output="".join(block.text for block in response.content if block.type == "text"))
except Exception as exc:
    interaction.end(output=str(exc), success=False)
    raise
finally:
    voxmith.shutdown()

Manual setup: OpenTelemetry

Python: automatic instrumentation

Install

pip install anthropic openinference-instrumentation-anthropic \
            opentelemetry-sdk opentelemetry-exporter-otlp-proto-http

Setup

import os
from anthropic import Anthropic
from openinference.instrumentation.anthropic import AnthropicInstrumentor
from openinference.instrumentation import using_attributes
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter

os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = "https://otel.voxmith.com"
os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = "X-Voxmith-Org-ID=<your-org-id>"

provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(provider)
AnthropicInstrumentor().instrument(tracer_provider=provider)

client = Anthropic()
with using_attributes(session_id="sess-123", user_id="u-42"):
    client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=1024,
        messages=[{"role": "user", "content": "Hi"}],
    )

Tool-use blocks are unpacked. You get llm.input_messages.*, llm.output_messages.*, tool.name, tool.parameters, and llm.token_count.{prompt,completion}.

Alternative

The Traceloop alternative (opentelemetry-instrumentation-anthropic) emits gen_ai.* and traceloop.*: also recognized by Voxmith.

Verify

Run one client.messages.create call, then open Events in Voxmith. Confirm message and tool-use attributes appear as expected.

Troubleshooting

  • Confirm AnthropicInstrumentor().instrument(...) runs before Anthropic calls.
  • Confirm OTEL_EXPORTER_OTLP_HEADERS contains X-Voxmith-Org-ID=<your-org-id>.
  • Confirm using_attributes wraps the call you want grouped.

References

TypeScript: manual instrumentation

Install the OpenTelemetry packages alongside your existing Anthropic SDK:

npm install @opentelemetry/api @opentelemetry/sdk-node \
  @opentelemetry/exporter-trace-otlp-proto

Start OpenTelemetry before creating the Anthropic client, then wrap the call you want to track:

import Anthropic from '@anthropic-ai/sdk';
import { SpanStatusCode, trace } from '@opentelemetry/api';
import { NodeSDK } from '@opentelemetry/sdk-node';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-proto';

const sdk = new NodeSDK({
  traceExporter: new OTLPTraceExporter({
    url: 'https://otel.voxmith.com/v1/traces',
    headers: { 'X-Voxmith-Org-ID': process.env.VOXMITH_ORG_ID! },
  }),
});
await sdk.start();

const client = new Anthropic();
const tracer = trace.getTracer('anthropic-app');

const response = await tracer.startActiveSpan('anthropic.messages.create', async (span) => {
  span.setAttribute('gen_ai.operation.name', 'chat');
  span.setAttribute('gen_ai.provider.name', 'anthropic');
  span.setAttribute('gen_ai.request.model', 'claude-sonnet-4-5');
  span.setAttribute('gen_ai.conversation.id', 'conversation-123');
  span.setAttribute('user.id', 'user-42');
  span.setAttribute('input.value', prompt);

  try {
    const message = await client.messages.create({
      model: 'claude-sonnet-4-5',
      max_tokens: 512,
      messages: [{ role: 'user', content: prompt }],
    });
    const output = message.content
      .filter((block) => block.type === 'text')
      .map((block) => block.text)
      .join('');
    span.setAttribute('output.value', output);
    return message;
  } catch (error) {
    span.recordException(error as Error);
    span.setStatus({ code: SpanStatusCode.ERROR });
    throw error;
  } finally {
    span.end();
  }
});

await sdk.shutdown();

Run one message call, then open Events in Voxmith and confirm the input, output, model, user, and conversation fields are present.

Next steps

  • Conversations: review the complete Anthropic interaction.
  • Events: inspect the SDK or OpenTelemetry records.
  • Intents: organize production conversations by what users wanted.