なぜ生データはRAGの「悪夢」なのか?
RAG(Retrieval-Augmented Generation)プロジェクトの実戦で半年が過ぎ、私が得た教訓は「チャットボットの効率の80%はデータの質に依存する」ということです。GPT-4やClaude 3.5がいかに優れていても、入力が「ゴミ」であればお手上げです。50ページの財務報告書(複雑な表を含む)を標準的なテキスト読み取りライブラリに投入することを想像してみてください。結果は、文字がバラバラになり、コンテキストが完全に失われた支離滅裂なものになるでしょう。
実際の導入において、Unstructured.ioは真の「救世主」となりました。単に生のテキストを読み取るのではなく、ドキュメントをTitle、NarrativeText、Table、ListなどのElement(要素)に分解します。これにより、ドキュメントの論理構造を維持できます。長さに合わせてやみくもにチャンク化するのではなく、メタデータにタイトルを付与することで、その後の検索(retrieval)の精度が劇的に向上します。
PyPDF2やLangChainのデフォルトのLoaderと比較して、UnstructuredはWord (.docx)、PowerPoint (.pptx)、およびOCR統合による画像ファイルの処理能力において圧倒的に優れています。扱いにくいフォーマットを、コンピュータが理解できるデータへと変換します。
インストールと準備
2つの選択肢があります。公式のAPIを使用するか、ローカルでオープンソースライブラリを実行するかです。機密性の高くないデータでテストする場合は、APIが最も手軽な選択肢です。ただし、パイプラインを完全に制御するためには、ローカル版のインストールをお勧めします。
Unstructuredは、OCRやファイル形式の処理のためにシステム依存関係がかなり「重い」です。Ubuntu/Debianの場合は、以下のコマンドを実行してください:
# 必要なシステムライブラリをインストール
sudo apt-get update
sudo apt-get install -y libmagic-dev poppler-utils tesseract-ocr libreoffice pandoc
次にPythonライブラリをインストールします。PDFからOfficeまでフルサポートするために、通常は [all-docs] 版を使用します:
pip install "unstructured[all-docs]" langchain-unstructured
高度な抽出パイプラインの設定
このライブラリの核となるのは partition 関数です。ファイル形式を自動的に識別し、適切な抽出戦略を適用します。本番環境(production)で使用する場合は、デフォルト設定ではなくパラメータを微調整する必要があります。
1. レイアウトを維持した抽出
以下のコードは、複雑な技術文書を処理するために使用しているものです。hi_res 戦略は、AIモデルを使用してページレイアウトを認識します:
from unstructured.partition.pdf import partition_pdf
elements = partition_pdf(
filename="bao_cao_ky_thuat.pdf",
strategy="hi_res", # AIを使用してレイアウトを認識(Title, Table, Figure)
infer_table_structure=True, # 表構造をHTMLとして抽出
chunking_strategy="by_title", # 直近のタイトルに基づいてテキストをグループ化
max_characters=1200, # コンテキストウィンドウを最適化するため、各チャンク의 長さを制限
combine_text_under_n_chars=250 # 断片的なチャンクを防ぐ
)
2. データクレンジング (Data Cleaning)
抽出後のデータには、特殊文字や改行エラーが含まれることがよくあります。Unstructuredは、数行のコードでこれらをクリーンアップできる cleaners 関数を提供しています:
from unstructured.cleaners.core import clean, group_broken_paragraphs
for element in elements:
# 余分な空白の削除、箇条書きの修正、誤った改行の修正
element.text = clean(element.text, extra_whitespace=True, dashes=True, bullets=True)
element.text = group_broken_paragraphs(element.text)
3. 表の処理 – 精度向上の鍵
私の経験上、表をプレーンテキストのままにしてはいけません。LLMは行と列の関係を理解できないからです。代わりに、表をHTML形式で取得してください。この構造により、GPT-4は生のテキスト形式よりも40%高い精度で表データを理解できるようになります。
tables = [el for el in elements if el.category == "Table"]
if tables:
# プロンプトに入力するために表の内容をHTML形式で取得
table_html = tables[0].metadata.text_as_html
print(f"抽出された表: {table_html[:100]}...")
計測と最適化
自動化システムに導入する場合、品質管理は必須です。以下の2つの重要な指標に注意してください:
- レイテンシ (Latency):
hi_res戦略は、ビジョンモデルを実行するため、PDF 1ページあたり10〜15秒かかる場合があります。速度が必要な場合は、テキストレイヤーが既にあるファイルに対してfastを使用してください。 - メタデータの精度: 出力されるJSONファイルを確認してください。Unstructuredは
page_numberとテキストの座標を提供します。この情報は「ソースの引用」機能を作成する際に非常に価値があり、ユーザーがクリックして元のファイルの正確な場所を確認できるようにします。
from unstructured.staging.base import elements_to_json
elements_to_json(elements, filename="debug_output.json")
実際のシステムにUnstructuredを導入した結果、データの前処理コードの量が60%削減されました. 複雑な構造を持つドキュメントにおいて、検索(Retrieval)フェーズの精度は約35%向上しました。真にプロフェッショナルなRAGシステムを構築したいのであれば、これは必須のツールです。

