format-extract — DOCX 格式提取与质量评估
职责边界:本 Skill 只负责"docx → HTML/images"与"HTML 质量评估"两件事。产物交付后如何使用(登记到哪个 yaml、喂给哪个下游流程、在什么阶段触发)完全由调用方决定,本 Skill 不做任何假设。
| 入口 | 用途 | 何时选用 |
|---|---|---|
run.py(一键入口) |
docx → HTML,自动做门禁检查 + artifact_id 目录隔离 + 产物校验 | 默认首选,适合 Agent 调用 |
node dist/cli.cjs convert |
底层 CLI,支持单文件/批量/自定义输出路径 | 需要完全自定义路径或批量处理 |
node dist/cli.cjs assess |
独立评估 HTML 质量(5 项检查) | 怀疑转换质量、需要量化报告 |
底层 CLI 参数、编程式 API、返回结构详见 references/cli-reference.md,日常调用无需阅读。
输入契约(调用方需提供)
本 Skill 不负责判断"是否应该触发"或"如何找到要转的 docx"——这些都是调用方的职责。调用方在确定要用本 Skill 时,提供:
| 参数 | 必填 | 说明 |
|---|---|---|
<docx-path> |
是 | 要转换的 .docx 文件路径,优先绝对路径以规避 cwd 差异 |
--output-dir |
是 | 自定义输出的父目录;脚本会在其下自动追加 <artifact_id>/ 子目录做隔离 |
⚠️ 本 Skill 不再自行猜测输出位置:调用方(如 doc-formatter)必须显式传入
--output-dir,通常应指向 pipeline 目录下 stage 的中间产物区(例如<workspace>/output/<request_id>/stage2/intermediate/format-extract/)。不传直接报错退出(exit code 2)。这是"关注点分离"——产物落点由编排层拥有,脚本只负责转换。
⚠️ 为什么不在 Skill 里做"是否触发"判定:触发时机强依赖调用方的业务语义(是用户上传的模板?是批处理任务?是质量抽检?),放在本 Skill 里会与调用方耦合。调用方自己判断"现在要不要跑这个 Skill",跑的时候把 docx 路径和输出目录都传进来。
标准流程(推荐走 run.py 一键入口)
步骤 1 — 定位 run.py
Skill 的安装位置与当前 Agent 的 cwd 可能不一致,按优先级尝试:
| 优先级 | 策略 |
|---|---|
| L1 | 调用方显式告知路径(最稳) |
| L2 | 相对 cwd 拼 skills/format-extract/run.py |
| L3 | 相对 cwd 拼历史笔误目录 workpace/...(兼容) |
| L4 | 从 cwd 向上最多 10 级查找包含本 Skill 的祖先目录 |
四级都找不到 → 走 <failure-fallback>。
步骤 2 — 环境前置(run.py 内部会自动检查,手动调 CLI 时需自检)
P1 — Node.js ≥ 18.0.0:跑 node -v,不达标则参照 references/node-install.md 安装。bundled CLI 依赖 Node 18+ 的原生 API(ESM / structuredClone / fetch),低版本直接抛 SyntaxError。
P2 — bundled CLI 可用:跑 node <skill-dir>/dist/cli.cjs --version,若报 Cannot find module / ENOENT 说明分发异常,走失败兜底。不要用 npx docx2html 绕过——本 Skill 已脱离 npm 全局安装,绕过会引入未知版本差异。
步骤 3 — 执行
# --output-dir 为**必传参数**;脚本会在其下自动追加 <artifact_id> 子目录
python3 <run.py 路径> <输入 docx 路径> --output-dir <目标父目录>
不传 --output-dir 会以 exit code 2 报错退出——本 Skill 不再猜测输出位置。
run.py 内部自动完成:
- 计算
artifact_id:<docx_stem>_<md5_8>,例如财报_38fb08de- 同一 docx 多次处理 → 相同 artifact_id(幂等,复用同一目录)
- 不同 docx → 不同 artifact_id(永不互相覆盖)
- docx 内容变更 → 哈希变化,自动隔离新旧版本
- 产物落到
<--output-dir 值>/<artifact_id>/(若--output-dir末尾已是 artifact_id,则原样使用不重复嵌套):reference_format.html— 语义化 HTMLformat_artifact.json— manifest(artifact_id / 源 docx 路径与哈希 / images_dir / 时间戳)images/— 提取的图片资产
- P1 / P2 门禁检查
- 调用 bundled CLI 完成转换
- 存在性校验(输出目录 + HTML 产物 + manifest)
脚本会在
--output-dir下自动追加 artifact_id,调用方无需自己拼接哈希。
步骤 4 — 捕获产物路径
成功时 stdout 最后一行即 HTML 绝对路径,调用方直接读这一行拿到结果。
成功示例 stdout(末行):
<--output-dir 值>/财报_38fb08de/reference_format.html
同级的 images/ 与 format_artifact.json 与 HTML 在同一 artifact 隔离目录下。
若要拿到 manifest 路径,从 HTML path 推导:Path(html_path).parent / "format_artifact.json"。
步骤 5 — 单次重试策略
首次调用失败(exit ≠ 0)时看 stderr 关键词:
| 错误关键词 | 应对 |
|---|---|
输入文件不存在 |
转绝对路径后重试 1 次 |
缺少必传参数 --output-dir / exit code 2 |
调用方 bug——补上 --output-dir 后重试;不再兜底猜位置 |
| 其它 | 不再重试,走失败兜底 |
反复重试超过一次没有意义——同类错误重跑只是在耗时间预算。
交付边界
本 Skill 在返回 HTML 绝对路径那一刻职责结束。
调用方接手做的事(本 Skill 不规定,仅列出常见用法供参考):
- 读 HTML 分析排版特征(h1/h2 层级、表格样式、段落缩进、字体色……)
- 把产物路径写入自己的上下文 / yaml / 数据库
- 决定如何在下游流程中使用这些特征
- 决定 HTML 或 images 的生命周期(保留 / 清理 / 归档)
Skill 不登记任何外部字段、不修改调用方的任何文件。
设计理念
格式提取失败不应阻塞调用方的主流程。本 Skill 通过清晰的退出码 + 详细的 stderr 让调用方自己决定如何降级——是跳过格式分析继续走、还是直接给用户报错,由调用方的业务逻辑决定,本 Skill 不越俎代庖。
Skill 侧的契约
| 场景 | exit code | stdout | stderr |
|---|---|---|---|
| 转换成功 | 0 | 最后一行 = HTML 绝对路径 | 进度信息 |
| P1 Node 版本不达标 | 1 | — | 版本信息 + 提示升级 |
| P2 CLI 不可用 | 1 | — | Cannot find module 等 |
| 输入文件不存在 / 损坏 | 1 | — | ENOENT / 格式错误 |
| 超时 / 其它 | 1 | — | 具体错误栈 |
调用方侧的建议降级动作
if skill_exit_code != 0:
# 记录失败原因(stderr),根据业务决定:
# - 可接受格式降级 → 继续主流程,标记"未提取格式"
# - 格式是硬需求 → 终止并反馈用户
...
对用户的透明化建议
如果选择"继续主流程",建议调用方在最终响应里向用户透明标注**"本次未成功提取参考文档格式特征"**,而不是静默降级——对用户隐瞒降级比降级本身更糟糕。
- ❌ 不要自行实现 docx → HTML 逻辑:必须通过
run.py/cli.cjs统一入口,绕开会破坏产物可重现性和后续的 assess 质量检查 - ❌ 不要反复重试超过 2 次(首次 + 策略性重试 1 次):同类错误重跑是在耗光 Agent 的时间预算
- ❌ 不要用
npx docx2html绕过 bundled CLI:本 Skill 已完全脱离 npm 全局安装,绕过会引入未知版本差异 - ❌ 不要在本 Skill 内登记调用方的字段(如某个 yaml、某个数据库):产物路径返回给调用方,后续写入由调用方自己决定
- ❌ 不要在 SKILL.md 里引用任何调用方的具体阶段 / 字段 / 脚本名:Skill 应对调用方保持无知,文档里只讨论"输入 docx / 输出 HTML"
可选:独立 HTML 质量评估
怀疑转换质量(如表格错位、冗余 mso-* 属性)时,单独跑 assess:
node <skill-dir>/dist/cli.cjs assess <html-file> [--output <report-path>]
- exit code 0 = 5 项检查全过
- exit code 1 = 有未过项(不是程序崩溃),看报告里
❌的条目定位问题
详见 references/cli-reference.md 的 assess 章节。
相关文档
references/cli-reference.md— CLI 参数 / 编程式 API / 返回结构 / 5 项检查维度 / 反模式references/node-install.md— Node ≥ 18 跨平台安装脚本