CLAUDE LABEN
FORK — Claude Code 2.1.212で/forkの挙動が変わりました。会話を新しいバックグラウンドセッションへ複製し、作業を続けたまま並走できます。従来のセッション内サブエージェントは/subtaskに移りましたLIMITS — WebSearchの呼び出しがセッション単位で既定200回に制限されました。サブエージェントの起動も既定200回が上限で、暴走した検索・委譲のループを止められますMCPBG — 2分を超えるMCPツール呼び出しは自動的にバックグラウンドへ移り、セッションが固まらなくなりました。しきい値はCLAUDE_CODE_MCP_AUTO_BACKGROUND_MSで調整できますPLANFIX — プランモードがtouchやrmといったファイルを変更するBashコマンドを、許可プロンプトもcanUseToolコールバックも通さずに実行してしまう不具合が修正されましたSONNET5 — Claude Sonnet 5は導入価格として入力100万トークンあたり2ドル、出力10ドルで提供中です。8月31日を過ぎると3ドルと15ドルに戻りますIPO — Anthropicが早ければ10月の株式公開を視野に、引受銀行が投資家との面談を組み始めたと報じられていますFORK — Claude Code 2.1.212で/forkの挙動が変わりました。会話を新しいバックグラウンドセッションへ複製し、作業を続けたまま並走できます。従来のセッション内サブエージェントは/subtaskに移りましたLIMITS — WebSearchの呼び出しがセッション単位で既定200回に制限されました。サブエージェントの起動も既定200回が上限で、暴走した検索・委譲のループを止められますMCPBG — 2分を超えるMCPツール呼び出しは自動的にバックグラウンドへ移り、セッションが固まらなくなりました。しきい値はCLAUDE_CODE_MCP_AUTO_BACKGROUND_MSで調整できますPLANFIX — プランモードがtouchやrmといったファイルを変更するBashコマンドを、許可プロンプトもcanUseToolコールバックも通さずに実行してしまう不具合が修正されましたSONNET5 — Claude Sonnet 5は導入価格として入力100万トークンあたり2ドル、出力10ドルで提供中です。8月31日を過ぎると3ドルと15ドルに戻りますIPO — Anthropicが早ければ10月の株式公開を視野に、引受銀行が投資家との面談を組み始めたと報じられています
記事一覧/API & SDK
API & SDK/2026-05-29上級

Claude API の本番観測性を OpenTelemetry GenAI 規約で再設計する — モデル移行とコスト監査に耐える設計メモ

Claude API を組み込んだプロダクションサービスの観測性を、OpenTelemetry GenAI セマンティック規約に揃えて再設計するための実装メモ。スパン属性、メトリクス、コスト追跡、モデル切替時のリプレイ性を、個人開発サービスで運用してきた経験から具体的なコードで示します。

Claude API115OpenTelemetry2Observability2Production2Cost MonitoringGenAI

プレミアム記事

2014 年からの 12 年、AdMob 月収 150 万円規模の壁紙アプリ群を 1 人で回してきて学んだのは、観測性は「あったほうがよい」ではなく「ないと夜中に起きる回数が増える」ものだということでした。Claude API を本番サービスに組み込んでから半年、私が真っ先に詰まったのも観測性の標準化です。Anthropic の SDK は usage オブジェクトを返してくれますが、それをどう Prometheus と Datadog と Grafana にまたがる既存の運用ダッシュボードへ載せるか、Cloudflare Workers と Node ランタイムでスパン属性をどう揃えるかは自分で決めるしかありません。

OpenTelemetry には 2024 年に GenAI 向けセマンティック規約 (Semantic Conventions for GenAI) のドラフトが入り、2025 年に主要属性が安定化しています。これに揃えておくと、後で AWS Bedrock や Vertex AI と相乗りすることになっても、ダッシュボードのクエリが基本的に壊れません。本稿はその規約に沿って Claude API のスパンと指標を設計し直したときの記録です。Dolice Labs の 4 サイト並行運用 (Claude Lab / Gemini Lab / Antigravity Lab / Rork Lab) と、個人開発のアプリ群の両方で実装した結果を、コードと数値つきで残します。

なぜ独自スパン属性ではなく OpenTelemetry GenAI 規約に寄せるのか

最初の 3 ヶ月、私は anthropic.prompt_tokens anthropic.output_tokens anthropic.model といった独自属性で計装していました。動きはしましたが、3 つの実害が出ました。

ひとつ目は、Gemini Lab 側で Gemini API に同じダッシュボードを当てたい場面で、属性名が違うため Grafana の sum by 集約が機能しなかったこと。ふたつ目は、Datadog の APM 側でモデル別レイテンシを比較したかったのに、属性名が独自すぎて検索 UI に予測候補が出ず、毎回タグ名をコピペする運用になっていたこと。3 つ目は、新しく入る OSS の LLM ゲートウェイ製品 (LiteLLM, Helicone, Cloudflare AI Gateway) が GenAI 規約を前提に出してくるようになり、自分の独自属性とぶつかって混乱したことです。

OpenTelemetry GenAI 規約はその名の通り「生成 AI 共通」を狙っているので、gen_ai.system = "anthropic" gen_ai.request.model = "claude-sonnet-4-6" のようにベンダー名と実モデルを分けて持つだけで、後から系列が増えても整理がつきます。本番で 3 系統 (Claude / Gemini / OSS) を混ぜている個人開発者にとって、ここを揃えておくメリットは想像より大きく出ます。

Claude API 呼び出しに当てるスパン属性の最小セット

私が現在 4 サイト全体で標準化している属性は以下の通りです。OpenTelemetry GenAI 規約のうち、Anthropic API で意味があるものだけを抜粋しています。

// src/lib/otel-claude.ts
import { trace, SpanStatusCode } from "@opentelemetry/api";
import Anthropic from "@anthropic-ai/sdk";
 
const tracer = trace.getTracer("dolice.claude-api", "1.0.0");
const client = new Anthropic();
 
export async function tracedMessage(params: {
  model: string;
  system?: string;
  messages: Array<{ role: "user" | "assistant"; content: string }>;
  max_tokens: number;
  cache_control?: { type: "ephemeral" };
}) {
  return await tracer.startActiveSpan(
    `chat ${params.model}`,
    {
      attributes: {
        // GenAI semantic conventions
        "gen_ai.system": "anthropic",
        "gen_ai.operation.name": "chat",
        "gen_ai.request.model": params.model,
        "gen_ai.request.max_tokens": params.max_tokens,
        // 自社固有 — 本番ではテナント単位課金やレート制限で必須
        "dolice.tenant_id": currentTenantId(),
        "dolice.surface": currentSurface(), // "claudelab" | "gemilab" | "app:wallpaper" 等
      },
    },
    async (span) => {
      try {
        const startedAt = performance.now();
        const res = await client.messages.create({
          model: params.model,
          system: params.system,
          messages: params.messages,
          max_tokens: params.max_tokens,
        });
 
        span.setAttributes({
          "gen_ai.response.id": res.id,
          "gen_ai.response.model": res.model, // 実際にサーブされたモデル名
          "gen_ai.response.finish_reasons": JSON.stringify([res.stop_reason]),
          "gen_ai.usage.input_tokens": res.usage.input_tokens,
          "gen_ai.usage.output_tokens": res.usage.output_tokens,
          // Anthropic 固有 — キャッシュ系は規約外なのでベンダープレフィックス推奨
          "anthropic.usage.cache_creation_input_tokens":
            res.usage.cache_creation_input_tokens ?? 0,
          "anthropic.usage.cache_read_input_tokens":
            res.usage.cache_read_input_tokens ?? 0,
          "dolice.latency_ms": Math.round(performance.now() - startedAt),
        });
        span.setStatus({ code: SpanStatusCode.OK });
        return res;
      } catch (err) {
        span.recordException(err as Error);
        span.setStatus({
          code: SpanStatusCode.ERROR,
          message: (err as Error).message,
        });
        if (err && typeof err === "object" && "status" in err) {
          span.setAttribute("http.response.status_code", (err as any).status);
        }
        throw err;
      } finally {
        span.end();
      }
    },
  );
}

ここで意図的に外した属性が 2 つあります。gen_ai.prompt (入力本文) と gen_ai.completion (出力本文) です。規約では opt-in になっており、私は 2 つの理由で本番ではデフォルト OFF にしています。

  1. PII / 著作物の漏洩リスク。私のアプリでは引き寄せ系・癒し系の入力に個人の悩み事が入ることがあり、観測基盤に流すべきではありません。
  2. Datadog のインデックスコスト。1 件のスパンに数百〜数千トークン分の本文を載せるとログ単価が一気に跳ねます。月 300 万呼び出しで実測しましたが、本文を載せたケースは載せないケースの 7.3 倍のストレージ料金になりました。

代わりに、後述するリプレイ用ダンプは別バケットに JSONL で隔離し、TTL 30 日で消す運用にしています。

ここまでお読みいただきありがとうございます。

この記事の続きを読む

この先には、実装コードやベンチマーク結果など、実務でお役に立てる内容をご用意しています。このサイトは広告を掲載しておらず、サーバーや開発にかかる費用はメンバーの皆様のご支援で成り立っています。もしお役に立てていましたら、ご支援いただけますと大変ありがたいです。

この記事で得られること
Claude API 呼び出しに付ける GenAI 規約準拠のスパン属性 (gen_ai.system / gen_ai.request.model / gen_ai.usage.input_tokens 等) の具体配置例
入出力トークン・キャッシュヒット率・$0.003/$0.015 単価の3軸でコスト追跡する PromQL/SQL クエリと、月次の課金 ±5% 以内の整合性検証手順
claude-sonnet-4-6 から claude-opus-4-6 への切替時にリプレイ用ダンプとシャドートラフィックを 24 時間流して回帰検知する Python 実装
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

この先の内容をすべてお読みいただけます。一度のご購入で、いつでも何度でもアクセスできます。このサイトは広告を掲載しておらず、皆さまのご支援がサーバー費用などの運営を支えています。

または
メンバーシップなら全記事が読み放題 →
シェア

お読みいただきありがとうございます

Claude Lab は広告なしで運営しており、サーバー費用などの運営コストはメンバーシップのご支援で賄っています。実装コード・ベンチマーク・本番設計パターンなど、実務でお役立ていただける記事を毎日更新しています。もし読んでよかったと感じていただけましたら、ぜひご覧ください。

  • コピー&ペーストで使える実装コード付き
  • 毎日新しい上級ガイドを追加
  • ¥580/月 または ¥1,480 の永久アクセス
メンバーシップを見る →

関連記事

API & SDK2026-04-25
Claude API × Convex でリアクティブな AI アプリを本番構築する — データフロー設計とエージェントパターン
Convex のリアクティブデータベースと Claude API を組み合わせて、本番運用に耐えるチャット・エージェント系アプリを構築する方法をまとめました。スキーマ設計、Action/Mutation/Query の境界、ストリーミング、ツール状態管理、冷え始めの落とし穴まで、開発現場の判断軸を共有します。
API & SDK2026-07-13
画像を原寸で送るか縮小するか — Opus 4.7 の高解像度ビジョンで1枚ごとに解像度を決めるコスト設計
Opus 4.7 の高解像度ビジョンで壁紙の細部分類は上がったのに、全部を原寸で送ったら週のトークンが跳ねました。1枚ごとに解像度と使うモデルを決める preflight を設計し、精度を保ったままコストを下げた実測を残します。
API & SDK2026-07-12
Claude API の 413 request too large を設計で避ける — 送信前サイズ見積もりと分割の実装
長文と画像と tool_result を1リクエストに詰めすぎると Claude API は 413 request too large で落ちます。32MB の壁・base64 の膨張・処理段階で起きる隠れた上限を実測し、送信前にサイズを見積もって安全に分割する設計をコード付きでまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →