@nickscamara_: 在AnyDoc中引入OCR 现在你的代理可以免费读取扫描文档 → 非OCR处理时间低于5毫秒 → 每页OCR处理时间中位数190毫秒…
摘要
AnyDoc现在包含OCR功能,可用于读取扫描文档,提供快速处理时间和通过Firecrawl的免费托管选项。
查看缓存全文
缓存时间: 2026/08/28 01:44
在 anydoc 中引入 OCR:现在您的智能体可以免费读取扫描文档
→ 非 OCR 文档处理时间低于 5 毫秒 → OCR 文档处理中位时间为每页 190 毫秒 → 支持版面检测、表格、公式 → 通过 @firecrawl 提供托管 OCR 选项 → 免费,无需 API 密钥 https://t.co/MvxaRV5bNV https://t.co/bjyDouuqpR
firecrawl/anydoc
源码:https://github.com/firecrawl/anydoc
anydoc
Crates.io (https://crates.io/crates/anydoc) npm (https://www.npmjs.com/package/@firecrawl/anydoc) PyPI (https://pypi.org/project/firecrawl-anydoc/) 许可协议:MIT skills.sh (https://skills.sh/firecrawl/anydoc)
一个快速的 Rust 库,可将文档(Word、PowerPoint、Excel、OpenDocument、RTF、EPUB、CSV 和 PDF)转换为干净的 GitHub 风格 Markdown。包含 Node.js、Python 和 浏览器 (WebAssembly) 的绑定。
由 Firecrawl (https://firecrawl.dev) 构建,旨在将任何办公文档在个位数毫秒内转换为可直接供 LLM 使用的 Markdown,并且无论输入何种格式,输出都保持一致。它驱动着 Firecrawl Parse (https://firecrawl.dev/parse),因此如果您不想自己运行,托管 API 可以提供相同的转换功能,外加我们针对 anydoc 无法自行读取的扫描页面的 OCR 模型。
在浏览器中试用 (https://firecrawl.github.io/anydoc/):演示页面将该库作为 WebAssembly 运行,因此文件在本地转换,永远不会离开您的机器。
快速开始
智能体技能
anydoc 作为一项智能体技能 (https://agentskills.io) 发布,因此您的智能体可以读取它遇到的任何文档:
npx skills add firecrawl/anydoc
该技能教会智能体使用 anydoc CLI 转换文档。兼容 Claude Code (https://claude.ai/code)、Codex (https://openai.com/codex/)、Cursor (https://cursor.com)、OpenCode (https://opencode.ai) 和任何其他兼容的智能体 (https://agentskills.io/clients)。
CLI
npx @firecrawl/anydoc report.docx # Markdown 输出到标准输出
npx @firecrawl/anydoc slides.pptx -o slides.md # 或输出到文件
npx @firecrawl/anydoc - --format csv < data.csv # 从标准输入读取
npx @firecrawl/anydoc scan.pdf --ocr hosted # 通过 Firecrawl Parse 处理扫描页面
npx 首次运行时会下载适用于您平台的预构建二进制文件。要获得永久性的 anydoc 命令,请使用 npm install -g @firecrawl/anydoc 全局安装。运行 anydoc --help 查看所有选项。
Node.js
npm install @firecrawl/anydoc
import { toDocument, toMarkdown, toMarkdownBytes } from '@firecrawl/anydoc';
// 从文件路径:
const markdown = await toMarkdown('report.docx');
// 从字节数组(自动检测格式):
const fromBytes = await toMarkdownBytes(bytes);
// 或指定格式(CSV 等无格式签名的格式需要):
const fromCsv = await toMarkdownBytes(bytes, 'csv');
// 或停在文档模型层(同时包含嵌入式资源):
const document = await toDocument(bytes);
完整 API 参考:node/README.md
Python
pip install firecrawl-anydoc
import anydoc
# 从文件路径:
markdown = anydoc.to_markdown("report.docx")
# 从字节数组(自动检测格式):
markdown = anydoc.to_markdown_bytes(data)
# 或指定格式(CSV 等无格式签名的格式需要):
markdown = anydoc.to_markdown_bytes(data, "csv")
# 或停在文档模型层(同时包含嵌入式资源):
document = anydoc.to_document(data)
完整 API 参考:python/README.md
浏览器 (WebAssembly)
npm install @firecrawl/anydoc-wasm
import init, { toMarkdownBytes, toDocument } from '@firecrawl/anydoc-wasm';
await init();
// 从字节数组(自动检测格式):
const markdown = toMarkdownBytes(bytes);
// 或指定格式(CSV 等无格式签名的格式需要):
const fromCsv = toMarkdownBytes(bytes, 'csv');
// 或停在文档模型层(同时包含嵌入式资源):
const document = toDocument(bytes);
完整 API 参考:wasm/README.md
Rust
cargo add anydoc
// 从文件路径:
let markdown = anydoc::to_markdown("report.docx")?;
// 从字节数组(自动检测格式):
let markdown = anydoc::to_markdown_bytes(&bytes, None)?;
// 或指定格式(CSV 等无格式签名的格式需要):
let markdown = anydoc::to_markdown_bytes(&bytes, anydoc::Format::Csv)?;
// 或停在文档模型层(同时包含嵌入式资源):
let document = anydoc::to_document(&bytes, None)?;
OCR
anydoc 在本地读取基于文本的 PDF,但不执行 OCR,因此包含扫描或仅图像页面的 PDF 会因 NeedsOcr 而失败。选择启用后,这些文档将发送至 Firecrawl Parse (https://firecrawl.dev/parse),它会进行 OCR 并返回相同的 Markdown。无需注册;设置 FIRECRAWL_API_KEY 可获得更高配额。
| 启用方式 | 密钥,或 FIRECRAWL_API_KEY | |
|---|---|---|
| CLI | anydoc scan.pdf --ocr hosted | --api-key <key> |
| Node | toMarkdown('scan.pdf', { ocr: 'hosted' }) | apiKey |
| Python | anydoc.to_markdown("scan.pdf", ocr="hosted") | api_key |
只有需要 OCR 的文档才会离开机器,并且是整个文档发送,因为 Parse 不支持页面选择。如果 Parse 无法转换,Node 会以 code: 'hosted' 拒绝,Python 则会引发 HostedError。
--api-url、apiUrl 和 api_url,或环境变量 FIRECRAWL_API_URL,用于指向其他 Parse 部署。Rust crate 没有 ocr 选项,且从不发起网络请求。
功能特性
- 单一输出,适用所有格式。 每种格式都解析为共享文档模型,并通过单一 Markdown 序列化器渲染,因此无论是来自 2003 年的
.doc还是昨天生成的.pptx,转义、表格、标题锚点和脚注的行为都完全相同。 - 完整的文档结构。 带锚点的标题、粗体/斜体/删除线、行内代码和代码块、链接和内部交叉引用、带原始编号的项目/编号/嵌套/任务列表、带合并单元格和表头行的表格、块引用、脚注和尾注以及演讲者备注。
- 方程式转为 LaTeX。 Word 和 PowerPoint (OMML)、OpenDocument 和 EPUB (MathML) 以及 RTF 方程式会转换为 GitHub 风格的数学公式:行内用
$...$,块级用$$。 - 嵌入式资源。 图像和嵌入式对象在 Markdown 中呈现为它们的替代文本,原始字节保留在文档模型上,并标记其媒体类型。带有外部 URL 的图像会变成普通的 Markdown 图像。
- 基于内容的格式检测。 格式是从字节本身读取的,使用其规范指定的标记:PDF 头、RTF 开始组、OLE 流名称、ZIP 包的 mimetype 和内容类型。CSV 没有此类标记,因此通过扩展名或显式格式名来指定。
- 快速。 纯 Rust,无机器学习模型,无外部服务。中位转换时间低于每文档 5 毫秒。
- 绑定不干扰性能。 Node.js 转换在 libuv 线程池上运行,从不阻塞事件循环;Python 释放 GIL,因此其他线程可以继续运行。TypeScript 类型和 Python 存根随包一起发布。
- 内置 PDF 支持。 基于文本的 PDF 通过 pdf-inspector (https://github.com/firecrawl/pdf-inspector) 在本地转换,无需 OCR 服务。扫描页面可选择启用托管 OCR。
- 智能体就绪。 作为智能体技能发布:只需一个
npx skills add firecrawl/anydoc,任何智能体都能读取办公文档。
支持的格式
| 格式 | 扩展名 |
|---|---|
| Word | .doc, .docx, .docm |
| PowerPoint | .ppt, .pps, .pot, .pptx, .pptm, .ppsx, .ppsm |
| Excel | .xls, .xlsx, .xlsm, .xlsb |
| OpenDocument | .odt, .ods, .odp |
| 富文本格式 | .rtf |
| EPUB | .epub |
| CSV | .csv |
.pdf |
基准测试
anydoc 与其他六个转换器在 100 个涵盖十四种格式的真实文档上进行了比较。分数范围为 0 到 100,越高越好;速度是转换一个文档的中位时间。
| 工具 | 支持格式数 | 中位时间 (毫秒) | 评判文档数 | 综合得分 | 完整度 | 结构 | 格式化 | 整洁度 |
|---|---|---|---|---|---|---|---|---|
| anydoc | 14/14 | 4.4 | 94 | 81 | 87 | 79 | 78 | 81 |
| libreoffice | 12/14 | 1129.5 | 87 | 40 | 59 | 42 | 40 | 24 |
| unstructured | 8/14 | 572.9 | 58 | 63 | 76 | 59 | 51 | 63 |
| markitdown | 6/14 | 134.8 | 33 | 65 | 78 | 66 | 60 | 52 |
| pandoc | 5/14 | 102.1 | 34 | 56 | 74 | 57 | 56 | 38 |
| docling | 4/14 | 513.6 | 21 | 57 | 60 | 60 | 57 | 51 |
| mammoth | 1/14 | 52.5 | 8 | 70 | 84 | 71 | 75 | 51 |
按格式逐一对比:
| 格式 | anydoc | libreoffice | unstructured | markitdown | pandoc | docling | mammoth |
|---|---|---|---|---|---|---|---|
| doc | 87 | 57 | 67 | - | - | - | - |
| docm | 84 | 48 | - | - | - | - | - |
| docx | 88 | 56 | 53 | 71 | 68 | 71 | 70 |
| epub | 77 | - | 72 | 72 | 52 | - | - |
| odp | 86 | 23 | - | - | - | - | - |
| ods | 82 | 38 | - | - | - | - | - |
| odt | 80 | 51 | 68 | - | 60 | - | - |
| ppt | 80 | 26 | - | - | - | - | - |
| pptx | 74 | 24 | - | 66 | - | 52 | - |
| rtf | 88 | 53 | 46 | - | 45 | - | - |
| xls | 80 | 38 | 66 | 62 | - | - | - |
| xlsm | 76 | 32 | - | - | - | - | - |
| xlsx | 72 | 30 | 66 | 55 | - | 47 | - |
质量评分方法: 一位 LLM 评审员 (Claude Sonnet 5) 盲测比较两个工具的输出与基准真值:文档的前六页,由 LibreOffice 渲染为图像。每个输出在完整度、结构、格式化和整洁度上进行评分。每对比较都进行两次,输出位置互换以消除位置偏见,共计 482 次评判。每个工具的 score 是其在各支持格式上得分的平均值,因此语料库中某种格式的占比过高不会影响它。这也意味着每行平均的是不同格式集合(mammoth 的 69 分仅基于 docx,而 anydoc 的 81 分涵盖所有十四种格式),因此按格式对比表才是公平的比较。
速度是在 Ryzen 9 9950X3D (Windows 11, 64 GB DDR5-6400) 上每个文档进行一次热转换的时间。anydoc 和 Python 库的计时排除了进程启动时间;CLI 工具包含启动时间,因为这是它们的实际使用方式。
测试框架位于 bench/;语料库不可重新分发且不在仓库中。
最佳适用场景: 需要处理混合办公文档并要求输出一致、结构化 Markdown 的管道。在本次比较中,anydoc 是唯一覆盖所有十四种格式的工具,在每个被评判的格式上得分最高,并且转换文档的速度比次快工具快一个数量级。
格式检测
格式是从文件内容中读取的,使用其规范指定的标记:PDF 头、RTF 开始组、OLE 流名称、ZIP 包的 mimetype 和内容类型。CSV 没有此类标记,因此通过扩展名或显式格式名来指定。
Format::from_bytes(&bytes); // Some(Format::Docx), 或 None(无匹配)
Format::from_extension("pptm"); // Some(Format::Pptx)
Format::from_path(Path::new("report.odt")); // Some(Format::Odt)
Node (formatFromBytes, …) 和 Python (anydoc.format_from_bytes, …) 中也存在相同的三个函数。
错误处理
转换仅在无法从文件生成完整 Markdown 时返回 Err。ConvertError 指明具体问题:
match anydoc::to_markdown(path) {
Ok(markdown) => Some(markdown),
// 这些情况不会生成文档,因此记录该文件并处理下一个。
Err(
error @ (ConvertError::Encrypted | ConvertError::Unsupported(_) | ConvertError::NeedsOcr { .. }),
) => {
unconverted.push((path, error));
None
}
Err(error) => return Err(error),
}
| 错误变体 | 含义 |
|---|---|
Unsupported | 未知格式,或无法转换的格式 |
NeedsOcr | PDF 的扫描页面或仅图像页面,在 pages 中列出 |
Malformed | 结构损坏:无法提取有意义的内容 |
Encrypted | 加密或密码保护 |
ResourceLimit | 超过固定安全限制(解压缩、嵌套、节点数) |
MissingPart | 缺少生成任何有意义输出所必需的部分 |
Io | 无法读取文件,仅来自 to_markdown |
Node 和 wasm 在 error.code 上发布变体名称;Python 为每个变体引发一个 anydoc.ConvertError 子类,或在文件无法读取时引发 OSError。
anydoc 在本地转换,不执行 OCR,因此包含扫描页面的 PDF 会因 NeedsOcr 而失败。在 Node 中使用 ocr: 'hosted',在 Python 中使用 ocr="hosted",或在 CLI 中使用 --ocr hosted 可选择将该文档发送至 Firecrawl Parse (https://firecrawl.dev/parse)。无需注册。设置 FIRECRAWL_API_KEY 可获得更高配额。
工作原理
文档字节流
│
├─► 格式检测 → 使用内容标记(而非扩展名)
│
├─► 格式解析器 → 每种格式一个 (doc, docx, ppt, pptx, xls,
│ xlsx, odt/ods/odp, rtf, epub, csv)
│ │
│ └─► 文档对象 → 共享模型:块、行内元素、表格、
│ 脚注、资源
│
│ └─► GFM 序列化器 → Markdown
│
└─► PDF → pdf-inspector → 直接生成 Markdown
因为每种格式都通过相同的文档模型和序列化器,所以输出问题只需修复一次。针对 docx 的表格转义修复会自动成为 rtf、odt 等所有格式的表格转义修复。
开发
cargo test
cd node && npm install && npm run build && npm test
cd python && pip install maturin && maturin develop && python -m unittest discover -s tests
wasm-pack build wasm --release --target web --scope firecrawl && node --test wasm/test.mjs # 参见 wasm/README.md
已提交的测试夹具库在 tests/fixtures/ 下进行快照测试,tests/robustness.rs 对每个夹具进行变异测试,fuzz/ 包含每种格式的 cargo-fuzz 目标。
速度和质量基准测试位于 bench/。发布标签为 v,该操作会从 .github/workflows/release.yml 发布 crate、npm 包和 PyPI 轮子包。
版本号存在于三个位置,发布时需同步更新:
Cargo.toml:cratenode/package.json:npm 包python/Cargo.toml:轮子包 (python/pyproject.toml读取此版本)
许可协议
相似文章
@AdinaYakup: Unlimited-OCR——@PaddlePaddle的新OCR模型,能够单次处理数百页文档,同时保持速度稳定…
PaddlePaddle发布了Unlimited-OCR,一种新的OCR模型,使用参考滑动窗口注意力(R-SWA)在解码过程中保持恒定的KV缓存,在OmniDocBench上达到了93%的准确率,相比之前的方法提升了6%。
@techNmak:1.7B 参数轻量 VLM,在 OmniDocBench 上碾压巨头的 OCR 新王者
仅 1.7B 参数的多语言文档解析器 dots.ocr,用轻量体积实现 SOTA,证明文档理解无需巨无霸模型。
ATH-MaaS/OvisOCR2
OvisOCR2 是一个紧凑的0.8B端到端模型,用于页面级文档解析,在OmniDocBench和PureDocBench基准测试中达到了最先进的性能。
@oliviscusAI: 您现在可以用一个 17 亿参数的模型解析任何文档,它就是 dots-ocr。一个处理文本、表格等的系统。
本文介绍了 dots-ocr,这是一个拥有 17 亿参数的模型,能够在超过 100 种语言中解析文档中的文本、表格、公式和图像,而无需单独的 OCR 处理流程。
@DataScienceDojo: 一家中国公司刚刚开源了一个𝐎𝐂𝐑,它修复了大多数AI驱动OCR工具默默挣扎的一个问题:……
Unlimited-OCR,一家中国公司新发布的开源OCR模型,解决了AI OCR工具中常见的内存增长问题——无论文档多长,内存使用都保持平稳,从而能够在32K上下文长度下一次性读取数十页。它采用MIT许可,拥有30亿参数,支持多语言,并且在GitHub上已经广受欢迎。