CLAUDE LABEN
CHROME — Compliance API のローカルセッション取得が、Claude in Chrome のトランスクリプトにも対応しました。Enterprise 向けのベータで、9月18日の追加です2.1.278 — Claude Code は9月19日の 2.1.278 から進んでいません。auto モードの分類器がサーバーサイド既定になった版で、分類器分は課金されません11/17 — 未文書化の client-certificate フォールバック設定は11月17日で受付終了です。残り56日で、11月3日からアプリ内に警告が出ますTMPDIR — Windows の Bash には TMPDIR がありません。習慣で書かれた $TMPDIR 付きのコマンドが Permission denied で落ち、そのまま黙って再試行されているという報告ですNEW — 非推奨の通知が出た朝、設定を書き換える前にバージョンを確かめた話TOOLS — 承認をどこまで自動化するか。Claude Code の hooks と permissions、Antigravity の Deny / Ask / Allow を並べてみると、自分の線引きが決めやすくなりますCHROME — Compliance API のローカルセッション取得が、Claude in Chrome のトランスクリプトにも対応しました。Enterprise 向けのベータで、9月18日の追加です2.1.278 — Claude Code は9月19日の 2.1.278 から進んでいません。auto モードの分類器がサーバーサイド既定になった版で、分類器分は課金されません11/17 — 未文書化の client-certificate フォールバック設定は11月17日で受付終了です。残り56日で、11月3日からアプリ内に警告が出ますTMPDIR — Windows の Bash には TMPDIR がありません。習慣で書かれた $TMPDIR 付きのコマンドが Permission denied で落ち、そのまま黙って再試行されているという報告ですNEW — 非推奨の通知が出た朝、設定を書き換える前にバージョンを確かめた話TOOLS — 承認をどこまで自動化するか。Claude Code の hooks と permissions、Antigravity の Deny / Ask / Allow を並べてみると、自分の線引きが決めやすくなります
記事一覧/API & SDK
API & SDK/2026-09-22中級

PDF の入力トークンは文字数では読めません — 送る前にページ数から上限で挟む

Claude API に PDF を送る前の入力トークンを、文字数ではなくページ数から上限で挟んで見積もる手順です。A4 9 ページの日本語文書で文字数見積もりの 6.6 倍になった実測と、解像度ティアとトークナイザの二重の増分、count_tokens が file_id を数えられない制約までをまとめます。

claude-api83pdf4token-counting3cost4vision8

受け取った資料をまとめて要約させる小さな仕組みを、個人開発の片手間で動かしております。入力は毎回 PDF です。

月初に立てた見積もりと、月末に出てくる入力トークンが、どうしても噛み合わない週がありました。文字数は数えていたのです。抽出した本文の文字数に単価を掛けて、これくらいだろう、と。ところが実績はその何倍かで着地します。

最初に疑ったのは自分のプロンプトでした。けれども原因はそこではありませんでした。PDF は、本文だけが渡っているわけではなかったのです。

ページは、文字と絵の両方で渡っています

PDF support の公式ドキュメントは、受け取った PDF に何が起きるかを三段階で書いています。各ページが画像に変換され、そのページから抽出されたテキストが画像と一緒に添えられ、Claude は両方を見て答える——という流れです。

つまり入力は二本立てです。公式はコストの節にこう補足しています。テキスト側はページあたりおおむね 1,500〜3,000 トークン、画像側は通常の画像とまったく同じ計算が当てはまる、と。

文字数だけを数えていた私の見積もりからは、この画像側が丸ごと抜け落ちておりました。抜けているものが「少し」ではなく「もう一本分」だったので、何倍かになるのは当然でした。

画像側には、ページ 1 枚ごとの上限があります

Claude は画像をピクセルではなく 28×28 ピクセルの升目で見ています。1 枚の画像が使う視覚トークンは ⌈幅 / 28⌉ × ⌈高さ / 28⌉ 個です。

ここに上限が二つ掛かります。長辺の上限と、視覚トークン数の上限です。どちらかを超えると、縦横比を保ったまま両方に収まる最大の大きさまで縮められてから読まれます。上限の値はモデルの解像度ティアで変わります。

ティア対象モデル長辺の上限視覚トークンの上限
標準Claude 4.7 より前のモデル1568 px1568
高解像度Claude 4.7 以降のモデル2576 px4784

画像なら、こちらで縮めてから送るという手が打てます。PDF ではそれができません。座標とバウンディングボックスの項に、PDF のページはこちらが決められない大きさでサーバー側でラスタライズされると明記されています。返ってきた座標を元のページに重ねられない理由として書かれている一文ですが、コストの話にもそのまま効きます。

