项目快照:microsoft/markitdown,约 173,898 个 Star,12,703 个 Fork;最新推送时间 2026-07-29T18:18:09Z。本文基于仓库公开资料撰写。

项目地址:https://github.com/microsoft/markitdown

markitdown 从代码、运行环境到实践流程的项目封面
markitdown 的项目能力与实践流程示意。

项目速览(TL;DR)

markitdown 是 Microsoft 开源的轻量级 Python 工具,用于把文件和 Office 文档转换为 Markdown。项目默认分支为 main,使用 Python 编写,采用 MIT 许可证;GitHub 仓库资料显示其拥有 173898 个 Star 和 12703 个 Fork。

它的重点不是还原适合人工出版的高保真排版,而是保留标题、列表、表格、链接等文档结构,输出面向大语言模型(Large Language Model,LLM)和文本分析流水线的 Markdown。支持范围覆盖 PDF、PowerPoint、Word、Excel、图片、音频、HTML、CSV、JSON、XML、ZIP、YouTube URL 和 EPUB 等类型,但每种格式所需的依赖与外部服务并不相同。

  • 项目类型:Python 文件与文档转换工具。
  • 主要输出:Markdown 文本。
  • 最低 Python 版本:Python 3.10。
  • 安装方式:PyPI 安装或从源码以可编辑模式安装。
  • 运行入口:命令行程序 markitdown,以及 Python API 中的 MarkItDown
  • 许可证:MIT License。

定位与目标用户

MarkItDown 的定位是“面向文本分析工具的结构化文本提取”,而不是面向出版、印刷或网页渲染的文档复刻。选择它的核心依据,应当是下游是否需要可被文本处理系统消费的 Markdown,而不是是否要求页面级视觉一致性。

目标用户包括需要把异构文件汇入知识处理流程的 Python 开发者、需要在本地批量提取文档内容的工程团队,以及需要为 LLM 提供结构化文本输入的应用开发者。对于包含扫描图片、音视频或结构化业务字段的场景,README 还提供了 OCR 插件、Azure Document Intelligence 和 Azure Content Understanding 等扩展方向。

输出取舍

README 明确说明,工具会尽量保留标题、列表、表格和链接等重要内容,但输出主要服务于文本分析工具。根据本文作者的经验判断,如果验收标准是像素级版式、字体、页眉页脚和复杂布局完全一致,应先验证转换结果,再决定是否采用该工具。

核心功能

核心功能由“输入资源识别、格式转换、Markdown 汇总”组成。用户可以通过命令行传入本地路径、标准输入流,或在 Python 中调用转换接口;输出可以写到标准输出、文件,或从返回结果中读取文本。

Office 文档与 PDF 转换

对于 PDF、PowerPoint、Word 和 Excel,转换器读取相应文件内容,并把可识别的结构映射为 Markdown。README 将这些格式列为当前支持范围,并通过可选依赖组分别启用 pdfpptxdocxxlsxxls 功能。

触发条件是输入文件属于对应格式且安装了相应依赖;输入可以是命令行路径,也可以由 Python API 接收。输出结果面向文本分析,因此表格、标题和列表是重点保留对象,而非完整的 Office 页面布局。

图片元数据与 OCR 扩展

图片转换器可以处理 EXIF 元数据和 OCR 相关内容。仓库还提供 markitdown-ocr 第三方插件,为 PDF、DOCX、PPTX 和 XLSX 中嵌入的图片增加 OCR 能力;该插件通过 LLM Vision 读取图片文字,沿用图片描述使用的 llm_clientllm_model 模式。

插件安装后,只有在启用插件并提供 llm_client 时才会执行对应的 LLM OCR。README 明确指出,如果没有提供 llm_client,插件仍会加载,但 OCR 会被静默跳过,随后使用标准内置转换器。

音频转写与 YouTube 转写

音频能力覆盖 EXIF 元数据和语音转写;音频转写的可选依赖组为 audio-transcription,适用于 README 提到的 WAV 和 MP3 文件。YouTube URL 转写则由 youtube-transcription 可选依赖组提供。

这两类能力与本地文档解析不同:输入可能需要访问音频内容或 YouTube 资源,输出则进入 Markdown 文本。仓库资料没有给出转写服务的具体实现、支持语言、超时、重试策略或费用信息,部署前应以最新 README 和实际依赖行为为准。

HTML、文本格式与 ZIP

HTML、CSV、JSON 和 XML 属于文本或标记类输入,工具将其内容转换为 Markdown 形式。ZIP 文件的处理方式是遍历压缩包内容,再对其中可识别的文件执行转换;这意味着输入 ZIP 内部的文件类型会影响最终结果。

对 ZIP、HTML 和文本格式的处理不等于安全消毒。转换进程会按照当前进程权限访问资源,压缩包内容也应在受控范围内处理,尤其不能把不可信上传直接交给拥有宽泛文件系统权限的进程。

Azure 云端转换能力

README 提供 Azure Document Intelligence 和 Azure Content Understanding 的可选集成。Azure Content Understanding 面向文档、图片、音频和视频,并支持通过分析器抽取结构化字段,将字段序列化为 YAML front matter。

根据 README,Content Understanding 适合需要音频和视频处理、领域字段抽取、复杂表格或多页文档云端布局分析的场景。其自定义分析器通过 cu_analyzer_id 配置,统一入口由 cu_endpoint 承担;资料未提供具体端点格式、认证字段、区域限制和计费细节。

系统架构与关键模块

仓库资料没有给出完整的架构图、包级依赖图或类关系图。根据 README 的安装路径、CLI 用法、插件目录和转换器描述,可以确认它采用“命令行入口与 Python API + 按格式转换器 + 可选依赖与插件”的组织方式;其中更细的内部调用顺序应以源码为准。

入口层

命令行入口名为 markitdown,能够从文件路径读取内容、从标准输入接收管道数据,并使用 -o 指定输出文件。Python 入口示例使用 from markitdown import MarkItDown 创建转换对象,再调用 convert 并读取 result.text_content

格式转换层

格式转换层按文件类型选择处理路径,PDF、Office、图片、音频、HTML、文本格式、ZIP、EPUB 与在线资源分别对应不同能力。可选依赖组使安装范围与使用场景分离,用户不必在资料所列的场景中全部安装专用依赖。

插件与云服务层

第三方插件默认禁用,命令行可以通过 --list-plugins 查看已安装插件,通过 --use-plugins 启用插件。仓库提供 packages/markitdown-sample-plugin 作为插件开发参考,并在 README 中列出 markitdown-ocr 的安装与使用方式。

Azure 相关能力属于可选云端集成,不应与离线内置转换器混同。采用云端服务时,输入文档会涉及外部处理边界,数据分类、授权和留存策略需要由部署方单独确认。

依赖与运行环境

MarkItDown 要求 Python 3.10 或更高版本,README 建议使用虚拟环境以避免依赖冲突。资料给出了标准 Python、uv 和 Anaconda 三种环境创建方式,但没有给出完整固定版本清单,因此不能据此推断某个具体依赖版本。

虚拟环境创建

Bash
python -m venv .venv
source .venv/bin/activate

使用 uv 时,README 指定 Python 3.12 作为示例,并特别说明在该虚拟环境中应使用 uv pip install,而不是直接使用 pip install。使用 Anaconda 时,资料给出的环境名称为 markitdown,Python 示例版本为 3.12。

可选依赖分组

依赖组 用途 资料中的触发方式
all安装全部可选依赖pip install 'markitdown[all]'
pdfPDF 文件处理pip install 'markitdown[pdf]'
docxWord 文件处理pip install 'markitdown[docx]'
pptxPowerPoint 文件处理pip install 'markitdown[pptx]'
xlsxExcel 文件处理pip install 'markitdown[xlsx]'
xls旧版 Excel 文件处理pip install 'markitdown[xls]'
audio-transcriptionWAV 和 MP3 音频转写安装对应可选依赖
youtube-transcriptionYouTube 视频转写安装对应可选依赖

Docker 运行环境

仓库 Dockerfile 使用 python:3.13-slim-bullseye 作为基础镜像,并通过系统包管理器安装 ffmpegexiftool。镜像设置了 EXIFTOOL_PATH=/usr/bin/exiftoolFFMPEG_PATH=/usr/bin/ffmpeg,默认入口为 markitdown

Dockerfile 还定义了 INSTALL_GITUSERIDGROUPID 构建参数,并将默认用户设置为 nobody:nogroup。这些信息来自仓库 Dockerfile,不代表所有本地安装方式都需要同样的系统包。

快速开始(含最小可运行示例)

最小闭环包含创建环境、安装软件、转换本地文件和检查输出四步。下例只处理本地仓库中的 README 文件,不访问外部资源,也不使用云端凭据。

安装

Bash
python -m venv .venv
source .venv/bin/activate
pip install 'markitdown[all]'

[all] 会安装 README 列出的全部可选依赖。如果只处理 PDF、DOCX 和 PPTX,资料给出的精简安装命令是 pip install 'markitdown[pdf, docx, pptx]';实际输入类型应与安装的依赖组相匹配。

运行

Bash
markitdown README.md -o document.md
cat document.md

命令使用仓库中已经存在的 README.md 作为本地输入,并把结果写入 document.md。命令行也支持标准输出方式:markitdown path-to-file.pdf > document.md,还支持通过管道传入内容:cat path-to-file.pdf | markitdown

Python API 验证

Python
from markitdown import MarkItDown

md = MarkItDown()
result = md.convert("README.md")
print(result.text_content)

该示例验证 Python API 能够读取本地 README 并输出转换文本。资料明确展示了 MarkItDownconvertresult.text_content 的用法;其他 convert_* 方法的完整签名,官方仓库资料未提供,建议以最新 README 和源码为准。

配置说明

README 展示的配置主要围绕可选依赖、插件开关、LLM 客户端和 Azure Content Understanding 参数展开。下表只列出资料中明确出现的字段或选项;没有明确默认值的地方统一标记为“未提供”,不根据示例代码推断默认行为。

字段名 类型 默认值 作用
enable_plugins布尔值未提供Python API 示例中用于启用插件。
llm_client客户端对象未提供向图片描述或 OCR 插件提供 LLM 客户端。
llm_model字符串未提供指定图片描述或 OCR 使用的 LLM 模型;示例值为 gpt-4o
cu_endpoint字符串未提供Azure Content Understanding 的统一服务入口。
cu_analyzer_id字符串未提供指定 Content Understanding 自定义分析器。
EXIFTOOL_PATH环境变量/usr/bin/exiftoolDockerfile 中配置 exiftool 路径。
FFMPEG_PATH环境变量/usr/bin/ffmpegDockerfile 中配置 ffmpeg 路径。
-o命令行选项未提供指定 Markdown 输出文件。
--use-plugins命令行选项插件默认禁用启用已安装的第三方插件。

上表中的 llm_client 示例使用 OpenAI Python 客户端构造,但仓库资料没有给出 API Key 的环境变量名、客户端连接参数或兼容客户端清单。需要接入模型时,应把凭据放在受控的测试环境配置中,不要把真实密钥写入源码、日志或提交记录。

进阶用法

进阶使用的重点是按输入类型收敛依赖和处理路径,并显式决定是否启用插件或云端能力。README 特别提醒,应调用满足场景所需的最窄转换函数,例如 convert_stream()convert_local();这些函数的完整参数说明不在给定资料中。

启用插件

Bash
markitdown --list-plugins
markitdown --use-plugins path-to-file.pdf

第一条命令用于列出已安装插件,第二条命令在转换指定文件时启用插件。插件默认禁用,因此仅安装插件并不会自动改变转换路径;启用后仍需检查插件所需依赖和外部服务是否已经准备好。

OCR 插件示例

Python
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.text_content)

该示例来自 README 的插件用法,使用 pip install markitdown-ocr 安装 OCR 插件,并使用 pip install openai 安装示例客户端。示例中的 OpenAI() 需要由运行环境提供相应认证配置;资料没有指定认证变量名,因此不能在本文补充未经核实的环境变量。

Azure Content Understanding 选择条件

如果需求包含视频处理,README 指出 Azure Content Understanding 是资料中列出的支持选项,因为内置转换器不支持视频。若需求是 YAML front matter 形式的结构化字段、自定义分析器或复杂扫描文档的云端布局分析,也应优先评估该集成。

