做 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_bytes、format_from_extension、format_from_path三个 API。
四、性能:不是空谈,是碾压
直接看数据。
anydoc 官方做了一组 benchmark,在100 份真实文档上对比了 6 个同类工具。评分由 Claude Sonnet 5 做盲测,从完整性、结构保留、格式保真度、输出整洁度四个维度打分,每对输出交换顺序评判两次以消除位置偏差,总共 481 次判决。
综合得分(0-100):
| 工具 | 支持格式 | 中位耗时 | 综合得分 |
|---|---|---|---|
| anydoc | 14/14 | 4.4 ms | 81 |
| libreoffice | 12/14 | 1129.5 ms | 39 |
| unstructured | 8/14 | 572.9 ms | 62 |
| markitdown | 6/14 | 134.8 ms | 64 |
| pandoc | 5/14 | 102.1 ms | 56 |
| docling | 4/14 | 513.6 ms | 57 |
| mammoth | 1/14 | 52.5 ms | 69 |
中位耗时 4.4 毫秒,比第二快的 pandoc(102ms)快了一个数量级。按这个速度,500 个 DOCX 文件大约 2.2 秒就能处理完。
按格式逐一对比(分数越高越好):
| 格式 | anydoc | libreoffice | unstructured | markitdown | pandoc | docling | mammoth |
|---|---|---|---|---|---|---|---|
| doc | 87 | 57 | 67 | - | - | - | - |
| docm | 85 | 45 | - | - | - | - | - |
| docx | 86 | 54 | 53 | 73 | 67 | 71 | 69 |
| epub | 77 | - | 72 | 72 | 52 | - | - |
| odp | 86 | 23 | - | - | - | - | - |
| ods | 82 | 38 | - | - | - | - | - |
| odt | 80 | 52 | 68 | - | 60 | - | - |
| ppt | 80 | 26 | - | - | - | - | - |
| pptx | 75 | 24 | - | 61 | - | 52 | - |
| rtf | 88 | 54 | 45 | - | 44 | - | - |
| xls | 80 | 38 | 66 | 62 | - | - | - |
| xlsm | 76 | 32 | - | - | - | - | - |
| xlsx | 72 | 30 | 66 | 55 | - | 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
夜雨聆风