CLAUDE LABEN
MCP — エンタープライズ管理型MCPコネクタが追加。管理者が一度繋げばユーザーは初回ログイン時にゼロタッチで利用できます(Okta連携・Team/Enterpriseベータ)LEGAL — 法務向けMCPコネクタ20以上と実務領域プラグイン12本が公開され、リサーチ・契約・案件管理を扱えますAGENTS — Code w/ ClaudeでManaged Agentsを発表。計画を立て数百のサブエージェントへ分配し、出力を検証してから返しますLIMIT — Pro・Max・Team・EnterpriseのClaude Code 5時間レート枠が2倍に拡大されましたBILLING — 6/15予定だったAgent SDK等の課金分離は撤回(保留)され、従来どおりサブスク上限内で扱われますFIX — スピナーの固着やサブエージェントのトランスクリプト不整合など、Claude Codeの安定性修正が続いていますMCP — エンタープライズ管理型MCPコネクタが追加。管理者が一度繋げばユーザーは初回ログイン時にゼロタッチで利用できます(Okta連携・Team/Enterpriseベータ)LEGAL — 法務向けMCPコネクタ20以上と実務領域プラグイン12本が公開され、リサーチ・契約・案件管理を扱えますAGENTS — Code w/ ClaudeでManaged Agentsを発表。計画を立て数百のサブエージェントへ分配し、出力を検証してから返しますLIMIT — Pro・Max・Team・EnterpriseのClaude Code 5時間レート枠が2倍に拡大されましたBILLING — 6/15予定だったAgent SDK等の課金分離は撤回(保留)され、従来どおりサブスク上限内で扱われますFIX — スピナーの固着やサブエージェントのトランスクリプト不整合など、Claude Codeの安定性修正が続いています
記事一覧/API & SDK
API & SDK/2026-06-20上級

Cloudflare AI Gateway を Claude の手前に置くと、見えるはずの数字が見えなくなる — 運用で効いた計装メモ

Cloudflare AI Gateway を Claude API の前段に置いたあと、コスト按分・セマンティックキャッシュの誤ヒット・フォールバックの静かな品質低下・予算の実効化で実際につまずいた箇所と、その手当てをコード付きでまとめます。

Claude API80Cloudflare AI Gateway本番運用27コスト最適化17セマンティックキャッシュフォールバック3Cloudflare Workers13観測性

プレミアム記事

ゲートウェイを入れた翌週、コストの内訳が読めなくなった

Cloudflare AI Gateway を Claude API の前段に入れる動機は、たいてい四つに集約されます。リクエストを可視化したい、スパイクでレート上限に当たる前に自分で絞りたい、重複呼び出しをキャッシュで削りたい、モデル障害時に別モデルへ逃がしたい。どれも正当な要求で、ゲートウェイは確かにそれらを一枚のマネージドレイヤーで引き受けてくれます。

ところが、個人開発者として Dolice Labs の4サイトのコンテンツ生成パイプラインの前段にこれを入れた翌週、私自身が直面したのは「入れる前より内訳が読めなくなった」という逆説でした。総コストとレイテンシのグラフは綺麗に出る。けれど「どの機能が、どのバッチが、どれだけ使ったのか」がダッシュボードからは落ちていたのです。ゲートウェイは通信を仲介するだけなので、こちら側の文脈を渡さなければ、すべてのリクエストは区別のつかない一塊として記録されます。

この記事は、ゲートウェイ導入の手順書ではありません。導入したあとに「思っていたほど見えない・効かない」と気づく四つの箇所——コスト按分・キャッシュの誤ヒット・フォールバックの静かな品質低下・予算の実効化——について、実際に手を入れたコードと判断を残しておきます。

まず、計装の文脈をリクエストに括り付ける

ゲートウェイのログを後から絞り込めるかどうかは、リクエストを投げる瞬間にメタデータを括り付けたかどうかで決まります。cf-aig-metadata ヘッダに渡した値はそのままログに残るので、ここに「あとで按分したい軸」を全部入れておきます。私の場合は「どのサイトの」「どの生成種別の」「どのバッチ実行の」という三軸でした。

// src/lib/claude-gateway.ts
import Anthropic from "@anthropic-ai/sdk";
 
const GATEWAY_BASE_URL = process.env.CLOUDFLARE_GATEWAY_URL;
const ANTHROPIC_API_KEY = process.env.ANTHROPIC_API_KEY;
 
if (!GATEWAY_BASE_URL || !ANTHROPIC_API_KEY) {
  throw new Error("CLOUDFLARE_GATEWAY_URL と ANTHROPIC_API_KEY の両方が必要です");
}
 
// baseURL をゲートウェイに差し替えるだけで、既存の SDK 呼び出しはそのまま通る
const client = new Anthropic({
  apiKey: ANTHROPIC_API_KEY,
  baseURL: GATEWAY_BASE_URL,
});
 
