Claude APIのOpenTelemetry比較 — SDK tracingとAPI tracingの選び方
Claude APIのOpenTelemetryトレースは、SDK tracingとAPI tracingで見える範囲が違います。必要な権限・対応クラウド・併用で1本のトレースになる条件を表で比べます。
Claude APIのOpenTelemetry出力には、アプリ側のSDKが出す「SDK tracing」と、Claude Consoleに送信先を登録して受け取る「API tracing」の2系統があります。見える範囲は重なりつつ、片方にしかないものがあります。
結論から言うと、モデルの1回ごとの実行やManaged Agentsのターンを見たいならAPI tracing、自前のツール実行や権限のない環境で始めたいならSDK tracingです。両方入れると、1リクエストのスパンが1本のトレースにつながります。なお、OpenTelemetry出力はベータ機能です。
SDK tracingとAPI tracingで何が見えるか
OpenTelemetryでは、1リクエストの全記録を「トレース」、その中の1ステップ(モデル呼び出しやツール実行)を「スパン」と呼びます。Claude側のスパンはGenAIセマンティック規約の属性を使うので、規約に対応する観測基盤ならそのまま認識できます。
スパンを出す場所が違う
SDK tracing
SDKがアプリ内でスパンを出し、アプリのOpenTelemetry exporterが観測基盤へ送ります。
API tracing
APIがスパンを出します。Consoleに登録した送信先(destination)へ、コードを変えずに届きます。
見えるものと前提条件を、公式の比較表に沿って並べます。
| 項目 | SDK tracing | API tracing | 併用 |
|---|---|---|---|
| Messages APIのリクエスト | SDK tracing見える | API tracing見える | 併用見える |
| Sessions APIのリクエスト | SDK tracing見える | API tracing見える | 併用見える |
| トークン使用量 | SDK tracing見える | API tracing見える | 併用見える |
| リクエスト内の各モデル実行 | SDK tracing見えない | API tracing見える | 併用見える |
| Managed Agentsのターン | SDK tracing見えない | API tracing見える | 併用見える |
| APIが実行するサーバーツール | SDK tracing見えない | API tracing見える | 併用見える |
| tool runnerが実行するクライアントツール | SDK tracing見える | API tracing見えない | 併用見える |
| セルフホストsandbox内のツール | SDK tracing見える | API tracing見えない | 併用見える |
| ファイルアップロードなど他のAPIリクエスト | SDK tracing見える | API tracing見えない | 併用見える |
| 必要な権限 | SDK tracing不要 | API tracing管理者(Admin) | 併用管理者(Admin) |
| カバー範囲 | SDK tracingSDKを使うクライアント | API tracing任意のクライアント | 併用任意のクライアント |
| 対応クラウド | SDK tracing制限なし | API tracingClaude Platform / Claude Platform on AWS | 併用同左 |
分かれ目は「誰がその処理を実行したか」です。サーバーツールとモデル実行はAPI側で動くのでAPI tracingに出ます。自分のアプリが動かすクライアントツールやセルフホストsandboxのツールは、API側からは見えないのでSDK tracingに出ます。
自分の状況ならどちらを入れるか
状況から逆引きすると、次のようになります。
- Console管理者の権限がない、または自分のコードだけで試したい: SDK tracingです。必要な権限はなく、コードにtracer providerを登録するだけで始められます
- Bedrock・Google Cloud・Microsoft Foundry経由でClaudeを使っている: SDK tracingです。API tracingの対応クラウドにこれらは載っておらず、SDK側の対応プラットフォームにはAmazon Bedrock・Google Cloud・Microsoft Foundryが含まれます
- SDKを使わないクライアント(別言語のHTTP直叩きなど)も追いたい: API tracingです。リクエストの送り手を問いません
- Managed Agentsのターンやモデル実行ごとの所要時間を見たい: API tracingです。SDK tracingにはこれらのスパンが出ません
- セルフホストsandboxでツールを動かしている: SDK tracingが必要です。sandboxが動かすツールのスパンはSDK側から出ます
- アプリの自前スパンの下にClaudeの処理をぶら下げたい: 併用です
API tracingを選ぶ場合は組織のConsoleで管理者権限が要ります。developerロールの人は送信先を見られるだけで、追加や変更はできません。Claude Platform on AWSを使う組織は、AWS Console経由でConsoleにサインインします。AWS上の運用はClaude Platform on AWSへの移行、クラウドごとのAPI機能差はBedrockとGoogle Cloudの比較にまとめています。
SDK tracingの設定
SDKをインストールし、アプリでtracer providerを登録します。tracer providerはスパンを作ってexporterに渡すOpenTelemetry側の部品で、SDKの呼び出しコード自体は変わりません。最初はコンソールにスパンを出力して形を確かめるのが手早い方法です。公式の例に沿ったPythonの形は次のとおりです。
from anthropic import Anthropic
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import ConsoleSpanExporter, SimpleSpanProcessor
provider = TracerProvider()
provider.add_span_processor(SimpleSpanProcessor(ConsoleSpanExporter()))
trace.set_tracer_provider(provider) # 最初の呼び出しより前に登録する
client = Anthropic()
message = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
messages=[{"role": "user", "content": "Hello, Claude"}],
)本番では、コンソールexporterをOTLP exporterに置き換えて観測基盤へ送ります。SDKの主な設定は次の表のとおりです。
| オプション | 役割 | 既定値 |
|---|---|---|
traces.content_mode(環境変数 ANTHROPIC_OPEN_TELEMETRY_TRACES_CONTENT_MODE) | 役割プロンプトと応答をスパンに含める | 既定値metadata_only |
traces.max_content_bytes | 役割スパンごとの内容の上限 | 既定値0.75 MB |
conversation_id | 役割複数の呼び出しを1つの会話にまとめる(gen_ai.conversation.idに書かれる) | 既定値なし |
open_telemetry | 役割クライアント単位でスパンを止める(ANTHROPIC_OPEN_TELEMETRY=false) | 既定値有効 |
conversation_idは両方のコンテンツモードで送信されるため、個人情報や秘密情報を入れないでください。また、クライアントにopen_telemetryを渡すと、その設定はANTHROPIC_OPEN_TELEMETRY*系の環境変数を丸ごと上書きします。ネストした項目を省くと、環境変数が設定されていても既定値に戻ります。
ベータ期間中は、SDKのバージョンが上がるとスパン名・属性名・オプション名・環境変数名が変わることがあると公式が注意しています。ダッシュボードやクエリを組むなら、SDKのバージョンを固定して移行のタイミングを自分で決めるのが安全です。
ストリーミングにも注意点があります。ストリームのanthropic.messages.createスパンは、ストリームを最後まで読むか閉じた時点で終わります。途中で読むのをやめるなら、必ず閉じてください。コンテンツモードで応答がスパンに入るのは、messages.stream()で読んだ場合に限られます。
API tracingの設定
API tracingは、Consoleで送信先を登録して使います。コード変更はありません。
API tracingを有効にする流れ
- 1
OTLP/HTTPエンドポイントを用意する
protobuf形式を受け付けるHTTPSのURLで、ポートは443です。自前のOpenTelemetry Collectorは既定で4318番で待ち受けるため、443で受けるか、手前にロードバランサーやリバースプロキシを置きます。
- 2
送信先を追加する
ConsoleのOpenTelemetry設定ページで「Add destination」を押し、Provider・エンドポイントURL・リクエストヘッダー・コンテンツモード・対象ワークスペースを入力します。
/v1/tracesはAPIが付けるので、URLに足さないでください。 - 3
Testで疎通を確かめる
送信先のメニューから「Test」を実行し、
anthropic.testスパンが観測基盤に届くか確かめます。 - 4
実リクエストで確認する
対象ワークスペースでリクエストを送り、Delivery列がHealthyになるのを待ちます。観測基盤では
service.nameがclaude-platformのスパンを探します。
Console以外に、Admin APIでも送信先を作れます。公式の例に沿ったcurlの形は次のとおりです。
curl --fail-with-body -sS \
"https://api.anthropic.com/v1/organizations/telemetry_destinations" \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: telemetry-destinations-2026-08-11" \
-H "content-type: application/json" \
-d '{
"endpoint_url": "https://gateway.example.com/otlp",
"headers": {"authorization": "Bearer YOUR_OBSERVABILITY_API_KEY"},
"traces": {"content_mode": "metadata_only"},
"workspaces": {"type": "all"}
}'ここでのANTHROPIC_API_KEYはAdmin APIキーです。通常のAPIキーでは送信先を作れません。ワークスペースは「All」「Selected」「All except」から選べます。APIは、リクエストやセッションが動くワークスペースを対象にしている有効な送信先すべてへスパンを送ります。
併用すると1本のトレースになる
API tracingだけだと、APIのスパンは既定でアプリのトレースとは別のトレースに入ります。つなぐ条件は2つです。
- SDK tracingを設定する
- 自分のスパンの内側でSDKを呼ぶ
こうすると、自分のスパンがSDKのスパンを含み、SDKのスパンがAPIのスパンを含みます。SDKはアプリのpropagatorを使って、traceparentヘッダーでトレースコンテキストをAPIへ渡しています。すべてを同じ観測基盤に送れば、1本のトレースとして表示されます。
tracer = trace.get_tracer("my-service")
with tracer.start_as_current_span("answer_question"):
message = client.messages.create(
model="claude-opus-5-5",
max_tokens=1024,
messages=[{"role": "user", "content": "今日の天気は?"}],
)公式が示すMessages APIの例では、tool runnerを使うリクエストの1回ごとに、SDKのクライアントスパンとAPIのサーバースパンが並びます。順番は次のとおりです。
tool runnerを使うトレースの並び
- 1自前のスパンが開始
answer_questionの中でtool runnerを呼ぶ(anthropic.messages.tool_runnerスパン)。 - 2最初のリクエスト
APIがweb searchツールを2回のモデル実行の間で動かす。モデルがカスタムの
get_weatherを要求して、リクエストが終わる。 - 3ツールをクライアントで実行
anthropic.custom_tool_use get_weatherスパン。ここはSDK側にしか出ない。 - 42回目のリクエスト
ツール結果を送り、モデルが最終回答を返す。
web searchの実行はAPI tracing、get_weatherの実行はSDK tracingでしか見えません。片方だけでは、トレースのどこかに穴が開きます。web searchの課金はweb_search料金の解説で扱っています。
Managed Agentsのセッションも同じ形です。Sessions APIのリクエストごとにスパンがあり、エージェントのターンごとにanthropic.session.turnスパンが付きます。ターンの中には、モデル実行・APIが動かすツール・outcome評価のスパンが入ります。カスタムツールlist_issuesが呼ばれるとターンはrequires_actionで終わり、ツール結果を送ると次のターンが始まります。
セッションのスパンは複数のトレースに分かれることがあります。たとえば、後のリクエストを新しいルートトレースから送った場合です。探し方はIDで決まります。
- 1つのスレッドを追う:
gen_ai.conversation.idでグループ化し、開始時刻で並べる - セッション全体(全スレッド)を追う:
anthropic.session.idでグループ化する(トレースをまたぐ)
セッションの状態遷移とイベントの追い方はManaged Agentsのworkflow runで扱っています。
併用時にトークンを二重に数えない
併用すると、同じリクエストがSDKとAPIの両方のスパンに出ます。両方ともanthropic.messages.createという名前で、種別(kind)で区別します。SDK側がCLIENT、その子のAPI側がSERVERです。トークンを集計するときは、1リクエストにつき片方の源だけを足します。
| 集計対象 | 足すスパン |
|---|---|
| SDKのスパン | 足すスパンanthropic.messages.create。compactionがあるならanthropic.usage.compaction.input_tokensとoutput_tokensも足す |
| Messages APIのAPIスパン | 足すスパンanthropic.messages.createかanthropic.model_requestのどちらか一方。compactionがあるならanthropic.compactionも足す |
| Managed AgentsのAPIスパン | 足すスパンanthropic.model_requestとanthropic.session.outcome_evaluation |
SDKとAPIの両方がある場合は、APIのスパンを足します。gen_ai.usage.input_tokensにはプロンプトキャッシュの読み書き分がすでに含まれるので、キャッシュ用の属性を足し込まないでください。スパンは再送で重複して届くことがあり、観測基盤が重複を除かないなら、トレースIDとスパンIDで1回だけ数えます。
出力されたスパンは、API利用量の完全な記録ではありません。配信はベストエフォートで、スパンが失われることがあります。呼び出し側がtraceparentのsampledフラグを落とせば、そのリクエストのスパンは出ません。APIキーごとの使用量を追うなら、スパンのない呼び出しも数えるUsage APIを使います。
コンテンツモードとデータの扱い
送信先とSDKクライアントには、それぞれコンテンツモードがあります。
- Metadata only(SDKでは
metadata_only): 既定です。識別子・所要時間・ステータス・トークン数と、エージェントやツールの名前・説明など、自分で決めて付けたテキストが入ります - Full content(SDKでは
content): プロンプトと応答も入ります。失敗や遅延の理由を読み、実トラフィックから評価データを作れます
Full contentのスパンには会話の中身が乗り、観測基盤側の保存・アクセス・保持の設定に従います。送る前に、組織の要件を満たすか確かめてください。HIPAA・FERPA・K-12のデータ取り扱い制限がある組織では、送信先の設定にかかわらずメタデータだけが出力されます。SDKのスパンには影響しません。Full contentで「プロンプトが空」になる場合は、まずここを疑う価値があります。
ゼロデータリテンション(ZDR)でもFull contentは使えます。Messages APIでは、APIが内容を配信まで保持するのはメモリ上だけです。一方、Managed AgentsはZDRの対象外で、OpenTelemetryを使ってもデータ保持の扱いは変わりません。
内容が上限を超えると、SDKやAPIが切り詰めてanthropic.content.truncatedをtrueにします。リクエストのスパンはシステムプロンプトと古いメッセージから先に落とします。既定の上限は1スパン0.75 MBです。200kトークンの英語テキストが収まり、多くの観測基盤やプロキシの1 MB上限を下回ります。1Mトークンの文脈をそのまま入れるには約4 MBが必要です。
配信の仕様と制限
API tracingの配信ルールは、運用で効いてくる順に押さえておくと安心です。
- 同じスパンが複数回届くことがある(at least once)。重複除去にはトレースIDとスパンIDを使う
- スパンは配信前に失われることがあり、失われたスパンは再送されない
- 最初のリクエストはgzip圧縮で送り、
400か415が返ると圧縮なしで即座に再送する - 接続やTLS、DNSの失敗、
408・429・5xxのときは、一定回数まで後で再試行する - エンドポイントは、TLSハンドシェイクとレスポンスヘッダーをそれぞれ5秒以内に返す必要がある。1回の配信は合計10秒でタイムアウトする
エンドポイントが3xxリダイレクトを返す、ホスト名が公開されていないIPアドレスに解決される、24時間すべての配信が失敗する、のいずれかで、APIは送信先を自動的に無効化します。直したあとはConsoleで「Enable」を押すと、約1分で再開します。
Consoleに出る配信エラーは、切り分けの手がかりになります。401・403は認証ヘッダーの誤り、404はエンドポイントURLかトレース用URLのパスの誤りです。
送信先の上限は、組織あたり10件(無効なものを含む)です。ほかに、1つの送信先で選べるワークスペースが1,000件、リクエストヘッダーが20個、ヘッダー値が4,096バイトなどの制限があります。
隣接するテレメトリとの違い
この記事で扱ったのは、Claude PlatformのMessages APIとManaged Agentsのトレースです。Claude Code・Agent SDK・Coworkのテレメトリは別の仕組みで、公式も別ページに分けています。
- Claude Codeの利用量とコスト: Claude CodeのOpenTelemetry
- Agent SDKで動かすエージェントの可観測化: Agent SDKのOpenTelemetry実装ガイド
- 組織の監査ログとの関係: Claude Compliance APIとOpenTelemetryの違い
まとめ
最小の構成は、権限のいらないSDK tracingでスパンの形をコンソールに出し、見たい範囲に穴があるかを確かめることです。Managed Agentsのターンやサーバーツールまで追う段階で、管理者にAPI tracingの送信先を登録してもらう流れが無理がありません。併用時は、トークンを足すスパンの源を1つに決めておくことで、二重計上を避けられます。