
先给你看一个离谱的对比:同样把一份 Word 转成纯文本,LibreOffice 平均要 1129 毫秒,anydoc 只要 4.4 毫秒——快了 256 倍。而且 it 还全格式通吃:Word、PPT、Excel、PDF、RTF、EPUB 一共 14 种格式全覆盖,转出来是干干净净的 Markdown,专供 AI 读。19 天,1.8 万星,月均 2.85 万。Firecrawl 出品——就是那个做网页抓取工具的团队。这篇拆完你能拿走五样:它凭什么快 256 倍、统一中间模型为什么是神来之笔、benchmark 是怎么严谨到「敢公开裁判方法」的、四端绑定(Rust/Node/Python/WASM)怎么玩、以及它和#04repomix 怎么凑成「喂 AI 一条龙」。
01 / 它到底干了件啥把 office 文档一键变 Markdown,快得离谱
一行命令,任何文档变 AI 能吃的格式
Firecrawl 是做网页抓取的团队,anydoc 是他们出的文档转换库——但跟常见的转换工具完全不是一个路子。它不是「能转就行」,是「转得快、转得干净、转得一致」:
全格式:doc/docx、ppt/pptx、xls/xlsx、odt/ods/odp、rtf、epub、csv、pdf——14 种,官方口径全支持。
全结构:标题锚点、加粗/斜体/删除线、代码块、链接、嵌套列表(保留源编号)、合并单元格表格、引用块、脚注尾注、演讲者备注——全保留。
公式转 LaTeX:Word/PPT 的 OMML、ODF/EPUB 的 MathML、RTF 公式,全部转成 GitHub 风格数学公式。
嵌入式资源:图片转成 alt 文本,原始字节保留在文档模型里。
用法极简:npx @firecrawl/anydoc report.docx,Markdown 直接打到 stdout。还支持从 stdin 读、指定格式名(CSV 这类没有签名标记的格式需要显式命名)。
转成 Markdown 打 stdout$ npx @firecrawl/anydoc slides.pptx -o slides.md # 或者写到文件$ npx @firecrawl/anydoc - --format csv < data.csv # 从 stdin 读$ npx skills add firecrawl/anydoc # 装成 Agent Skill# npx 首次运行自动下载对应平台的预编译二进制Node.jstoMarkdown / toDocumentlibuv 线程池跑,不阻塞事件循环Pythonanydoc.to_markdown("report.docx")释放 GIL,其他线程继续跑浏览器 (WASM)文件在本地转,不出你的机器官方演示页就是纯浏览器跑还有 Rust crate(cargo add anydoc)——五端覆盖,想在哪用都行。
02 / 为什么快 256 倍纯 Rust,无模型,无外部服务
LibreOffice 是开一个重量级进程去解析,anydoc 是纯函数式转换
anydoc 快的原因很朴素:它不依赖 LibreOffice、不跑 OCR、不调外部服务——纯 Rust 写的解析器,单份文档中位数 4.4ms。对比下:LibreOffice 要拉起整个办公套件进程(1129ms),unstructured 和 docling 走的是 ML 模型管线(572ms / 513ms),markitdown 和 pandoc 是常规解析(134ms / 102ms)。
这个速度意味着什么?批量转换不是「批处理任务」,而是「每条请求都能实时转」。比如 RAG 管线要喂 1000 份文档,anydoc 几秒钟全转完,别的工具要等十几分钟。对 AI 应用来说,这是从「离线预处理」到「在线即时转换」的量级跃迁。
03 / 最聪明的设计统一中间模型:修一次,全局生效
所有格式进同一个 Document 模型,走同一个 Markdown 序列化器
这是 anydoc 架构的灵魂。看它的转换流程:文档字节 → 格式检测 → 格式解析器(每种格式一个)→共享 Document 模型→ GFM Markdown 序列化器。
关键在「共享 Document 模型」:docx、rtf、odt、pptx 解析完,全都汇入同一个数据结构(blocks、inlines、tables、footnotes、assets)。然后不管什么格式进来,都走同一个 Markdown 渲染器输出。
这带来的好处是「修一次,全局生效」:修好 docx 的表格转义,rtf、odt、epub 的表格转义自动跟着修好——因为它们走同一个渲染器。输出的一致性不是靠约定,是靠架构保证的。2003 年的 .doc 和昨天的 .pptx 转出来,行为完全一致。
04 / 严谨到敢公开裁判方法benchmark 不糊弄
100 份真实文档、14 种格式、6 个对手、482 次盲评
大多数项目的 benchmark 是「自说自话」,anydoc 这个做得很讲究:
语料:100 份真实世界文档,覆盖 14 种格式。
裁判:LLM 判官(Claude Sonnet 5)盲评两份工具的输出 vs 真值(文档前 6 页转图片),按完整性/结构/格式/清洁度打分。
去偏:每对工具评两次、输出对调,抵消位置偏差——一共 482 次裁决。
公平:每个工具的分按它支持的格式平均,避免「语料偏重某种格式」扭曲结果。mammoth 的 70 分只是 docx 一种格式,anydoc 的 81 分横跨全部 14 种。
结果:anydoc 14/14 格式全支持、每个格式单项都第一、中位数 4.4ms 比第二名快一个数量级。但最有意思的是 README 里那句「Best fit」:它没吹自己天下无敌,而是说「最适合那些收到一堆杂七杂八 office 文档、需要统一结构化 Markdown 输出的管线」——定位写得清清楚楚。
05 / 工程细节格式检测、错误类型、测试三件套
不信任扩展名,靠文件内容判断格式
几个值得抄的工程细节:
格式检测看内容不看扩展名:PDF 读文件头、RTF 读开头分组、OLE 读流名、ZIP 包读 mimetype。文件被错命名也能正确转换。只有 CSV 这种没有签名标记的格式,才需要显式传格式名。
错误类型化:Unsupported(未知格式/纯图片 PDF)、Malformed(结构损坏)、Encrypted(加密)、ResourceLimit(超安全上限)、MissingPart(缺必需部分)、Io。调用方可以按类型决定「记下来继续下一个」还是「上报」。
测试三件套:fixture 快照测试(固定语料)、robustness.rs 变异测试(每个 fixture 变异后仍不崩)、fuzz/ 每格式 fuzz 目标——这不是「有测试」,是「把文档转换往死里测」。
06 / 和 #04 repomix 配一对「喂 AI 一条龙」的输入侧
repomix 打包代码给 AI,anydoc 把文档转给 AI
熟悉这个系列的话,你会发现 anydoc 跟#04拆的 repomix 是天生一对:
一个是「代码进」,一个是「文档进」,但目标一致:把 AI 读不懂的输入,转成 AI 读得懂的格式,让模型不用瞎猜。配合起来就是「喂 AI 一条龙」的输入侧完整方案。
07 / 那到底装不装分场景说话
适合谁、谁先别急、装完立刻做什么
适合装:做 RAG / 知识库的人——文档转 Markdown 是必经环节,它快 256 倍;给 AI agent 配「读文档」能力的开发者(一行装成 Skill);处理大量 office 文件的办公自动化场景。
先别急:要转扫描件 PDF 的(纯图片 PDF 它转不了,得靠 Firecrawl 托管 API 的 OCR);只需要「偶尔手动转一份」的人(LibreOffice 足够,装它图啥)。
装完立刻做:npx skills add firecrawl/anydoc装进你的 agent,让 AI 从此能读 office 文档;跑npx @firecrawl/anydoc 你的文件.docx试转一份;想批量用就研究下 toMarkdownBytes + 内容检测,别手动传格式。
夜雨聆风