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: Voxmith skill
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 voxmithRun 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 voxmithnpm install voxmithaiimport 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()import Anthropic from '@anthropic-ai/sdk';
import * as voxmith from 'voxmithai';
voxmith.init('your-org-id');
const client = new Anthropic();
const interaction = voxmith.begin({
userId: 'u-42',
agentName: 'anthropic-support',
input: prompt,
});
try {
const response = await client.messages.create({
model: 'claude-sonnet-4-5',
max_tokens: 512,
messages: [{ role: 'user', content: prompt }],
});
const output = response.content
.filter((block) => block.type === 'text')
.map((block) => block.text)
.join('');
interaction.end(output);
} catch (error) {
interaction.end(String(error), false);
throw error;
} finally {
await voxmith.shutdown();
}Manual setup: OpenTelemetry
Python: automatic instrumentation
Install
pip install anthropic openinference-instrumentation-anthropic \
opentelemetry-sdk opentelemetry-exporter-otlp-proto-httpSetup
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_HEADERScontainsX-Voxmith-Org-ID=<your-org-id>. - Confirm
using_attributeswraps 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-protoStart 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.