写在前面

如果你正在做 RAG、Agent、智能问答、知识库整理,或者只是想把手头一堆 PDF / Word / Excel / PPT / 图片快速喂给 ChatGPT、Claude、Gemini,那”先把文件转成 Markdown”几乎是绕不开的一步。Markdown 既接近纯文本、token 效率高,又是主流 LLM 原生”会读会写”的结构化格式。

微软开源的 MarkItDown 就是专门为了这件事而生的:把各种办公文档、网页、媒体文件批量转成干净、结构化的 Markdown,直接喂给大模型。

本文基于官方仓库 microsoft/markitdown(MIT 协议、Python 3.10–3.14、仍在快速迭代中),带你看清它的能力边界、上手方式、扩展机制和安全注意事项。


一、它到底是什么

1.1 一句话定位

MarkItDown 是一个轻量级 Python 工具,用于将各种文件转换为 Markdown,专供 LLM 和相关文本分析流水线使用。

它的定位很明确:

  • 不是为人类阅读做高保真排版(不像 Adobe Acrobat 那种);
  • 是为下游的文本分析、检索增强生成(RAG)、模型微调、提示工程等场景提供结构良好、token 友好的中间产物。

1.2 与 textract 的区别

仓库里把它和经典工具 textract 做了对比。两者都能从各种文件中”抠文字”,但 MarkItDown 多了关键一点:

维度 textract MarkItDown
目标产物 纯文本 结构化 Markdown
标题/列表/表格 容易糊成一坨 尽量保留为 #、-、Markdown 表格
链接、加粗、代码块 基本丢失 尽量保留
LLM 友好度 一般 原生适配
图片/音频 仅元数据 可结合 OCR / 语音转文字 / LLM 视觉描述

二、为什么偏偏是 Markdown

README 里专门有一节叫 “Why Markdown?”,观点非常清醒:

  1. 极简:几乎就是纯文本加一点点标记,结构信息(标题、列表、表格、链接)都能承载;
  2. LLM 原生:OpenAI GPT-4o、Anthropic Claude、Google Gemini 等主流大模型不仅看得懂,还经常主动用 Markdown 来组织回答——说明它们训练语料里 Markdown 含量极大;
  3. Token 友好:相比 HTML、JSON、PDF 解析出的复杂结构,Markdown 的 token 密度更高,长文档塞进上下文窗口更划算。

这也是为什么”先 MarkItDown,再喂 LLM”成为一条很顺的链路。


三、它能处理哪些格式

官方列出的内置转换器覆盖了非常广的场景:

3.1 办公文档

  • PDF(基于 pdfminer.six + pdfplumber,可叠加云端 OCR)
  • PowerPoint(.pptx)
  • Word(.docx,通过 mammoth 转换)
  • Excel(.xlsx / .xls)
  • Outlook 邮件(.msg)

3.2 媒体文件

  • 图片:EXIF 元数据 + OCR(可选叠加 LLM 视觉描述)
  • 音频(.wav / .mp3):EXIF 元数据 + 语音转录
  • 视频:通过 Azure Content Understanding 处理(详见后文)

3.3 网页与文本

  • HTML
  • CSV / JSON / XML
  • EPUB 电子书
  • Jupyter Notebook(.ipynb)
  • RSS
  • YouTube 链接:自动抓取视频转录文本
  • Bing SERP 结果
  • 维基百科页面
  • ZIP:自动迭代解压并转换内部每个文件

从 PDF 到 YouTube 转录,从 Excel 表格到邮件附件,几乎覆盖了”个人/团队日常会遇到的非结构化文档”的大部分场景。


四、上手指南

4.1 环境准备

需要 Python 3.10 至 3.14。建议使用虚拟环境:

1
2
python -m venv .venv
source .venv/bin/activate # Windows 用 .venv\Scripts\activate

uv 用户:

1
2
uv venv --python=3.12 .venv
source .venv/bin/activate

4.2 安装

一次性安装全部依赖(最省心):

1
pip install 'markitdown[all]'

从源码安装(推荐用于贡献代码):

1
2
3
git clone [email protected]:microsoft/markitdown.git
cd markitdown
pip install -e 'packages/markitdown[all]'

按需安装(控制依赖体积):

1
pip install 'markitdown[pdf, docx, pptx]'

可选依赖组很多,常见的几组:

extras 作用
pdf PDF 转 Markdown
docx / pptx / xlsx / xls Office 三件套
outlook Outlook .msg 邮件
audio-transcription 语音转文字
youtube-transcription YouTube 转录抓取
az-doc-intel Azure Document Intelligence(云端版)
az-content-understanding Azure Content Understanding(多模态)

4.3 命令行使用

最简单的一行:

1
markitdown path-to-file.pdf > document.md

指定输出文件:

1
markitdown path-to-file.pdf -o document.md

从标准输入读(适合管道):

1
cat path-to-file.pdf | markitdown

4.4 Python API

最基础的用法:

1
2
3
4
5
from markitdown import MarkItDown

md = MarkItDown(enable_plugins=False)
result = md.convert("test.xlsx")
print(result.markdown)

需要为图片生成描述?接上任意 OpenAI 兼容的 LLM:

1
2
3
4
5
6
7
8
9
10
11
from markitdown import MarkItDown
from openai import OpenAI

client = OpenAI(max_retries=5)
md = MarkItDown(
llm_client=client,
llm_model="gpt-4o",
llm_prompt="可选的提示词覆盖",
)
result = md.convert("example.jpg")
print(result.markdown)

如果 LLM 调用失败,MarkItDown 会尝试回落到其他可用转换器;只有全部失败才抛 FileConversionException——这个 fallback 行为对批处理非常友好。


五、进阶能力

5.1 Azure Document Intelligence(云端高保真)

内置 PDF 转换器用的是本地解析,扫描件、复杂排版可能效果一般。Azure Document Intelligence 提供云端的版式分析 + OCR,质量更高:

1
2
export MARKITDOWN_DOCINTEL_ENDPOINT="<your-endpoint>"
markitdown path-to-file.pdf -o document.md -d

Python 端等价:

1
2
md = MarkItDown(docintel_endpoint="<document_intelligence_endpoint>")
result = md.convert("test.pdf")

5.2 Azure Content Understanding(多模态王者)

这是 MarkItDown 当前最”重磅”的能力,背后是 Azure 的多模态服务,支持:

  • 文档、图片、音频、视频
  • 结构化字段抽取(输出 YAML front matter)
  • 自定义 analyzer

零配置示例:

1
2
3
4
5
6
from markitdown import MarkItDown

md = MarkItDown(cu_endpoint="<content_understanding_endpoint>")
print(md.convert("report.pdf").markdown) # 文档 → prebuilt-documentSearch
print(md.convert("meeting.mp4").markdown) # 视频 → prebuilt-videoSearch
print(md.convert("call.wav").markdown) # 音频 → prebuilt-audioSearch

自定义 analyzer(用于发票字段抽取等场景):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
md = MarkItDown(
cu_endpoint="<content_understanding_endpoint>",
cu_analyzer_id="my-invoice-analyzer",
)
print(md.convert("invoice.pdf").markdown)
# 输出会带 YAML front matter,类似:
# ---
# contentType: document
# fields:
# VendorName: CONTOSO LTD.
# InvoiceDate: '2019-11-15'
# ---
# <!-- page 1 -->
# ...

为了避免乱花钱,可以用 cu_file_types 限定只让某些格式走云端:

1
2
3
4
5
6
from markitdown.converters import ContentUnderstandingFileType

md = MarkItDown(
cu_endpoint="...",
cu_file_types=[ContentUnderstandingFileType.PDF],
)

5.3 插件系统

MarkItDown 内核只维护”通用、保真”的格式。如果你想支持某个冷门格式,不必改主仓库,写一个第三方插件就行:

1
2
markitdown --list-plugins        # 列出已安装的插件
markitdown --use-plugins path-to-file.pdf # 启用插件

官方提供了 packages/markitdown-sample-plugin 作为开发模板,发布时给仓库打上 #markitdown-plugin 这个 GitHub topic,方便被发现。

社区已经有不少插件:

  • markitdown-ocr:用 LLM Vision 给 PDF / DOCX / PPTX / XLSX 里的图片做 OCR,不需要额外装 ML 库:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    from markitdown import MarkItDown
    from openai import OpenAI

    md = MarkItDown(
    enable_plugins=True,
    llm_client=OpenAI(),
    llm_model="gpt-4o",
    )
    result = md.convert("document_with_images.pdf")
    print(result.markdown)
  • markitdown-mcp:把 MarkItDown 包装成 Model Context Protocol(MCP)服务,让 Claude Desktop / Cursor / 其他 MCP 客户端能直接调用。

5.4 Docker

不想污染本地 Python 环境?一行搞定:

1
2
docker build -t markitdown:latest .
docker run --rm -i markitdown:latest < ~/your-file.pdf > output.md

六、安全注意事项(划重点)

官方在 README 顶部就贴了红色 IMPORTANT 提示,必须重视:

  1. 它会继承当前进程的权限:就像 open()、requests.get() 一样,可以读你机器能读的任何东西。所以不要把用户上传的文件名 / URL 不加校验地传给 MarkItDown。

  2. 在服务端环境务必消毒输入:限制文件路径、限制 URI scheme、屏蔽私网 / loopback / link-local / 云元数据地址等。

  3. 使用最小权限的 API:

    API 适用场景
    convert() 万能:本地文件、URI、字节流都接受
    convert_local() 只读本地文件,更安全
    convert_response() 自己用 requests.get() 取回来再喂
    convert_stream() 打开自己控制的流,最大可控

做 SaaS / 内部工具时,强烈建议默认使用 convert_local(),而不是 convert()。


七、仓库结构与生态

整个 monorepo 拆成了几个独立可发布的子包:

路径 作用
packages/markitdown 核心库 + CLI
packages/markitdown-mcp MCP 协议封装,给 LLM 客户端当工具用
packages/markitdown-ocr 用 LLM Vision 做 OCR 的插件
packages/markitdown-sample-plugin 第三方插件开发模板

每个包都有独立的 pyproject.toml,可以单独发布到 PyPI。

贡献边界

官方很坦率地说明了哪些贡献收、哪些不收:

✅ 收:

  • 现有转换器的保真度改进
  • Bug 修复、性能、安全补丁
  • CLI、markitdown-mcp 包
  • 测试、文档、开发者工具

❌ 不收:

  • Web 服务、REST / HTTP API、托管转换服务
  • Web 前端、桌面应用(PyQt / Electron / Flutter 等)
  • 移动端 App

作者的态度是:这些东西确实有用,请另起一个独立仓库去维护,依赖 PyPI 上的 markitdown 即可。


八、适合谁用、怎么用

结合上面的能力,几个典型场景 MarkItDown 都能直接顶上:

  • 个人知识库 / RAG 检索:把 PDF、Word、PPT 批量转 Markdown 入库;
  • AI 助手 / Agent 工具:通过 markitdown-mcp 让 LLM 直接读取本地文件;
  • 发票 / 合同抽取:用 Azure Content Understanding 的自定义 analyzer 输出 YAML 字段;
  • 媒体字幕化:音频转录 + YouTube 转录抓取,便于二次分析;
  • 数据迁移:把老旧的 Office / PDF 仓库统一成结构化文本。

相比直接调各种云端 OCR / 转换 API,MarkItDown 的好处是:

  • 本地优先(隐私可控)
  • 统一接口(一套 API 处理几十种格式)
  • 渐进式升级(要更好效果就接 Azure / LLM)

九、写在最后

MarkItDown 不是”又一个文档转换工具”。它真正瞄准的是 LLM 时代的结构化中间层:把人类世界那些杂七杂八的文件,统一成模型最擅长消化、token 最划算的 Markdown。

如果你正在做:

  • RAG / 知识库
  • Agent / 工具调用
  • 数据集准备 / 微调语料整理
  • 自动化办公 / 文档流水线

强烈建议把它纳入工具箱。项目在 github.com/microsoft/markitdown,MIT 协议,可放心商用。

一句话总结:MarkItDown = 把”任意文件 → LLM 友好 Markdown”这一件事做到极致。