news 2026/9/24 11:22:07

Ekko Studio OCR 与文档提取技能实战:从扫描 PDF 到结构化 Markdown 的本地优先工作流

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Ekko Studio OCR 与文档提取技能实战:从扫描 PDF 到结构化 Markdown 的本地优先工作流
  • AI 应用
  • 人工智能
  • AI Agent
  • 本地部署
  • 前端
  • 后端
  • 工作流自动化

【免费下载链接】ekko-studio

Ekko Studio is a local-first AI workspace for multi-agent chat, coding, and visual workflows, available on desktop and the web.

项目地址:https://gitcode.com/gh_mirrors/he/ekko-studio
点击查看免费下载

导读

Ekko Studio(本地优先的多 Agent 协作工作区)内置了一组 Agent Skills,其中ocr-and-documents专门解决"普通文本提取失效"的场景——扫描件、纯图片型 PDF 和复杂版式文档。本文基于 ocr-and-documents 技能目录 及其 SKILL.md,系统讲解该技能的适用判断、轻重两条提取路径、命令行用法、隐私边界与结果校验方法,并结合仓库内两个 Python 助手脚本的源码与测试用例,带你掌握一套可复制、可落地的本地文档 OCR 工作流。


一、这个 Skill 解决什么问题

ocr-and-documents在 DESCRIPTION.md 中的定位非常明确:

Skills for extracting text from PDFs, scanned documents, images, and other file formats using OCR and document parsing tools.

而在 SKILL.md 中则进一步收敛了使用边界:

Use this Skill when ordinary document extraction fails because the source is scanned, image-based, or layout-heavy.

即:只有当普通文本提取失效时才启用。对于生来就是数字文本的文档(born-digital),应该走各自的常规技能——PDF 用pdfSkill,Word 用docxSkill,而不是盲目地对一切文件做 OCR。

在 ekko-agent/README.md 的内置技能清单中,ocr-and-documentspdfdocxxlsxpowerpoint等一同被列为包内置(package-owned)技能,随 Agent 自动同步安装,属于skill_list/skill_view/skill_manage工具可发现的默认能力之一。这意味着:你不需要手动部署,Agent 会通过skill_list检索、skill_view加载技能目录,并返回可执行脚本所在的baseDirectory

典型触发场景

场景特征推荐路径
扫描版 PDF(合同、票据)纯图片页,无文本层先用pdfSkill 渲染页面 + 视觉检查,再按需转录
文本型扫描 PDF有文本层但质量差extract_pymupdf.py(轻量)
复杂版式:表格、公式、多页扫描版式密集、结构复杂extract_marker.py(重量级,需谨慎)
URL 指向的文档HTML 或文件不确定先用浏览器/HTTP 工具判别,再下载本地处理

二、核心原则:先走最轻的路

SKILL.md 给出了明确的四步决策阶梯,这是整个技能的灵魂——不要一上来就上重型 OCR

  1. 常规提取优先:PDF 用pdfSkill,.docxdocxSkill,不对数字文本做 OCR。这与 pdf/SKILL.md 中的约定相互印证——pdf Skill 明确写着"Use OCR only when normal text extraction is empty or clearly incomplete. Route scanned documents through the ocr-and-documents Skill",两个技能形成了清晰的分工与转介关系。
  2. 少量扫描页:先用pdfSkill 渲染页面,再用view_image查看渲染图,只转录用户要求的页面。
  3. 文本型扫描 PDF:尝试extract_pymupdf.py——这是更轻的本地路径,依赖只有 PyMuPDF。
  4. 复杂版式/表格/公式/大量扫描页:确认需求并检查资源后,才使用extract_marker.py

这个阶梯设计的背后是对资源成本的清醒认识:marker-pdf 可能需要数 GB 的包和模型下载,而 PyMuPDF 路径只需一个 pip 包。仓库中extract_marker.py--check参数(见下文第四节)正是为这一决策提供磁盘空间依据。


三、轻量路径:extract_pymupdf.py 全解

3.1 基本用法

python3 <baseDirectory>/scripts/extract_pymupdf.py input.pdf -o extracted.md

其中<baseDirectory>是调用skill_view后返回的技能目录绝对路径。运行依赖:

python3 -m pip install pymupdf

--markdown模式额外需要pymupdf4llm

从源码看,extract_pymupdf.py 采用延迟导入策略:pymupdfpymupdf4llmpandas都在各自函数内部导入,因此只跑普通文本提取时无需安装全套依赖,这也与"轻量优先"的定位一致。

3.2 五种提取模式(互斥)

脚本通过argparseadd_mutually_exclusive_group定义了四种互斥模式,外加默认的纯文本模式:

参数作用底层实现要点
(无参数)纯文本提取逐页document[index].get_text(),输出带--- Page N/M ---分页标记
--markdown结构化 Markdown 提取pymupdf4llm.to_markdown(path, pages=pages),需额外安装pymupdf4llm
--tables表格识别为 Markdown 表格page.find_tables()检测表格,table.to_pandas().to_markdown(index=False)输出
--images DIRECTORY提取 PDF 内嵌图片遍历page.get_images(full=True),输出page{N}_img{M}.png;当pixmap.n >= 5(如 CMYK)时先转换到 RGB 再保存
--metadata输出文档元数据 JSON返回页数、标题、作者、主题、创建者、生产者、格式等字段,json.dumps(..., ensure_ascii=False)保留中文

