Claude呼び出し前にトークン数を数える

Claude.ai エンジニアリング 5分で読めます

「このプロンプトは何トークンか」「コンテキストウィンドウに収まるか」を送信前に把握したいことはよくあります。Claudeには専用の count_tokens エンドポイントがあり、実際に推論を走らせずに正確なトークン数を見積もれます。この記事では使い方と、tiktoken を使ってはいけない理由を解説します。

なぜ事前にトークンを数えるか

トークン数を送信前に知っておくと、コンテキストウィンドウに収まるかの判断、入力コストの見積もり、長い入力を分割(チャンク)するかどうかの判断ができます。特に大きなファイルやドキュメントを扱うアプリケーションでは、送る前に見積もることで「途中で切れる」「予想外に高い」といった事故を防げます。

count_tokensの使い方

count_tokens エンドポイント(POST /v1/messages/count_tokens)を使います。トークン数はモデルごとに異なるため、実際に推論で使うのと同じモデルIDを渡してください。

from anthropic import Anthropic

client = Anthropic()
resp = client.messages.count_tokens(
    model="claude-opus-4-8",
    messages=[{"role": "user", "content": "こんにちは、Claude"}],
)
print(resp.input_tokens)

TypeScriptでは await client.messages.countTokens({model, messages}) を呼び、.input_tokens を参照します。

ファイルやプロンプトを数える

ファイルの中身をそのまま content に渡せば、そのテキストのトークン数を数えられます。

resp = client.messages.count_tokens(
    model="claude-opus-4-8",
    messages=[{"role": "user", "content": open("CLAUDE.md").read()}],
)
print(resp.input_tokens)

エンドポイントはステートレスなので、あるファイルの2つのバージョンの差分を数えたい場合は、それぞれ別々に数えて引き算します。

def count(text):
    return client.messages.count_tokens(
        model="claude-opus-4-8",
        messages=[{"role": "user", "content": text}],
    ).input_tokens

diff = count(after) - count(before)

tiktokenを使わない理由

tiktoken はClaude用ではありません

tiktoken はOpenAIのトークナイザです。一般的なテキストでClaudeのトークン数を約15〜20%少なく見積もり、コードや非英語の入力ではさらに大きくずれます。tiktokengpt-tokenizer などから得た推定値はClaudeでは正確ではありません。

正確な数値が必要な場面(コンテキスト上限の判定、コスト計算、レートリミットのしきい値)では、必ずモデル指定つきの count_tokens を使ってください。ブラウザ側の概算トークナイザで代用すると、モデルが変わったときにずれが生じます。

コスト見積もりに使う

入力トークン数が分かれば、モデルの入力単価を掛けて概算コストを出せます。

count_response = client.messages.count_tokens(
    model="claude-opus-4-8",
    messages=messages,
    system=system,
)
estimated_input_cost = count_response.input_tokens * 0.000005  # 100万トークンあたり$5の例
print(f"入力コスト概算: ${estimated_input_cost:.4f}")

単価はモデルによって異なるため、最新の価格は公式ドキュメントで確認してください。本記事は非公式翻訳です。