若输入可以在本地完成处理,内置转换器能够减少外部数据传输范围;若需要 Azure 服务,则应同时评估网络访问、数据驻留、凭据管理和服务费用。仓库资料没有提供 Azure 服务的价格、SLA 或区域可用性。

可观测性与运维

给定资料只展示了转换命令、输出文件和 Python 返回结果,没有提供日志格式、指标名称、追踪集成、健康检查、重试策略或服务端口。生产运维不能把这些能力视为项目已经内置,需在调用方补充必要的记录与失败处理。

建议至少记录输入类型、处理成功或失败、输出目标和异常摘要,同时避免记录文档原文、访问令牌及音视频内容。对于批处理任务,应将原始输入、转换结果和错误信息分开管理,并为失败文件保留可复现的本地样本。

容器运维边界

仓库 Dockerfile 将进程用户设置为 nobody:nogroup,并清理了 APT 缓存。它安装了 ffmpegexiftool,同时默认安装 markitdown[all] 与示例插件;这构成了仓库提供的容器基线。

Dockerfile 没有声明服务端口,也没有提供 Docker Compose 文件或健康检查配置。官方仓库未提供这些信息,建议以最新 README 和 Dockerfile 为准,不要假设该镜像会启动 HTTP 服务。

安全与合规边界

安全重点是输入资源访问权限,而不是转换结果本身。README 的重要提示指出,MarkItDown 会以当前进程权限执行 I/O,因此不可信输入必须先清理,并应调用满足场景所需的最窄 convert_* 函数。

MarkItDown performs I/O with the privileges of the current process. Like open() or requests.get(), it will access resources that the process itself can access.
来源:README

授权与隔离

  • 只处理调用方明确授权的本地文件、标准输入或远程资源。
  • 不可信上传应放在权限受限、路径边界明确的隔离环境中,避免转换进程读取宿主机敏感文件。
  • ZIP、HTML、音频、YouTube URL 和带外部服务的转换应分别评估资源访问、内容解析和数据外传风险。
  • 启用 OCR 或 Azure 集成前,应确认文档图片、音频和视频是否允许发送给相应模型或云服务。
  • 不要把 API Key、文档原文或转写内容写入公开日志、容器镜像和版本库。

资料没有提供漏洞公告、CVE 清单、沙箱实现、文件大小限制、并发限制或数据保留承诺。部署方应自行建立补丁、依赖审计、输入大小控制和数据删除策略;本文不对未在仓库资料中出现的安全保证作推断。

许可证与商用条款

仓库 LICENSE 文件明确采用 MIT License,版权归 Microsoft Corporation。MIT 许可证授予获得软件及相关文档副本的人员使用、复制、修改、合并、发布、分发、再许可和销售软件副本的许可。

因此,按 LICENSE 文本,软件可以用于商业场景;分发全部或实质性部分副本时,需要保留版权声明和许可声明。许可证同时规定软件按“原样”提供,不提供明示或默示担保,作者或版权持有人不承担许可证列明的责任范围之外的损害责任。

商用发布仍需核对依赖包、可选依赖、插件和 Azure 服务各自的许可与合同条件。第三方组件并不会因为主仓库采用 MIT License 就自动适用同一条款;具体分发和合规判断应以仓库 LICENSE、各依赖许可证及服务条款为准。

局限性与已知限制

最明确的限制是输出目标。README 将 MarkItDown 与 textract 进行功能定位上的比较,但强调其关注 Markdown 中重要文档结构,并指出它不一定适合人工消费所需的高保真文档转换;因此,复杂视觉排版的验收不能只看文本是否成功生成。

  • 不同格式需要不同的可选依赖,未安装对应依赖时不能据此认为该格式可用。
  • 内置转换器不支持视频,音频只有基础转写能力;README 将更高质量的音视频处理指向 Azure Content Understanding。
  • 结构化字段抽取并非内置转换器或当前 Document Intelligence 集成暴露的能力,README 将 YAML front matter 字段抽取归于 Content Understanding。
  • OCR 插件依赖 LLM 客户端;没有 llm_client 时,OCR 会静默跳过。
  • 仓库资料没有给出转换准确率、性能基准、并发上限、文件大小上限或 SLA。
  • 远程 URL 和云端能力会引入网络、凭据、隐私及服务可用性依赖。

适合谁 / 不适合谁

