クリーンなデータでより良いRAGを:Pythonパイプライン向けMicrosoft MarkItDown活用ガイド

AI tutorial - IT technology blog
AI tutorial - IT technology blog

クリーンなMarkdownがRAG戦略のバックボーンである理由

RAGプロジェクトが失敗する最大の原因は、多くの場合データインジェスト(取り込み)にあります。長年、煩雑なインジェストパイプラインと格闘してきた結果、私は一つの普遍的な事実にたどり着きました。それは、LLMの有効性は、それが消費するデータの構造に依存するということです。

業界が最新のベクトルデータベースや埋め込みモデルに熱中する一方で、原材料であるドキュメントそのものが軽視されがちです。企業の知識の多くは、100ページに及ぶPDFや複雑なExcelスプレッドシート、古いWord文書に閉じ込められています。それらのデータから意味的な文脈を損なわずに抽出することは、非常に大きなハードルです。

ローカルでの概念実証(PoC)から本番環境のシステムへ移行するには、高精度なデータが必要です。構造化されていない未加工のテキストをベクトルストアに投入すると、ヘッダーやテーブルの相関関係といった重要な文脈が失われてしまいます。Microsoft MarkItDownは、これらのフォーマットをクリーンなMarkdownに標準化する統一された手法を提供することで、この問題を解決します。LLMはMarkdownを好みます。HTMLよりもトークン消費が少なく、シンプルで予測可能な構文によってドキュメントの階層構造を保持できるからです。

Microsoft MarkItDownのセットアップ

MarkItDownの真の利点は、統合(集約)にあります。python-docxopenpyxlPyPDF2といった不安定になりがちなライブラリのスタックを個別に管理する代わりに、それらすべてを処理できる単一のインターフェースを利用できます。Python 3.10以上が必要です。グローバルな環境を汚さないよう、仮想環境の使用を強くお勧めします。

# 新しい環境をセットアップ
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

# コアパッケージをインストール
pip install markitdown

コアパッケージは、テキストベースのファイルであればすぐに動作します。OCRを使用して画像を処理したり、LLMを介して説明文を生成したりする必要がある場合は、オプションの依存関係としてopenaiライブラリをインストールできます。インストール後は、クイックチェック用のコマンドラインツール、または自動化のためのPython APIのいずれかを使用できます。

Pythonによる変換のオーケストレーション

CLIは単発のタスクには便利ですが、本番環境のパイプラインには自動化が不可欠です。5,000冊の技術マニュアルを処理する場合、スクリプトが必要になります。Python APIは驚くほど簡潔です。MarkItDownオブジェクトを初期化し、ファイルを指定するだけです。

基本的な単一ファイルの変換

このスニペットは、標準的な変換方法を示しています。ローカルのドキュメントを読み込み、Markdownコンテンツを直接出力します。

from markitdown import MarkItDown

md = MarkItDown()
result = md.convert("architecture_spec.pdf")

print(result.text_content)

resultオブジェクトは単なる文字列ではありません。変換プロセスに関するメタデータが含まれており、大規模なデータセットに対してバッチジョブを実行する際のログ記録や監査において非常に重要です。

ディレクトリのバッチ処理

典型的なデータエンジニアリングのワークフローでは、単一のファイルではなく、山のようなレガシードキュメントを扱うことになります。私は、ディレクトリをクロールし、サポートされているファイルを変換して、ベクトルデータベースのインデックス作成用に準備するために、以下のパターンを使用しています。

import os
from markitdown import MarkItDown

def batch_convert(input_dir, output_dir):
    md = MarkItDown()
    os.makedirs(output_dir, exist_ok=True)

    for filename in os.listdir(input_dir):
        if filename.lower().endswith((".pdf", ".docx", ".xlsx", ".pptx")):
            try:
                print(f"変換中: {filename}")
                result = md.convert(os.path.join(input_dir, filename))
                
                out_path = os.path.join(output_dir, f"{os.path.splitext(filename)[0]}.md")
                with open(out_path, "w", encoding="utf-8") as f:
                    f.write(result.text_content)
            except Exception as e:
                print(f"{filename} の変換に失敗しました: {e}")

batch_convert("./raw_data", "./formatted_markdown")

難関の処理:ExcelとPDF

Excelファイルは、取り込みが難しいことで有名です。ほとんどのライブラリは、スプレッドシートを浮動小数点が散乱した混沌とした塊に変えてしまいます。MarkItDownは異なります。Excelシートを適切にフォーマットされたMarkdownテーブルに変換します。これにより行と列のロジックが維持され、RAGシステムが『セルB2』が『ヘッダーB』に関連していることを実際に理解できるようになります。

PDFには別の課題があります。MarkItDownはインテリジェントなロジックを使用して、ヘッダーやリスト構造を識別します。デフォルトでは専用のOCRエンジンではありませんが、検索可能なPDFから正しい読み取り順序を維持しながらテキストを抽出することに非常に長けています。これにより、古い抽出ツールでよく見られる『マルチカラム(多段組)』レイアウトのバグを防ぐことができます。

マルチモーダル取り込みのためのAI統合

ドキュメントに重要な図表やチャートが含まれている場合、テキストのみの抽出では『目隠し』をされた状態になります。MarkItDownを設定してGPT-4oのようなLLMを使用し、これらの視覚的要素を説明させることができます。これにより、単なるテキストの羅列が、豊かでマルチモーダルなデータソースへと変わります。

from markitdown import MarkItDown
from openai import OpenAI

# 画像解析のためにLLMを設定
client = OpenAI()
md = MarkItDown(llm_client=client, llm_model="gpt-4o")

result = md.convert("manual_with_diagrams.pdf")
with open("enriched_manual.md", "w") as f:
    f.write(result.text_content)

検証とモニタリング

パイプラインを設定して終わりにしてはいけません。出力の品質を検証する必要があります。私は2段階の検証プロセスを採用しています。まず、構造チェックを行います。テーブルは壊れていないか?H1タグやH2タグは正しくネストされているか?Markdownの構造が崩れると、チャンク分割の戦略が失敗し、LLMは文脈を欠いた断片を受け取ることになります。

次に、パフォーマンスとコストに注意を払います。MarkItDown自体は高速ですが、LLMによる画像説明を追加すると、処理時間が1ページあたりミリ秒単位から秒単位に増加する可能性があります。また、トークンコストも発生します。ファイルごとの処理時間をログに記録することをお勧めします。数百枚の画像を含む500ページのPDFに遭遇した場合、別の処理キューにルーティングすることを検討すべきかもしれません。

入力の標準化は、プロンプトエンジニアリングの醍醐味に比べると退屈な作業に思えるかもしれません。しかし、精度を向上させるために最も効果的な(レバレッジの効く)活動です。Microsoft MarkItDownとPythonを使用することで、再現可能な基盤を構築できます。RAGシステムに断片的なノイズではなく、構造化されたインテリジェンスが供給されるようになるのです。

Share: