【Azure AI Foundry:第7回(おまけ①)】実務PDFの救世主:Document Intelligenceによる表構造マークダウン抽出
【新連載:Azure AI Foundryとマルチエージェント】
※本連載は、Azure AI Foundry SDK (
azure-ai-projects) を用い、実務で安全・強力に動作する「エンタープライズ仕様の自律チームエージェント」を構築するステップバイステップのハンズオン連載です。
1. イントロダクション(今回の到達目標)
前回で、テレメトリ可視化と自動評価を含めたマルチエージェント協調の基本設計(全6回)が完結しました。
今回からは、連載の最後に実戦知識を付け加える「補足編(おまけ)」の2回構成をお届けします。実務におけるRAG(独自検索)やエージェント開発において、開発者が直面する最大の壁があります。それが、「PDFに埋め込まれた複雑な表(テーブル)データの読み取り」です。
多くの標準的なPDF解析ライブラリは、ドキュメント内のテキストを上から順に抽出するだけであり、表データを単なる空白区切りの「改行テキスト」に分解してしまいます。これでは列と行の関係性が完全に崩壊し、AIが売上集計やデータ分析を行うことは不可能です。
今回は、高度なレイアウト解析エンジンを備えたコグニティブサービスである「Azure AI Document Intelligence」を構築し、Python SDKを用いて決算書などの表入りPDFから表の二次元構造を維持したまま、美しいマークダウンテキストへと変換・抽出するプログラムを構築することを目標とします。
前提条件(Prerequisites)
- 動作確認済みライブラリ:
azure-ai-documentintelligence>=1.0.0b4(または最新バージョン),azure-identity - Azure上の追加リソース:
- Azure AI Document Intelligence サービスの作成。
- 作成したリソースの「キーとエンドポイント」ページから、エンドポイント(
https://...)とAPIキーをコピーしておきます。
2. なぜ「Markdown形式での表構造抽出」が必要なのか
RAGのインフラにPDFデータを取り込む(インジェストする)際、従来の簡易的なテキスト抽出ライブラリ(PyPDFやpdfplumber等)を使用すると、以下のような問題が発生します。
【元の表】
製品名 2023年売上 2024年売上
製品A 100万円 120万円
製品B 80万円 90万円
【従来のパーサーでの抽出結果】
製品名 2023年売上 2024年売上 製品A 100万円 120万円 製品B 80万円 90万円
このように、二次元の表が「一次元の文字列」になってしまうと、LLMは「120万円という数値が、製品Aの2024年のものか、あるいは製品Bの2023年のものか」を正しく判定できなくなります。これが、RAGやデータ分析エージェントが誤った回答(ハルシネーション)を出力する最大の原因です。
Azure AI Document Intelligence の 「Layoutモデル(prebuilt-layout)」 は、ドキュメントの視覚的特徴から見出しや段組、表を検出し、セル結合などの複雑なレイアウトも再現します。さらに、出力形式を Markdown に指定することで、表を完璧なマークダウン・HTMLテーブルの表記(<table>タグや <tr>タグ)として書き出すことができます。
このフォーマットであれば、LLMはヘッダー(列名)とボディ(各セルの値)の対応関係を正確に解釈することができ、検索や集計の精度が100%近くまで向上します。
3. 【実践】Document IntelligenceによるPDF解析とマークダウン出力
手元にあるPDFファイル(例: financial_report.pdf など)を指定し、クラウドの Document Intelligence で解析してマークダウンファイルへ変換する完全な Python スクリプトを実行してみましょう。
# 動作確認済みライブラリバージョン: azure-ai-documentintelligence==1.0.0b4
import os
from azure.core.credentials import AzureKeyCredential
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.ai.documentintelligence.models import DocumentContentFormat
def main():
# 1. 接続資格情報の取得
endpoint = os.environ.get("AZURE_DOCUMENTINTELLIGENCE_ENDPOINT")
api_key = os.environ.get("AZURE_DOCUMENTINTELLIGENCE_KEY")
if not all([endpoint, api_key]):
print("Error: 環境変数 AZURE_DOCUMENTINTELLIGENCE_ENDPOINT, AZURE_DOCUMENTINTELLIGENCE_KEY が設定されていません。")
return
pdf_file_path = "sales_report.pdf" # 解析したいローカルのPDFファイルパス
if not os.path.exists(pdf_file_path):
print(f"Error: 対象ファイル '{pdf_file_path}' がカレントディレクトリに存在しません。")
return
# 2. クライアントの初期化
print(f"⚡ システム: Document Intelligence エンドポイント {endpoint} に接続します...")
credential = AzureKeyCredential(api_key)
client = DocumentIntelligenceClient(endpoint=endpoint, credential=credential)
# 3. PDFファイルを読み込み、非同期解析を開始
print(f"📤 ファイル '{pdf_file_path}' をアップロードして解析中 (モデル: prebuilt-layout)...")
with open(pdf_file_path, "rb") as f:
# output_content_format に DocumentContentFormat.MARKDOWN を指定するのが最大のポイントです
poller = client.begin_analyze_document(
model_id="prebuilt-layout",
body=f,
output_content_format=DocumentContentFormat.MARKDOWN
)
# 4. 解析完了まで待機し、結果を取得
result = poller.result()
print("✅ 解析完了。マークダウンの書き出しを実行します。")
# 5. マークダウンコンテンツを抽出し、ファイルへ保存
# result.content に表や見出しの構造を保持したマークダウン文字列が入っています
markdown_content = result.content
output_md_path = "sales_report.md"
with open(output_md_path, "w", encoding="utf-8") as out_f:
out_f.write(markdown_content)
print(f"\n🎉 変換成功!結果を '{os.path.abspath(output_md_path)}' に保存しました。")
# コンテンツの先頭部分を確認用に表示
print("\n--- 変換結果のサンプル (先頭500文字) ---")
print(markdown_content[:500])
print("----------------------------------------")
if __name__ == "__main__":
main()
4. まとめと次回の展望
今回は、prebuilt-layout モデルと output_content_format=DocumentContentFormat.MARKDOWN を用いることで、PDF内の表構造やセルの結合関係を一切崩すことなく、LLMが理解しやすいプレーンなマークダウンデータへ自動変換する Python スクリプトを実装しました。
これによって、どんなに複雑なビジネスPDFが相手であっても、AIエージェントに正確な「インプット(前提データ)」を渡すための前処理基盤が整いました。
次回、新連載の最終回となる第8回(補足編おまけ②)。
今回 Document Intelligence で抽出した「表構造のマークダウンテキスト」を、実際に Azure AI Search のRAGインデックスにインジェストします。そして、第5回で作成した「マルチエージェントチーム」の Coordinator Agent に対し、「PDF内の表データに基づいて、売り上げ推移の棒グラフを Code Interpreter サンドボックスで描画せよ」という高度な複合命令を与え、チームワークで正確なグラフを描ききる、本連載の「総仕上げテスト」に挑みます。
すべてのパーツが一つに繋がり、エンタープライズエージェントが実力を遺憾なく発揮する最後のハンズオンへ進みましょう。