export interface CallContext {
  site: string;       // 例: "claudelab"
  workload: string;   // 例: "recovery" / "brushup" / "daily"
  runId: string;      // バッチ単位の識別子
}
 
export async function gatewayChat(
  params: Anthropic.MessageCreateParamsNonStreaming,
  ctx: CallContext
) {
  return client.messages.create(params, {
    headers: {
      // ここに入れた値が AI Gateway のログに残り、後から軸で絞れる
      "cf-aig-metadata": JSON.stringify({
        site: ctx.site,
        workload: ctx.workload,
        runId: ctx.runId,
        ts: new Date().toISOString(),
      }),
    },
  });
}

なぜ baseURL の差し替えだけで済むかというと、Anthropic の TypeScript SDK は HTTP の宛先を baseURL で受け取り、認証ヘッダやリトライ処理はそのまま使い回すからです。ゲートウェイは Anthropic 互換のパスを通すので、アプリ側のロジックは一行も変えずに済みます。逆に言えば、メタデータを渡し忘れたリクエストは「匿名の一塊」としてしか記録されません。導入直後の私のログがまさにこれでした。

按分の集計は、Logs API を叩いてメタデータでグループ化します。ここで初めて「どのワークロードが効いているか」が数字になります。

// src/lib/gateway-attribution.ts
interface CostByWorkload {
  [workload: string]: { requests: number; tokens: number; usd: number };
}
 
// モデル別の概算単価(USD / 1M tokens, 2026-06 時点・入力基準の概算)
const INPUT_PRICE: Record<string, number> = {
  "claude-haiku-4-5": 1,
  "claude-sonnet-4-6": 3,
  "claude-opus-4-8": 15,
};
 
export async function attributeCost(
  accountId: string,
  gatewayId: string,
  apiToken: string,
  since: Date
): Promise<CostByWorkload> {
  const url =
    `https://api.cloudflare.com/client/v4/accounts/${accountId}` +
    `/ai-gateway/gateways/${gatewayId}/logs?since=${since.toISOString()}`;
 
  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${apiToken}` },
  });
  const { result = [] } = await res.json();
 
  const acc: CostByWorkload = {};
  for (const log of result) {
    const meta = safeParse(log.metadata);
    const key = meta?.workload ?? "unattributed";
    const price = INPUT_PRICE[log.model] ?? 3;
    const usd = (log.tokens_in ?? 0) * (price / 1_000_000);
    acc[key] ??= { requests: 0, tokens: 0, usd: 0 };
    acc[key].requests += 1;
    acc[key].tokens += log.tokens_in ?? 0;
    acc[key].usd += usd;
  }
  return acc;
}
 
function safeParse(s: unknown) {
  try { return typeof s === "string" ? JSON.parse(s) : s; } catch { return null; }
}

"unattributed" のバケツが膨らんでいたら、それはメタデータを渡し損ねている呼び出しが残っているサインです。私はこの数字をゼロに寄せることを、計装が完成したかどうかの目安にしています。

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

この記事の続きを読む

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

この記事で得られること
ゲートウェイのダッシュボードだけでは欠ける『機能別・ユーザー別のコスト按分』を、メタデータ設計で復元する具体的な手順
セマンティックキャッシュが似て非なる質問に古い答えを返す誤ヒットを、キャッシュキー名前空間とスキップ条件で抑える実装
フォールバックが『落ちない代わりに静かに品質を下げる』挙動を可視化し、予算超過を本当に止めるゲートのコード
Stripe による安全な決済 · いつでもキャンセル可能

この記事を購入する

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

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

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

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

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

関連記事

API & SDK2026-05-02
Claude API × LiteLLM でコスト最適化マルチプロバイダー AI ゲートウェイを本番設計する — フォールバック・A/B テスト・プロバイダー移行戦略
LiteLLMを使いClaude APIを中心とした本番マルチプロバイダーAIゲートウェイを構築。フォールバック設計・A/Bテスト・コストベースルーティング・プロバイダー移行戦略まで実装コード付きで解説。
API & SDK2026-06-20
effort パラメータを工程ごとに振り分けて Claude の出力コストと待ち時間を整える
Claude API の effort パラメータは思考・本文・ツール呼び出しを含む出力トークン全体を制御します。一律 high をやめ、工程ごとに段階配分する実装と動的ルーターを、個人開発の自動運用での実測とともに解説します。
API & SDK2026-06-17
Claude API のドキュメント抽出が「確信を持って間違える」とき — 検証層の設計メモ
Claude API で請求書や契約書を構造化抽出するとき、最も怖いのは例外ではなく「もっともらしく間違った JSON」です。スキーマ検証・算術整合・二重抽出の一致率で誤抽出を本番前に捕まえる検証層を、TypeScript の実装とともにまとめました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →