GEMINI LABEN
NANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定ですNANOLITE — Nano Banana 2 Liteが登場しました。Googleで最も速く、最もコスト効率の高いGemini Imageモデルで、軽量な画像生成を安く回したい用途に向いていますOMNIFLASH — Gemini Omni Flashがpublic previewになりました。ネイティブにマルチモーダルなモデルで、企業や開発者が独自の動的な動画ワークフローを構築できますAGENTS — Managed Agentsが拡張されました。background: trueでサーバー側の非同期実行とポーリング、リモートMCPサーバー連携、対話をまたぐ認証情報のリフレッシュに対応しますMEMORY — Memory BankのIngestEvents APIが一般提供になりました。イベントの取り込みとメモリ生成を分離し、コンテンツを継続的にストリームできますTHROUGHPUT — Provisioned Throughputで、同一モデル・同一リージョンに対して最大7件の保留オーダーを提出できるようになりましたDEPRECATE — 画像生成モデルは8月17日に、Gemini Enterprise Agent PlatformのGrok 4.1系は8月20日に停止される予定です
記事一覧/API / SDK
API / SDK/2026-05-02中級

Gemini API のPDF入力で詰まったときの原因切り分けと解決法

Gemini API でPDFを送ったのに本文が返ってこない、サイズ制限に引っかかる、ページ数が多くて落ちる—そんな現場のつまずきを症状ごとに切り分けて、最短ルートで直していきます。

gemini102gemini-api279pdf6troubleshooting57files-api4

「PDFを inline_data で送ったのに、応答が空っぽで返ってきた」「アップロードは成功したのに、本文を一行も認識してくれない」—Gemini API でPDFを扱い始めた方からよく相談を受けるのが、この種の沈黙系の不具合です。エラーが派手に出てくれれば原因にたどり着けるのですが、PDF入力は何も言わずに落ちることが多く、最初の切り分けで時間を取られがちな領域でもあります。

ここではGemini API(gemini-2.5-pro / gemini-2.5-flash)でPDFを処理するときに私自身が踏み抜いてきた落とし穴を、症状別に整理しています。コードはすべて Python 用 google-genai SDK で書いてありますが、Node.js でも考え方はそのまま適用できます。

症状から原因を絞り込むフローチャート

最初に、典型的な4パターンを症状ベースで整理しておきます。これだけでも当たりをつけやすくなります。

  • 応答が空、または「PDFが読めない」と返る → スキャン画像PDF / OCR必要 / インラインデータの破損を疑う
  • 400 INVALID_ARGUMENT: request payload size exceeds the limit → 20MBインライン上限を超過
  • 400 The document has too many pages → 1,000ページ制限を超過、または1ページあたりのトークンが極端に多い
  • ページの一部だけ反応する、後半が無視される → トークン上限とページ毎トークンコストの問題

それぞれを順に見ていきます。

原因1: スキャンされた画像PDFを送ってしまっている

PDFには大きく分けて「テキストレイヤを持つPDF」と「画像だけのPDF(スキャナや複合機で取り込んだもの)」の2種類があります。前者なら Gemini はテキスト抽出と画像理解の両方を使ってくれますが、後者は事実上「画像の集合」として扱われ、解像度や言語によっては読み取り精度が大きく落ちます。

切り分け方は単純で、ローカルでテキストが取り出せるかを確認することです。

# pip install pypdf
from pypdf import PdfReader
 
reader = PdfReader("sample.pdf")
text = "".join(page.extract_text() or "" for page in reader.pages)
print(f"抽出文字数: {len(text)}")
# 0 または極端に少ない場合は画像PDFの可能性が高い

文字数がほぼゼロなら、Gemini に投げる前に OCR を挟むのがおすすめです。私のプロジェクトでは、簡単な日本語スキャンPDFなら gemini-2.5-flash に「このPDFは画像のみで構成されています。各ページの文字を起こしてください」と明示的に指示するだけで体感がかなり改善しました。指示なしだと「読み取れません」と返ってくることが多いので、システム指示の一言が効きます。

原因2: 20MBのインライン上限に引っかかっている

inline_data でPDFを送る場合、リクエストペイロード全体で20MBまでという制約があります。PDFそのものが小さくても、Base64 エンコード後は約1.33倍にふくらむので、原本15MB前後で警戒した方が安全です。

20MBを超えたら、Files API(client.files.upload)に切り替えてファイル URI を渡す方式が定石になります。Files API なら最大2GBまで扱えますし、複数の呼び出しで使い回せるのも利点です。

from google import genai
 
client = genai.Client()
 
# 20MB超のPDFは Files API へ
uploaded = client.files.upload(file="large_report.pdf")
print(f"State: {uploaded.state}")  # ACTIVE になるまで待つ必要あり
 
# state チェックを挟むと安定する
import time
while uploaded.state == "PROCESSING":
    time.sleep(2)
    uploaded = client.files.get(name=uploaded.name)
 
response = client.models.generate_content(
    model="gemini-2.5-pro",
    contents=[uploaded, "このPDFの結論を3つ箇条書きで教えてください。"],
)
print(response.text)

state を確認せずに即 generate_content を呼ぶと、たまに FAILED_PRECONDITION で弾かれます。PROCESSING から ACTIVE への遷移を待つガードは入れておくと事故が減ります。なお、Files API のファイルは48時間で自動削除されるので、長期セッションを跨ぐ場合は再アップロードのロジックも必要です(詳しくは Files API のファイルが消える問題の対処法 で別途まとめています)。

原因3: 1,000ページの上限とトークン消費

Gemini API のPDF処理には「1リクエスト最大1,000ページ」という上限があります。さらに、ページ毎にテキストはトークン化、画像領域は約258トークン分として課金されるため、ページ数が増えると入力トークンが爆発しがちです。

実務でよく出会うのが、500ページ前後の長大なPDFを丸ごと投げて応答が極端に短くなったり、後半のページが無視されているように見えるケースです。これは gemini-2.5-pro の100万トークンウィンドウに収まっていても、出力トークン上限(既定で8,192)に対して入力が大きすぎて、応答側で要約が荒くなっているのが正体です。

対策はチャンク分割が王道です。

from pypdf import PdfReader, PdfWriter
 
def split_pdf(src: str, chunk_size: int = 100):
    reader = PdfReader(src)
    chunks = []
    for start in range(0, len(reader.pages), chunk_size):
        writer = PdfWriter()
        for i in range(start, min(start + chunk_size, len(reader.pages))):
            writer.add_page(reader.pages[i])
        out_path = f"{src}.part{start//chunk_size}.pdf"
        with open(out_path, "wb") as f:
            writer.write(f)
        chunks.append(out_path)
    return chunks

100ページ単位に分けて、章ごとに Gemini に渡し、後でメタ要約を作る—この流れに切り替えるだけで、長文PDFの処理品質は驚くほど安定します。チャンクごとの要約戦略は 長尺PDFを章単位でチャンク要約する設計 でもう少し丁寧に書いています。

原因4: MIME タイプ違いと拡張子だけの一致

意外と見落としやすいのが MIME タイプの問題です。inline_data を組み立てる際、mime_typeapplication/pdf ではなく application/octet-stream にしてしまうと、Gemini はバイナリブロブとして受け取り、PDFとして解釈しません。SDK 経由で Part.from_bytes を使う場合も、mime_type を必ず明示してください。

from google.genai import types
 
with open("report.pdf", "rb") as f:
    pdf_bytes = f.read()
 
response = client.models.generate_content(
    model="gemini-2.5-flash",
    contents=[
        types.Part.from_bytes(data=pdf_bytes, mime_type="application/pdf"),
        "このPDFの目的と読者像を1段落で要約してください。",
    ],
)

それから、拡張子が .pdf でも実体が暗号化されていたり、PDF/A の特殊な構成で pypdf ですらページを開けないケースもあります。pypdf.errors.PdfReadError が出たら、qpdf --decrypt などで一度きれいに解いてから再アップロードするのが確実です。

原因5: 表組みや数式が崩れて返ってくる

PDFがちゃんと読まれていても、表や数式が崩れて返ってくる相談も多いです。これは「PDFの読み取り失敗」ではなく「LLMの出力フォーマット問題」なので、対処は別系統になります。

私が現場で効果を感じているのは次の3つです。

  • Markdown ではなく明示的な構造化を要求する: 「表は | 区切りではなく、行ごとに 項目名: 値 の箇条書きで返してください」と書くと、再構成しやすい形で安定します
  • response_mime_type="application/json" と組み合わせる: 表構造をスキーマで縛ってしまうと、Markdown崩れに悩まされなくなります
  • 数式は LaTeX で要求する: 「数式は $$ ... $$ で囲み、TeX 記法で出力してください」と指定すると、画像化された数式も比較的安定して LaTeX 化されます

それでも直らないときの最終チェック

ここまで来ても解決しない場合は、次の3つを順に確認してみてください。

  • 同じPDFが Google AI Studio(Web 版)で正しく処理できるか—できなければPDF側の問題、できればAPIリクエスト側の問題と切り分けられます
  • 別の小さいPDF(テキストレイヤありの数ページのもの)で同じコードが通るか—コードの最小再現を取るのは原因特定の最短ルートです
  • usage_metadata.prompt_token_count をログに出して、入力トークンが想定通りか確認する—想像より少なければ、PDFがほとんど認識されていない兆候です

このあたりの基礎は Gemini API でつまずきがちなエラーと解決策 にも別の切り口でまとめてあるので、合わせて参照してみてください。

PDF処理は腰を据えて取り組むほど面白い領域でもあります。

まずは手元のPDFで len(text) を確認するところから始めてみてください。「画像PDFをそのまま投げていた」「mime_type が違っていた」のどちらかで解決するケースが、私の体感では半分以上を占めます。原因が一つに絞れたら、対処はシンプルです。

シェア

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

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

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

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

関連記事

API / SDK2026-05-10
Gemini API で大きなPDFや動画を inlineData で送ると RESOURCE_EXHAUSTED — Files API への切り替え判断
Gemini API で大きなPDFや動画ファイルを inlineData で送って RESOURCE_EXHAUSTED が出る原因と、Files API への現実的な移行手順を、個人開発の現場感覚でまとめます。
API / SDK2026-05-10
Gemini API で User location is not supported が出たときに、本番環境で試した解決の順番
Cloudflare Workers や Vercel から Gemini API を呼んだときに突然出る『User location is not supported』エラー。個人開発のサーバー移行中に遭遇した実例をもとに、原因切り分けから本番復旧までの順番をまとめました。
API / SDK2026-07-14
Gemini Code Execution の計算結果とモデルの文章がずれる — 実行結果だけを信頼する検証ゲートの実装
Gemini の Code Execution は実際に走らせた計算結果と、それを説明する自然文を別々に返します。文章側の数値を鵜呑みにすると幻覚を掴みます。実行結果だけを真実として抽出し照合する検証ゲートの実装を、動くコードで解説します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →