Anthropic Python SDKのcount_tokens機能が0.75.0~正式版に変わりました:移行ガイド

Anthropic Python SDKのcount_tokens機能が0.75.0~正式版に変わりました:移行ガイド

こんにちは!

本日は Anthropic Claude API を使用するのに便利な Anthropic Python SDK に関する話題です!

2週間ほど前にわりと大きな変更がありましたので、解説いたします。

はじめに

「あれ、client.count_tokens() が動かない...」

Anthropic Python SDKをアップデートしたら、今まで動いていたトークンカウントのコードがエラーになった。そんな経験をされたLLMエンジニアの方も多いのではないでしょうか。

当社のBestllamのように、LLM統合サービスを開発していると、実際にユーザーがどれほどのトークンを使用しているのかを正確に把握することは非常に重要になります。利用料金の計算、コンテキストウィンドウの管理、そしてユーザーへの使用量の可視化など、トークンカウント機能はサービスの根幹を支える機能です。そのため、この機能が突然動かなくなると影響は小さくありません。

ゆえに本番サービスを提供している場合、pip install で気軽にSDKバージョンを上げてはいけません。

さて、Anthropic Python SDK ですが、実は、0.74.1(2025年11月20日リリース)から0.75.0(2025年11月25日リリース)にかけて大きな変更がありました。

さらに、それより前にもSDKのバージョン0.39.0(2024年11月5日リリース)でトークンカウント機能は大きく刷新されましたので、そこからの更新も本記事の対象としたいと思います。
それでは、これら変更の背景と、新しいAPIへの移行方法を解説していきます!

1.何が変わったのか

廃止されたAPI

バージョン0.38.x以前では、以下のようにトークン数を取得していました。

# 旧API(0.38.x以前)- もう動きません
client = Anthropic()
token_count = client.count_tokens("こんにちは、世界")

シンプルで使いやすいAPIでしたが、バージョン0.39.0でこの client.count_tokens() と client.get_tokenizer() は完全に削除されました。

アップデート後にこれらを呼び出すと AttributeError が発生します。

なぜ廃止されたのか→マルチモーダル化に対応するため

理由はClaudeの進化にあります。Claude 3以降、モデルは画像やPDFを理解できるようになりました。旧APIはテキスト専用だったため、これらマルチモーダルコンテンツのトークン数を計算できませんでした。

また、システムプロンプトやツール定義など、実際のAPI呼び出しで消費される全てのトークンを正確に計算することも困難でした。

Anthropicは中途半端な互換性維持よりも、新しい設計への完全移行を選択してようですね。

2.新しいAPIの使い方

基本形

新しいAPIは client.messages.count_tokens() です。messages.create() とほぼ同じパラメータを受け付けます。

# 新API(0.75.0以降)
from anthropic import Anthropic

client = Anthropic()

response = client.messages.count_tokens(
    model="claude-sonnet-4-5-20250929",
    messages=[
        {"role": "user", "content": "こんにちは、世界"}
    ]
)

print(response.input_tokens)  # トークン数

ただ、重要な違いは三点あります。

まず、model パラメータが必須になりました。トークン化の方法はモデルによって異なるためです。

次に、テキストを直接渡すのではなく、メッセージ構造として渡します。最後に、返り値が整数ではなくオブジェクトになり、.input_tokens でトークン数を取得します。

システムプロンプトやツールも計算できる

この新APIの強みは、実際のAPI呼び出しと同じ構造でトークン数を計算できる点です。

response = client.messages.count_tokens(
    model="claude-sonnet-4-5-20250929",
    system="あなたは親切なアシスタントです。",
    messages=[
        {"role": "user", "content": "こんにちは"},
        {"role": "assistant", "content": "こんにちは!何かお手伝いできますか?"},
        {"role": "user", "content": "天気を教えて"}
    ],
    tools=[
        {
            "name": "get_weather",
            "description": "天気を取得します",
            "input_schema": {
                "type": "object",
                "properties": {
                    "location": {"type": "string"}
                },
                "required": ["location"]
            }
        }
    ]
)

response.input_tokens でトークン数を取得できます

# トークン数を取得
print(response.input_tokens)  # 例: 142

システムプロンプト、会話履歴、ツール定義、全てのトークン数が正確に計算されます。

画像やPDFにも対応

マルチモーダルコンテンツのトークン数も計算できます。これが一番重要なポイントでしょう。

import base64

with open("image.png", "rb") as f:
    image_data = base64.standard_b64encode(f.read()).decode("utf-8")

response = client.messages.count_tokens(
    model="claude-sonnet-4-5-20250929",
    messages=[
        {
            "role": "user",
            "content": [
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": "image/png",
                        "data": image_data
                    }
                },
                {"type": "text", "text": "この画像を説明してください"}
            ]
        }
    ]
)

print(response.input_tokens)  # 画像サイズに応じたトークン数が返る

3.移行の手順

ステップ1:SDKをアップデートする

まず、SDKを0.75.0以上(2025年12月9日、ブログ執筆時点で最新)にアップデートしてください。

pip install anthropic>=0.75.0

実は冒頭にも書きましたが、0.39.0から0.74.xの間は client.beta.messages.count_tokens() という形式でベータ提供されていました。

# ベータ版API(0.39.0〜0.74.x)- 2025/12/9現在は非推奨
response = client.beta.messages.count_tokens(
    betas=["token-counting-2024-11-01"],  # ベータヘッダーが必要だった
    model="claude-3-5-sonnet-20241022",
    messages=[
        {"role": "user", "content": "こんにちは"}
    ]
)
print(response.input_tokens)

0.75.0以降は正式版として client.messages.count_tokens() が使えます。ベータヘッダーの指定も不要になりました。

# 正式版API(0.75.0以降)- 現在の推奨
response = client.messages.count_tokens(
    model="claude-sonnet-4-5-20250929",
    messages=[
        {"role": "user", "content": "こんにちは"}
    ]
)
print(response.input_tokens)

ステップ2:コードを書き換える

旧コードと新コードの対応を示します。

# 旧:シンプルなテキスト
count = client.count_tokens("Hello")

# 新:メッセージ構造で渡す
response = client.messages.count_tokens(
    model="claude-sonnet-4-5-20250929",
    messages=[{"role": "user", "content": "Hello"}]
)
count = response.input_tokens

あらかじめ、こういうヘルパー関数を作っておくと移行が楽になります。

def count_tokens(client, text, model="claude-sonnet-4-5-20250929"):
    """旧APIと同じ感覚で使えるヘルパー関数"""
    response = client.messages.count_tokens(
        model=model,
        messages=[{"role": "user", "content": text}]
    )
    return response.input_tokens

ステップ3:requirements.txtを更新する

本番環境では、バージョンを明示的に固定することをお勧めします。

anthropic>=0.75.0,<1.0.0

4.FAQ

「0.39.0のままだと問題ある?」

0.39.0でも動きますが、client.beta.messages.count_tokens() という形式でベータヘッダーの指定が必要です。0.75.0以降なら正式版として安定したAPIが使えるため、こちらをお勧めします。

「APIコールとして課金されますか?」

count_tokens はAPIリクエストとしてカウントされますが、トークン課金はされません。ただし、レート制限の対象にはなる可能性があるため、大量のリクエストを送る場合は注意しましょう。

「非同期で使えますか?」

使えます。AsyncAnthropic クライアントで同じメソッドを await 付きで呼び出してください。

from anthropic import AsyncAnthropic

client = AsyncAnthropic()
response = await client.messages.count_tokens(
    model="claude-sonnet-4-5-20250929",
    messages=[{"role": "user", "content": "Hello"}]
)

おわりに

トークンカウントAPIの変更は、Claudeのマルチモーダル化という大きな進化に伴うものでした。マルチモーダル化は正常進化だと思っていましたが、案外APIは目の前の仕様(テキストのみのやりとり)のみ設計思想のベースにしていたことが逆に意外でしたね。

新しいAPIは、テキストだけでなく画像やPDF、ツール定義まで含めた正確なトークン数を計算できます。

移行作業は少し手間がかかりますが、より正確で実用的なトークン管理が可能になります。この機会にぜひアップデートしてみてください。

それでは、また次回お会いしましょう!

Read more

ゼロから作るコーディングエージェント【第3回】「止まらなかった」は「進んだ」ではない。空転を数え、思考は切らずに上限だけ置く

ゼロから作るコーディングエージェント【第3回】「止まらなかった」は「進んだ」ではない。空転を数え、思考は切らずに上限だけ置く

300ターン走ってAPIが0本。「モデルの限界」と結論を書いた翌日、記録を読み直すと234ターンがツールを1度も呼んでいませんでした。空転率という指標、1つ塞ぐと次の形に移る空転、思考をオフにすると95点が71点に落ちて時間も縮まなかった話、出力枠を広げたら反対側を数える話を書きます。

By Qualiteg プロダクト開発部
Ubuntuの自動更新でカーネルだけ上がり、再起動したらGPUが消えた。NVIDIAモジュールが置き去りになる原因と3つの対策

Ubuntuの自動更新でカーネルだけ上がり、再起動したらGPUが消えた。NVIDIAモジュールが置き去りになる原因と3つの対策

Ubuntu 24.04のGPUサーバーを再起動したらnvidia-smiが動かない。原因はunattended-upgradesがカーネルだけを更新し、NVIDIAモジュールが依存関係の都合で見送られていたこと。ログで原因を突き止め、1コマンドで復旧し、apt-mark holdを含む3つの再発防止策を比べて採用した記録。

By Qualiteg プロダクト開発部
ゼロから作るコーディングエージェント【第2回】完了は「作った」ではなく「動いた」で決める。完了の門と、押し戻しに書くこと

ゼロから作るコーディングエージェント【第2回】完了は「作った」ではなく「動いた」で決める。完了の門と、押し戻しに書くこと

モデルの「完了しました」は5つの形ですり抜けました。構文検査だけ、テストは通るが動かない、待ち受けは立つが最初の要求で落ちる、起動するが仕様のAPIが無い、assertの無いテスト。完了の門を3段で閉じる設計と、押し戻しに「落ちた行と調べ方」を書いて「答え」を書かない理由を、数字つきで書きます。

By Qualiteg プロダクト開発部