PDF文書は、企業や個人の情報保存のための重要なキャリアとして、データ処理の分野で常に大きな課題となってきた。Google DeepMindによるGemini 2.0モデルの導入により、この分野はかつてない変化を遂げつつある。本稿では、PDF処理のパターンを完全に変えるGemini 2.0を探求し、実際のコード例を通して、様々な種類のPDF文書を扱うためにこの技術をどのように使用するかを示す。
PDF処理の伝統的課題
長い間、PDF文書を機械が読み取り可能な構造化データに変換することは、AIやデータ処理分野の「大問題」であった。従来のソリューションは、大きく3つのカテゴリーに分けられる:
- オープンソース・エンド・ツー・エンド・モデルレイアウトの複雑さに圧倒され、テーブルやグラフィック、特殊なタイポグラフィを正確に認識するのに苦労する。
- マルチモデルコンビネーションプログラム例えば、NVIDIAのnv-ingestは、Kubernetes上に8つのサービスと複数のGPUをデプロイする必要があり、デプロイが複雑なだけでなく、スケジューリングにもコストがかかる。
- 商業ベースのフィー・フォー・サービスある程度の利便性はあるが、複雑なレイアウトを扱うと精度が安定せず、大規模に適用するとコストが指数関数的に増大する。
これらのソリューションでは、正確性、拡張性、費用対効果のバランスを取るのが難しく、特に数億ページの文書を処理する必要があるシナリオに直面した場合、そのコストは法外なものになることが多い。

環境の設定とGemini 2.0のセットアップ
PDF文書を処理するためにGemini 2.0を使い始めるには、まず環境をセットアップし、推論クライアントを作成する必要があります。以下に具体的な手順を示します:
必要なライブラリをインストールする
%pipインストール "google-genai>=1"
クライアントとモデル設定の作成
from google import genai
# クライアントを作成する
api_key = "YOUR_API_KEY" # APIキーに置き換えてください。
クライアント = genai.Client(api_key=api_key)
# 使用するモデルを定義します。
model_id = "gemini-2.0-flash" # "gemini-2.0-flash-lite-preview-02-05 "または "gemini-2.0-pro-exp-02-05 "も使用します。
PDFファイルのアップロードと処理
# PDFファイルのアップロード
invoice_pdf = client.files.upload(file="invoice.pdf", config={'display_name': 'invoice'})
# ファイルが変換されたトークンの数を確認する
file_size = client.models.count_tokens(model=model_id, contents=invoice_pdf)
print(f'ファイル:{invoice_pdf.display_name}は{file_size.total_tokens}トークンに等しい')
# サンプル出力: File: invoice equals to 821 tokens
以上の手順で、基本環境の設定が完了し、最初のPDFファイルをアップロードして処理することに成功しました。なお、Gemini File APIでは、1プロジェクトあたり最大20GB、1ファイルあたり最大2GBのファイルを保存することができ、アップロードされたファイルは48時間保存されます。
構造化PDFデータ抽出実習
Gemini 2.0の強力な機能は、PDFファイルから構造化データを抽出する機能です。以下では、この機能を実現するためにGeminiでPydanticモデルを使用する方法を、実践的な例を通して紹介します。
一般的なデータ抽出方法を定義する
まず、PDFファイルを処理して構造化データを返す汎用メソッドを定義します:
def extract_structured_data(file_path: str, model: BaseModel).
# File APIにファイルをアップロードする
file = client.files.upload(file=file_path, config={'display_name': file_path.split('/')[-1].split('.)[0]})
# Gemini APIを使用して構造化応答を生成する
prompt = f "次のPDFファイルから構造化データを抽出する"
response = client.models.generate_content(model=model_id、
model=model_id, contents=[prompt, file]、
'response_schema': model})
#はレスポンスをPydanticモデルに変換し、それを返します。
return response.parsed
ケース1:請求書データの抽出
請求書クラスPDFについて、主要な情報を抽出するために以下のモデルを定義することができます:
from pydantic import BaseModel, Field
class Item(BaseModel).
description: str = Field(description="アイテムの説明")
quantity: float = Field(description="アイテムの数量")
gross_worth: float = Field(description="商品の総価値")
class Invoice(BaseModel).
"""請求書番号、日付、説明、数量、総価値、および総価値の合計を持つすべてのリスト項目を抽出する""""
invoice_number: str = Field(description="請求書番号 例: 1234567890")
date: str = Field(description="請求書の日付 例: 2024-01-01")
items: list[Item] = Field(description="明細、数量、総額が記載された項目のリスト")
total_gross_worth: float = Field(description="請求書の総額")
# このモデルを使用してデータを抽出する
result = extract_structured_data("invoice.pdf", 請求書)
# 結果を出力
print(f "抽出された請求書: {result.日付}の{result.invoice_number}、総価値{result.total_gross_worth}")
for item in result.items: print(f "アイテム: {item_gross_worth}")
print(f "アイテム: {item.description}、数量{item.quantity}、総価値{item.gross_worth}")

ケース2:手書き内容を含むフォーム処理
手書きの内容を含むフォームについても、同様に特別なモデルを定義することができる:
class Form(BaseModel).
"""フォーム番号、会計年度開始日、会計年度終了日、プラン負債の年度開始日と年度終了日を抽出する。""""
form_number: str = Field(description="案件番号")
開始日: str = Field(説明="発効日")
begin_of_year: float = Field(description="年度の負債開始日")
end_of_year: float = Field(説明="年度末の制度債務")
# データの抽出
result = extract_structured_data("handwriting_form.pdf", Form)
#出力結果
print(f'Extracted Form Number: {result.form_number} with start date {result.start_date}.\result.begin_of_year}と{result.end_of_year}の年始{result.begin_of_year}と年末{result.end_of_year}のプラン負債')
# 出力例: フォーム番号:CA530082、開始日:02/05/2022 を抽出。
# 年初40000.0、年末55000.0の計画負債。
上記の例を通して、Gemini 2.0は、PDF内のテキストコンテンツを、手書きのテキストも含めて正確に識別し、構造化されたJSONデータフォーマットに変換することができ、データ抽出プロセスを大幅に簡素化できることがわかります。
高度なアプリケーション:ドキュメント・チャンキングと意味理解
RAG(Retrieval Augmented Generation)システムでは、ドキュメントのチャンキングは基本的なテキスト抽出に加えて重要なステップであり、Gemini 2.0はOCRとセマンティックチャンキングの両方を1つのステップで行うことができる。
PDFセマンティック・チャンキングの例
PDFからMarkdownへの変換とセマンティック・チャンキングを同時に行うためのヒント・ワードをご紹介します:
CHUNKING_PROMPT = """次のページをMarkdownにOCRしてください。 表はHTMLとしてフォーマットしてください。
出力を三重バックティックで囲まないでください。
ドキュメントをおおよそ250~1000語のセクションに分割してください。 私たちのゴールは
私たちの目標は、同じセマンティックなテーマを持つページの部分を特定することです。
これらのチャンクはRAGパイプラインに埋め込まれて使われる。
htmlタグでチャンクを囲む。""""
#は処理のためにこのプロンプトを使用します
response = client.models.generate_content(
model=model_id、
contents=[CHUNKING_PROMPT, pdf_file].
)
chunked_content = response.text
このアプローチは、文書の意味的境界を識別し、より意味のあるテキストの塊を生成することで、その後の検索の精度を大幅に向上させる。文字数に基づく従来の機械的なチャンキングに比べ、セマンティック・チャンキングはコンテンツの一貫性と整合性を保つことができる。
Pydanticによる複雑なデータ抽出
より複雑なシナリオの場合、複数のレベルのデータを扱うために、ネストされたPydanticモデルを定義することができる:
class Person(BaseModel): first_name: str = Field(description="その人のファーストネーム")
first_name: str = Field(description="その人のファーストネーム")
last_name: str = Field(description="その人の姓")
last_name: str = Field(description="その人の姓") last_name: str = Field(description="その人の年齢")
work_topics: list[トピック] = Field(description="その人の興味のある分野。")
# Personモデルを使用してレスポンスを生成する
prompt = "Philipp SchmidはGoogle DeepMindのシニアAIデベロッパーリレーションズエンジニアで、Gemini、Gemmaに取り組んでいます。を支援することを使命としています。"
response = client.models.generate_content(
model=model_id、
contents=prompt、
config={'response_mime_type': 'application/json', 'response_schema': Person}.
)
# SDKは自動的にレスポンスをPydanticモデルに変換します。
philipp: Person = response.parsed
print(f "ファーストネームは {philipp.first_name}")
パフォーマンスの最適化とベストプラクティス
ここでは、PDF文書を大規模に処理する際の効率と精度を向上させるためのベストプラクティスをいくつか紹介します:
バッチ処理とトークンの最適化
大量のPDFシーンを処理する必要がある場合、バッチ処理で効率を向上させることができます:
async def batch_process_pdfs(file_paths, model, batch_size=10):: results = [].
結果 = [].
for i in range(0, len(file_paths), batch_size):: バッチ = file_paths[i:i+batch_size): バッチ = file_paths[i:i
バッチ = file_paths[i:i+batch_size]: 結果 = [] for i in range(0, len(file_paths), batch_size).
タスク = [extract_structured_data(path, model) for path in batch].
batch_results = await asyncio.gather(*tasks)
results.extend(batch_results)
print(f "バッチを処理しました {i//batch_size + 1}/{(len(file_paths)+batch_size-1)//batch_size}")
結果を返す
モデルの選択とコスト管理
実際の要件に適したモデルバリエーションを選択することで、コストを大幅に削減することができる:
- ジェミニ2.0フラッシュコストパフォーマンスに優れ、汎用的なシーンに最適です。
- ジェミニ2.0フラッシュライト:: シンプルな文書でより高いコストパフォーマンスを実現
- ジェミニ2.0プロ非常に複雑な文書や、高い精度が要求されるシーンの処理
以下は、各モデルの処理効率の比較である:
モデリング | 1ドルあたり処理されるPDFページ(Markdown変換) |
---|---|
ジェミニ2.0フラッシュ | 約6,000ページ |
ジェミニ2.0フラッシュライト | 約12,000ページ |
ジェミニ1.5フラッシュ | 約10,000ページ |
オープンAI 4ミニ | 約450ページ |
OpenAI 4o | 約200ページ |
人間クロード-3.5 | 約100ページ |
エラー処理と再試行メカニズム
本番環境では、堅牢なエラー処理メカニズムを実装することが重要である:
def extract_with_retry(file_path, model, max_retries=3):: for attempt in range(max_retries).
for attempt in range(max_retries).
try.
return extract_structured_data(file_path, model): for attempt in range(max_retries): try.
except Exception as e: if attempt == max_retries
if attempt == max_retries - 1: print(f "ファイルへのアクセスに失敗しました。
print(f "{max_retries}回試行した後、{file_path}の処理に失敗しました: {e}")
リターン None
print(f "試行{attempt+1}に失敗しました、再試行:{e}")
time.sleep(2 ** attempt) # 指数関数的リトライ戦略

フォーム処理の最適化
複雑なフォームを含むPDFの場合、フォーム認識精度を向上させるために以下のキューワードを使用することができます:
TABLE_EXTRACTION_PROMPT = """PDFからすべての表をHTMLの表として取り出します。
マージされたセル、ヘッダー、書式を含む正確な構造を保持する。
各表は意味的に完全でなければならず、セル間の関係を維持しなければなりません。
数値については、文書に示されているとおりの正確な書式を維持します。""""
結語
この記事で紹介する方法とサンプルコードを通して、あなたはすでにGemini 2.0を使って強力なPDF文書処理システムを構築し始めることができます。単純なテキスト抽出から複雑な構造化データの解析、そしてセマンティックチャンキングまで、Gemini 2.0は優れたパフォーマンスと非常に高い費用対効果を示しています。
バウンディングボックスの認識などにはまだ改善の余地がありますが、技術が進化し続けるにつれて、PDF処理の未来はよりインテリジェントで効率的なものになると信じる理由があります。個人や組織で文書データを大規模に処理する必要がある場合、Gemini 2.0は間違いなく注目に値するものであり、技術的なブレークスルーを採用する価値がある。