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-04-15中級

Gemini 2.5 Pro でつくるAIドキュメントアシスタント — PDF・画像・テキストを一括解析してMarkdownレポートを自動生成する

Gemini 2.5 Pro の File API とマルチモーダル機能を活用し、PDF・画像・テキストを一括解析してMarkdownレポートを自動生成するPythonスクリプトを実装します。実務で使えるコード付きで解説します。

gemini102gemini-2.5-pro13file-api6multimodal24python103document-analysis2automation34

「複数のドキュメントを読んで要点をまとめてくれ」という依頼が来るたびに、何時間も費やしてきた経験はないでしょうか。PDFを開いて、画像の文字を読み取って、テキストファイルを確認して……この繰り返し作業こそ、Gemini 2.5 Pro が最も得意とする領域です。

なぜ Gemini 2.5 Pro なのか

ドキュメント解析ツールを作る際に最初に直面する壁は「どのモデルを選ぶか」です。2026年4月時点で、Gemini 2.5 Pro を選ぶ理由は明確です。

まずコンテキストウィンドウ。Gemini 2.5 Pro は最大100万トークンのコンテキストを扱えるため、数十ページのPDFや大量の画像を一度に渡せます。GPT-4o の128KやClaude Sonnetの200Kと比べて相応の優位性があります。

次にネイティブマルチモーダル。PDF・画像・音声・動画を追加の変換なしに直接入力できます。従来のアプローチ(pdfplumberでテキスト抽出→pytesseractでOCR→APIに送信)と異なり、ページレイアウトや図表の視覚的な文脈ごとモデルに渡せます。

最後に精度と速度のバランス。Thinking モードをオフにすれば高速・低コスト、複雑な推論が必要な場面では thinking_budget を設定するという柔軟な制御が可能です。

実装の全体設計

今回構築するシステムの流れを先に整理しておきます。

入力ファイル群(PDF / JPG / PNG / TXT / MD)
    ↓
File API へアップロード(並列処理)
    ↓
Gemini 2.5 Pro で一括解析
    ↓
Markdownレポート出力

ポイントは「File API を経由する」という点です。1MBを超えるファイルや複数ファイルを効率よく扱うには、インラインデータ(base64埋め込み)よりもFile APIが適しています。アップロードしたファイルは48時間有効なため、同じドキュメントセットを複数の観点で解析する際の再利用も可能です。

環境セットアップ

まず必要なパッケージをインストールします。

pip install google-genai pathlib2

google-genai は2025年以降の公式推奨パッケージです。旧来の google-generativeai から移行済みの方はそのまま利用できますが、APIの呼び出し方が異なるため注意してください。

環境変数にAPIキーを設定します。

export GOOGLE_API_KEY="YOUR_GEMINI_API_KEY"

Google AI Studio(aistudio.google.com)でキーを発行し、プロジェクトへのアクセスが有効であることを確認してください。

Step 1: File API へのアップロード処理

import os
import time
import concurrent.futures
from pathlib import Path
from google import genai
from google.genai import types
 
client = genai.Client(api_key=os.environ["GOOGLE_API_KEY"])
 
SUPPORTED_MIME = {
    ".pdf":  "application/pdf",
    ".jpg":  "image/jpeg",
    ".jpeg": "image/jpeg",
    ".png":  "image/png",
    ".webp": "image/webp",
    ".txt":  "text/plain",
    ".md":   "text/markdown",
}
 
def upload_file(file_path: Path) -> types.File | None:
    """単一ファイルをFile APIへアップロードする。
    
    戻り値: アップロード済みFileオブジェクト(失敗時はNone)
    """
    suffix = file_path.suffix.lower()
    mime = SUPPORTED_MIME.get(suffix)
    if mime is None:
        print(f"  ⚠ スキップ(未対応形式): {file_path.name}")
        return None
 
    try:
        uploaded = client.files.upload(
            file=file_path,
            config=types.UploadFileConfig(mime_type=mime),
        )
        # アップロード完了まで待機(処理中ステータスの場合)
        while uploaded.state == "PROCESSING":
            time.sleep(2)
            uploaded = client.files.get(name=uploaded.name)
 
        if uploaded.state == "FAILED":
            print(f"  ✗ アップロード失敗: {file_path.name}")
            return None
 
        print(f"  ✓ アップロード完了: {file_path.name} ({mime})")
        return uploaded
    except Exception as e:
        print(f"  ✗ エラー: {file_path.name}{e}")
        return None
 
def upload_files_parallel(file_paths: list[Path], max_workers: int = 4) -> list[types.File]:
    """複数ファイルを並列アップロードする。"""
    print(f"\n📤 {len(file_paths)}件のファイルをアップロード中...")
    results = []
    with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
        futures = {executor.submit(upload_file, p): p for p in file_paths}
        for future in concurrent.futures.as_completed(futures):
            result = future.result()
            if result is not None:
                results.append(result)
    print(f"✅ {len(results)}件のアップロード完了\n")
    return results

