AI Nexus HubAI Nexus Hub
PostsQuestionsDiscussions

Command Palette

Search for a command to run...

AI Nexus Hub

CONTACT:
axc@cyberlogitec.com

Content
PostsQuestionsDiscussionsTopics
Stay in the loop

Weekly digest of the best AI posts. No spam.

© CLT 2026. All rights reserved.
Privacy
Posts  /  #AI  /  See Inside Every Agent Run: Hands-On with OpenTelemetry Traces on the Claude Platform
0
#AI

See Inside Every Agent Run: Hands-On with OpenTelemetry Traces on the Claude Platform

HL
Hung Lay
Oct 16, 2026 · 13 min read

AXC AI News · Friday, October 16, 2026
Topic: Claude Developer Platform · Observability · Managed Agents · Fast mode
Reading time: ~9 min · Hands-on time: ~25 min

TL;DR

  • What's new: On Oct 14, 2026, Anthropic launched OpenTelemetry (OTel) export (beta). Every Messages API request, model run, tool use and Managed Agents turn can become a span in the observability tool you already use: Langfuse, Grafana, Datadog, Honeycomb, Sentry, New Relic, LangSmith and others.

  • Two ways in:

    • SDK tracing: the Claude SDK (Python, TS, C#, Go, Java, PHP, Ruby) emits spans from your app. You only need to register a tracer provider, and no admin rights.

    • API tracing: an org admin adds a destination in the Claude Console, and Anthropic's servers send spans without any code change, including what happens inside the API: each model run, server tools such as web search, and agent turns.

  • Also new (Oct 15): Fast mode for Claude Opus 5.5 is out of research preview. Add speed: "fast" to get up to 2.5× more output tokens/sec at 2× the price (40 per Mtok). You no longer need a waitlist or beta header.

  • Today's hands-on: trace a small tool-using agent locally in 5 minutes, ship the traces to Langfuse, then use those traces to measure whether fast mode is worth it for your workload.


1. Why this matters: agents are black boxes until you trace them

Last issue we ran up to 1,000 agents with a single prompt. The next question your tech lead will ask is fair: "What did they actually do, how long did each step take, and where did the tokens go?"

Until this week, the honest answers were:

Approach

What you see

What you miss

print(response.usage)

Totals per call

Which step was slow, which tool failed, how calls relate to each other

Hand-rolled wrapper spans

Your client-side calls

Everything inside the API: each model run, server tools, Managed Agents turns, sub-threads

Third-party proxy

Request/response pairs

Agent structure, and you add a hop to every request

OTel export closes the gap. The API now emits the spans it produces server-side and nests them under your spans through the standard W3C traceparent header. In one trace you see a single tree: your HTTP handler → the SDK call → each model run inside the API → each tool → the next turn.

POST /chat  (your service)
└─ anthropic.messages.tool_runner                    ← SDK (your app)
   ├─ anthropic.messages.create  [CLIENT]            ← SDK
   │  └─ anthropic.messages.create  [SERVER]         ← Claude API (destination)
   │     ├─ anthropic.model_request
   │     ├─ anthropic.tool_use web_search            ← server tool, run by the API
   │     └─ anthropic.model_request
   ├─ anthropic.custom_tool_use get_weather          ← your tool, run by the tool runner
   └─ anthropic.messages.create  [CLIENT]
      └─ anthropic.messages.create  [SERVER] …

All spans use the OpenTelemetry GenAI semantic conventions (gen_ai.usage.input_tokens, gen_ai.conversation.id, gen_ai.tool.name …), so Claude data sits next to your other services in the same dashboards. Customers from the launch post: Ramp scores Langfuse traces automatically and reports 10–20% lower token usage on some agents, and FloQast puts every model call in the same Grafana trace as the accounting workflow it served, so auditors can review it.


2. The key facts (from the official docs)

Item

SDK tracing

API tracing (destination)

Set up via

Code: register a tracer provider

Console → Settings → OpenTelemetry → Add destination (or Admin API / ant CLI)

Permission

None

Admin role (developers can view)

Messages API & Sessions API requests

✅

✅

Each model run inside a request

—

✅

Managed Agents turns, sub-threads, outcome evaluations

—

✅

Server tools (web search, MCP connector…)

—

✅

Client tools run by the SDK tool runner

✅

—

Works on Bedrock / Vertex / Foundry

✅

Claude Platform & Claude Platform on AWS only

Content modes. The default is Metadata only: IDs, timing, status, token counts, and the names of agents, tools and MCP servers. Full content adds prompts and responses (gen_ai.input.messages, gen_ai.output.messages, gen_ai.system_instructions). Each span holds up to 0.75 MB of content by default; longer content is truncated and flagged with anthropic.content.truncated = true.

Destination requirements. An HTTPS OTLP/HTTP (protobuf) endpoint on port 443, with a hostname, not an IP. Delivery is at least once and best effort. The API disables a destination that sends a 3xx redirect, resolves to a non-public IP, or fails for 24 hours straight. Limits: 10 destinations per org, 20 headers each.

Partners with a ready-made Console provider: Arize, Braintrust, Databricks, Datadog, Grafana Cloud, Honeycomb, Langfuse, LangSmith, New Relic, PostHog, Sentry, Splunk, or Custom for any OTLP endpoint.


3. Hands-on: trace an agent, then measure fast mode (25 min)

We'll use Langfuse. It's open source, has a free cloud tier, and can also be self-hosted. Any OTLP backend works the same way.

Step 0 — Setup (3 min)

python -m venv .venv && source .venv/bin/activate     # Windows: .venv\Scripts\activate
pip install --upgrade anthropic opentelemetry-sdk opentelemetry-exporter-otlp-proto-http
export ANTHROPIC_API_KEY=sk-ant-...                    # PowerShell: $env:ANTHROPIC_API_KEY="sk-ant-..."

⚠️ The SDK's OTel options and span names are beta and can change between SDK versions. Pin the anthropic version in requirements.txt once your dashboards work.

Step 1 — Save this as traced_agent.py

The script runs a small tool-using agent inside your own span. If you set OTEL_EXPORTER_OTLP_ENDPOINT, spans go to Langfuse. If you don't, they print to the console, so you can try it in 5 minutes with no account.

"""traced_agent.py — a tiny tool-using agent, fully traced with OpenTelemetry.
Usage:
  python traced_agent.py            # standard speed
  python traced_agent.py --fast     # Opus 5.5 fast mode (2x price, up to 2.5x output tok/s)
"""
import json
import os
import sys
import time

from anthropic import Anthropic, beta_tool
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
    BatchSpanProcessor, ConsoleSpanExporter, SimpleSpanProcessor,
)

# 1) Register a tracer provider BEFORE creating the client / first call.
provider = TracerProvider(resource=Resource.create({"service.name": "axc-trace-demo"}))
if os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT"):
    from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
    # Reads OTEL_EXPORTER_OTLP_ENDPOINT / _HEADERS from the environment, appends /v1/traces.
    provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
else:
    provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("axc-trace-demo")

# 2) Full content = prompts & responses in spans. Use metadata_only for anything sensitive.
client = Anthropic(open_telemetry={"traces": {"content_mode": "content"}})

FAST = "--fast" in sys.argv


@beta_tool
def list_open_tickets(team: str) -> str:
    """List open tickets for a team.

    Args:
        team: Team name, e.g. 'payments'
    """
    time.sleep(0.4)  # pretend this is a slow internal API, so it shows up in the trace
    return json.dumps([
        {"id": "PAY-101", "title": "Refund webhook retries twice", "age_days": 12},
        {"id": "PAY-117", "title": "Currency rounding in invoice PDF", "age_days": 3},
        {"id": "PAY-120", "title": "Timeout calling FX provider", "age_days": 1},
    ])


@beta_tool
def get_ticket_details(ticket_id: str) -> str:
    """Get the description and recent comments for a ticket.

    Args:
        ticket_id: The ticket ID, e.g. 'PAY-101'
    """
    return json.dumps({"id": ticket_id, "description": "Customer charged, webhook fired "
                       "twice because our handler returned 500 after committing."})


# 3) Wrap the agent in YOUR span: the SDK spans (and API spans, if a destination
#    exists) nest under it in one trace.
with tracer.start_as_current_span("triage_payments_backlog") as span:
    span.set_attribute("app.speed", "fast" if FAST else "standard")
    extra = {"speed": "fast"} if FAST else {}
    t0 = time.perf_counter()

    runner = client.with_options(
        open_telemetry={**client.open_telemetry, "conversation_id": "triage-demo-1"}
    ).beta.messages.tool_runner(
        model="claude-opus-5-5",
        max_tokens=2048,
        tools=[list_open_tickets, get_ticket_details],
        messages=[{"role": "user", "content":
                   "List the payments team's open tickets, open the oldest one, and write "
                   "a 5-bullet triage note with a likely root cause and a first fix."}],
        **extra,
    )
    final = runner.until_done()
    elapsed = time.perf_counter() - t0

    print("\n".join(b.text for b in final.content if b.type == "text"))
    print(f"\n⏱  {elapsed:.1f}s · output tokens (last turn): {final.usage.output_tokens}"
          f" · speed used: {getattr(final.usage, 'speed', 'n/a')}")

provider.shutdown()  # flush spans before exit

Step 2 — Run it locally (2 min)

python traced_agent.py

Scroll through the console output. You'll see JSON spans named anthropic.messages.tool_runner, anthropic.messages.create (one per round trip) and anthropic.custom_tool_use list_open_tickets, each with timing, gen_ai.usage.* token counts and, because we chose content mode, the full prompt and response. They all share one trace ID under your triage_payments_backlog span.

Step 3 — Ship the traces to Langfuse (5 min)

  1. Sign up at cloud.langfuse.com (free) or self-host it, create a project, and go to Settings → API Keys to create a key pair.

  2. Build the Basic-auth string from public:secret:

# bash / Git Bash
export AUTH=$(echo -n "pk-lf-xxx:sk-lf-xxx" | base64 -w 0)
export OTEL_EXPORTER_OTLP_ENDPOINT="https://cloud.langfuse.com/api/public/otel"   # US: https://us.cloud.langfuse.com/...
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Basic ${AUTH},x-langfuse-ingestion-version=4"
# PowerShell
$env:AUTH = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes("pk-lf-xxx:sk-lf-xxx"))
$env:OTEL_EXPORTER_OTLP_ENDPOINT = "https://cloud.langfuse.com/api/public/otel"
$env:OTEL_EXPORTER_OTLP_HEADERS  = "Authorization=Basic $($env:AUTH),x-langfuse-ingestion-version=4"
  1. Run python traced_agent.py again and open Tracing in Langfuse. You'll get a waterfall: your span → tool runner → two or three model calls, with the 0.4 s list_open_tickets tool clearly visible between them.

💡 The x-langfuse-ingestion-version=4 header makes traces appear in real time. Without it, OTel data can take up to 10 minutes to show up.

Step 4 — Is fast mode worth 2× the price? Measure it (5 min)

python traced_agent.py            # run 3x
python traced_agent.py --fast     # run 3x

In Langfuse, filter by app.speed and compare the anthropic.messages.create durations. Before you judge the results, keep these points from the docs in mind:

  • Fast mode raises output tokens per second (up to 2.5×). It does not cut time-to-first-token. Long answers and code generation gain the most; short tool-calling turns gain little.

  • Fast and standard requests don't share the prompt cache. Switching speeds mid-conversation is a cache miss.

  • Fast mode isn't available with the Batch API, Priority Tier, or on Claude Platform on AWS. It needs the Start, Build or Scale usage tier (not Evaluation).

  • usage.speed in the response tells you which speed was actually used. On a 429, the SDK retries twice, or you can fall back to standard by retrying without speed.

Rule of thumb: use fast mode where a human is waiting on a long answer, such as interactive code generation or live demos. Keep standard speed for background agents and batch jobs. Now you have a trace to back that up.

Step 5 (admin, optional) — Turn on server-side spans (5 min)

Ask an org admin to open Console → Settings → OpenTelemetry → Add destination, pick Langfuse as the provider, choose the region, paste the keys, and select the workspaces. Then click Test in the destination's menu and look for the anthropic.test span.

You can also do it from the CLI:

ant auth login --profile admin --scope "org:admin"
ant --profile admin beta:organization:telemetry-destinations create \
  --endpoint-url https://cloud.langfuse.com/api/public/otel \
  --headers '{authorization: "Basic <BASE64_PK:SK>"}' \
  --traces.content-mode metadata_only \
  --workspaces.type all

Run the script again. Each anthropic.messages.create CLIENT span now has a SERVER child (service.name = claude-platform) with anthropic.model_request spans inside it. For Managed Agents, you get one anthropic.session.turn per turn, including sub-threads from multi-agent runs. Group by anthropic.session.id to see the whole session, or by gen_ai.conversation.id to read one thread as a transcript.

Shortcut: the docs suggest simply asking Claude Code: "Set up OpenTelemetry tracing with the Claude API and Claude SDK." Claude Code 2.1.301 added OTel guidance to the built-in claude-api skill for exactly this.


4. Gotchas we found in the docs (read before you build dashboards)

  1. Don't double-count tokens. The SDK span and the API span are both named anthropic.messages.create. Tell them apart by span kind (CLIENT vs SERVER) or service.name. Per request, sum one source only. For Managed Agents, sum anthropic.model_request + anthropic.session.outcome_evaluation.

  2. gen_ai.usage.input_tokens already includes cache reads and writes. Don't add the cache attributes on top.

  3. Traces aren't billing. Delivery is best effort and spans can be lost or duplicated (dedupe on trace ID + span ID). For per-key usage, such as spotting a leaked key, use the Usage API.

  4. Full content means your prompts leave Anthropic. The observability vendor stores them under its retention rules. Use metadata_only for customer data unless security has approved it. Orgs with HIPAA, FERPA or K-12 restrictions always export metadata only.

  5. Streams: the span ends only when you finish reading or close the stream. Content is captured only with messages.stream().

  6. Node users: if you use @opentelemetry/auto-instrumentations-node, set openTelemetry: { propagation: false }. An undici bug otherwise adds a second traceparent header and breaks the trace context.

  7. Self-hosted collectors: the API only sends to HTTPS on 443, while the Collector's OTLP/HTTP default is 4318. Put a reverse proxy in front of it.

  8. conversation_id is always exported, even in metadata-only mode, so never put emails or user names in it.


5. Where we could use this right away

Use case

What to look at in the trace

"Why is the bot slow today?"

Waterfall: model time vs. our tool or API time

Cost per feature / per team

Sum gen_ai.usage.* grouped by our own span names or workspace

Agent review before widening its access

Full-content traces of every tool call and its arguments (gen_ai.tool.call.arguments)

Building evals from production

Export real conversations from Langfuse into a dataset

Fast vs standard, Haiku vs Opus decisions

A/B durations and token counts, with evidence instead of gut feel


6. Also new this week in the Claude ecosystem

  • Fast mode GA for Opus 5.5 (Oct 15): no beta header and no access request. It has a default rate limit in Start/Build/Scale tiers and is also on Microsoft Foundry (Azure-hosted deployments).

  • Claude Code 2.1.300 → 2.1.301:

    • Claude Code's own trace spans now carry GenAI semantic-convention attributes (gen_ai.provider.name, gen_ai.conversation.id, gen_ai.tool.name, error.type), so Claude Code, SDK and API traces line up in one backend.

    • OTel tool_decision events gained classifier_verdict, permission_mode and classifier_category, so you can tell auto-mode classifier blocks apart from permission rules.

    • api_request events now split cache writes into cache_creation_5m_tokens / cache_creation_1h_tokens.

    • Also: vim % motion, CLAUDE_CODE_RETRY_WATCHDOG_MAX_USAGE_LIMIT_WAIT_MS, and a smarter summary when you switch to a smaller-context model.

  • Managed Agents scheduled deployments are now available on Claude Platform on AWS (Oct 14).

  • Compliance API (Enterprise, beta, Oct 15) now returns users' saved Instructions for Claude and Cowork Global instructions.

  • Anthropic opened a Singapore office and signed an MOU with the Government of Singapore (Oct 14). That's relevant if you work with customers in APAC.

7. On the GitHub radar (weekly trending, Oct 16)

  • morluto/rea ("Reverse Engineer Anything") is this week's runaway #1. It's an MCP server that lets Claude Code, Codex, Cursor and others analyze binaries, Electron/JS apps, .NET assemblies, APKs and network captures, with evidence for every claim. Setup: npx rea-agents setup. MIT. Use it only on software you own or are authorized to examine, and install only from the official repo or npm package, because look-alike copies exist.

  • heygen-com/hyperframes: write HTML, render deterministic MP4 video, built for agents. It's a Claude Code plugin: claude plugin marketplace add heygen-com/hyperframes and then claude plugin install hyperframes@hyperframes. Apache-2.0. It's handy for release-note videos and demo clips.

  • mattpocock/skills: a well-known engineer's personal agent-skills directory, still climbing.

  • cathrynlavery/diagram-design: 44 editorial diagram types as self-contained HTML/SVG for AI coding tools.

(Star counts on github.com/trending moved by tens of thousands between snapshots this week, so we've left them out.)


Your 3-step challenge for today

  1. ☐ Run traced_agent.py locally and find your custom_tool_use span in the console output.

  2. ☐ Send it to Langfuse and run the fast vs standard A/B three times each. Post the median durations in the team channel.

  3. ☐ Pick one of our Claude-powered services and wrap its main handler in a span. Next week, ask an admin to add a metadata-only destination for its workspace.

Show us your waterfalls, especially the surprising ones. 🔍🚀


Sources

  • Claude Docs: OpenTelemetry overview · SDK tracing · API tracing / destinations · Span reference · Fast mode · Pricing · Tool runner

  • Claude Platform release notes (Oct 14 & 15, 2026)

  • Launch article: Trace agents with OpenTelemetry on the Claude Platform · New Relic

  • Langfuse: Claude Platform integration · OpenTelemetry endpoint

  • Claude Code CHANGELOG (v2.1.300 – 2.1.301) · Anthropic News

  • GitHub radar: github.com/trending (weekly) · gittrend.io AI agents

##ai#ai#research
Y
Be kind. Markdown supported. · @ to mention
TL;DR1. Why this matters: agents are black boxes until you trace them2. The key facts (from the official docs)3. Hands-on: trace an agent, then measure fast mode (25 min)Step 0 — Setup (3 min)Step 1 — Save this as traced_agent.pyStep 2 — Run it locally (2 min)Step 3 — Ship the traces to Langfuse (5 min)Step 4 — Is fast mode worth 2× the price? Measure it (5 min)Step 5 (admin, optional) — Turn on server-side spans (5 min)4. Gotchas we found in the docs (read before you build dashboards)5. Where we could use this right away6. Also new this week in the Claude ecosystem7. On the GitHub radar (weekly trending, Oct 16)Your 3-step challenge for todaySources

Related posts

Use the Claude Code extension in Cursor? Check your machine for the 2.1.312 / 2.1.313 backdoor in 2 minutes

TL;DR On 2026-10-29, malicious builds of the Claude Code extension (versions 2.1.312 and 2.1.313) were on the Cursor marketplace for about 11 hours. They tried

HLHung LayNov 2, 20261 min
0 0 0

Lock down any MCP server or agent command with one word: Anthropic's srt sandbox, no container needed

TL;DR srt is Anthropic's open-source sandbox CLI, the same engine that Claude Code's /sandbox mode is built on. Put srt in front of any command or local MCP ser

HLHung LayOct 29, 20261 min
0 0 1

Claude Code on Bedrock or Vertex with a custom model name? Keep the full system prompt after the 2.1.312 update with one setting

TL;DR What it is: Claude Code 2.1.312 (released 2026-10-27) now sends a shorter system prompt when your model name is one it does not recognize on Bedrock, Vert

HLHung LayOct 29, 20261 min
0 0 0

Turn Claude Code into a security auditor that checks its own findings: Cloudflare's security-audit skill, installed in 2 minutes

TL;DR What it is: cloudflare/security-audit-skill is one agent skill that makes Claude Code run a six-phase security audit, where a different agent tries to dis

HLHung LayOct 28, 20261 min
0 0 4

More from Hung Lay

Use the Claude Code extension in Cursor? Check your machine for the 2.1.312 / 2.1.313 backdoor in 2 minutes

TL;DR On 2026-10-29, malicious builds of the Claude Code extension (versions 2.1.312 and 2.1.313) were on the Cursor marketplace for about 11 hours. They tried

HLHung LayNov 2, 20261 min
0 0 0

Lock down any MCP server or agent command with one word: Anthropic's srt sandbox, no container needed

TL;DR srt is Anthropic's open-source sandbox CLI, the same engine that Claude Code's /sandbox mode is built on. Put srt in front of any command or local MCP ser

HLHung LayOct 29, 20261 min
0 0 1

Claude Code on Bedrock or Vertex with a custom model name? Keep the full system prompt after the 2.1.312 update with one setting

TL;DR What it is: Claude Code 2.1.312 (released 2026-10-27) now sends a shorter system prompt when your model name is one it does not recognize on Bedrock, Vert

HLHung LayOct 29, 20261 min
0 0 0

Turn Claude Code into a security auditor that checks its own findings: Cloudflare's security-audit skill, installed in 2 minutes

TL;DR What it is: cloudflare/security-audit-skill is one agent skill that makes Claude Code run a six-phase security audit, where a different agent tries to dis

HLHung LayOct 28, 20261 min
0 0 4