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-03-28上級

Gemini API で実現するマルチモーダル文書解析システム — 画像・PDF・動画を統合処理する実践アーキテクチャ

Gemini API のマルチモーダル機能を活用し、画像・PDF・動画を統合的に解析するシステムの設計と実装を解説。ファイルアップロードから構造化データ抽出、バッチ処理パイプラインの構築まで実践的にカバーします。

Gemini API191マルチモーダル24文書解析PDF解析画像認識5動画解析2構造化データ3

取り組みの背景

業務で扱うドキュメントは、テキストだけではありません。請求書のスキャン画像、契約書のPDF、会議の録画動画——こうした多様な形式のファイルから必要な情報を効率的に抽出するのは、これまで非常に手間のかかる作業でしました。

Gemini API のマルチモーダル機能を使えば、画像・PDF・動画といった異なる形式のファイルを1つのAPIで統合的に処理できます。ここではこうしたマルチモーダル文書解析システムの設計から実装、本番運用まで体系的に解説します。

Gemini API のマルチモーダル入力を理解する

サポートされるファイル形式

Gemini API は以下の形式をネイティブにサポートしています。

  • 画像: JPEG, PNG, GIF, WebP, HEIC, HEIF
  • PDF: 複数ページ対応(最大3,600ページ)
  • 動画: MP4, MPEG, AVI, FLV, MKV, MOV, WebM 等
  • 音声: MP3, WAV, FLAC, AAC, OGG 等

特筆すべきは、PDF をネイティブに理解できる点です。OCR を別途実行する必要がなく、テキストと画像が混在するPDFも1回のAPI呼び出しで処理できます。

2つのファイル入力方式

Gemini API では、ファイルサイズに応じて2つの入力方式を使い分けます。

インラインデータ(20MB以下): Base64 エンコードしてリクエストボディに含める方式。小さなファイルに最適です。

import google.generativeai as genai
import base64
from pathlib import Path
 
genai.configure(api_key="YOUR_GEMINI_API_KEY")
model = genai.GenerativeModel("gemini-2.5-pro")
 
# 画像をインラインで送信
image_data = Path("receipt.jpg").read_bytes()
response = model.generate_content([
    "この領収書から、日付、店舗名、合計金額を抽出してJSON形式で返してください。",
    {
        "mime_type": "image/jpeg",
        "data": base64.b64encode(image_data).decode("utf-8")
    }
])
print(response.text)

File API(20MB超): サーバーにファイルをアップロードし、URIで参照する方式。PDFや動画など大容量ファイルに使用します。

import google.generativeai as genai
 
genai.configure(api_key="YOUR_GEMINI_API_KEY")
model = genai.GenerativeModel("gemini-2.5-pro")
 
# PDFをFile APIでアップロード
uploaded_file = genai.upload_file(
    path="contract.pdf",
    display_name="契約書",
    mime_type="application/pdf"
)
 
# アップロード完了を待機
import time
while uploaded_file.state.name == "PROCESSING":
    time.sleep(2)
    uploaded_file = genai.get_file(uploaded_file.name)
 
# PDFの内容を解析
response = model.generate_content([
    "この契約書から以下の情報をJSON形式で抽出してください: "
    "契約当事者、契約日、契約期間、主要な条件、解約条件",
    uploaded_file
])
print(response.text)

マルチモーダル文書解析パイプラインの設計

アーキテクチャ概要

実用的な文書解析システムは、以下の4段階で構成します。

  1. ファイル受付: アップロードされたファイルの形式判定と前処理
  2. 解析実行: Gemini API へのリクエスト(形式に応じたプロンプト選択)
  3. 構造化出力: JSON Schema を指定して構造化データを取得
  4. 後処理: バリデーション、データベース保存、通知

統合解析クラスの実装

import google.generativeai as genai
from pathlib import Path
from dataclasses import dataclass
from enum import Enum
import json
import mimetypes
 
class FileType(Enum):
    IMAGE = "image"
    PDF = "pdf"
    VIDEO = "video"
    AUDIO = "audio"
 
@dataclass
class AnalysisResult:
    file_name: str
    file_type: FileType
    extracted_data: dict
    confidence: float
    raw_response: str
 
class MultimodalAnalyzer:
    """マルチモーダル文書解析エンジン"""
 
    # 形式別のシステムプロンプト
    PROMPTS = {
        FileType.IMAGE: (
            "この画像を詳細に分析してください。"
            "テキスト、数値、表、図表を全て抽出し、"
            "構造化されたJSON形式で返してください。"
        ),
        FileType.PDF: (
            "このPDF文書を全ページ分析してください。"
            "タイトル、セクション見出し、本文、表、"
            "図表のキャプションを構造化JSON形式で返してください。"
        ),
        FileType.VIDEO: (
            "この動画の内容を分析してください。"
            "主要なシーン、テキスト表示、発話内容の要約を"
            "タイムスタンプ付きのJSON形式で返してください。"
        ),
    }
 
    def __init__(self, api_key: str, model_name: str = "gemini-2.5-pro"):
        genai.configure(api_key=api_key)
        self.model = genai.GenerativeModel(
            model_name,
            generation_config={
                "response_mime_type": "application/json",
                "temperature": 0.1,  # 解析精度を重視
            }
        )
 
    def detect_file_type(self, file_path: str) -> FileType:
        """ファイル形式を自動判定"""
        mime_type, _ = mimetypes.guess_type(file_path)
        if mime_type:
            if mime_type.startswith("image/"):
                return FileType.IMAGE
            elif mime_type == "application/pdf":
                return FileType.PDF
            elif mime_type.startswith("video/"):
                return FileType.VIDEO
            elif mime_type.startswith("audio/"):
                return FileType.AUDIO
        raise ValueError(f"サポートされていないファイル形式: {file_path}")
 
    def analyze(
        self,
        file_path: str,
        custom_prompt: str | None = None
    ) -> AnalysisResult:
        """ファイルを解析し、構造化データを返す"""
        path = Path(file_path)
        file_type = self.detect_file_type(file_path)
        file_size = path.stat().st_size
 
        # ファイルサイズに応じてアップロード方式を選択
        if file_size > 20 * 1024 * 1024:  # 20MB超
            uploaded = genai.upload_file(path=str(path))
            import time
            while uploaded.state.name == "PROCESSING":
                time.sleep(2)
                uploaded = genai.get_file(uploaded.name)
            file_input = uploaded
        else:
            import base64
            mime_type, _ = mimetypes.guess_type(str(path))
            file_input = {
                "mime_type": mime_type,
                "data": base64.b64encode(
                    path.read_bytes()
                ).decode("utf-8")
            }
 
        # プロンプトの選択
        prompt = custom_prompt or self.PROMPTS.get(
            file_type, self.PROMPTS[FileType.IMAGE]
        )
 
        # API呼び出し
        response = self.model.generate_content([prompt, file_input])
        raw_text = response.text
 
        # JSON パース
        try:
            extracted = json.loads(raw_text)
        except json.JSONDecodeError:
            extracted = {"raw_text": raw_text}
 
        return AnalysisResult(
            file_name=path.name,
            file_type=file_type,
            extracted_data=extracted,
            confidence=0.95,  # 実装例
            raw_response=raw_text,
        )

構造化出力で解析精度を高める

JSON Schema の活用

Gemini API の response_mime_typeresponse_schema を組み合わせることで、出力のJSON構造を厳密に制御できます。

import google.generativeai as genai
from google.generativeai import types
 
# 請求書解析用のスキーマ定義
invoice_schema = types.Schema(
    type=types.Type.OBJECT,
    properties={
        "invoice_number": types.Schema(type=types.Type.STRING),
        "date": types.Schema(type=types.Type.STRING),
        "vendor": types.Schema(
            type=types.Type.OBJECT,
            properties={
                "name": types.Schema(type=types.Type.STRING),
                "address": types.Schema(type=types.Type.STRING),
            },
        ),
        "items": types.Schema(
            type=types.Type.ARRAY,
            items=types.Schema(
                type=types.Type.OBJECT,
                properties={
                    "description": types.Schema(type=types.Type.STRING),
                    "quantity": types.Schema(type=types.Type.INTEGER),
                    "unit_price": types.Schema(type=types.Type.NUMBER),
                    "amount": types.Schema(type=types.Type.NUMBER),
                },
            ),
        ),
        "subtotal": types.Schema(type=types.Type.NUMBER),
        "tax": types.Schema(type=types.Type.NUMBER),
        "total": types.Schema(type=types.Type.NUMBER),
    },
)
 
model = genai.GenerativeModel(
    "gemini-2.5-pro",
    generation_config={
        "response_mime_type": "application/json",
        "response_schema": invoice_schema,
    },
)
 
# 請求書画像を解析
response = model.generate_content([
    "この請求書の内容を正確に抽出してください。",
    uploaded_invoice_image,
])
 
# 型安全なJSONが返る
invoice_data = json.loads(response.text)
print(f"請求額: ¥{invoice_data['total']:,.0f}")

複数ファイルの同時処理

Gemini API は1回のリクエストで複数のファイルを処理できます。関連する文書をまとめて送信し、横断的な分析を行うことも可能です。

# 複数の請求書を一括処理
files = [
    genai.upload_file("invoice_2026_01.pdf"),
    genai.upload_file("invoice_2026_02.pdf"),
    genai.upload_file("invoice_2026_03.pdf"),
]
 
response = model.generate_content([
    "これら3件の請求書を比較分析してください。"
    "月ごとの合計金額の推移、共通の費目、"
    "異常値があれば指摘してください。",
    *files,
])

バッチ処理パイプラインの構築

非同期バッチ処理の実装

大量のファイルを処理する場合、非同期処理とリトライ機構が不可欠です。

import asyncio
import aiofiles
from typing import List
from dataclasses import dataclass
 
@dataclass
class BatchResult:
    total: int
    succeeded: int
    failed: int
    results: List[AnalysisResult]
    errors: List[dict]
 
class BatchProcessor:
    """大量ファイルのバッチ解析"""
 
    def __init__(
        self,
        analyzer: MultimodalAnalyzer,
        max_concurrent: int = 5,
        max_retries: int = 3,
    ):
        self.analyzer = analyzer
        self.semaphore = asyncio.Semaphore(max_concurrent)
        self.max_retries = max_retries
 
    async def process_file(
        self, file_path: str
    ) -> tuple[AnalysisResult | None, dict | None]:
        """1ファイルをリトライ付きで処理"""
        async with self.semaphore:
            for attempt in range(self.max_retries):
                try:
                    # 同期APIを非同期で実行
                    result = await asyncio.to_thread(
                        self.analyzer.analyze, file_path
                    )
                    return result, None
                except Exception as e:
                    if attempt < self.max_retries - 1:
                        # 指数バックオフで待機
                        wait = 2 ** attempt
                        await asyncio.sleep(wait)
                    else:
                        return None, {
                            "file": file_path,
                            "error": str(e),
                            "attempts": self.max_retries,
                        }
 
    async def process_batch(
        self, file_paths: List[str]
    ) -> BatchResult:
        """複数ファイルを並行処理"""
        tasks = [
            self.process_file(path) for path in file_paths
        ]
        outcomes = await asyncio.gather(*tasks)
 
        results = []
        errors = []
        for result, error in outcomes:
            if result:
                results.append(result)
            if error:
                errors.append(error)
 
        return BatchResult(
            total=len(file_paths),
            succeeded=len(results),
            failed=len(errors),
            results=results,
            errors=errors,
        )

使用例

import asyncio
 
analyzer = MultimodalAnalyzer(api_key="YOUR_GEMINI_API_KEY")
processor = BatchProcessor(analyzer, max_concurrent=3)
 
# フォルダ内の全PDFを一括処理
import glob
pdf_files = glob.glob("invoices/*.pdf")
 
batch_result = asyncio.run(processor.process_batch(pdf_files))
print(f"処理完了: {batch_result.succeeded}/{batch_result.total} 成功")
# 期待出力: 処理完了: 48/50 成功
 
if batch_result.errors:
    print(f"失敗: {batch_result.failed}件")
    for err in batch_result.errors:
        print(f"  - {err['file']}: {err['error']}")

コスト最適化のテクニック

モデルの使い分け

全ての処理に Gemini 2.5 Pro を使う必要はありません。タスクの複雑さに応じてモデルを切り替えることでコストを大幅に削減できます。

  • Gemini 2.5 Flash: 定型フォーマットの文書(請求書、領収書、名刺)の解析
  • Gemini 2.5 Pro: 複雑な契約書の条項分析、複数文書の横断分析
  • Gemini 2.5 Flash Lite: 単純なテキスト抽出、ファイル形式の判定

コンテキストキャッシュの活用

同じシステムプロンプトやスキーマで大量のファイルを処理する場合、コンテキストキャッシュを利用することで入力トークンのコストを最大75%削減できます。

from google.generativeai import caching
import datetime
 
# キャッシュを作成(1時間有効)
cache = caching.CachedContent.create(
    model="models/gemini-2.5-pro",
    display_name="invoice-analysis-cache",
    system_instruction=(
        "あなたは請求書解析の専門家です。"
        "アップロードされたファイルから正確にデータを抽出し、"
        "指定のJSON形式で返してください。"
    ),
    ttl=datetime.timedelta(hours=1),
)
 
# キャッシュを使ってモデルを初期化
cached_model = genai.GenerativeModel.from_cached_content(cache)
 
# 以降のリクエストではシステムプロンプトのトークンが課金されない
for pdf in pdf_files:
    response = cached_model.generate_content([
        "この請求書を解析してください。",
        genai.upload_file(pdf)
    ])

まとめ

Gemini API のマルチモーダル機能は、これまでバラバラのツールで行っていた文書解析ワークフローを一本化できる強力な基盤です。画像・PDF・動画を同じAPIで処理でき、構造化出力やコンテキストキャッシュと組み合わせることで、本番品質の文書解析パイプラインを効率的に構築できます。

まずは1種類のファイル形式(たとえば請求書PDF)の解析から始めて、徐々に対応形式を広げていくアプローチがおすすめです。構造化出力の本番パターンを活用し、RAGパイプラインプロンプトエンジニアリングと組み合わせることで、さらに高度な文書解析システムを実現できるでしょう。

シェア

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

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

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

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

関連記事

API / SDK2026-03-19
Unity × Gemini マルチモーダル AI 実装 完全コード集【上級編】
Unity に Gemini API のマルチモーダル機能(テキスト+画像+音声)を統合する完全実装ガイド。ストリーミング応答、画像認識NPC、音声対話システム、コンテキスト管理まで本番レベルのC#コードを公開。
API / SDK2026-06-28
Gemini API で動画を「時刻つき」で読む — 該当シーンだけを引き出す
画面録画やアプリのデモ動画から「あの操作はどこ?」を探すのは骨が折れます。Gemini API の動画理解を使い、タイムスタンプ付きで該当箇所だけを引き出す方法と、FPS・解像度でトークンを抑える設計をまとめます。
API / SDK2026-06-15
ヘルプ記事とスクリーンショットを1つの File Search に入れて、画像も引用できる回答を返す
テキストのヘルプ記事と画面スクリーンショットを別々のストアで管理していて、回答に手順画像を添えられない。gemini-embedding-2 のマルチモーダル対応で両者を同じ File Search に入れ、引用元の画像まで返すまでを実装で整理しました。
📚RECOMMENDED BOOKS
大規模言語モデル入門
山田育矢
LLM開発
生成AIプロンプトエンジニアリング入門
我妻幸長
プロンプト
Claude CodeによるAI駆動開発入門
平川知秀
AI駆動開発
※ アフィリエイトリンクを含みます
もっと見る →