是否采用该项目,可以通过输入格式、输出验收标准、部署权限和外部服务要求做出判断。以下条件来自仓库能力描述,具体容量和性能仍需使用真实样本验证。

适合的判断信号

  • 团队使用 Python 3.10 或更高版本,并希望通过 PyPI 或源码安装。
  • 输入同时包含 PDF、Office、HTML、CSV、JSON 或 XML,需要统一转成 Markdown。
  • 下游是 LLM、搜索索引或文本分析流水线,重点关注标题、列表、表格和链接等结构。
  • 可以把格式相关依赖按需安装,并接受通过插件扩展 OCR 或其他转换能力。
  • 业务已具备 Azure Content Understanding 的合规和网络条件,需要视频、结构化字段或云端多模态分析。

不适合的判断信号

  • 验收要求是页面视觉效果、字体、分页和复杂布局的高保真复刻。
  • 运行环境禁止安装对应格式依赖,也不能安装 Dockerfile 中涉及的系统工具。
  • 输入包含敏感数据,但组织政策不允许发送到 LLM 或 Azure 等外部服务。
  • 业务要求项目原生提供 HTTP 端口、SLA、指标体系或明确的高并发保证,而仓库资料没有这些承诺。
  • 需求依赖视频的本地离线转换,且不接受 Azure Content Understanding 等云端方案。

常见问题与排查(FAQ / Troubleshooting)

排查顺序应先确认 Python 版本和可选依赖,再确认插件、输入路径及外部服务边界。仓库资料没有提供统一错误码,因此下面以可核对的安装和用法为主。

为什么命令找不到 markitdown

先确认虚拟环境已经激活,并在该环境中执行了 pip install 'markitdown[all]',或按源码方式安装了 packages/markitdown[all]。如果使用 uv,README 要求在对应环境中使用 uv pip install

为什么某种文件无法转换?

核对输入格式对应的可选依赖组,例如 PDF 使用 pdf,Word 使用 docx,PowerPoint 使用 pptx,Excel 使用 xlsxxls。安装全部可选依赖可以减少遗漏,但会扩大环境依赖范围。

为什么 OCR 没有提取图片文字?

确认已安装 markitdown-ocr,并在 Python API 中设置 enable_plugins=Truellm_clientllm_model。README 明确说明缺少 llm_client 时 OCR 会静默跳过;还应检查模型客户端的认证配置和外部网络策略。

为什么容器中的音频或元数据处理失败?

核对容器是否基于仓库 Dockerfile,且包含 ffmpegexiftool。Dockerfile 中的路径是 /usr/bin/ffmpeg/usr/bin/exiftool;其他镜像的安装位置、系统包和运行用户可能不同,不能直接套用该路径。

是否可以据此确定性能和并发能力?

不能。官方仓库资料未提供 Benchmark、吞吐量、并发上限、超时策略或 SLA;上线前应使用目标格式、目标文件规模和实际部署资源进行测试,并由调用方补充队列、超时和失败重试策略。

源码安装与容器构建

源码安装适用于需要修改项目或验证本地工作树的场景,Dockerfile 则提供了包含系统级运行依赖的容器构建路径。两种方式都应在受控环境中执行,并对构建上下文中的敏感文件进行检查。

Bash
git clone git@github.com:microsoft/markitdown.git
cd markitdown
pip install -e 'packages/markitdown[all]'

上述命令来自 README 的源码安装示例。仓库 Dockerfile 的关键构建逻辑如下,完整构建参数和镜像发布流程应以仓库文件为准。

Text
FROM python:3.13-slim-bullseye

ENV EXIFTOOL_PATH=/usr/bin/exiftool
ENV FFMPEG_PATH=/usr/bin/ffmpeg

RUN apt-get update && apt-get install -y --no-install-recommends \
    ffmpeg \
    exiftool

Dockerfile 最终安装 /app/packages/markitdown[all]/app/packages/markitdown-sample-plugin,并以 markitdown 作为入口。资料没有提供镜像标签、仓库发布地址或生产编排配置,部署时不要据此虚构镜像版本和端口。

项目地址与资源

以下链接均来自仓库资料或 README 中出现的官方服务页面,可用于核对安装、许可证和云端能力说明。