powered by TechFeed
表示モード
ハウツー

PDFのテーブルをテキストに平坦化するとRAGが数値を幻覚する — 構造を保ったまま処理する5つの操作

9月3日、Angela ShiおよびKezhan Shiが「Tables in PDFs for RAG: Don't Flatten the Grid」と題した記事を公開した。Angela ShiはMLエンジニアリングおよびRAGシステム設計を専門とし、Kezhan Shiはドキュメント解析と非構造化データ処理を専門とする研究者・エンジニアだ。この記事では、RAGパイプラインでPDF内のテーブルを「テキストに平坦化」せず構造を保ったまま処理するための診断手法と5つの操作について詳しく紹介されている。

9月3日、Angela ShiおよびKezhan Shiが「Tables in PDFs for RAG: Don't Flatten the Grid」と題した記事を公開した。Angela ShiはMLエンジニアリングおよびRAGシステム設計を専門とし、Kezhan Shiはドキュメント解析と非構造化データ処理を専門とする研究者・エンジニアだ。この記事では、RAGパイプラインでPDF内のテーブルを「テキストに平坦化」せず構造を保ったまま処理するための診断手法と5つの操作について詳しく紹介されている。


テーブルをテキストに潰すと何が起きるか

RAGの標準的なパイプラインは、PDFを読み込んでテキストにチャンク化し、埋め込みで検索する。箇条書きや段落はこれで十分機能するが、答えがテーブルのセル内にある瞬間、パイプラインは数値を幻覚し始める。そして誰も気づかないまま、監査人がソース文書を開いて初めて発覚する、というのが典型的な失敗パターンだ。

PDF内のテーブルを扱う難しさはRAGに限った問題ではなく、LlamaParseAzure Document Intelligenceといったドキュメント解析ツールが専用の構造復元ロジックを備えるほど、業界全体で認識されている根本課題だ。その理由はPDFというフォーマットの性質にある。PDF内のテーブルは、データ構造としてのテーブルではない。ページ上に描画された矩形の集合であり、パーサーは空間的な位置関係からグリッドを復元しなければならない。これが失敗すると3つの問題が同時に発生する。

  1. 行・列の構造が失われ、LLMは関係性のない値の羅列を見ることになる
  2. 複数ページにまたがるテーブルでは、ヘッダーが最初のページにしかなく、2ページ目以降が数値ノイズになる
  3. 行が復元されていない以上、「47行目」を引用・参照できない

根本原因は同一だ。テーブルは元々データだったものを、配布フォーマットの都合でレイアウトに変換したものに過ぎない。正しいアプローチは「テキストとしてうまく扱う」ことではなく、早期に構造化データへ復元し、以後はデータとして処理することである。


4段階の表現レベル

記事では、同一のテーブルをパイプライン内で4つの構造レベルで表現できるとしている。テーブルのサイズ、スキーマの安定性、質問の形式に応じて適切なレベルを選ぶのが最初の設計判断だ。

  • A. line_df内の行として保持:デフォルト。Markdownのパイプ記法(| col1 | col2 |)で1行として扱う。混在コンテンツ文書のテーブルの大多数はここで止まる
  • **B. 独立したtable_df**:複数ページにまたがる連結、特定列への射影、行フィルタリングが必要な場合に昇格させる
  • C. 名前付き・型付きの列ストア:同一スキーマのテーブルが複数文書にわたって繰り返し登場する場合(保険契約の保険料テーブル、財務諸表の収益サマリーなど)。SQLで集計・結合できる状態にする
  • D. 異種混在の列ストア:Cを目指したがスキーマを正規化できなかった場合のフォールバック

大半のテーブルはAで止まる。 一部がBに昇格し、繰り返し登場するものがCへ昇格する。


診断:5つの直交するプロパティ

ディスパッチャーが表現レベルを決定するために、各テーブルについて以下の5項目を記録したtable_df_metaを構築する。

プロパティ 値の例
パース品質 Perfect / Partial / Failed
サイズ (n_rows, n_cols)
ヘッダー有無 Present / Absent / Continuation
複数ページ連続性 Autonomous / Continued-from-N / Continues-to-M
文書レベルのテーブル比率 テーブル面積 / テキスト面積(例: 6%, 13%, 26%)

特に「文書レベルのテーブル比率」は重要な指標だ。文書の本文の半分近くをテーブルが占める場合、アーキテクチャそのものを「テキストRAG+テーブル例外処理」から「SQLによるテーブル検索+テキストはアノテーション」へ切り替えることを検討すべきだと記事は指摘する。


5つの操作:最も重要な2つを深掘りする

O1. 位置情報からの構造再構築

パース品質が「Partial」で、単語のバウンディングボックスが利用可能な場合に適用する。x座標のヒストグラムピークで列バンドを、y座標のギャップで行バンドをクラスタリングし、グリッドを再構築する。コストは1ページあたりの幾何学的な1パスのみで、ほぼゼロ。ただし、行をまたいでセルが結合されているような不規則なテーブルはO1では対処できず、O5に引き継ぐ。

O5. Vision-LLMフォールバック

O1が失敗した場合、またはパース品質が「Failed」の場合に適用する。テーブル周辺のページ領域を画像としてレンダリングし、Vision対応のLLMにJSON形式での出力を求める。コストはO1の少なくとも10倍以上であるため、必ずフォールバックとして位置づけなければならない。デフォルトにすると長大な文書でコストが急膨張する。

その他3つの操作

  • O2. 複数ページ連結とヘッダー伝播:同一列構造のテーブルが複数ページに分断されている場合、ヘッダーを各ページの行へコピーして単一のtable_dfに連結する。source_page列で出典ページを保持する
  • O3. 質問駆動の射影:テーブルがコンテキストウィンドウを超える場合に適用する。元記事が定義するscope_filters(対象範囲を絞り込む条件、例:特定の年度や地域)とconcept_keywords(注目すべき概念・用語のリスト)に基づいて列を射影し、行をフィルタリングしてからLLMに渡す
  • O4. 列ストアへの昇格(B→C または B→D):テーブルが複数文書にわたって繰り返す場合、SQLエージェントが処理できる列ストアへ昇格させる

操作の組み合わせ

これらは合成可能だ。「Partial品質 + 3ページ目から継続 + 大型テーブル + フィルタリングが必要」なケースなら O1 → O2 → O3 を順に適用する。各操作はべき等(preconditionを満たさない操作は何もせずスキップされる性質)なので、安全に合成できる。


実装コードはdoc-intel/notebooks-vol1にRunnable Notebookとして公開されている。

詳細はTables in PDFs for RAG: Don't Flatten the Gridを参照していただきたい。