乐于分享
好东西不私藏

任何文档,4.4毫秒变markdown

任何文档,4.4毫秒变markdown

先给你看一个离谱的对比:同样把一份 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 一条龙」。

三个数字,先记住它GitHub API 实测(2026-08-22)17.8kStar · 19 天涨完Firecrawl 出品 · 今天还在推4.4ms中位数转换耗时/份LibreOffice 要 1129ms14/14格式全支持doc/pptx/xlsx/pdf/rtf/epub…它解决什么问题AI 读不了 office 文档——Word/PPT/Excel 是二进制或 ZIP 包anydoc 把任何文档转成 AI 最熟悉的 Markdown,一行命令跟#04repomix 正好配对:repomix 把代码打包给 AI,anydoc 把文档转给 AI——「喂 AI 一条龙」。
三个数字卡:17.8k 星 / 4.4ms / 14 格式,外加它解决的问题定位

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 这类没有签名标记的格式需要显式命名)。

用法:一行命令,四种姿势$ npx @firecrawl/anydoc report.docx

转成 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)——五端覆盖,想在哪用都行。

一行命令四姿势 + 四端绑定:CLI / Node / Python / 浏览器 WASM

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 应用来说,这是从「离线预处理」到「在线即时转换」的量级跃迁。

转换速度对比(中位数,ms/份)来自官方 benchmark——数值越小越快,anydoc 一骑绝尘anydoc4.4msmammoth52.5mspandoc102.1msmarkitdown134.8msdocling513.6msunstructured572.9mslibreoffice1129.5ms为什么速度意味着质变· 批量喂 RAG:1000 份文档,anydoc 几秒转完,LibreOffice 要十几分钟· 在线场景:用户上传即转即返回,不用「先转好再等」· 嵌入到 agent 工具链:agent 需要读文档时,毫秒级返回不打断流程这是从「离线预处理」到「在线即时转换」的量级跃迁。
速度柱状图:anydoc 4.4ms vs LibreOffice 1129.5ms——256 倍差距一目了然

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 转出来,行为完全一致。

统一中间模型:格式进,Markdown 出每种格式一个解析器,但共享同一个模型和渲染器docx parserpptx parserxlsx parserrtf / odt / epub…共享 Document 模型blocks · inlines · tablesfootnotes · assets所有格式汇入同一结构GFM 序列化器唯一的 Markdown 输出标题锚点 · 表格 · 数学公式escaping 规则集中在一处「修一次,全局生效」修好 docx 的表格转义 → rtf / odt / epub 的表格转义自动跟着修好,因为它们走同一个渲染器。输出一致性不是靠「约定」,是靠架构保证的。2003 的 .doc 和昨天的 .pptx 行为完全一致。
每种格式一个解析器,全汇入共享 Document 模型,再由唯一渲染器输出——修一次全局生效

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 输出的管线」——定位写得清清楚楚。

综合质量分(0-100,越高越好)来自官方 benchmark —— 注意每行覆盖的格式数不同,anydoc 横跨全部 14 种anydoc (14/14)81mammoth (1/14)70(只有 docx)markitdown (6/14)65unstructured (8/14)63docling (4/14)57pandoc (5/14)56libreoffice (12/14)40裁判方法(README 原话级别)1. LLM 判官盲评两份工具输出 vs 真值(前 6 页转图片),按完整性/结构/格式/清洁度打分2. 每对评两次、输出对调 → 抵消位置偏差,共 482 次裁决3. 每工具分按它支持的格式平均 → 语料重格式不扭曲结果「裁判怎么打分的」全公开——想复现就能复现,这才是可信的 benchmark。
综合质量分柱状图 + 裁判方法公开:anydoc 81 分覆盖全部格式,mammoth 的 70 只是 docx

05 / 工程细节格式检测、错误类型、测试三件套

不信任扩展名,靠文件内容判断格式

几个值得抄的工程细节:

格式检测看内容不看扩展名:PDF 读文件头、RTF 读开头分组、OLE 读流名、ZIP 包读 mimetype。文件被错命名也能正确转换。只有 CSV 这种没有签名标记的格式,才需要显式传格式名。

错误类型化:Unsupported(未知格式/纯图片 PDF)、Malformed(结构损坏)、Encrypted(加密)、ResourceLimit(超安全上限)、MissingPart(缺必需部分)、Io。调用方可以按类型决定「记下来继续下一个」还是「上报」。

测试三件套:fixture 快照测试(固定语料)、robustness.rs 变异测试(每个 fixture 变异后仍不崩)、fuzz/ 每格式 fuzz 目标——这不是「有测试」,是「把文档转换往死里测」。

工程三件套:检测 / 错误 / 测试格式检测看内容PDF 头 · RTF 开组 · OLE 流名ZIP mimetype · 内容类型错命名也能转对 · 只有 CSV 要显式错误类型化Unsupported / Malformed / EncryptedResourceLimit / MissingPart / Io按类型决定「跳过」还是「上报」测试三件套fixture 快照测试(固定语料)robustness.rs 变异测试fuzz/ 每格式 fuzz 目标为什么「检测看内容」很重要现实世界里的文件扩展名经常是错的:改名保存、邮件转发、下载工具乱命名。按内容判断 → 这些「脏文件」照样转对。按扩展名判断 → 一律报 Unsupported。同样的思路:错误类型化让批量管线能「记下转不了的,继续下一个」——不是所有错误都值得中断整个批处理。变异测试 + fuzz = 把文档转换往死里测——这层功夫在「能转」的玩具和「敢生产用」的库之间划了条线。
工程三件套:内容检测 / 类型化错误 / 快照+变异+fuzz 测试

06 / 和 #04 repomix 配一对「喂 AI 一条龙」的输入侧

repomix 打包代码给 AI,anydoc 把文档转给 AI

熟悉这个系列的话,你会发现 anydoc 跟#04拆的 repomix 是天生一对:

REPOMIX(#04
:代码仓库 → 单文件给 LLM
手法:tree-sitter 只留签名
省 token:~70%
场景:让 AI 读整个代码库
ANDOC(#12
:office 文档 → Markdown 给 LLM
手法:纯 Rust 解析 + 统一模型
:4.4ms/份
场景:让 AI 读 Word/PPT/PDF

一个是「代码进」,一个是「文档进」,但目标一致:把 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 + 内容检测,别手动传格式。

AI 应用的瓶颈从来不是模型,是「喂进去的东西干不干净」。anydoc 用 4.4ms 回答了一个朴素问题:把办公文档喂给 AI 这件事,凭什么不能快得像读文本一样。