スキャンPDFまで毎回OCRに送り、処理時間と費用が読めなくなっていませんか。
最短の解決策は、OCRの前にpdf-inspector PDF OCRの判定層を置くことです。テキストPDFは原生解析、スキャンPDFはOCR、混在PDFはページ単位で処理し、判定の信頼情報と失敗時の回退先も保存してください。
この手順が必要なチーム
契約書、報告書、論文を一括処理するバックエンド開発者向けです。RAG用の文書パイプラインで、すべてのPDFをOCRに送る設計を見直したいAIエンジニアにも適しています。
また、負荷試験用の開発環境をレンタルするチームは、先に1文書あたりの処理方式、同時実行数、成果物の受け渡し方法を決めておく必要があります。
最終更新日は2026年8月10日です。インストール方法、Python API、分類値、ページ単位のOCR情報は、執筆時点の公式READMEとPython API仕様、最新タグとリリース履歴を確認しています。
0日目:先に4種類の分流結果を決める
最初に「検出できたか」ではなく、「次に何をするか」を決めます。現在の公式仕様では、分類結果としてtext_based、scanned、image_based、mixedが示され、信頼度やOCR対象ページも扱えます。分類と結果型の説明に合わせ、下流サービスの入力形式まで定義してください。
| 判定 | 基本経路 | 保存する成果物 |
|---|---|---|
| テキストPDF | 原生テキスト抽出、Markdown変換 | 本文、ページ番号、解析情報 |
| スキャンPDF | 画像化してOCR | OCR本文、座標、OCRエンジン情報 |
| 混在PDF | OCR対象ページだけ処理 | ページ別本文、原生解析結果 |
| 異常ファイル | 隔離、再試行、手動確認 | ハッシュ、エラー原因、再処理結果 |
下流が必要とするものが純粋な本文なのか、Markdownなのか、表構造なのか、OCR座標なのかで実装は変わります。判定だけ完成させても、成果物をRAG登録処理が読めなければ運用には入りません。
注意:PDFの見た目が文字でも、フォントマッピングが壊れていると抽出文字が空になる場合があります。文字数だけで成功判定せず、エンコーディング異常や本文品質を回退条件に含めてください。
1時間目:最小経路をクリーン環境で確認する
現行のPython仕様では、パッケージを導入し、process_pdfで検出と抽出をまとめて実行できます。検出だけを先に行う場合はdetect_pdfを使います。API名や戻り値は更新される可能性があるため、固定した記事内コードをそのまま本番へ貼らず、必ず公式Pythonドキュメントとリリース内容を照合してください。
pip install pdf-inspector
最小確認は次の順序で行います。
- 仮想環境を作成し、依存関係を記録します。
- コピー可能な文字PDFを1件用意します。
- 画像だけで構成されたスキャンPDFを1件用意します。
detect_pdfで種類、信頼度、ページ数、OCR対象ページを確認します。- それぞれの判定が想定した下流経路へ渡ることを確認します。
import pdf_inspector
result = pdf_inspector.detect_pdf("document.pdf")
print(result.pdf_type)
print(result.confidence)
print(result.page_count)
print(result.pages_needing_ocr)
本番コードでは、pdf_typeだけで分岐しないでください。信頼度が低い、OCR対象ページがある、文字抽出が空、エンコーディング異常がある、といった条件を組み合わせます。公式仕様には、ページ数、処理時間、ページ別OCR理由、表や段組みの情報も定義されています。
混在PDFは全体OCRか、ページ単位か
混在PDFでは、原則としてページ単位のOCRを選びます。表紙や本文がテキストで、添付資料だけ画像になっている文書を全体OCRへ送ると、すでに存在する文字情報を捨てる可能性があるためです。
公式のページ抽出機能には、ページごとのMarkdownとneeds_ocr情報があります。ページ単位抽出の仕様を使える版なら、次の条件で分けます。
- OCR対象ページが少なく、原生テキストの構造を残したい場合はページ単位。
- ほぼ全ページが画像で、ページ間のレイアウト統一が重要なら全体OCR。
- 表や段組みが多く、OCR後の座標統合が難しい場合は、まず5〜10件程度の代表文書で比較します。
「混在」と出ても、下流が文書単位の単一テキストしか受け取れないなら、ページごとの結果を最後に統合する設計が必要です。検出方式と納品形式を分けて考えると、後からRAG用のチャンク処理を作り直さずに済みます。
Pythonサービスへ組み込む長尾処理
既存のPython APIへ接続する場合は、アップロード処理とOCR処理の間に、次の5段階を置きます。
- ファイルを一時領域へ保存し、SHA-256などのハッシュを計算します。
- ファイルサイズ、拡張子、MIMEタイプ、ハッシュを記録します。
detect_pdfでPDFタイプ、信頼度、ページ数を取得します。- 判定に応じて原生抽出、ページ別OCR、隔離キューへ送ります。
- 判定結果と下流の品質確認を同じジョブIDへ紐付けます。
暗号化PDF、壊れたxref、空白ページ、異常フォント、極端に大きい画像、パスワード付き文書は、通常のOCR失敗と分けてください。復旧不能な文書を同じ再試行キューへ入れると、無限再処理や費用増加につながります。
1日目:単一ファイルを批量ジョブへ変える
一括処理では、入力キュー、実行キュー、隔離キューを分けます。OCRだけ同時実行数を制限し、軽いPDF検出と原生抽出まで同じ上限に合わせない構成が扱いやすいです。
| 管理項目 | 最低限保存する値 | 目的 |
|---|---|---|
| 文書識別 | ファイルハッシュ、ジョブID | 重複処理と再実行の防止 |
| 判定履歴 | 検出バージョン、PDFタイプ、信頼度 | 仕様変更後の比較 |
| 実行履歴 | 開始時刻、終了時刻、経路 | 処理時間の把握 |
| 回退情報 | OCR理由、例外、再試行回数 | 障害分析 |
| 成果物 | 本文、Markdown、座標、ページ情報 | 下流処理と監査 |
並列数は、いきなり最大値を決めないでください。原生解析、画像変換、OCR、Markdown統合では負荷の性質が違います。まず小さな同時実行数でキューの滞留とメモリ使用量を観察し、OCR待ちが増えた場合だけ段階的に拡張します。
2日目:失敗時の回退と品質確認を追加する
検出に失敗した場合の回退は、最低でも3段階にします。
- 判定処理の一時失敗なら、短い間隔で再試行する。
- PDF構造の異常なら、隔離して別の解析器または手動確認へ送る。
- 判定は成功したが本文品質が低いなら、OCR前処理へ戻す。
OCR前処理では、画像解像度、傾き、余白、ページ回転、空白ページを確認します。ただし、前処理を全PDFへ適用するのではなく、スキャンPDFまたは文字抽出品質が基準未満のページに限定します。
公式リポジトリには、デバッグ用のログ設定を説明したトラブルシューティング資料もあります。障害調査では、入力ハッシュ、処理モード、ライブラリ版、対象ページ、エラー種別を一緒に残すと、再現性を確保できます。
経験則:分類結果が正しくても、抽出本文の読み順、表の列崩れ、文字化けが下流品質を壊します。受入試験は「戻り値が返ったか」ではなく、実際の検索結果やチャンク内容まで確認してください。
3日目:本番前の受入基準を固定する
人工ラベル付きのサンプルを用意し、テキストPDF、スキャンPDF、混在PDF、暗号化PDF、空白ページを含む異常文書を入れます。各文書に期待する経路を付け、分類結果だけでなく本文品質も比較します。
次の観測値をダッシュボードへ出してください。
- PDFタイプ別の構成比
- OCRへ回ったページと文書の比率
- 判定失敗率と回退率
- 文書あたりの処理時間
- OCR待ちキューの長さ
- 文字化け、空本文、表崩れの件数
公式READMEのベンチマークでは、200 PDFを対象に、バージョン0.2.6の比較結果として総合スコア0.875、読み順0.915、表評価0.814、処理時間2.8秒と記載されています。ただし、これは特定の評価コーパスとApple M4 Pro環境での結果であり、あなたの文書やOCRサービスの性能保証ではありません。評価条件と再現用成果物を確認し、同じサンプルで回帰試験を行ってください。
先に抽出するか、OCRへ送るかの判断表
| 条件 | 選ぶ経路 | 回退条件 |
|---|---|---|
| テキストPDFで信頼度が十分、本文も読める | 原生抽出 | 文字化け、空本文、表崩れ |
| スキャンPDFでOCR対象ページが大半 | OCR前処理後に全体OCR | OCR品質が基準未満 |
| 混在PDFでOCR対象ページが限定的 | ページ単位OCR | 下流がページ統合に対応しない |
| 判定失敗、暗号化、構造異常 | 隔離・手動確認 | 解析器変更後に再処理 |
実装方式を選ぶための比較
| 方式 | 向いている状況 | 注意点 |
|---|---|---|
| Python API | 既存の文書処理サービスへ組み込みたい | 依存関係と版固定が必要 |
| CLI | バッチやシェルの既存基盤へ追加したい | 終了コードとJSON形式を監視する |
| Node.js連携 | JavaScript系のアップロード基盤を使っている | 型定義とパッケージ版を確認する |
| Rust組み込み | 高い制御性と単一バイナリを重視する | Rust環境とビルド管理が必要 |
短期の検証ならPython API、既存の定期処理ならCLI、サービス本体がNode.jsならNode.js連携という選び方が無難です。なお、利用可能な機能はリリースごとに変わるため、Node.js向けAPIの現行仕様とタグの差分を確認してください。
「先に抽出」か「先に拡張」かを決める
| 状況 | 推奨判断 | 次の作業 |
|---|---|---|
| 文書サンプルが少なく、分類精度が未確認 | 先に抽出と人工確認 | ラベル付きデータセットを作る |
| OCR待ちが長く、原生PDFの比率が高い | 検出層を先に運用化 | キューと回退理由を記録する |
| 失敗理由が文書構造ごとに分かれている | 前処理を分岐 | 暗号化、空白、異常フォントを隔離する |
| 代表文書で品質が安定している | 段階的に拡張 | 同一データセットで版更新を検証する |
現在の全件OCR構成には、不要なOCR待ち、原生テキストの構造損失、OCRサービスへの転送管理という3つの弱点があります。pdf-inspector PDF OCRの分流層を置けば、テキストPDFを先に解析し、スキャンPDFだけをOCRへ回す設計へ移行できます。
ただし、長期運用で大量のOCRやGPU処理を常時行う場合は、自前サーバーや専用クラウドの方が管理しやすいこともあります。反対に、短期間の負荷試験、Python環境の検証、RAG用の文書パイプライン確認なら、KvmkitのMacレンタル環境を使って処理方式と受け渡しを先に確かめる方法が現実的です。環境選定の入口はKvmkitのサービス案内で確認できます。
M4 Mac mini で CI/CD を回すのが一番ラク
Xcode, Fastlane, CocoaPods, and SPM are first-class on macOS. Mac mini M4 unified memory keeps signing and archiving smooth; ~4W standby power suits 24/7 build nodes.