MicrosoftのmarkitdownでPDF・Office・音声をMarkdownに変換|RAGパイプライン構築の実践ガイド

約19分で読めます by ぽんたぬき
MicrosoftのmarkitdownでPDF・Office・音声をMarkdownに変換|RAGパイプライン構築の実践ガイド

MicrosoftのmarkitdownでPDF・Office・音声をMarkdownに変換|RAGパイプライン構築の実践ガイド

ねえねえ、キミ!!社内ナレッジをLLMに食わせようとしたら、PDF・Word・PowerPoint・Excel・画像・音声……って何でもあり状態になってて「どうすんのコレ😭」ってなったコト、あるよネ!?

僕もサ、先月やらかしちゃいましたヨ……。RAGシステム作ろうと意気込んでPDFをテキスト抽出したんだケド。表は消える、見出し構造は死ぬ、で「コレじゃチャンキングもまともにできんじゃん!!😭」って3時間溶かしちゃったワケ。

そんなキミと僕を救う神ツールが、Microsoftの markitdown でございますヨ!!✨ GitHubスター11万超って、もうロングヒットにもほどがあるよネ😆🎉


なぜ今、MarkdownへのRAG前処理にmarkitdownが使われるのか

企業ナレッジの「フォーマット散乱」問題

聞いてヨ、コレ大事な話でサ。

企業ナレッジって、現実問題バラバラなんですヨ。営業は.pptxで資料を作るし、総務は.xlsxで管理するし、法務は.pdfで契約書を送ってくるし、現場はスキャンした紙の画像をメールで飛ばしてくる……。

でネ、従来の「テキスト抽出だけ」アプローチって、構造情報をゴッソリ捨てちゃうんですヨ😭 見出しがただの文字列になって、表がぐちゃぐちゃになって、「第3章の要件一覧はどこ?」って聞いてもLLMが的外れな回答を返してくる地獄。

RAGの精度って、前処理フェーズで8割くらい決まると僕は思ってるんですヨ!!💡

LLMがMarkdownを好む理由とトークン効率

GPT-4oみたいな大規模LLMは、学習データにMarkdownが大量に含まれてるから、構造をネイティブに理解できるんですネ🎵

しかもトークン効率が全然違うんですヨ!!

HTMLの場合: <h1 class="title-large">My Title</h1>  → 約23トークン
Markdownの場合: # My Title                          → わずか3トークン

コレが数千ドキュメント規模になると……コンテキストウィンドウの節約もできるし、コストも下がるし、精度も上がるし、一石三鳥じゃないですか!!😆🎉


markitdownのインストールとPython環境セットアップ

インストール手順(Python 3.10以上が必須)

まずはサクッと環境を整えましょうネ!!

# 基本インストール
pip3 install markitdown

# 音声文字起こし機能も使いたい場合
pip3 install 'markitdown[audio-transcription]'

# YouTube字幕取得も追加
pip3 install 'markitdown[youtube-transcription]'

# Azure Document Intelligence(高精度OCR)
pip3 install 'markitdown[az-doc-intelligence]'

動作要件と最新バージョン

Python 3.10以上が必須でサ、最新版はv0.1.5(2026年2月リリース)ですヨ!!✨ 最近はMCPサーバー対応もしてきてサ、Claude DesktopといったLLMアプリから直接呼び出せる「ドキュメント変換マイクロサービス」として運用できる時代になってきましたネ😆


markitdownの対応フォーマット一覧と変換品質

対応フォーマットがとんでもない量でサ、まず一覧を見てほしいんですヨ!!✨

カテゴリ フォーマット
オフィス文書 PDF, Word (.docx), PowerPoint (.pptx), Excel (.xlsx/.xls)
画像 JPEG/PNG等(EXIFメタデータ+OCR)
音声 MP3/WAV等(メタデータ+文字起こし)
Web・構造化 HTML, CSV, JSON, XML, EPUB
その他 ZIP, YouTubeのURL!

フォーマット別のMarkdown変換品質と注意点

ぶっちゃけちゃいますヨ😅

Excelはサ、テーブルのMarkdown変換がかなりキレイ!!シートごとに見出しが付いて、セルの中身もちゃんとMarkdownの表として出てくるんですヨ。

PowerPointはスライドのタイトルと本文を##見出しで構造化してくれて、RAGのチャンキング材料としては申し分ないネ!!🎉

PDFはサ……正直ネ、スキャンPDFは弱い😭 テキストレイヤーがあるPDFは問題ないケド、複雑な表や図表は「あ、そこはちょっと……」ってなる場面もあるヨ。Azure Document Intelligenceと組み合わせると段違いで改善されるんだケドサ!

Docling・MarkerとのMarkdown変換処理速度比較

markitdownの最大の強みのひとつが、この処理速度でサ!!

ツール 処理速度(目安)
markitdown v0.1.5 約0.6秒
Docling v2.x 約41秒
Marker v1.x 約2分14秒

測定条件: MacBook Pro M2 / メモリ16GB / Python 3.11 / テスト対象:テキストレイヤーありのA4・10ページPDF 1件 / CPU推論(GPUなし) / 各ツール3回計測の中央値。スキャンPDFや画像ファイルはこの限りではないのでご注意をネ!!

markitdownに切り替えてバッチ処理したら爆速で終わって、思わず「オオオ!!😆」って声が出ちゃいましたヨ!!


CLIとPython APIによるMarkdown変換の使い分け

CLIで素早くMarkdown変換する方法

シェルスクリプトへの組み込みも簡単でサ、動作確認にも重宝しますヨ!!

# ファイルを直接変換
python3 -m markitdown report.pdf -o report.md

# パイプラインで使う場合
cat document.docx | python3 -m markitdown > output.md

# バッチ処理(シェルスクリプト例)
for f in ./docs/*.pdf; do
  python3 -m markitdown "$f" -o "${f%.pdf}.md"
done

ちなみにサ、markitdownをCIパイプラインに組み込んでドキュメントを自動変換する構成を試してみたんだケドサ……想像以上にシンプルに動いてしまって「アレッ、もう終わり!?!!😆」ってなりましたヨ。キミもぜひ試してみてネ!!

Python APIでRAGパイプラインにmarkitdownを組み込む

Python APIを使うと、RAGパイプラインへの統合がグッとスマートになりますヨ!!

from markitdown import MarkItDown

# 基本的な変換
md = MarkItDown(enable_plugins=False)

result = md.convert("report.xlsx")
print(result.text_content)

# LLMビジョンモデルで画像内テキストを解釈
from openai import OpenAI
client = OpenAI()
md_vision = MarkItDown(llm_client=client, llm_model="gpt-4o")
result = md_vision.convert("diagram.jpg")
print(result.text_content)

enable_plugins=Falseがデフォルトでサ、明示的にTrueにしないとプラグインは動かないんですヨ💡 セキュリティ上の考慮もあって、コレは正しい設計だと思いますネ!!

CLIとAPIの使い分けまとめ

ユースケース 推奨
素早い動作確認・単発変換 CLI
シェルスクリプト・バッチ処理 CLI
RAGパイプライン組み込み Python API
LangChain連携・自動化スクリプト Python API
LLMビジョンOCR連携 Python API

画像のOCRとEXIFメタデータ処理の活用例

EXIFメタデータの自動抽出

JPEG画像を変換するとサ、撮影日時・カメラ機種・GPS座標がMarkdownに自動で埋め込まれるんですヨ✨ 写真資産管理システムやメディア検索に使うと、「いつ・どこで・何で撮った写真か」が検索できるようになるんですネ🎵

LLMビジョンを使ったmarkitdownの高精度OCR

ビジョンモデルとの組み合わせがコレまた便利でサ、実際のコードを見てみましょうネ!!

from markitdown import MarkItDown
from openai import OpenAI

client = OpenAI()

# GPT-4oで画像内のテキストをMarkdown化
md = MarkItDown(llm_client=client, llm_model="gpt-4o")

# 手書きメモやスキャン図面でもバッチリ!
result = md.convert("handwritten_note.jpg")
print(result.text_content)

動いた時は「うおおお!!🎉😆」ってなりましたヨ!!

エンタープライズOCR:Azure Document IntelligenceとmarkitdownのPDF変換

法務文書や請求書処理で精度が命!ってときはコッチでサ!!

from markitdown import MarkItDown
from azure.ai.documentintelligence import DocumentIntelligenceClient
from azure.core.credentials import AzureKeyCredential

client = DocumentIntelligenceClient(
    endpoint="https://your-endpoint.cognitiveservices.azure.com/",
    credential=AzureKeyCredential("your-key")
)

md = MarkItDown(docintel_client=client)
result = md.convert("invoice.pdf")
print(result.text_content)

複雑な表が混じった請求書でもバッチリ構造を保持してくれるんですヨ!!精度が段違いでサ、試した瞬間「コレだヨ!!😆」ってなること間違いなしでサ🎉


音声ファイルのWhisper文字起こしとYouTube字幕取得

MP3/WAVのMarkdown文字起こし(Whisper利用)

まず追加パッケージを入れてネ!!

pip install 'markitdown[audio-transcription]'

入れたら、あとはたったこれだけでサ!!

from markitdown import MarkItDown

md = MarkItDown()
result = md.convert("meeting_record.mp3")
print(result.text_content)
# → 会議の文字起こしがMarkdownで出力される

社内会議録をそのままRAGに突っ込めるようになるワケでサ😆 「あの会議でAさんが言ってた件」がLLMに聞けるようになる未来、キミは想像できますか!!✨

YouTube URLからMarkdown字幕を自動取得する方法

URLをそのまま渡すだけ……というのが、信じられないくらいシンプルでサ!!

from markitdown import MarkItDown

md = MarkItDown()
# URLをそのまま渡すだけ!!
result = md.convert("https://www.youtube.com/watch?v=xxxxx")
print(result.text_content)
# → 字幕・トランスクリプトがMarkdownで出てくる

技術系YouTubeの動画を全部RAGに突っ込んで「あの解説動画で言ってた手法」を検索できるようになったら、最高じゃないですか!!🔥


RAGパイプラインへのmarkitdown組み込み方法

さあ、ここが本番でサ!!キミのために全部まとめちゃいますヨ♪

全体フロー:markitdown変換→チャンキング→Embedding→ベクトルDB

ソースファイル(PDF/Word/PPT/画像/音声)
    ↓ markitdown で変換
Markdown テキスト(構造保持)
    ↓ セマンティックチャンキング
チャンク(見出し境界で分割)
    ↓ Embedding
ベクトル
    ↓ ベクトルDB(Chroma/Pinecone)
    ↓ クエリ
LLM が回答生成

MarkdownHeaderTextSplitterを使ったセマンティックチャンキング

コレがmarkitdownをRAGに使う最大のメリットでサ!!💡 ###という見出しをセマンティックな境界として使うと、恣意的なトークン分割よりはるかに精度が上がるんですヨ!

LangChainのMarkdownHeaderTextSplitterと組み合わせると、コレが非常にスマートに実装できますネ🎵

社内ナレッジベースをmarkitdown+LangChain+Chromaで構築する実装例

実際に動くやつをまるごとお見せしましょうネ!!

import os
from pathlib import Path
from markitdown import MarkItDown
from langchain.text_splitter import MarkdownHeaderTextSplitter
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma

def build_knowledge_base(docs_dir: str, db_dir: str):
    md = MarkItDown(enable_plugins=False)
    embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

    # 見出しをセマンティック境界として指定
    headers_to_split = [
        ("#", "h1"),
        ("##", "h2"),
        ("###", "h3"),
    ]
    splitter = MarkdownHeaderTextSplitter(
        headers_to_split_on=headers_to_split
    )

    all_chunks = []
    target_extensions = {".pdf", ".docx", ".pptx", ".xlsx", ".mp3"}

    for file_path in Path(docs_dir).rglob("*"):
        if file_path.suffix.lower() not in target_extensions:
            continue

        print(f"変換中: {file_path.name}")
        try:
            result = md.convert(str(file_path))
            chunks = splitter.split_text(result.text_content)

            # メタデータにファイル情報を追加
            for chunk in chunks:
                chunk.metadata["source"] = str(file_path)
                chunk.metadata["filename"] = file_path.name
            all_chunks.extend(chunks)

        except Exception as e:
            print(f"スキップ: {file_path.name}{e}")

    # Chromaに格納
    vectorstore = Chroma.from_documents(
        documents=all_chunks,
        embedding=embeddings,
        persist_directory=db_dir
    )
    vectorstore.persist()
    print(f"完了! {len(all_chunks)} チャンクをベクトルDBに格納しました")
    return vectorstore

# 実行
vectorstore = build_knowledge_base("./company_docs", "./chroma_db")

「動いたヨ!!」ってなった瞬間、思わずガッツポーズしちゃいましたヨ😆✨ キミも絶対なるから!!


よくあるハマりどころと対処法|markitdown実践Tips

ちょっと聞いてヨ……僕さ、いくつかやらかしちゃいましたヨ……😭 キミには同じ轍を踏ませたくないんでサ!!

enable_plugins=Trueによるバッチ処理の速度低下

# ❌ 無意識にTrueにしていたら処理が重くなった
md = MarkItDown(enable_plugins=True)

# ✅ RAGパイプラインではデフォルトのまま使う
md = MarkItDown(enable_plugins=False)  # デフォルト設定

プラグインを有効化したままバッチ処理したら、想定外にパフォーマンスが落ちてしまいましたヨ……😭 特にRAGパイプラインではenable_plugins=False(デフォルト)のままにしておくのが鉄則ですネ!!

スキャンPDFのMarkdown変換でテキストが消える問題

テキストレイヤーのないスキャンPDFをデフォルト設定で変換すると、まともなテキストが出てこないんですヨ……。コレは本当にやらかしちゃいましたヨ……😭

解決策はAzure Document Intelligenceとの連携でサ!!前述のコードの通り、docintel_clientを渡してあげるだけで段違いの精度になりますヨ!!✨ スキャンPDFや図表が多い文書を扱うなら必須の組み合わせですネ!!

トークン数チャンキングによるRAG精度低下とMarkdownHeaderTextSplitterの使い方

markitdownで変換したMarkdownを、何も考えずにトークン数ベースで分割してたんだケドサ……精度が全然出なくてハマりましたヨ……😭

見出し境界を使ったMarkdownHeaderTextSplitterに切り替えたら、一気に改善しましたヨ!!💡 markitdownが保持してくれた構造情報を、チャンキングにもちゃんと活かさないともったいないですヨネ!! 前のセクションの実装コードがそのまま使えるので、ぜひ参考にしてほしいですネ!!


まとめ:markitdownでRAGパイプラインのMarkdown前処理を制する

というワケでサ、キミ!!markitdownの可能性、伝わりましたかネ!!✨

  • フォーマット変換の統一:PDF・Word・Excel・画像・音声をmarkitdownで一括Markdown化
  • RAG精度の向上:見出し構造を活かしたセマンティックチャンキングで検索精度アップ
  • 圧倒的な処理速度:Doclingの約68倍、Markerの約224倍の変換速度
  • 拡張性の高さ:LLMビジョン・Azure Document Intelligence・MCPサーバー対応

ドキュメント前処理のゴタゴタに悩んでるキミ、まずはpip install markitdownから始めてみてヨ!!絶対「コレだヨ!!😆」ってなるから、保証しますヨ!!🎉✨

関連記事

Anthropicが公開した金融業界向けAIエージェント基盤「financial-services」完全解説——11種のClaudeエージェントとManaged Agents APIによる実装アーキテクチャ
AI・機械学習

Anthropicが公開した金融業界向けAIエージェント基盤「financial-services」完全解説——11種のClaudeエージェントとManaged Agents APIによる実装アーキテクチャ

AnthropicがOSS公開した金融業界向けAIエージェント基盤「financial-services」を徹底解説。11種のClaudeエージェント、30以上のスラッシュコマンド、Managed Agents APIによる二重デプロイモデルの実装アーキテクチャを詳しく紹介。

AIエージェントに必要なのはプロンプトではなくコントロールフローだ——決定論的設計でLLMの信頼性を高める「サンドイッチアーキテクチャ」入門
AI・機械学習

AIエージェントに必要なのはプロンプトではなくコントロールフローだ——決定論的設計でLLMの信頼性を高める「サンドイッチアーキテクチャ」入門

LLMエージェントの信頼性を高める「サンドイッチアーキテクチャ」を解説。プロンプトのMANDATORY頼みを卒業し、決定論的な前後処理レイヤーでLLMを挟む設計パターンで安定稼働を実現する方法を紹介。

コメント

0/2000