Word、PowerPoint、Excel、EPUB、PDF,各有各的文件结构。想把它们统一转成 Markdown,往往要先适配多套转换工具。
AnyDoc 想解决的就是这件事:用一套 Rust 库接收多种办公文档,统一输出 GitHub 风格 Markdown。
我在 macOS arm64、Node.js 22.21.1 环境里,用 @firecrawl/anydoc 0.1.9 跑了仓库自带的 DOCX 样本。标题、表格、列表和嵌入对象提示都成功保留下来;换成普通 PNG 输入,它会明确返回 unsupported input,不会把图片当成文档,更不会自动做 OCR。
下面结合官方资料和本机复现,讲清它的结构、接入方式与使用边界。
01|AnyDoc 到底解决什么问题?
AnyDoc 是 Firecrawl 开源的一套文档转换库,核心使用 Rust 编写,当前版本为 0.1.9,采用 MIT License。
它支持八类文档家族:Word、PowerPoint、Excel、OpenDocument、RTF、EPUB、CSV 和 PDF,覆盖常见的 doc/docx、ppt/pptx、xls/xlsx、odt/ods/odp、rtf、epub、csv、pdf 扩展名。
它会尽量保留标题、链接、列表、表格、脚注、备注和嵌入资源等结构,再输出 GitHub-Flavored Markdown(GFM)。
官方浏览器 Demo 使用 WebAssembly 直接在页面内运行转换器。文件在浏览器本地处理,不需要上传服务器。下面这张图是官方 Demo 把 report.csv 转成 Markdown 表格后的真实页面。

**它适合“输入格式很杂,但下游只想接收一种文本结构”的任务。**例如内容迁移、文档预览、搜索索引和数据清洗。
02|为什么不同格式能得到相对一致的输出?
如果只看“支持八类格式”,很容易把 AnyDoc 理解成一堆转换脚本的集合。真正值得看的,是它在解析器和 Markdown 之间放了一层共享的 Document 模型。
官方 README 给出的处理链路可以概括成五步:
1. 读取文档字节。 2. 根据文件内容标记识别格式。 3. 交给对应格式的解析器。 4. 解析为共享的 Document 模型。 5. 通过同一套 GFM serializer 输出 Markdown。

这里有两个设计点。
**第一个是优先按内容识别格式,而不是只信扩展名。**PDF、RTF 和 Office 文件都有对应内容标记;CSV 没有可靠签名,仍需扩展名或显式指定格式。
大多数格式共用中间模型和 serializer。解析器先把标题、段落、表格、脚注和资源收进 Document,再统一转成 Markdown。
这样做的直接收益,是输出规则不用按格式重复维护。官方举的例子很直观:修复一次表格转义,docx、rtf、odt 等格式都会一起受益。
PDF 是一个特殊分支。文本型 PDF 通过 pdf-inspector 直接生成 Markdown,不经过上面的共享 Document 路径。

这套设计不能保证复杂文档百分之百还原,但能让下游少适配多套输出差异。
03|怎么接入:CLI、Node.js、Python 和浏览器
如果只想快速转换一个文件,CLI 最直接:
npx @firecrawl/anydoc report.docxnpx @firecrawl/anydoc slides.pptx -o slides.md第一条输出到终端,第二条写入文件。首次执行时,npx 会下载预编译二进制。
Node.js、Python 和浏览器 WebAssembly 也有官方绑定。需要保留嵌入资源时,可以停在 Document 中间模型。具体吞吐仍要用自己的文档和并发模型验证。
04|本机跑一遍:成功路径和失败路径
我使用的验证环境是:
• macOS Darwin 25.5.0,arm64 • Node.js 22.21.1 • npm 10.9.4 • @firecrawl/anydoc 0.1.9
成功路径使用仓库里的 sample-rich.docx:
npx --yes @firecrawl/anydoc@0.1.9 sample-rich.docx实际输出保留了标题、表格、列表和嵌入对象提示:
Quarterly Widgets| Quarter | Widgets || --- | --- || Q1 | 10 || Q2 | 14 |Embedded object: Excel.Sheet.12失败路径直接传入一张普通 PNG:
anydoc: unsupported input:unrecognized file content and extension
这个结果只证明:**在上述环境和样本上,DOCX 成功转换,普通 PNG 被正确拒绝。**它不能外推成“所有 Office 文档都能无损转换”,也不能说明 AnyDoc 具备图片识别能力。
05|官方 benchmark 很亮眼,但要看清口径
AnyDoc README 公布了一组项目方 benchmark:100 份真实文档、14 种格式,对比六种转换工具。
官方表格里,AnyDoc 覆盖 14/14 格式,中位转换时间为 4.4 ms,综合分为 81。

这些数字可以帮助我们了解项目的设计目标,但不能直接当成独立选型结论,原因有三点:
• 数据由项目维护者提供,不是第三方测评。 • 质量分使用 LLM judge,对文档前六页的渲染图和转换结果进行比较。 • 测试语料不可再分发,没有包含在仓库中,我们无法原样复现整套质量比较。
所以更稳妥的读法是:官方 benchmark 说明 AnyDoc 在“多格式覆盖 + 低转换开销”上有明确目标,也给出了公开测试方法;真正接入前,仍要拿自己的复杂文档建立回归集。
06|边界在哪里,什么时候适合用?
最重要的边界是 OCR。
AnyDoc 可以本地处理文本型 PDF,但扫描页和纯图片 PDF 没有可提取文本,会返回 Unsupported。它不会调用模型,也不会自动把图片识别成文字。
如果不想自己运行,AnyDoc 也是 Firecrawl Parse 的底层转换组件。根据官方说明,托管 API 在相同转换能力之外增加了 OCR 模型,用来处理 AnyDoc 自身无法读取的扫描页面。
如果准备把它放进正式系统,我建议先做四项检查:
1. 输入是不是以 Office、EPUB、CSV 和文本型 PDF 为主?如果大量是扫描件,必须额外准备 OCR。 2. 是否需要本地、确定性的文档转换?如果是,纯 Rust、无外部服务是明显优势。 3. 是否依赖复杂表格、批注、特殊字体或嵌入对象?先用真实样本验证,不要只看简单 Demo。 4. 失败文件怎么处理?**至少记录错误类型、原始文件和重试策略,不要静默丢文档。
当前版本仍是 0.1.x。这不代表项目不能用,但意味着生产接入更应该依赖自己的回归测试,而不是只依赖 README 的示例和 benchmark。
07|结论:它是一层文档转换器,不需要被包装成别的东西
AnyDoc 的价值很具体:支持多种办公文档,用共享中间模型和一套 GFM serializer,把输入统一转换成结构化 Markdown。
需要 CLI、Node.js、Python、Rust 或浏览器本地转换时,它都提供了对应入口;需要扫描件 OCR 时,则要额外接识别服务,或者使用包含 OCR 的托管方案。
如果你准备试用,先选三份最复杂的真实文档:一份 Word、一份 PPT、一份 Excel。转换后重点检查标题层级、合并单元格、列表编号、脚注和嵌入对象,再决定是否进入正式流程。
你平时最难处理的是哪类文档:复杂 Word、PPT,还是 Excel?可以把具体结构说出来,我再用 AnyDoc 做一次针对性验证。
关于作者
我是老罗,一个持续学习和实践新技术的程序员。我会把学到的知识、做过的项目和踩过的坑,整理成真正能用起来的内容。
不止聊 AI,更想和你一起把 AI 用起来。
夜雨聆风