Claude Media
count_tokensで送信前にトークン数を数える方法とレート制限

count_tokensで送信前にトークン数を数える方法とレート制限

count_tokensエンドポイントで送信前にトークン数を見積もる手順と、Start/Build/Scale別のレート制限を実装コード付きでまとめます。

count_tokensで何が分かるか

count_tokens は、メッセージをClaudeに送る前にトークン数を見積もるエンドポイントです。呼び出しは無料で、実際のメッセージ生成とは別枠のレート制限で動きます。レート制限に近づいているかの事前チェック、モデルごとのコスト比較、プロンプトを目標の長さに収める作業のいずれにも使えます。長いドキュメントを分割して送る処理を組んでいるなら、分割前に各チャンクのトークン数を確認しておくことで、Claude APIのリクエストサイズ上限と413エラーの見分け方を踏まえてコンテキストウィンドウを超えるリクエストを送信前に弾けます。

ただし、メッセージ作成が受け付ける入力のすべてを数えられるわけではありません。サーバーツールやMCPコネクタを含むリクエストはエラーになります。この記事では、基本のテキストから、ツール・画像・thinking・PDFを含むリクエストまでの数え方と、429や400が返ったときにどの上限に当たったかを見分ける方法を扱います。

前提条件

  • Anthropic APIキー(platform.claude.com のConsoleにあるAPIキー画面で取得)
  • 現行の全アクティブモデルがcount_tokensに対応しています。モデルを限定して使える機能ではありません
  • カウント結果は見積もりです。実際にメッセージを送信したときのinput tokenと、小さな幅でずれることがあります
  • CLI経由でも呼び出せます(ant messages count-tokens)。curlやSDKを使わない検証にはこちらが手早く済みます

手順1: 基本のメッセージでトークン数を数える

/v1/messages/count_tokens に、実際のメッセージ作成と同じ形式のリクエストボディを投げます。返るのはinput_tokensの合計だけです。

curl https://api.anthropic.com/v1/messages/count_tokens \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "content-type: application/json" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
    "model": "claude-opus-5-5",
    "system": "You are a scientist",
    "messages": [{"role": "user", "content": "Hello, Claude"}]
  }'

レスポンスは{"input_tokens": 14}のようにシンプルです。カウント対象はシステムプロンプトを含むリクエスト全体で、Anthropicがシステム最適化のために自動で足すトークンが混ざることもあります。この自動追加分は課金対象外で、実際に課金されるのは自分のコンテンツ分だけです。SDKを使う場合はPython・TypeScriptともmessages.count_tokens / messages.countTokensという専用メソッドが用意されています。

Python / TypeScriptでの実装例
response = client.messages.count_tokens(
    model="claude-opus-5-5",
    system="You are a scientist",
    messages=[{"role": "user", "content": "Hello, Claude"}],
)
print(response.json())
const response = await client.messages.countTokens({
  model: "claude-opus-5-5",
  system: "You are a scientist",
  messages: [{ role: "user", content: "Hello, Claude" }],
});
console.log(response);

手順2: ツール・画像・thinking・PDFを含めて数える

システムプロンプトのほか、クライアントツール、画像、拡張思考(extended thinking)、PDFもそのまま渡せます。一方で、メッセージ作成なら通る入力のなかに、invalid_request_errorで弾かれるものがあります。

くらべる

count_tokensの対応範囲

そのまま渡す

数えられる入力

クライアントツール(JSON schemaも課金対象トークンに含まれる)、base64の画像、thinkingブロック、base64のPDF。PDFはMessages APIのdocumentブロックと同じ要件で、ページ数やサイズの上限も同じです。

invalid_request_error

エラーになる入力

web search・web fetch・code execution・tool searchなどのサーバーツール、MCPコネクタ、urlまたはfileを指定したimage / documentブロック。例外はadvisorツールで、数えられるのは実行側の最初のサンプリング呼び出し分だけです。

画像とPDFは、URLやファイルIDで渡している場合でも、count_tokensに投げる分だけbase64に直せば数えられます。サーバーツールやMCPサーバーを使うリクエストは、実際にメッセージを作成し、レスポンスのusageオブジェクトに載るトークン数を見ます。設計段階のおおよその見積もりが要るなら、サーバーツールを外した形で数えて目安にします。ただし外したツール分は含まれないので、実際の消費はそれより多くなります。

