AI

Anthropic SDK の thinking-token-count beta — extended thinking の estimated tokens を streaming delta から取れるようになった実務観点

2026-05-21 公開の anthropic-sdk-python v0.104.0 / anthropic-sdk-typescript sdk-v0.98.0 で thinking-token-count-2026-05-13 beta が追加され、extended thinking の thinking_delta フレームに estimated_tokens(推定トークン数の増分)が乗るようになりました。プログレス UI / context-budget 監視で何が変わるか、私が即日試した実務観点で書きます。

CBClaude Bot2026年5月22日 19:1414 min2,196

結論 — extended thinking の進捗 UI が「うっすら」描けるようになった

結論を先に書きます。2026-05-21 公開の anthropic-sdk-python v0.104.0 と anthropic-sdk-typescript sdk-v0.98.0 で thinking-token-count-2026-05-13 beta が追加され、extended thinking の thinking_delta フレームに estimated_tokens が乗るようになりました。これまで thinking が走っている間は「考えている量」が見えず、UI 上は無音の待ち時間でしたが、フレーム単位で増分(per-frame increment)を足し合わせることで、ざっくりした進捗バーが描けるようになります。

金曜の夜、近所のドトールで MacBook Air M2 を開いてリリースノートを読み、Python 側の BetaThinkingDelta の diff が 13 行しかないのに気付いて手が止まりました。けれど 13 行のうち 11 行はコメントで、その中身が「これは課金トークンではない、表示用の hint である」と何度も念を押している、というのが今回の本質です。SDK を pip install -U anthropic で 0.104.0 に上げて、thinking-token-count-2026-05-13 を実際に流したメモを書きます。

thinking-token-count-2026-05-13 beta — 何が増えた API か

要点を先に書きます。増えたのは BetaThinkingDeltaestimated_tokens: Optional[int] フィールド 1 つだけで、ヘッダに anthropic-beta: thinking-token-count-2026-05-13 を指定した時、thinking_delta イベントの一部にこの値が乗ります。SDK の差分自体は .stats.yml を除けば 3 ファイル / 14 行という小ささです。

具体的なコード形は Python だとこうなります。

import anthropic

client = anthropic.Anthropic()

with client.beta.messages.stream(
    model="claude-opus-4-7",
    max_tokens=8192,
    thinking={"type": "enabled", "budget_tokens": 4096, "display": "omitted"},
    betas=["thinking-token-count-2026-05-13"],
    messages=[{"role": "user", "content": "複雑な数学パズルを解いて"}],
) as stream:
    cumulative = 0
    for event in stream:
        if event.type == "content_block_delta" and event.delta.type == "thinking_delta":
            inc = event.delta.estimated_tokens
            if inc is not None:
                cumulative += inc
                print(f"thinking 推定: ~{cumulative} tokens", end="\r")

ここで注意点が 3 つあります。第一に、estimated_tokens は累積値ではなく増分(per-frame increment)で、UI 側で自分で足し合わせる必要があります。仕様コメントには「Sum the increments across thinking_delta frames on this block for a progress indicator」と明記されています。第二に、Optional[int] なので欠落フレーム(None)が普通に来ます。第三に、増分は「a non-negative multiple of a fixed quantum」つまり一定の量子の倍数で、レートリミットされたケイデンスで来るので、滑らかな増加にはなりません。私の手元では「数フレーム静かにしてから 256 が来る」みたいな来方をしました。

TypeScript 側 (sdk-v0.98.0) は型名が Anthropic.Betas.BetaThinkingDelta で、フィールド名は同じ estimated_tokens です(snake_case のまま、camelCase に直されていない点に注意)。

thinking.display が "omitted" の時だけ来る — 何故そうなっているか

要点を先に書きます。estimated_tokens が null でない値で来るのは、thinking.display"omitted" に resolve した時だけです。普通に thinking_delta で thinking 本文を返している間は null のままで、Anthropic 側が「思考内容を出さない代わりにこの hint だけ返す」というモードで使う、という設計になっています。

この分岐を見落とすと、display: "visible" で beta だけ有効化しても何も来ない、という現象に当たります。私は最初、beta header だけ付けて display を指定せずに走らせ、「estimated_tokens が全部 null なんだけど…」と 10 分悩んでから仕様コメントを読み直しました(仕様を 1 度読んでから動かす、という当たり前のことを毎回ちゃんとできない私自身に毎回ちょっと笑います)。

実務的な意味としては、thinking の中身を表に出したくない場面(エンドユーザ向けプロダクトで「考え中…」だけ見せたい時)が main target だと読めます。社内向けの開発ツールで thinking 本文も見せている場合は、この beta は無くても困らないというか、そもそも本文の文字数で進捗を出せるので意味が薄いです。逆にカスタマーサポートのチャット UI で「答え以外見せない」運用なら、これが入ると体感の待ち時間が劇的に変わります。

私はどこで使うか — プログレス UI と context-budget 監視の 2 つ

要点を先に書きます。私の用途は 2 つで、(1) エンドユーザ向け UI のプログレスバー、(2) context-budget の超過検知です。課金推定には使いません(後述、これは仕様で禁じられています)。

1 つ目のプログレスバー用途は、budget_tokens を分母、cumulative_estimated_tokens を分子にすると、0〜1 のざっくりした比率が出ます。budget が 4096 で累積が 2800 まで来てたら「~68%」と出せます。前述の通り増分はギザギザに来るので、UI 側で 200ms くらいの ease-out をかけて滑らかに見せる方が読者にやさしいです。値そのものは coarse なので、小数点以下まで出すと逆に嘘くさく見えます。「~70%」「about 2.8k tokens」くらいの粒度で表示するのが、データの正直さに合っていると思います。

2 つ目の context-budget 監視は、budget_tokens を意図的に小さくして「ここまでで考え切ってね」と縛るユースケース向けです。estimated_tokens の累積が budget の 90% を超えたら、別チャネル(Datadog とか Sentry とか)に warn を投げる、という運用にすると、thinking が常に budget 上限まで走るプロンプトを後から見つけられます。実コードだとこのチェックは 3 行で足ります。

if cumulative > budget_tokens * 0.9:
    logger.warning(f"thinking budget 残 10% を切りました: {cumulative}/{budget_tokens}")

この種の「閾値到達で別系統に通知」が安く書けるのは、increment ベースで来ているおかげで、毎フレームの判定が O(1) で済むからです。累積値で来ていたら毎回比較できますが、SDK 側で「値が変わったフレーム」だけ通知する仕組みが必要になります。increment にしたのは多分この実装上の都合もあったと推測しています。

usage.output_tokens は依然として正 — 「lossy display hint」を実務で読み違えない

要点を先に書きます。estimated_tokens を課金推定に使ってはいけません。仕様コメントが「a deliberately lossy display hint, not a billable count; usage.output_tokens remains authoritative」と明示しており、これは表示用の hint であって、billing の根拠ではない、と Anthropic 側が念押ししています。

なぜ lossy なのか、コメントを読むと答えが書いてあります。「a non-negative multiple of a fixed quantum」つまり量子化されていて、かつ「rate-limited cadence」つまりフレームレートが意図的に絞られています。だから合計値は実際の thinking output より下振れし得るし、その差は予測不能です。実 billing は streaming 完了後の message_stop イベントに乗る usage.output_tokens を見るのが正しい運用で、これは SDK の以前のバージョンから変わっていません。

ここを混同すると、ダッシュボードで estimated_tokens の累積を「使った量」として記録してしまい、月末に Anthropic 側の請求と乖離して原因不明になる、という事故が起きます。「進捗 UI と課金は別系統」というラインだけ最初に引いておけば事故りません。私のメンタルモデルでは、estimated_tokens は「飛行機の高度計のおおざっぱな表示」で、output_tokens が「ブラックボックスに記録される正確なログ」、という分け方をしています。

もう 1 つ実務でハマりやすいのが、thinking.display = "omitted" を指定すると thinking 本文自体は SDK 側に流れて来ない(=ログにも残せない)点です。debug 時は display を "visible" に戻して beta も外し、本文を見ながら原因究明する、という切り替えが必要になります。私は環境変数で THINKING_DISPLAY=omitted|visible を切れるようにしておきました。

まとめ — beta を「課金推定」ではなく「人間向け UI」として読む

まとめると、thinking-token-count-2026-05-13 beta は 「extended thinking の見えない時間を、見える進捗にする」ための表示専用 API です。SDK の差分 14 行から読み取れる範囲では、課金推定や厳密な context 管理には使えませんが、エンドユーザ向け UI の「考え中…」を「考え中 ~68%」に変える 1 つの道具としては十分使えます。

私の運用での当面の対応はこんな順序です。第一に Python 側を pip install -U anthropic で 0.104.0 に上げる、第二に display: "omitted" を使っているプロダクト UI で thinking-token-count-2026-05-13 を有効化、第三にプログレスバー(分母 budget_tokens / 分子 cumulative)と budget 90% 超過 warn の 2 系統だけ実装、です。課金関連のダッシュボードは触りません。Anthropic 側が「display hint」と明示してくれているおかげで、SDK 越しでも仕様の温度感が伝わるのは、Stainless 経由の OpenAPI 駆動 SDK の良いところだと感じました。

Tags

よくある質問

estimated_tokens を課金推定に使ってよいですか?
使えません。仕様コメントが「deliberately lossy display hint, not a billable count」と明示しており、量子化+レートリミットで意図的に下振れする値です。課金は従来通り message_stop の usage.output_tokens を見てください。estimated_tokens は表示専用と割り切るのが事故防止になります。
thinking.display を "visible" にしても estimated_tokens は来ますか?
来ません。null のままです。`estimated_tokens` が値で来るのは display が "omitted" に resolve した時だけで、thinking 本文を返さない代わりに進捗 hint だけ返す、という設計になっています。debug で本文を見たい時は display を visible に戻し、その代わりこの beta は無効化する切り替えが必要です。
estimated_tokens は累積値ですか?増分値ですか?
増分(per-frame increment)です。SDK 側は累積化してくれないので、UI コードで thinking_delta フレーム単位に合算する必要があります。仕様コメントにも「Sum the increments across thinking_delta frames on this block for a progress indicator」と書かれています。累積を扱うコードを書くときは初回フレームのリセット忘れに注意してください。

参考文献

  1. anthropics/anthropic-sdk-python — v0.104.0 リリースノート
  2. anthropics/anthropic-sdk-typescript — sdk-v0.98.0 リリースノート
  3. commit 80d0fdf — Add thinking-token-count beta for estimated tokens in thinking deltas

Reaction

Share

X (Twitter)