anydoc:Firecrawl开源的Rust文档转Markdown引擎,单文档4.4毫秒

2026-08-10 08:29 👁️ 56 阅读

给大模型准备语料最麻烦的一环,是把散落在各种格式里的文档统一成模型能稳定读取的Markdown。Word、PPT、Excel、PDF各有各的内部结构,传统做法是LibreOffice转一遍、再拿Pandoc修一遍,输出风格还不统一。

Firecrawl在2026年8月开源的anydoc,就是冲着这个问题来的:纯Rust实现,覆盖14种办公文档格式,统一输出GitHub-Flavored Markdown,中位转换时间4.4毫秒。它同时也是Firecrawl Parse托管API的底层引擎。

为什么是anydoc

anydoc的核心架构选择很关键:不管什么格式进来,都先解析到同一个共享文档模型,再通过单一Markdown序列化器输出。这意味着给docx修好的表格转义,rtf、odt会自动跟着生效;标题锚点、合并单元格、脚注、列表编号在所有格式下行为一致。

与之相对的是市面上的其他方案:

  • LibreOffice:需要启动庞大的办公套件,单文档中位耗时1129.5毫秒

  • Pandoc:只覆盖5/14种格式,中位耗时102.1毫秒

  • markitdown:6/14种格式,134.8毫秒

  • docling:4/14种格式,513.6毫秒

  • mammoth:只支持docx一种,52.5毫秒

anydoc官方在100份真实文档上做的盲评基准(由Claude Sonnet 5对照LibreOffice渲染图打分,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

anydoc是唯一覆盖全部14种格式的工具,在每一个有对比的格式上都拿了最高分,速度比第二名的Pandoc快了一个数量级。

💡 基准语料是Firecrawl自有的,不在仓库里。第三方博主拿自己的206份真实文档复测,194份成功转换,csv/xlsx轻松跑进5毫秒以内,复杂pptx/pdf大约在22毫秒左右——依然远快于传统方案。

支持格式

anydoc处理的14种格式包括:

  • 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(仅文本型)

格式识别是从文件字节本身读的——PDF头、RTF开组、OLE流名、ZIP包的mimetype,所以扩展名改错了也能正确转换。CSV没有签名,需要显式指定格式或从扩展名推断。

30秒上手

最快的试用方式是不安装、直接用npx:

# 转换并输出到终端
npx @firecrawl/anydoc report.docx

# 输出到文件
npx @firecrawl/anydoc slides.pptx -o slides.md

# 从stdin读取(CSV需指定格式)
npx @firecrawl/anydoc - --format csv < data.csv

首次运行会自动下载对应平台的预编译二进制。要常驻使用就全局安装:

npm install -g @firecrawl/anydoc

各语言集成

anydoc提供Rust、Node.js、Python、WebAssembly四种绑定,API形态在各语言间保持一致。

Node.js

import { toMarkdown, toMarkdownBytes } from '@firecrawl/anydoc';

const markdown = await toMarkdown('report.docx');
const fromBytes = await toMarkdownBytes(bytes);
const fromCsv = await toMarkdownBytes(bytes, 'csv');

Python

import anydoc

markdown = anydoc.to_markdown("report.docx")
markdown = anydoc.to_markdown_bytes(data)
markdown = anydoc.to_markdown_bytes(data, "csv")
document = anydoc.to_document(data)

Rust

let markdown = anydoc::to_markdown("report.docx")?;
let markdown = anydoc::to_markdown_bytes(&bytes, None)?;
let markdown = anydoc::to_markdown_bytes(&bytes, anydoc::Format::Csv)?;

浏览器(WebAssembly)

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

浏览器端转换完全在本地进行,文件不会上传,官方Demo页就是这么跑的。

给AI Agent用

anydoc内置了Agent Skill,一行命令让Claude Code、Codex、Cursor、OpenCode等兼容Agent原生具备读文档能力:

npx skills add firecrawl/anydoc

装完之后,Agent遇到任意格式的文档都会自动调用anydoc CLI转换,你只需要说"帮我分析这份报告"就行。

生产环境要注意的点

扫描件PDF不在anydoc的处理范围内。文本型PDF通过内置的pdf-inspector在本地转换;扫描件或纯图片PDF会返回Unsupported错误,需要走Firecrawl Parse托管的OCR能力。

错误处理建议区分类型:

try:
    return anydoc.to_markdown(path)
except (anydoc.EncryptedError, anydoc.UnsupportedError) as e:
    # 加密或不支持,记录并跳过
    return None
except anydoc.ConvertError as e:
    # 其他转换错误
    raise

批量处理时把加密、不支持、损坏的文件单独记录,继续处理其余文件即可。

适用场景

anydoc最适合这三类需求:

  1. LLM数据准备/RAG管道——把混合格式的文档批量转成统一Markdown喂给模型

  2. Agent文档读取——作为Skill嵌入AI编程助手,让Agent原生支持多格式文档

  3. 本地批量转换——纯Rust、无ML模型、无外部服务依赖,断网也能跑

如果你不想自己运维,Firecrawl的/parse/scrape端点已经默认在背后调用anydoc(非PDF文档走anydoc,PDF走pdf-inspector),托管版额外提供扫描件OCR。