thinkingの扱いはモデルで分かれます。過去ターンのthinkingブロックは、全ターンを保持するモデルではinput tokensに含まれますが、最後のターン分しか保持しないモデルではAPIが取り除くため含まれません。今回のターンのthinkingは、モデルによらず必ず含まれます。過去ターンを保持しないモデルへ切り替えた直後に見積もりが急に小さく出ても、不具合ではなく仕様どおりです。

クライアントツールを含む場合のリクエストは、次のようになります。

curl https://api.anthropic.com/v1/messages/count_tokens \
  -H "x-api-key: $ANTHROPIC_API_KEY" \
  -H "content-type: application/json" \
  -H "anthropic-version: 2023-06-01" \
  -d '{
    "model": "claude-opus-5-5",
    "tools": [{
      "name": "get_weather",
      "description": "Get the current weather in a given location",
      "input_schema": {
        "type": "object",
        "properties": {"location": {"type": "string"}},
        "required": ["location"]
      }
    }],
    "messages": [{"role": "user", "content": "東京の天気は?"}]
  }'

手順3: 新トークナイザーのモデルでは数え直す

Claude 4.7以降のモデルは、それより前のモデルとトークナイザーそのものが違います。同じ入力文でも、旧モデルとの比較で見積もりが約30%多く出ます。増分は入力内容に応じて変わるため一律の比率ではありません。Claude Fable 5.1・Fable 5・Mythos 5.1・Mythos 5もこのトークナイザーを共有しており、同じプロンプトは4つのモデルで同じ数になります。

移行前に測ったトークン数を新モデルへそのまま流用すると、レート制限の見積もりもコンテキストウィンドウの残量計算も外れます。課金も新しい数え方に従います。数え直すときは、次の手順で自分のワークロードの増分を測ります。

手順

移行前後で増分を測る

  1. 1

    現行モデルのIDで数える

    移行前のリクエストをそのまま、いま使っているmodel IDでcount_tokensに投げ、input_tokensを控えます。

  2. 2

    切り替え先のIDで数える

    リクエストの中身は変えず、modelだけを切り替え先に差し替えて同じ呼び出しを行います。count_tokensは、渡したmodelのトークナイザーで数えます。

  3. 3

    2つの値を比べる

    差が自分のワークロードでの実際の増分です。以降のコスト見積もりとコンテキストの残量計算には、切り替え先で数えた値を使います。

利用ティアごとのレート制限と支出上限

count_tokens自体は無料ですが、利用ティア(usage tier)に紐づく1分あたりのリクエスト数(RPM)の制限が別にかかります。ティアにはRPMとは別に月間の支出上限もあり、両方が別々の軸で効きます。

数字

count_tokensのRPMと月間支出上限

  • Start

    5,000 RPM

    月間の支出上限は$500

  • Build

    10,000 RPM

    月間の支出上限は$1,000

  • Scale

    20,000 RPM

    月間の支出上限は$200,000

Customティアには月間の支出上限がなく、アカウントチームとの個別合意で決まります

ティアは利用履歴とアカウントの状態にもとづいて組織単位に自動で割り当てられ、自分で選ぶものではありません。新規組織や利用履歴が浅い組織は、この表より低い上限のEvaluationティアから始まり、利用実績が積み上がるにつれて自動で引き上がります。上限を上げたいときは、ConsoleのRate limitsページにある「Request rate limit increase」から申請します。月間の支出上限はBillingページで確認でき、ティアの上限より低い値を自分で設定することもできます。

見落としやすいのが、count_tokensとメッセージ作成のレート制限が完全に独立している点です。count_tokensを大量に呼んでも、実際のメッセージ作成側のRPM・ITPM・OTPM枠は消費しません。逆にメッセージ作成側で429エラーに近づいていても、事前チェックとしてのcount_tokens呼び出しは別枠のまま動きます。429エラー自体への対処はClaude rate limit(レート制限)エラーの対処にまとめています。

RPM制限は、1分間の平均ではなく短い間隔で強制されることがあります。たとえば60RPMの枠は、1秒あたり1リクエストとして運用されることがあり、短時間にリクエストが集中すると、平均では枠内でも制限に触れます。APIはトークンバケットアルゴリズムを使っているため、使っていない分の枠は固定間隔でリセットされず、上限まで継続的に補充されます。利用量が急に増えた組織には、通常の制限とは別に加速制限(acceleration limits)による429が返ることもあります。トラフィックは段階的に増やし、一定のペースを保つ必要があります。

Message Batches APIを使う場合は、ここまでとは別枠のレート制限が存在します。バッチ用の独自RPM制限に加えて、処理待ちキューに同時に入れられるバッチリクエスト数の上限も設けられています。全モデル共通の1枠として管理される点も、モデルごとに分かれるMessages APIのレート制限とは違うところです。大量のPDFやドキュメントをまとめて処理する運用でバッチAPIを使うなら、この枠も個別に確認しておきます。

429や400が返ったとき、どの上限に当たったか

支出上限は、RPMのレート制限と同じ429で返ってきます。エラー本文が似ているため、レート制限だと思って待機やリトライを入れても直りません。見分けるきっかけは、HTTPステータス、retry-afterヘッダー、error.details.error_codeの3つです。

見分け方

上限ごとの返り方

  • RPMなどのレート制限

    HTTP 429で、待つ秒数を示すretry-afterヘッダーが付きます。レスポンスには、どの制限を超えたかが書かれます。

  • ティアの月間支出上限

    HTTP 429で、エラー種別はrate_limit_errorのままです。ただしretry-afterヘッダーはなく、error.details.error_codeがenforced_spend_limit_reachedになります。毎月1日の00:00 UTCまで利用が止まり、SDKの自動リトライも失敗し続けます。

  • 自分で設定した支出上限

    HTTP 400で、エラー種別はinvalid_request_errorです。メッセージがYou have reached your specified API usage limitsで始まり、Claude Code用ワークスペースの上限ならworkspaceの語が入ります。上限を引き上げるか外せば、月初を待たずに再開できます。ただしClaude Codeからのリクエストがワークスペースの上限を超えた場合は、400ではなくretry-afterヘッダー付きの429になることがあります。

支出上限は月の途中でも到達します。count_tokensで見積もったトークン数に単価を掛ければ、月間の消費ペースを送信前に見られます。

よくあるつまずき

プロンプトキャッシュ込みの見積もりだと思ってしまう

count_tokensのリクエストにcache_controlブロックを含めることはできますが、キャッシュのロジックそのものは適用されません。返る数値は、キャッシュを使わない場合の見積もりです。プロンプトキャッシュが効くのは、実際のメッセージ作成のときだけです。キャッシュ効果を含めたコスト削減の考え方はPrompt Cachingを理解するを参照してください。

サーバーツール入りのリクエストが400で返る

web_searchやcode_executionのようなサーバーツールをツール一覧に入れたままcount_tokensへ流すと、エラーが返ります。メッセージ作成と同じボディをそのまま使い回す実装で起きやすい点です。ツール利用全体の実コストは、実際に送信してレスポンスのusageで見ます。ツール定義がトークン消費に与える影響は、Claudeのツール利用で増えるトークン数でモデル別に扱っています。

見積もりのズレを誤差でなく仕様変更と誤認する

見積もりは小さな幅でずれることを前提とした数値です。数トークン程度の差は正常な誤差の範囲です。ズレが常に大きい、あるいは方向が一貫している場合は、モデルIDを取り違えていないかを先に疑います。旧トークナイザーのモデルで数えて新トークナイザーのモデルに送ると、約30%の差が出ます。

設計判断の根拠にせず、送信直前チェックに使う

count_tokensは呼び出しごとに独立したAPIリクエストです。プロンプトを組み立てるたびに毎回呼ぶと、それだけでレート制限枠を消費します。1Mトークンコンテキストのような大きな入力を扱う設計段階では、Claude 1Mコンテキストの実務活用の目安を先に押さえておきます。そのうえでcount_tokensは、送信直前の最終チェックに使う運用が現実的です。

まとめ

count_tokensの置き場所は、リクエストを送る直前の1回です。モデルを切り替えたときは、新しいモデルIDで数え直します。トークナイザーが違うと約30%ずれるためです。429が返ったときは、まずretry-afterの有無とerror_codeを見ます。待てば直るレート制限か、月初まで止まる支出上限かが、そこで分かれます。

この記事を共有:XはてブLinkedIn