Skip to content

dsh-patent-figure-annotation

Verified

dsh-patent-figure-annotation · v1.4.5 · MIT

DSH 插件:只取【说明书附图】页,在附图标记旁叠加中文释义(深红 #B22222、透明底),并在 PDF 末尾追加「附图标记-中文释义对照表」。

Install

dsh plugin add dsh-patent-figure-annotation

Confirm the layer applied with dsh --profile default --dump-config — see the install guide.

Source

Tags

Readme

专利说明书附图附图标记中文加注

一个 DeepSeek Harness(DSH)插件:把「附图标记-中文释义对照表」附在所提供的中文专利原件或中文译文的最后——宿主自带【说明书附图】时把那几页就地替换为加注版(正红 #FF0000、透明底、原图一个像素都不改);中文译文没有附图部分时,用 figuresFrom 指定图纸来源(通常是外文原件),把加注后的附图追加在宿主之后,再放对照表。原文没有定义的标记绝不编造释义。

安装

方式一:npm(推荐,不需要本机安装 git)

DSH 桌面端 → 侧栏「插件」→「添加插件」,输入:

dsh-patent-figure-annotation

方式二:从 Gitee 仓库安装(需要本机已安装 git;地址必须带结尾的 .git)

https://gitee.com/hc905/dsh-patent-figure-annotation.git

不带 .git 的裸地址(https://gitee.com/hc905/dsh-patent-figure-annotation)会被 pnpm 当成 tarball 去解包,报 ERR_PNPM_TARBALL_EXTRACT;实测 pnpm 11.7.0 必须带 .git。

装完重启 DSH。

方式三:本地路径(离线包)

link:<解压目录>/plugins/dsh-patent-figure-annotation

注意:同一台机器不要同时安装 @local/ 版本和 npm 版本——两者的挂载 id 相同,会冲突。


它解决什么问题

把一份专利 PDF 变成一份可交付的中文加注版整册文件,中间有一堆"人容易做错、机器容易做对"的事:

容易出错的地方 插件怎么强制
只交附图、宿主稿件别的内容丢了 输出 = 宿主全文 +(必要时)加注附图 + 对照表,宿主页序/尺寸/旋转角不变
顺手动了宿主里的其他页面 未加注页面要求与宿主内容流逐字节一致,并抽样逐像素复核;追加模式下宿主一页都不许变
中文译文没有附图,只能手拼 figuresFrom 指定图纸来源,插件自动「宿主 + 加注附图 + 对照表」拼成一份
二次栅格化把线条弄糊、把原有标记抹掉 不重新绘制:页对象整体复制,只在上面叠一个文字对象
AI 自行翻译、意译、缩写术语 释义只能由调用方给出,工具不生成任何术语
原文无定义的标记被"猜"出释义 没有 label 就必须 undocumented: true,只登记不加注
对照表另存成单独文件、或排错位置 对照表永远排在全文最后(同一份 PDF),verify 检查位置
标注压住引线、轮廓线或原标记 用 200 DPI 渲染出的墨迹密度给候选位置打分,见下文
标注互相重叠、出界 候选框与页面已占用文字框逐一求交,出框即淘汰
白底块破坏原图 逐算子证明"附图页没有新增任何路径对象"
颜色、字号走样 颜色由 enforceStyle 锁定(正红 #FF0000),字号默认取原标记字号

提供的工具与技能

名称 类型 作用
patent_figure_outline 工具 读专利 PDF,判定每页章节归属,给出【说明书附图】起止页与需排除的摘要附图页;同节重复页眉合并成一节,整份没有文字层的扫描件走 72 DPI 像素判定区分图纸/正文
patent_figure_inspect 工具 按 ≥200 DPI 渲染附图页为 PNG(供看图),并返回文字层每项的 bbox/归一化坐标与疑似附图标记
patent_figure_annotate 工具 生成加注版:宿主全文 +(就地替换或追加的)加注附图 + 末尾对照表
patent_figure_verify 工具 交付前自检,10 项校验,见下
patent-figure-annotation 技能 完整作业流程:释义来源优先级、标注规范、自检清单、故障处理

输出结构

inputPath 是宿主——要附到的那份文件(中文原件或中文译文);figuresFrom 是图纸来源(通常是外文原件),省略时即等于宿主。

宿主自带【说明书附图】(不给 figuresFrom)
  输出 = 宿主第 1…页(pages 指定的附图页 → 原位换成"原图 + 正红中文标注")
       + 「附图标记-中文释义对照表」(1..n 页,排在全文最后)

中文译文没有附图部分(给 figuresFrom)
  输出 = 宿主第 1…页(一页未改)
       + 图纸来源 pages 指定的附图页(加注后追加)
       + 「附图标记-中文释义对照表」(全文最后)
  • 对照表不再单独出文件,标题锁定为「附图标记-中文释义对照表」,永远排在全文最后(附图后面若还有摘要附图等章节,对照表仍在其后)。
  • 输出总页数 = 宿主页数 +(追加的附图页数)+ 对照表页数。
  • 对照表版式(四列照《对应关系说明-格式规范》第六条的排版规则,插件强制):四列 附图标记|中文释义|出现位置|来源,列宽 [1700, 3400, 1900, 2638] twips 按可用宽度等比缩放;标题 14pt 居中;表头与正文 9pt、行距 11.5pt、统一最小行高 29pt;表头浅灰 #F2F2F2 全列居中,数据行首列居中、其余左对齐;每格四边 0.5pt 灰线;页边距 36pt;一行不跨页,续页重复表头并标「(续)」;表下无任何说明性文字。
    • 「出现位置」= 第 4 页;同一标记+同一释义出现在多页时合并成一行写 第 4、5 页。
    • 「来源」= 中文原文 / 中文译文 / 原文翻译 / 用户指定;原文无定义的条目写 原文无定义(第二列写「(原文无定义)」);调用方另给的 note 接在来源后面,如 中文原文;原文以"金属壳体 HS"表述。
  • 整份文档统一内嵌宋体(本机可嵌入的是华文宋体 STSONG.TTF;缺字形时按 宋体→仿宋→黑体→等线→楷体 自动退让并在 warnings 里说明)。

五条硬保证(都由 patent_figure_verify 独立复核)

  1. 宿主原样保留。 逐页比对内容流字节:每页的原始内容流必须原样出现在输出页里;未加注页面还要求与宿主逐字节一致(就地模式下附图页除外),并抽样做逐像素渲染比对。追加模式下宿主整份必须逐字节不变。
  2. 附图页只多了文字。 逐像素比对:把本次标注框遮住后,输出页与图纸来源页在 150 DPI 下必须完全一致(默认容差 0,因为页内容是整体复制的)。
  3. 没有白底/背景色块。 统计源页与输出页的路径类算子(constructPath/fill/stroke…),附图页不得新增任何一个——加了矩形必然被抓。
  4. 对照表位置正确。 必须排在全文最后;追加模式下它前面必须正好是追加进来的附图末页。
  5. 对照表完整。 必须出现表标题、每个标记、每条释义(折行也认),以及原文无定义条目的【原文无定义】。

另有五项:输出页数 = 宿主 +(追加附图)+ 对照表;标注是否齐全且位置与报告一致;颜色算子中出现 #FF0000 的次数是否覆盖全部加注。

标注位置怎么来的

一切都用归一化渲染坐标表示:页左上角为原点,x 向右、y 向下,取值 0..1 —— 与 patent_figure_inspect 输出的 PNG 同一坐标系,所以从图上看中的位置可以直接写进 position。

自动放置时,插件为每个标记生成"右 / 下 / 上 / 左 × 9 圈"的候选框,同一圈内按右 → 下 → 上 → 左取第一个干净的位置,依次淘汰:

  • 超出页面边距(默认 18 pt);
  • 与任何原有文字框相交(因此永远不会盖住原附图标记),或与本页已放标注的间隙小于 2‰;
  • 墨迹占比超过 cleanInk(默认 1.5%)。

所以标注默认落在标记右侧同一行;右侧被引线/轮廓占满或出界时退回标记正下方(左对齐,不会滑到旁边标记下面),再退到正上方、左侧。"下/上"与标记左对齐而不是居中,正是为了避免标注跑到相邻标记底下。长释义(如「最靠近近端的基板」)单行放不下时会自动折成两行再试一次。空间实在不够时才退而求其次,并在 warnings 里说明。

同一页同一标记重复出现(如六个 130)由 occupied 逐条互斥,不会互相覆盖。

扫描件(无文字层)怎么定位

扫描件里标记是像素而不是文字,文字层找不到目标。此时有两种办法,二者可以并用:

  • near 锚点:给该条注解传 near:{x,y}(归一化坐标,取自 patent_figure_inspect 的 PNG 或 rasterNumerals),插件把它当作"标记所在位置"的小框,走完全相同的右/下/上/左候选逻辑,并在该条警告里注明"已按 near 锚点放置,请人工确认"。注意 near 指标记本身的位置,position 指标注文本框的位置。
  • detectRasterNumerals:把 patent_figure_inspect 的该参数设为 true,插件对渲染图做连通域分析,返回每页 rasterNumerals 疑似标记框(尺寸/墨迹密度/周围留白三重过滤)。这是启发式候选、不做 OCR、ref 留空:必然有少量漏检与"图注/尺寸数字被当候选"的误检(实测 CNIPA 扫描件单页 19 个候选、命中 18、漏 2、误检 1 个图注),必须对照导出的 PNG 人工确认后再取用。

释义来源优先级(写进技能,工具只记录 source 字段)

  1. user —— 用户单独指定的译法(最高优先,例如 HS 一律"热沉");
  2. zh-original —— 中文专利原文的「附图说明」「具体实施方式」;
  3. translation —— 配套中文译文中的对应术语;
  4. translated —— 无中文译文时,基于原文翻译。

同一标记在不同实施例有多个限定术语时取最上位概念;全文都没有定义 → undocumented: true,只进对照表。

典型用法

patent_figure_outline({ path: "D4-WO2009011218A1.pdf" })          // 图纸来源是外文原件
patent_figure_inspect({ path: "D4-WO2009011218A1.pdf", pages: [60,61,62] })   // 用 read_image 看 PNG

// 情况 B:中文译文没有附图部分 → 把加注附图追加在译文后面,再接对照表
patent_figure_annotate({
  inputPath: "D4中文译文.pdf",              // 宿主:译文,一页不改
  figuresFrom: "D4-WO2009011218A1.pdf",    // 图纸来源
  pages: [60, 61, 62],                     // **图纸来源文件**里的附图页码
  annotations: [
    { page: 60, ref: "10", label: "密封圈", source: "translation" },
    { page: 61, ref: "HS", label: "热沉",   source: "user" },
    { page: 62, ref: "4",  undocumented: true },
  ],
})
// 省略 outputPath → 生成 D4中文译文附图标注版.pdf(宿主文件名 + 后缀,与宿主同目录)
// 输出 = D4中文译文.pdf 全文 + 加注后的第 60-62 页 + 对照表(全文最后)
patent_figure_verify({ inputPath: "D4中文译文.pdf", figuresFrom: "D4-WO2009011218A1.pdf",
                       outputPath: "D4中文译文附图标注版.pdf", pages: [60,61,62],
                       annotations: <上一步 annotated + undocumented 条目> })

// 情况 A:宿主自带【说明书附图】→ 不传 figuresFrom,就地替换
patent_figure_annotate({ inputPath: "CN118765432A.pdf", pages: [4,5,6], annotations: [ ... ] })

pages 必须是【说明书附图】的完整页集合(漏掉尾部的附图页,那些页就不会加注)。中文公告文本每张附图页页眉都印有「说明书附图」,patent_figure_outline 早期版本会把 figureTo 判得过早,现已按"重复页眉并入同一节"处理;仍请按页脚的「N/M 页」核对后再传 pages。插件在"附图末页的下一页文字也很稀疏(且不含摘要)"时会给出提醒。若宿主自身也印有「说明书附图」章节而你又传了 figuresFrom,插件会提醒附图可能重复。

扫描件(附图页没有文字层)时,先用光栅候选定位,再用 near 落笔:

patent_figure_inspect({ path: "扫描件.pdf", pages: [4,5], detectRasterNumerals: true })
// rasterNumerals 是启发式候选(无 ref),对照 PNG 确认哪个框是哪个标记
patent_figure_annotate({
  inputPath: "扫描件.pdf",
  pages: [4,5],
  annotations: [
    { page: 4, ref: "10", label: "密封圈", near: { x: 0.681, y: 0.197 } },
    { page: 5, ref: "HS", label: "热沉",  near: { x: 0.44,  y: 0.36  } },
  ],
})

patent_figure_annotate 返回的 annotated 数组(含 box,若用了 near 也会原样回显)可以直接当作 patent_figure_verify 的 annotations 传入。

配置(cordis.patch.yml 的 config)

键 默认 说明
color #FF0000 标注颜色;规范固定为正红
fontPath '' 内嵌中文字体路径(.ttf/.otf;.ttc 不受支持)。留空则宋体优先自动查找(华文宋体 STSONG.TTF),也可用环境变量 DSH_PATENT_FIGURE_FONT
dpi 200 墨迹采样与预览渲染分辨率
margin 18 版心边距(pt),标注不得越界
fontSize 0 0 = 自动取原标记字号
outputSuffix 附图标注版 默认输出文件名后缀:默认名为「原文件名 + 后缀」原名附图标注版.pdf,与源文件同目录(D1-CN100416828C.pdf → D1-CN100416828C附图标注版.pdf)。文件名里已带该后缀时不重复追加
tableTitle 附图标记-中文释义对照表 已锁定,只为兼容旧配置而保留;配置里的值一律忽略
enforceStyle true 锁定颜色等样式,忽略单条注解里的 color

输出命名不再使用 patentNumber:不传 outputPath 时一律按「原文件名 + 后缀」生成;patentNumber 仍可传入,但只作标注信息保留。需要别的名字就直接传 outputPath。

安装

plugin_manager({ action: "install_bundle", target: "<本目录的绝对路径>" })

手动安装等价于:

pnpm add <本目录的绝对路径>                     # 在 profile 目录执行

然后重启 Harness。

设计要点

  • 矢量叠加,不是画在图上。 原图一个字节都不重绘:pdf-lib 整体复制页对象,标注是叠加的文字对象;因此线宽、线型、原有文字全部原样保留,且标注是矢量的,放大不糊。
  • 文字层是定位依据。 pdfjs-dist 提取每个文本项的 transform 与宽度得到 bbox。这里有个容易错的点:transform 的 a/d 已经含了字号,再乘一次宽度会把框放大 12 倍——lib/pdf-util.js 里只取它的方向并归一化。
  • 中文必须内嵌子集,且整册统一宋体。 pdf-lib + @pdf-lib/fontkit 对华文宋体 STSONG.TTF 做子集化(只嵌入实际用到的字形),一个 12 pt 的"壳体"只让文件增长约 1.8 KB,不依赖阅读器端字体;落笔前用 hasGlyphForCodePoint 逐字预检,缺字形不会静默画成方框。
  • peerDependencies 是模块解析开关。 profile 装的是符号链接,插件真实路径在 profile 之外;Harness 只有在 peerDependencies 里看到 @deepseek-ai/* 名字时才会把裸导入拦截到安装目录。所以三个 Harness 包必须写进 peerDependencies,而 pdf-lib 等运行时依赖写进 dependencies(它们从插件自己的 node_modules 解析)。
  • 工具的输出也会被校验。 Harness 对 defineTool 的入参与返回值都按声明的 schema 校验(additionalProperties: false),少声明一个字段工具就会在运行时报错。
  • 遵守会话文件策略。 插件写 PDF/PNG,fs 服务做不到,所以直接用 node:fs,但会读 ctx.sandboxPolicy:read-only 拒绝写出,workspace-write 拒绝写到工作区之外。

已知边界

  • 章节定位(patent_figure_outline):以页眉的章节标题为主证据,并把同一节各页重复的页眉标题合并成一节(中文公告文本每张附图页都印「说明书附图」,早期实现会因此把附图范围截成 1 页);收尾依据是下一节标题,或页眉节内页码 n/M 页 的 M 变化(下一节标题没被识别出来时兜底)。页眉被拆成单字文本项(说/明/书/附/图)时会先按行合并再匹配,所以正文里的「附图说明」不会被误判;孤立一行的「附图」只有在旁边带刊物号或节内页码时才认。
  • 纯扫描件(整份没有文字层)的像素判定:标题与页脚页码都读不到时,自动把每页按 72 DPI 渲染、做连通域统计,按「字形样组件数 + 大组件墨迹占比」把图纸页与正文页分开(实测 CN 公告:正文页 809–1192 个字形组件、大组件墨迹 0.8%–39%;图纸页 69–117 个、94%–95%,差 5 倍以上)。结果标 confidence: medium,evidence 带上实测数字;紧邻区间的灰区页面单独警告;超过 250 页跳过。正文可读时不启用这一判定——插在正文里的插图同样"少量大轮廓",会被误判成图纸页。可用 detectDrawings: false / drawingDpi 控制。
  • 扫描件/无文字层:文字层里没有标记,patent_figure_inspect 的 numerals 会是空的。改用 detectRasterNumerals:true 拿到候选框(或自己看图定坐标),再用 near 指认标记位置,即可让标注紧贴标记落笔;两者都给出后仍建议人工看一眼。
  • 光栅候选是启发式的:不做 OCR、ref 留空,扫描件上必然有少量漏检(字形断裂/偏淡且贴引线时)与误检(图注、尺寸数字);页眉/页脚区(默认 y<4.5% 或 y>95.5%)与超大图形会被排除。
  • verify 的遮蔽:正路径用 annotate 回显的 box,逐像素比对是精确的;若调用方不给 box,遮蔽靠"同文本 + 最近位置、一对一"配对(同页重复标签不会互相顶掉),但该配对隐含"标注追加在内容流末尾"这一前提。
  • /Rotate 非 0 的页:坐标按渲染方向换算,标注方向随页旋转,一般无需干预。
  • .ttc 字体不受支持:fontkit 不能直接嵌入 TrueType 集合,请改用同族 .ttf。
  • 纯工程尺寸数字:会被当作"疑似标记"列出,是否加注由使用者判断;未登记的此类数字会出现在 verify 的 unannotatedNumerals 提示里,不影响 ok。
  • 加密 PDF 会被尽量忽略加密读取,解析失败会明确报错。
  • 光栅检测的性能:默认 200 DPI 单页约 50–70 ms;若把 dpi 调到 600,detectRasterNumerals 会明显变慢(仍可用)。

卸载

# npm 安装的(方式一):
pnpm remove dsh-patent-figure-annotation
# 本地链接安装的(方式三,开发用):
pnpm remove @local/dsh-patent-figure-annotation

再把包名从 package.json 的 dsh.profile.bundles 里删掉,重启 Harness。README.md 不属于运行时,删掉它不影响插件。