concurrent.futures.ThreadPoolExecutor で並列アップロードを実現しています。ファイルが10件あっても逐次処理より約4倍高速になります。max_workers=4 はAPIのレート制限(毎分アップロード数)を超えないよう抑えた値です。大量ファイルを扱う場合は time.sleep() を挿入して調整してください。

Step 2: Gemini 2.5 Pro による一括解析

ANALYSIS_PROMPT = """
以下のドキュメント群を解析し、Markdown形式でレポートを作成してください。
 
## レポート要件
1. **エグゼクティブサマリー**(200文字程度)— 全体の要点を一言でまとめる
2. **ドキュメント別要約** — 各ファイルの主要な情報を箇条書きで整理する
3. **重要な数値・データ** — 表・グラフ・数値情報を抽出してまとめる
4. **キーインサイト** — 複数のドキュメントを横断した共通テーマや矛盾点を指摘する
5. **アクションアイテム** — 次のステップとして推奨される具体的なアクション(あれば)
 
## 注意事項
- 図表やレイアウト情報も含めて解析してください
- 日本語のドキュメントは日本語で、英語は英語で要約してください
- 事実を正確に記述し、推測の場合は明示してください
"""
 
def analyze_documents(uploaded_files: list[types.File]) -> str:
    """アップロード済みファイルをGemini 2.5 Proで一括解析する。
    
    戻り値: Markdownレポート文字列
    """
    # ファイル参照をコンテンツリストに変換
    contents: list = [ANALYSIS_PROMPT]
    for f in uploaded_files:
        contents.append(
            types.Part.from_uri(file_uri=f.uri, mime_type=f.mime_type)
        )
 
    print("🤖 Gemini 2.5 Pro で解析中...")
    response = client.models.generate_content(
        model="gemini-2.5-pro-preview-05-06",
        contents=contents,
        config=types.GenerateContentConfig(
            temperature=0.2,  # レポートなので低め(事実重視)
            max_output_tokens=8192,
            # thinking_budget=2000,  # 複雑な推論が必要なら有効化
        ),
    )
 
    if not response.text:
        raise ValueError("モデルからの応答が空です。ファイルの内容を確認してください。")
 
    return response.text
 
def save_report(markdown_text: str, output_path: Path) -> None:
    """レポートをMarkdownファイルとして保存する。"""
    output_path.write_text(markdown_text, encoding="utf-8")
    print(f"📄 レポート保存: {output_path}")

temperature=0.2 は重要な設定です。ドキュメント要約・事実抽出の用途では創造性より正確性が求められます。0に近いほど安定したアウトプットになりますが、完全な0にするとやや機械的な文体になるため、0.2程度が実務的なバランスです。

Step 3: メイン処理とアップロード済みファイルのクリーンアップ

def cleanup_uploaded_files(uploaded_files: list[types.File]) -> None:
    """使用済みのアップロードファイルをFile APIから削除する。
    
    File APIのファイルは48時間後に自動削除されるが、
    機密情報を含む場合は即時削除することを推奨する。
    """
    for f in uploaded_files:
        try:
            client.files.delete(name=f.name)
        except Exception:
            pass  # 削除失敗は無視(自動削除で対応)
    print(f"🗑 {len(uploaded_files)}件のアップロードファイルを削除しました")
 
def main(input_dir: str, output_file: str = "report.md") -> None:
    """メイン処理。
    
    Args:
        input_dir:   解析するファイルが入ったディレクトリパス
        output_file: 出力するMarkdownレポートのファイル名
    """
    input_path = Path(input_dir)
    if not input_path.is_dir():
        raise FileNotFoundError(f"ディレクトリが見つかりません: {input_dir}")
 
    # 対応ファイルの収集
    file_paths = [
        p for p in input_path.iterdir()
        if p.is_file() and p.suffix.lower() in SUPPORTED_MIME
    ]
    if not file_paths:
        print("解析対象のファイルが見つかりませんでした。")
        return
 
    print(f"📁 解析対象: {len(file_paths)}件")
    for p in file_paths:
        print(f"  - {p.name}")
 
    uploaded_files = []
    try:
        # Step 1: 並列アップロード
        uploaded_files = upload_files_parallel(file_paths)
        if not uploaded_files:
            print("有効なファイルがアップロードされませんでした。")
            return
 
        # Step 2: 一括解析
        markdown_report = analyze_documents(uploaded_files)
 
        # Step 3: レポート保存
        output_path = Path(output_file)
        save_report(markdown_report, output_path)
        print("\n✅ 処理完了!")
 
    finally:
        # 機密情報保護のため確実にクリーンアップ
        if uploaded_files:
            cleanup_uploaded_files(uploaded_files)
 
if __name__ == "__main__":
    import sys
    input_dir = sys.argv[1] if len(sys.argv) > 1 else "./documents"
    output_file = sys.argv[2] if len(sys.argv) > 2 else "report.md"
    main(input_dir, output_file)

try/finally ブロックで確実にクリーンアップを実行するのがポイントです。エラーが発生した場合でもアップロードファイルが残り続けることを防ぎます。とくに契約書・財務資料など機密性の高いドキュメントを処理する場合は、48時間の自動削除を待たず即時削除することを強くお勧めします。

実行例と出力

以下のファイル構成でテストした場合:

documents/
├── Q1_report.pdf      # 四半期財務レポート(英語)
├── architecture.png   # システム構成図
└── meeting_notes.md   # 会議メモ(日本語)

実行コマンド:

python document_assistant.py ./documents report_20260415.md

期待される出力(コンソール):

📁 解析対象: 3件
  - Q1_report.pdf
  - architecture.png
  - meeting_notes.md

📤 3件のファイルをアップロード中...
  ✓ アップロード完了: Q1_report.pdf (application/pdf)
  ✓ アップロード完了: architecture.png (image/png)
  ✓ アップロード完了: meeting_notes.md (text/markdown)
✅ 3件のアップロード完了

🤖 Gemini 2.5 Pro で解析中...
📄 レポート保存: report_20260415.md
✅ 処理完了!
🗑 3件のアップロードファイルを削除しました

生成されるMarkdownレポートには、財務指標の抽出・アーキテクチャ図の説明・会議の決定事項が統合された形でまとめられます。

よくあるエラーとその対処法

RESOURCE_EXHAUSTED: Quota exceeded

無料プランのFile APIは1日あたりのアップロード上限があります。大量ファイルを扱う場合は有料プラン(Tier 1以上)へのアップグレード、またはtime.sleep(60)を挿入してリクエストを分散させてください。

INVALID_ARGUMENT: The File API does not support this MIME type

.docx(Word文書)や.xlsx(Excel)は直接アップロードできません。

File state is FAILED

破損したPDFや暗号化(パスワード保護)されたファイルはアップロードに失敗します。pikepdfPyMuPDFで事前にファイルを検証・修復する処理を追加することを検討してください。

応答が空になる(response.text が None)

安全フィルターによってブロックされた可能性があります。response.prompt_feedback を確認し、フィルタリング理由を把握してください。フィルタリングを回避するためにプロンプトを調整するか、必要に応じてsafety_settingsを変更してください。

プロンプトのカスタマイズ例

ANALYSIS_PROMPT は用途に応じて変更するだけで、大幅に異なるレポートを生成できます。

法務ドキュメントレビュー用

LEGAL_PROMPT = """
以下の契約書・法律文書を解析し、以下の観点でレポートを作成してください:
1. 当事者・締結日・有効期間
2. 主要な義務と権利
3. リスク条項(違約金・免責・守秘義務)
4. 不明確な表現・要確認事項
※ 法的判断ではなく情報整理として活用してください。
"""

競合分析レポート用

COMPETITIVE_PROMPT = """
添付の資料(プレスリリース・製品仕様書・SNS投稿等)を解析し:
1. 各社の最新動向と発表内容
2. 機能・価格の比較マトリクス
3. 市場ポジションの変化
4. 自社への示唆とリスク
をまとめてください。
"""

全体を振り返って

Gemini 2.5 Pro の File API とマルチモーダル能力を組み合わせることで、複数形式のドキュメントを一括解析してレポートを自動生成するシステムを、100行程度のPythonで構築できます。

次のステップとして、Gemini API のストリーミング機能を組み合わせて、解析進捗をリアルタイムに表示する対話型UIを追加するのがお勧めです。また、システムインストラクションの活用でモデルのキャラクターを固定すれば、チーム全体で一貫したレポートスタイルを維持できます。

シェア

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

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

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

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

関連記事

API / SDK2026-06-17
Gemini CLI 終了前に、自動化スクリプトを API へ載せ替えた記録
6/18 に Gemini CLI のホスト応答が停止します。シェルから gemini を呼んでいた自動化スクリプトを、google-genai SDK へ安全に載せ替える手順を、構造化出力・リトライ・コスト計測まで含めて実装ベースでまとめました。
API / SDK2026-05-18
Gemini Vision で壁紙アプリの自動カテゴリ分類を実装した話
個人開発の壁紙アプリで Gemini Vision API を使い、画像の自動カテゴリ分類を実装した実体験です。精度改善のプロセスと、公式ドキュメントには載っていない落とし穴、GPT-4o Vision とのコスト比較までまとめました。
API / SDK2026-05-16
Gemini Vision で壁紙アプリのカテゴリ自動分類を試した — 精度と落とし穴の実記録
壁紙アプリ(累計5,000万DL超)の運営者が Gemini Vision を使って画像カテゴリ自動分類を実装。精度67%→87%への改善プロセスと、個人開発者が実運用で感じた限界を具体的に紹介します。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →