AnyDoc 实测:14 种文档 4 毫秒转 Markdown,Firecrawl 这套开源方案凭什么把 MarkItDown 和 Pandoc 甩开一个数量级

阅读时长:16分钟

搞 AI Agent 的都懂一个心照不宣的秘密:一旦用户开始上传本地文档,整套流水线的品味立刻塌方。

一个二十年前的 .doc 合同、一份 2009 年导出的 .xls、一份路演 .pptx、一本 .epub,再夹一份扫描版 PDF。想让 LLM 认得,得先把它们统统翻译成 Markdown。可翻译这一步,从来没被谁真正搞定过。

老方案的四种痛法

先复盘一下过去这几年大家怎么凑合过日子。

MarkItDown:微软家的,Python 生态里最常见的一把小刀。docx 转得还行,pptx 勉强,xlsx 就开始飘,.doc 直接不认。速度中等偏慢。

Pandoc:万金油,写论文很香。缺点是格式覆盖偏窄——Excel 类完全不支持,PowerPoint 也不管,主要吃 docx / rtf / epub / odt。老技术栈,胜在稳。

Docling:IBM 出品,方向对着深度学习跑,能处理复杂版式的 PDF。但依赖重、启动慢、单文档五百毫秒起步,喂到批量流水线里马上变瓶颈。

Unstructured:野心大,什么格式都想吃一口,但吃得都不深。质量参差,输出经常带一堆冗余噪声。

LibreOffice CLI:无损,好像什么都支持。真跑起来一份文档要一秒多,纯写死的进程调用,别提做并发。

mammoth:docx 一枝独秀,其他都不管。

结果就是每个团队的文档管道,最后都长成同一副样子:

if pdf:      走 pdfplumber / pypdf → 图片页降级 OCR
elif docx:   走 mammoth 或 python-docx
elif xlsx:   走 openpyxl 硬解
elif pptx:   走 python-pptx 拼接
elif rtf:    ???
elif epub:   走 ebooklib 再自己遍历
else:        raise UnsupportedFormat

四五个库拼在一起,四五套依赖,四五种失败姿势,输出格式还各说各话——docx 出来的表格是一种样子,xlsx 出来的表格又是另一种。想给 LLM 一个统一的 Markdown 骨架?做梦。

AnyDoc 的登场姿势

AnyDoc 是 Firecrawl 在 2026 年 8 月开源的方案,GitHub 上已经拿了 17.6k stars。搭档是 pdf-inspector——同一个团队做的 PDF 专用引擎,13k stars,被内嵌进了 AnyDoc。

一句话:Rust 写的,一个二进制吃 14 种格式,中位转换 4.4 毫秒,输出统一 GitHub Flavored Markdown。

正式覆盖清单:

格式扩展名
Word.doc .docx .docm
PowerPoint.ppt .pps .pot .pptx .pptm .ppsx .ppsm
Excel.xls .xlsx .xlsm .xlsb
OpenDocument.odt .ods .odp
Rich Text.rtf
EPUB.epub
CSV.csv
PDF.pdf(纯文本页)

没有 API key,不依赖外部服务,不需要装 LibreOffice、不需要拉 Docker 镜像。npm install、pip install、cargo add 三选一,装完就能用。

一个调用,四种入口

同一个 API,四种语言绑定长得几乎一模一样。

CLI:

npx @firecrawl/anydoc report.docx > report.md

装成全局命令:

npm install -g @firecrawl/anydoc
anydoc report.docx -o report.md

Node.js:

import { toMarkdown } from '@firecrawl/anydoc';

const md = await toMarkdown('contract.docx');
// 或者从字节流,自动嗅探格式
const md2 = await toMarkdownBytes(bytes);

Python:

import anydoc

md = anydoc.to_markdown("contract.docx")
# 从字节流
md2 = anydoc.to_markdown_bytes(data)

Rust:

let md = anydoc::to_markdown("contract.docx")?;

浏览器(WebAssembly):

npm install @firecrawl/anydoc-wasm

这一条比较惊人。文档不出浏览器就能转成 Markdown,走 WASM 本地跑。合规敏感的场景直接省一整套后端。

Agent Skill:喂给 Claude Code 的最短路径

如果你在用 Claude Code、Codex、Cursor、OpenCode 这类 Agent 框架,AnyDoc 的最快接法是它自带的 Agent Skill:

npx skills add firecrawl/anydoc

一条命令下去,Agent 立刻学会"看到不认识的文档就去调 anydoc CLI 转 Markdown 再读"。不用你写 wrapper,不用你写 system prompt,不用你手工塞 tool schema。Skill 内部自带调用规约,AI 遇到 .docx、.pptx、.xlsx 会自己走这条路。

如果你熟悉 Claude Code Skills / MCP 的组合玩法,这个 Skill 就是那类"该到位的地方直接到位"的典范——不多一分抽象,也不少一分能力。(想深挖 Skill × MCP 联动可以顺手翻 Claude Code 多 Skill/MCP 实际工作流拆解。)

架构:为什么它能做到又快又统一

AnyDoc 的内部流水线很朴素:

document bytes
    │
    ├─► 格式检测(读文件头,不看扩展名)
    │
    ├─► 对应格式的 parser
    │      │
    │      └─► Document 共享模型(blocks / inlines / tables / footnotes / assets)
    │             │
    │             └─► GFM serializer → Markdown
    │
    └─► PDF → pdf-inspector → Markdown

三个设计点值得单独拎出来说。

格式检测走文件内容,不看扩展名。用户随手把 .pptx 存成 .pdf 这种事天天有。AnyDoc 直接读 ZIP 包的 mimetype、OLE stream 名字、PDF header、RTF open group。文件叫什么它不管,长什么样它才管。CSV 是唯一例外——没内容标记,必须靠扩展名或显式声明。

所有格式都走同一个 Document 模型。这一步是重头戏。docx 也好、rtf 也好、odt 也好,parser 输出的都是同一套抽象:block / inline / table / footnote / asset。最后由同一个 Markdown 序列化器落盘。

意思是:你不再需要"docx 表格的转义 bug"、“rtf 表格的转义 bug”、“odt 表格的转义 bug"分别写三次修复。修一次,全格式受益。

PDF 内嵌 pdf-inspector。这个组件本身值得单开一节讲。

pdf-inspector:给 PDF 分流的"路由器”

大多数 PDF 管道犯的是同一个错:默认每一页都可能是扫描件,所以都塞进 OCR。慢、贵、准确率还不如原文。

pdf-inspector 干的是路由这一层。它不渲染图像,只读 PDF 内部结构(字体编码、文本运算符、图像覆盖率),逐页判定:

  • 纯文本页:直接原生抽取,阅读顺序保留
  • 扫描或图像页:打标记,交给下游 OCR 处理

对于一份 200 页的报告,如果 150 页是纯文本,那 150 页压根不用碰 GPU。Firecrawl 自家的 Fire-PDF 靠这一层拿到了 3.5x 到 5x 的加速。

AnyDoc 里的 pdf 支持就是把 pdf-inspector 嵌了进来。文本 PDF 走它、无损、毫秒级;图像 PDF 会抛出 Unsupported——AnyDoc 明确不做 OCR。想要 OCR,要么自己接一层,要么走 Firecrawl 的托管 /parse API。

这是这套方案最诚实的边界。别指望它把扫描版合同变成结构化文本,那是另一个战场。

数字:4.4ms vs 1129ms

Firecrawl 团队跑了个基准测试,100 份真实文档,14 种格式,LLM 盲评质量。数字如下:

工具覆盖格式中位耗时 (ms)总分
anydoc14/144.481
libreoffice12/141129.540
unstructured8/14572.963
markitdown6/14134.865
pandoc5/14102.156
docling4/14513.657
mammoth1/1452.570

三件事得说清楚。

第一,总分口径。每个工具只算它支持的格式的平均分。mammoth 的 70 分是 docx 一个格式跑出来的,AnyDoc 的 81 分是 14 格式的平均。所以直接看总分不完全公平,得看单格式对比。

第二,单格式对比。就算按每个格式单独看,AnyDoc 在 doc、docm、docx、epub、odp、ods、odt、ppt、pptx、rtf、xls、xlsm、xlsx 上都是第一。没有第二。

第三,速度差是数量级级别。4.4ms 对 52ms(第二快的 mammoth),对 102ms(Pandoc),对 1129ms(LibreOffice)。批量场景差异非常吓人。

评测用的是 Ryzen 9 9950X3D 单核暖启动,corpus 是 Firecrawl 内部的(他们没开源,这一点保持诚实态度)。数字本身可以有争议,但架构给出的速度上限差得摆在明面上——纯 Rust 无 ML 模型对上一堆 Java/Python 进程 spawn,快十倍不奇怪。

错误处理:只在真的不行时才失败

AnyDoc 的错误类型设计得很干净:

错误含义
Unsupported未知格式,或图像版 PDF
Malformed结构损坏,抽不出任何东西
Encrypted加密或密码保护
ResourceLimit触发解压、嵌套、节点数上限
MissingPart关键部分缺失
Io读文件失败

这套设计意味着批量处理时你可以自信地 catch-and-continue。遇到 Encrypted 就记录跳过,遇到 Malformed 就报给用户重传,遇到 Unsupported 就走 OCR 分支。语义清晰,不用去猜异常里的 message 字符串。

适合谁,不适合谁

真值得换的场景:

  • 用户上传的文档格式五花八门,你不想再维护四五个 parser
  • 在做 RAG 或知识库,需要一致的 Markdown 结构做 chunk
  • 做 AI Agent 需要读 attach 的 office 文件(Claude Code / Codex Skill 直接接)
  • 批量转换任务,速度差异会直接变成成本差异
  • 隐私合规不想让文档过任何第三方 API(本地跑,浏览器也能跑)

别硬上的场景:

  • 主要处理扫描版 PDF:AnyDoc 不做 OCR,别为了图便宜勉强用,直接上 Mistral OCR、PaddleOCR、Fire-PDF、Tesseract 之类
  • 只处理一种格式且已经稳定跑起来:比如只有 docx 而且 mammoth 已经跑通,收益边际
  • 要求特定输出格式而非 Markdown:AnyDoc 出口就是 GFM,硬要 HTML/JSON 得自己再走一道
  • 需要保留复杂版式(多列排版、精确定位):Markdown 本身丢版面,这不是 AnyDoc 的锅但结果就是丢

三分钟上手

如果你只想试一下手感,最短路径:

# 装
npm install -g @firecrawl/anydoc

# 转一份看看
anydoc ~/Downloads/合同.docx > 合同.md

# 或者从 stdin
cat report.pdf | anydoc > report.md

想直接接进 Claude Code / Codex:

npx skills add firecrawl/anydoc

然后重启 Agent,让它自己处理 attach 的文档。

想在 Python 项目里内嵌:

pip install firecrawl-anydoc
import anydoc

def load_doc_as_markdown(path: str) -> str:
    try:
        return anydoc.to_markdown(path)
    except anydoc.ConvertError as e:
        # Encrypted / Malformed / Unsupported 分类处理
        return f"[无法解析: {type(e).__name__}]"

一点老实话

AnyDoc 不是革命,是收敛。

过去几年"把任何文档变成 LLM 能吃的东西"这个赛道,谁都想解决,谁都只解决了一半。MarkItDown 覆盖窄、Pandoc 老、Docling 重、LibreOffice 慢——它们背后的技术选型都有历史包袱。

Firecrawl 用纯 Rust 从零重写了这一层,没有历史包袱、没有 ML 模型依赖、没有 API key,一个二进制吃 14 格式,配套一个专门管 PDF 分流的 pdf-inspector。这不是魔法,就是在对的抽象层把力气花对了地方——共享 Document 模型让 bug 修一次通杀,格式检测走内容让扩展名骗不了它,把 OCR 明确划到边界之外让整个系统跑得又快又稳。

对于每天要处理各种奇怪文档格式的 AI 应用开发者来说,这是那种"用过就回不去了"的工具。

至于边界——AnyDoc 只做它能做好的部分。扫描版走 OCR,加密版走人工,复杂版式认命降级。诚实这一点,比"什么都能做"重要得多。

相关阅读

© 2026 softon.top

本站已稳定运行 279 天 0 小时 · 131 篇文章

使用 Hugo 构建 主题 Stack 由 Jimmy 设计 由 softon 魔改

最近构建时间:2026-10-07 08:46:24 CST