こちらにできるのは、ページ 1 枚がどこまで行くかを先に知っておくことだけです。公式の縮小規則をそのまま実装して、A4 縦を解像度ごとに数えてみました。

描画解像度ピクセル標準ティア高解像度ティア
72 dpi595×842682682
96 dpi794×11231,1891,189
150 dpi1240×17541,5512,835
200 dpi1654×23391,5514,756
300 dpi2480×35081,5514,756

200 dpi から先は、どれだけ細かく描いても値が動きません。A4 1 ページの画像トークンは、標準ティアで 1,551、高解像度ティアで 4,756 で頭打ちになります。 同じページが、モデルの世代が変わるだけで約 3.07 倍です。

ここで肩の荷が下りました。ラスタライズの解像度は分からないままでよかったのです。分からない値は当てにいかず、動かない上限のほうで挟みます。 見積もりの置き方を、そこで入れ替えました。

A4 9 ページの文書で、二通りに数えてみました

手元の A4 縦 9 ページ・本文 8,021 文字(空白を除く)の日本語文書で突き合わせました。1 ページあたり 891 文字ですので、文字としてはむしろ薄いほうの書類です。

文字側にもう一つ増分があります。トークンカウントの公式ドキュメントが、Claude 4.7 以降のモデルは新しいトークナイザを使っていて、同じ文章がおよそ 30% 多く数えられると書いています。8,021 文字が、旧世代で測ったつもりの数え方より 3 割ほど重くなる、ということです。

数え方入力トークンOpus 5 で 1 回(100 万トークン 5 ドル)
文字数だけ約 8,021約 0.040 ドル
本文(+30%)+ 標準ティアの画像上限約 24,386約 0.122 ドル
本文(+30%)+ 高解像度ティアの画像上限約 53,231約 0.266 ドル

現行世代のモデルで送ると、文字数から出した見積もりの 6.6 倍でした。1 通を 1 日 20 回、30 日回す仕組みなら、月 24 ドルのつもりが 160 ドルです。噛み合わなかったのは、この差でした。

内訳を見ると、増えた分のほとんどは画像側の 42,804 トークンです。文字側の 3 割増しは、金額で言えば添え物でした。

送る前に挟む見積もりを、40 行ほどで

公式の縮小規則を実装して、PDF のページ寸法だけから上限を出す関数です。API は一度も呼びません。フォルダごと数えても一瞬で終わります。

import math
from pypdf import PdfReader
 
PATCH = 28                                  # Claude が画像を見る升目の一辺
TIERS = {"standard": (1568, 1568),          # (長辺の上限, 視覚トークンの上限)
         "high": (2576, 4784)}              # high = Claude 4.7 以降
 
def visual_tokens(w, h):
    return math.ceil(w / PATCH) * math.ceil(h / PATCH)
 
def fits(w, h, max_edge, max_tokens):
    # 端は升目の切りのよいところまで詰められるので、切り上げてから長辺を見ます
    padded_edge = max(math.ceil(w / PATCH), math.ceil(h / PATCH)) * PATCH
    return padded_edge <= max_edge and visual_tokens(w, h) <= max_tokens
 
def page_ceiling(pt_w, pt_h, tier="high", dpi=300):
    """ページ 1 枚がどれだけ細かく描かれても超えない視覚トークン数を返します。"""
    max_edge, max_tokens = TIERS[tier]
    w, h = round(pt_w * dpi / 72), round(pt_h * dpi / 72)
    if fits(w, h, max_edge, max_tokens):
        return visual_tokens(w, h)
    # 縦横比を保ったまま、両方の上限に収まる最大の倍率を二分探索します
    lo, hi = 0.0, 1.0
    for _ in range(40):
        mid = (lo + hi) / 2
        if fits(max(round(w * mid), 1), max(round(h * mid), 1), max_edge, max_tokens):
            lo = mid
        else:
            hi = mid
    return visual_tokens(max(round(w * lo), 1), max(round(h * lo), 1))
 
def estimate_pdf(path, tier="high", text_per_page=(1500, 3000)):
    pages = PdfReader(path).pages
    image = sum(page_ceiling(float(p.mediabox.width),
                             float(p.mediabox.height), tier) for p in pages)
    n = len(pages)
    return {"pages": n, "image_tokens": image,
            "total_min": n * text_per_page[0] + image,
            "total_max": n * text_per_page[1] + image}
 
print(estimate_pdf("sample.pdf", tier="high"))
# {'pages': 9, 'image_tokens': 42804, 'total_min': 56304, 'total_max': 69804}

dpi=300 は「これ以上細かく描かれても値が変わらない」ところまで上げておくための既定値で、実際の変換解像度を言い当てているわけではありません。上限を出すための踏み台です。