3.3 页面范围选择

--pages参数接受从 0 开始的页索引,支持逗号分隔的单个页和-连接的区间,例如:

# 提取第 1~5 页(内部为索引 0-4) python3 <baseDirectory>/scripts/extract_pymupdf.py input.pdf --pages 0-4 -o first5.md # 提取第 1、3、6 页 python3 <baseDirectory>/scripts/extract_pymupdf.py input.pdf --pages 0,2,5 -o selected.md

源码中的parse_pages函数会做两类合法性校验:区间起点不能大于终点(否则抛ArgumentTypeError),页索引不能为负;超出文档实际页数的索引会被静默跳过(if index >= len(document): continue),因此可以放心给大范围。这个能力让"只转录用户要求的页面"这一轻量原则有了落地的抓手。

3.4 输出行为

  • 不传-o/--output时,结果直接打印到 stdout;
  • -o时,结果以 UTF-8 写入文件,同时 stdout 输出一行 JSON:{"output": "/abs/path/to/extracted.md"},方便 Agent 拿到绝对路径返回给用户。

任何ImportErrorOSErrorValueErrorRuntimeError都会以Error: ...形式写到 stderr 并返回退出码 2,便于上层捕获失败。


四、重量级路径:extract_marker.py 与资源检查

4.1 定位与风险提示

extract_marker.py基于marker-pdf(脚本源码),对复杂版式的处理能力远超 PyMuPDF 路径——它在内部调用PdfConvertercreate_model_dict(),会加载真实的视觉/版面模型。代价是:

  • 依赖包与模型下载可能占用数 GB 空间
  • SKILL.md 明确要求:绝不可自动安装,必须先检查磁盘空间并征求用户同意。

4.2 --check:先查资源再干活

python3 <baseDirectory>/scripts/extract_marker.py --check

check_requirements()函数用shutil.disk_usage计算当前磁盘可用空间(单位 GiB):

  • 可用空间 < 5GB:打印Only X.XGB free. marker-pdf needs about 5GB.并提示改用extract_pymupdf.py或释放空间,返回退出码 1;
  • 空间充足:打印X.XGB free; sufficient for marker-pdf.,返回 0。

关键设计:--check分支在import marker之前返回,因此即使 marker 尚未安装也能执行,用于快速、零成本地评估可行性。

4.3 转换用法与输出格式

# 默认 Markdown 输出 python3 <baseDirectory>/scripts/extract_marker.py input.pdf -o extracted.md # 结构化 JSON 输出(markdown + metadata 双字段) python3 <baseDirectory>/scripts/extract_marker.py input.pdf --json -o extracted.json # 同时把提取出的图片保存到目录 python3 <baseDirectory>/scripts/extract_marker.py input.pdf -o extracted.md --output-dir assets/ # 启用 marker 配置的 LLM 增强 python3 <baseDirectory>/scripts/extract_marker.py input.pdf --use-llm -o extracted.md

参数说明:

参数含义
document输入文档路径(--check模式下可省略)
-o/--output结果写入 UTF-8 文件;stdout 返回{"output": ...}JSON
--output-dir提取出的图片保存目录(脚本从rendered.images中逐张落盘)
--json输出{"markdown": ..., "metadata": ...}结构化 JSON
--use-llm{"use_llm": True}注入 marker 的ConfigParser,启用其配置的 LLM 增强环节
--check只做磁盘空间检查,不加载 marker

五、URL 来源的处理规范

当来源是 URL 时,SKILL.md 给出的流程是:

  1. 先用可用的浏览器或 HTTP 工具判别目标到底是 HTML 页面还是文档文件
  2. 只下载被请求的那一份文档,并尊重认证与访问边界(不要越权抓取);
  3. 下载为本地副本后,再走上述提取流程;
  4. 不要假设存在某个特定的 Web 工具——工具可用性以当前环境为准。

这保证了 URL 场景下依然保持"本地处理 + 最小权限"的隐私姿态。


六、隐私与依赖安全边界

整个技能有一条贯穿始终的红线,SKILL.md 与 pdf Skill 的约定一致:

  • 优先本地处理:未经用户明确授权,不得把私人文档上传到外部 OCR 服务;
  • 重型依赖不自动安装:marker-pdf 及其模型下载必须先检查磁盘空间、先征得用户同意;
  • 敏感内容不外泄:不要向外部服务发送敏感文档内容。

这与 ekko-agent/README.md 中对技能工具的描述相辅相成——skill_view只加载SKILL.md或允许的支持文件并返回baseDirectory,脚本由 Agent 在本地执行,天然适合处理含隐私信息的合同、票据、证件类文档。


七、结果校验清单(Verification)

OCR 结果的可靠性与校验投入成正比,SKILL.md 给出了明确的验收标准,这也是"提取 ≠ 完成"的关键一步:

  1. 保留结构与引用:阅读顺序、页码引用、标题、表格、脚注、置信度提示都要保留在输出中;
  2. 视觉比对:用view_image将提取文本与代表性渲染页面逐页对照(渲染页面可用pdfSkill 的pdf_page_image.py,参见 pdf/SKILL.md);
  3. 不猜不补:对不确定的字符和字段要显式标记,而不是凭猜测补全;
  4. 表格单独核验:列对齐与数值需要单独逐一核对(OCR 对表格数字的误识别率远高于正文);
  5. 返回映射关系:尽可能同时给出提取产物路径与原始来源/页码的映射,方便用户回溯验证。

八、自动化测试如何守护这两个脚本

仓库在 tests/test_ocr_documents.py 中为两个助手脚本提供了三个关键测试,可作为理解脚本契约的权威参考:

  • test_helpers_expose_non_loading_help:对两个脚本执行--help,断言退出码为 0 且输出中包含--output。注意测试名中的 "non-loading"——--help路径不触发重型依赖导入,保证在任何环境下都能查看用法;
  • test_marker_disk_check_does_not_import_marker:执行extract_marker.py --check,断言退出码为 0 或 1,且输出中包含GB。这正是对"检查不加载 marker"这一设计的直接验证;
  • test_pymupdf_writes_requested_output:用 PyMuPDF 现场生成一页含 "OCR helper smoke test" 文本的 PDF,运行extract_pymupdf.py --output,断言返回码为 0 且输出文件中包含该文本,端到端验证了"写文件 + UTF-8 编码 + 文本提取"全链路。

这三个测试覆盖了"无依赖可自检、轻量路径端到端可用"两条关键承诺,也是你在自己的环境中复现脚本行为的最小验证集。


九、端到端实战示例

综合以上内容,一个完整的"扫描 PDF 提取"典型会话流程如下:

# 1. Agent 加载技能,拿到 baseDirectory(示意路径) # skill_view -> <base>/skills/ocr-and-documents # 2. 先确认是否真的需要 OCR:渲染第 1 页看内容 python3 <base>/skills/pdf/scripts/pdf_page_image.py scan.pdf -o rendered --pages 1-3 # 3. 用 view_image 查看渲染图,确认是扫描件、需要提取的页码范围 # 4. 走轻量路径提取文本(假设第 1~10 页) python3 <base>/skills/ocr-and-documents/scripts/extract_pymupdf.py scan.pdf --pages 0-9 -o extracted.md # 5. 若版式复杂(表格/公式)且资源允许,先检查再走重量级路径 python3 <base>/skills/ocr-and-documents/scripts/extract_marker.py --check python3 <base>/skills/ocr-and-documents/scripts/extract_marker.py scan.pdf -o extracted_marker.md # 6. 渲染关键页,用 view_image 与提取结果逐一比对,标记不确定字符 # 7. 返回提取产物绝对路径 + 页码映射,说明置信度限制

整个过程无需任何外部 OCR 服务,文档全程留在本机,符合该技能"本地优先、用户授权优先"的核心理念。


参考资源

  • 技能说明:packages/ekko-agent/skills/ocr-and-documents/DESCRIPTION.md
  • 技能指南:packages/ekko-agent/skills/ocr-and-documents/SKILL.md
  • 轻量提取脚本:scripts/extract_pymupdf.py
  • 重型提取脚本:scripts/extract_marker.py
  • 自动化测试:tests/test_ocr_documents.py
  • 协作技能:pdf/SKILL.md、docx/SKILL.md
  • 技能机制总览:ekko-agent/README.md
  • AI 应用
  • 人工智能
  • AI Agent
  • 本地部署
  • 前端
  • 后端
  • 工作流自动化

【免费下载链接】ekko-studio

Ekko Studio is a local-first AI workspace for multi-agent chat, coding, and visual workflows, available on desktop and the web.

项目地址:https://gitcode.com/gh_mirrors/he/ekko-studio
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/24 11:17:38

双种群进化算法优化模糊柔性作业车间调度:完工时间与能耗协同

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 11:16:21

0成本实现CAD图纸精准翻译

引言海外工程、跨境设计协作中&#xff0c;图纸翻译长期面临“成本高、效率低、可编辑性差”的三重困局。传统人工翻译团队按页计费&#xff0c;单项目成本动辄过万&#xff1b;PDF图像级翻译后无法直接编辑&#xff0c;深化设计需反复返工&#xff1b;通用工具对行业术语“水土…

作者头像 李华
网站建设 2026/9/24 11:13:04

A/B测试工具全景图:主流平台一览

A/B测试工具分企业级套件、产品实验平台、开源自建和内置工具四类&#xff1b;选型先定预算与流量规模&#xff0c;再看统计引擎与数据底座&#xff0c;别被名气带偏。你在做A/B测试工具调研&#xff0c;会发现名字一大堆&#xff1a;Optimizely、VWO、Adobe Target&#xff0c…

作者头像 李华
网站建设 2026/9/24 10:59:41

EMC四大测试CE/RE/CS/RS:原理、整改与实战案例

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/24 10:59:12

AI PLC不是硬件升级,而是工业数据管道与控制范式重构

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华