乐于分享
好东西不私藏

4.4 毫秒,干翻 LibreOffice 和 Pandoc:一个 Rust 库引发的文档处理革命

4.4 毫秒,干翻 LibreOffice 和 Pandoc:一个 Rust 库引发的文档处理革命

做 RAG 和 AI Agent 的同学,应该都经历过这种绝望:

业务方甩过来一个压缩包,里面 Word、PPT、Excel、PDF 什么格式都有,你的任务是把它们全部转成干净的 Markdown 喂给 LLM。打开 LibreOffice 转一份文档要等一秒多,Pandoc 倒是快一点,但只支持 5 种格式。最后你只能每种格式单独写一套解析逻辑,维护成本高到怀疑人生。

最近开源社区冒出来的这个项目,可能会彻底改变这件事。


一、它是什么?

anydoc是 Firecrawl 团队开源的一个文档转换库,纯 Rust 实现,能把14 种办公文档格式转成干净的 GitHub Flavored Markdown。

支持格式清单:

Word:.doc.docx.docm

PowerPoint:.ppt.pps.pot.pptx.pptm.ppsx.ppsm

Excel:.xls.xlsx.xlsm.xlsb

OpenDocument:.odt.ods.odp

RTF、EPUB、CSV、PDF

背后是 Firecrawl——就是做网站转 Markdown API 的那家公司。anydoc 已经在生产环境跑了很久,Firecrawl Parse 的文档解析底层就是它。

项目采用MIT 许可证,代码在 GitHub 上全公开。


二、最核心的设计:一个模型,统一输出

这是 anydoc 和所有竞品最本质的区别。

大多数转换工具是“每种格式单独写一个解析器直出 Markdown”。docx 走一套逻辑,pptx 走另一套,rtf 再走一套。输出质量参差不齐,修了一个格式的 bug,其他格式该有的问题还在。

anydoc 的做法完全不同:

每种格式的解析器先把文档解析成同一个中间表示(Document Model),然后所有格式共用同一个 Markdown 序列化器

架构示意:

文档字节        ├─► 格式检测(基于内容特征,不靠扩展名)        ├─► 格式解析器(doc/docx/ppt/pptx/xls/xlsx/odt/ods/odp/rtf/epub/csv)                          └─► Document Model(统一的中间表示:块行内元素表格脚注资源)                                      └─► GFM 序列化器  Markdown        └─► PDF  pdf-inspector  直接转 Markdown

这意味着什么?一个表格转义规则的修复,同时修复了 docx、rtf、odt 等所有格式的输出。输出的一致性有保障,维护成本也降到了最低。

Document Model 里保留的信息相当完整:

带锚点的标题层级

粗体、斜体、删除线

行内代码和代码块

链接和内部交叉引用

带原始编号的项目符号列表、编号列表、嵌套列表、任务列表

带合并单元格和表头的表格

块引用、脚注、尾注

演讲者备注

嵌入资源也处理得很干净:图片渲染为 Markdown 的 alt 文本,原始字节保留在 Document Model 中,带 media type 标记,方便你后续自行处理。


三、格式检测:不看扩展名,看内容

很多转换工具靠文件扩展名判断格式。但现实中,文件扩展名经常被改错——明明是 PDF 却被人改成了.doc

anydoc 的格式检测直接从文件内容读取特征

PDF:读 PDF 头

RTF:读 RTF 开放标记

OLE 格式(.doc、.ppt、.xls):读 OLE 流名称

ZIP 包格式(.docx、.pptx、.xlsx):读 ZIP 包的 mimetype 和 content types

CSV 这种没有内嵌标记的格式,才需要显式指定扩展名或格式参数。

Rust、Node.js 和 Python 都提供了format_from_bytesformat_from_extensionformat_from_path三个 API。


四、性能:不是空谈,是碾压

直接看数据。

anydoc 官方做了一组 benchmark,在100 份真实文档上对比了 6 个同类工具。评分由 Claude Sonnet 5 做盲测,从完整性、结构保留、格式保真度、输出整洁度四个维度打分,每对输出交换顺序评判两次以消除位置偏差,总共 481 次判决

综合得分(0-100):

工具支持格式中位耗时综合得分
anydoc14/144.4 ms81
libreoffice12/141129.5 ms39
unstructured8/14572.9 ms62
markitdown6/14134.8 ms64
pandoc5/14102.1 ms56
docling4/14513.6 ms57
mammoth1/1452.5 ms69

中位耗时 4.4 毫秒,比第二快的 pandoc(102ms)快了一个数量级。按这个速度,500 个 DOCX 文件大约 2.2 秒就能处理完

按格式逐一对比(分数越高越好):

格式anydoclibreofficeunstructuredmarkitdownpandocdoclingmammoth
doc875767----
docm8545-----
docx86545373677169
epub77-727252--
odp8623-----
ods8238-----
odt805268-60--
ppt8026-----
pptx7524-61-52-
rtf885445-44--
xls80386662---
xlsm7632-----
xlsx72306655-47-

anydoc 是唯一覆盖全部 14 种格式的工具,在每一个有对比的格式上都拿了最高分

速度测试环境:Ryzen 9 9950X3D、Windows 11、64GB DDR5-6400。anydoc 和 Python 库的计时排除了进程启动开销;CLI 工具则包含进程启动,因为那是实际使用方式。


五、PDF 支持:不依赖 OCR 服务

anydoc 对文本型 PDF通过内置的pdf-inspector直接转换,不需要调用任何外部 OCR 服务。

市面上大约54% 的 PDF 是纯文本的,这部分可以直接本地转换,零网络延迟、零 API 费用。

对于扫描版 PDF 或图片型 PDF(anydoc 会返回Unsupported错误),有两种选择:

先用其他 OCR 工具处理,再把文本喂给 anydoc

使用 Firecrawl 的托管 API 版本,自带 OCR 模型


六、多语言绑定:Node.js、Python、浏览器、Rust

anydoc 不止是 Rust 库,还提供了完整的跨语言支持。

CLI(一行命令搞定):

npx @firecrawl/anydoc report.docxnpx @firecrawl/anydoc slides.pptx -o slides.mdnpx @firecrawl/anydoc - --format csv < data.csv   # 从 stdin 读

从 stdin 读

首次运行自动下载预编译二进制,全局安装用npm install -g @firecrawl/anydoc

Node.js(转换在线程池执行,不阻塞事件循环):

import { toMarkdown } from '@firecrawl/anydoc';const markdown = await toMarkdown('report.docx');

Python(转换时释放 GIL,其他线程继续跑):

import anydocmarkdown = anydoc.to_markdown("report.docx")

浏览器(WebAssembly)(文件本地转换,不上传任何服务器):

import init, { toMarkdownBytes } from '@firecrawl/anydoc-wasm';await init();const markdown = toMarkdownBytes(bytes);

官方还有在线 Demo:,在浏览器里直接跑 WASM,文件不会离开你的机器。

Rust(直接 crate 集成):

let markdown = anydoc::to_markdown("report.docx")?;

七、Agent Skill:AI 编程助手直接读文档

anydoc 还内置了Agent Skill支持:

npx skills add firecrawl/anydoc

这条命令让 Claude Code、Codex、Cursor、OpenCode 等 AI 编程助手学会用 anydoc 读取文档。你的 Agent 遇到 Word 或 PDF 文件时,可以直接调用 anydoc 转成 Markdown 再处理。


八、错误处理:精细化的失败分类

anydoc 的转换失败分得很细:

错误类型含义
Unsupported未知格式或无法转换(如图片型 PDF)
Malformed结构损坏,无法提取有意义内容
Encrypted加密或密码保护
ResourceLimit超出安全限制(解压、嵌套深度、节点数)
MissingPart缺少必要部件
Io文件读取失败

Node.js 和 WASM 通过error.code暴露错误类型;Python 抛出对应的anydoc.ConvertError子类。

这种精细化的错误分类,在生产 pipeline 里非常实用——你可以对不同错误做不同处理,比如把加密文件单独记录下来,而不是整个流程崩溃。


九、适用场景

anydoc 最适合的是需要批量处理混杂格式文档的 pipeline

RAG 系统的文档预处理

AI Agent 的文件读取能力

企业内部文档的索引构建

任意需要把办公文档转成 LLM 输入的环节

项目地址:github.com/firecrawl/anydoc