手を動かして確かめておいた点が一つあります。この関数に 1920×1080、2000×1500、3840×2160 を通すと、公式のビジョン解説にある表の 1560・1564・1560(標準)と 2691・3888・4784(高解像度)にそのまま一致しました。規則を自分で書き写すときは、この突き合わせまでやっておくと安心できます。

なお先ほどの 9 ページ文書の実測 53,231 は、この関数の下限 56,304 をわずかに下回っております。公式の「ページあたり 1,500〜3,000」は密度の高いページを想定した幅ですので、薄い書類では少し過大に出ます。挟んだ幅は、次の手順で締めます。

count_tokens で答え合わせをするときに引っかかること

トークンカウントのエンドポイントは PDF も数えてくれますし、料金はかかりません。Messages とは別枠のレート制限で、Start ティアでも毎分 5,000 リクエストあります。

ただし、ここで一度つまずきました。document ブロックの url ソースと file ソースは数えられません。 base64 で送ったものだけが対象です。大きい PDF ほど Files API に置いて file_id で参照したいのに、数えるときだけは手元で base64 に戻す必要がありました。

移行のときの注意も一つ添えられています。古いモデルで測った値を流用せず、送る予定のモデル ID で数え直すこと。先ほどの 30% 増は、まさにここで表に出ます。

私自身は、この二つを組み合わせる形に落ち着きました。

  1. フォルダ全体は page_ceiling で挟み、月の上限として先に予算を決めます
  2. 代表的な 1 通だけ base64 にして count_tokens を 1 回呼び、その書類種別の「1 ページあたり実測値」を取ります
  3. 以後はその実測値 × ページ数で回し、書類のレイアウトが変わったときだけ 2 をやり直します

上限は動きませんので、1 は作り置きが効きます。2 は無料で、月に一度で足ります。

決めたのは、絵として読む必要のあるページだけ PDF で渡すことでした

内訳を見てから、入力の渡し方そのものを分けました。

表やグラフ、レイアウトそのものを読んでほしいページは PDF のまま渡します。ここは画像側の費用を払う価値があります。本文が読めれば足りるページは、こちらでテキストを抜いて、テキストとして渡します。プレーンテキストは text/plain として Files API に置いて document ブロックから参照できますので、流れを大きく変えずに済みました。

先ほどの 9 ページの文書は、後者で足りる種類のものでした。画像側の 42,804 トークンが、そっくり消えます。

絵として読む必要のないページには、絵の代金を払いません。 上限を数えて分かったのは、この一行でした。

まずはお手元の PDF を 1 通だけ page_ceiling に通して、ページ 1 枚の上限を見てみてください。そこが 1,551 なのか 4,756 なのかで、予算の桁が変わります。画像をまとめて送る側の上限については画像は20枚ずつ送っています — 21枚目から全画像に別の上限がかかると知った日に、PDF の解析そのものの組み方はClaude Vision API 実装パターン — 画像解析・PDF 処理・OCR を本番品質で動かすまでに書き残しております。

見積もりが合わない理由を探していた時間は、いま思えば数え方を一つ足すだけで済む話でした。同じところで手が止まっている方の助けになれば嬉しく思います。お読みいただきありがとうございました。

シェア

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

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

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

もしこの記事がお役に立ちましたら、チップ(¥150)で応援いただけると大変励みになります。広告なしでの運営を続けるため、皆さまのご支援が大きな力になっています。

関連記事

API & SDK2026-07-09
20万トークンの崖で夜間バッチの請求が跳ねた — count_tokens プリフライトで長コンテキスト単価を避ける
Sonnet 5 のネイティブ1Mコンテキストは、入力が20万トークンを超えた瞬間にリクエスト全体が長コンテキスト単価へ切り替わります。無人バッチで請求が静かに倍増する崖を、課金対象外の count_tokens プリフライトで手前に止めた実装を、Python と TypeScript の動くコードで記録します。
API & SDK2026-03-26
Claude API で PDF 解析・要約アプリを構築する:Vision + Extended Thinking 活用ガイド
契約書やレポートなど大量のPDFを手作業で読む時間を減らすため、Claude APIのVisionとExtended Thinkingを組み合わせた解析・要約アプリを構築します。PDFの画像変換からページ内容の抽出、深い要約の生成、完成版パイプラインまでをPythonのコードとともに段階的に解説します。
API & SDK2026-05-29
Claude API に画像 URL を渡すと invalid_request_error が出るときの切り分け
Claude API の Messages で `source.type: url` を指定した画像が invalid_request_error で落ちるとき、原因は URL スキーム・MIME・サイズ・到達性のどれかにほぼ収束します。診断順に整理します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます