feat(ocr): 扫描件与图片识别——OCR 进文字层、资质库上传识别、大图浏览

计划见 docs/architecture/vision-plan.md(VS1–VS13,docs/decisions.md)。

- 验证:OCR(RapidOCR + PP-OCRv6 small,CPU)和 DeepSeek Flash 看图在国动投标文件
  和 7 张证书上初测(tech-validation §7,代码 spikes/s5-ocr/)
- OCR 服务 services/ocr(镜像、Compose 服务):整页转正(含 180°)、红章附近按红色通道重读
- 扫描页和插图识别后并入文字层 v6,句子标 source=ocr;出处标「OCR」(迁移 0013);
  依据识别文字的问题降级,规则不查扫描附件;国动端到端见 check-eval §16
- 资质库上传识别:添加资质对话框最上面传证书照片,识别后填表,只预填和 OCR 文字
  对得上的字段;识别值留痕、照片挂成附件(迁移 0014,提示词 vision.cert_fields v1)
- 资质库改为查看详情(只读键值 + 附件缩略图),附件用大图浏览控件看,不开新标签页
  (设计规范 §7.23);PDF 附件按页出预览图

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
YANG JIANKUAN
2026-11-05 17:50:13 +08:00
parent 0b783ababa
commit 3344f09563
63 changed files with 4973 additions and 345 deletions

View File

@@ -1,4 +1,4 @@
# 技术验证 S1–S4 结论(2026-11-03)
# 技术验证结论(S1–S4 2026-11-03;S5、S6 初测 2026-11-05)
> 依据:架构文档 `architecture.md` §10。代码在 `spikes/`(一次性代码,复现步骤见 `spikes/README.md`),由样本派生的产物都在各子目录的 `out/` 里,不进 git。
> 环境:本机 Docker 29.8.2(Apple Silicon,**arm64**),Gotenberg 8.39.0;样本是 `samples/tenders/` 的 S01–S10。
@@ -12,208 +12,75 @@
| S2 | **可行**:在规范化 PDF 上识别「斜体且下划线」,和 DOCX 原文件逐字对得上 | 4 份文件按字符 100% 一致;片段级召回 0.993~1.0 | 不需要 Docling 来保格式 |
| S3 | **正文可行,表格要改进**:原句高亮的几何位置全部正确;切句在表格里会把相邻单元格拼在一起 | 几何回读 50/50、300/300;文本保真:正文 97.5%,表格内 78% | 切句要识别表格单元格和页眉页脚 |
| S4 | **可行**:两道证据校验 + 第三道「依据校验」后,抽取结果可用;★ 类条款建议用规则兜底保召回 | ★ 召回 93.5%(扣除银标准噪音后约 96.6%),斜体下划线 99.8%;采纳条目 95.2% 属实;每份文件约 0.15 元(高峰价) | §3.6 新增依据校验和规则兜底 |
| S5 | **可行(初测)**:RapidOCR(PP-OCRv6 small,CPU)识别字准、坐标准、够快;整页横放能自动转正;红章压字要局部按红色通道重读 | 国动投标文件 102 页(扫描 + 图表)62 秒;合成扫描件字符差 0.1%~1.1%;坐标回画全部对上 | §3.5 OCR 阶段可以照计划做,见 §7 |
| S5 视觉 | **可行(初测)**:DeepSeek Flash 收图片,页面分类、证书 / 合同字段、图表概述都能用;字段引用 OCR 行做校验能拦住两边读错的情况,但拦不住语义错和手写 | 102 页 23 秒,约 0.47 元(每页约 0.005 元);86 个字段 70 个和 OCR 行一致,16 个不一致里 10 个是跨行 | vision-plan §2 的交叉校验要支持多行、加字段格式校验 |
| S6 | **部分**:印章有无模型判断大体对,浅色骑缝章会漏;手写签名能认出 | 102 页里判「有章」44、「看不清」6;抽查 2 页漏 1 个边缘骑缝章 | 签章位检查要加红色像素初筛;准确率要等有标注的样本 |
## 1. S1 Word 转 PDF 的保真度
## 7. S5 / S6 扫描件识别初测(2026-11-05)
### 1.1 环境核实
> 计划见 `vision-plan.md`。代码在 `spikes/s5-ocr/`(独立虚拟环境,Python 3.12),产物在 `out/`,不进 git。
> 样本:国动真实投标文件(`samples/tenders/GD/响应文件-最新.pdf`,183 页)。本次没有扫描版招标文件样本(用户:招标文件通常是文字稿),证书扫描件用户随后提供。
- **Gotenberg 镜像**:`gotenberg/gotenberg:8`(8.39.0)有 **arm64 版本**,镜像约 2.5GB,基础系统是 Debian 13。
- **LibreOffice 版本**:26.8.1,比参考项目踩过坑的 7.3 / 24.2 都新。
- **自带中文字体**:只有 Noto Sans / Serif CJK。宋体、仿宋、黑体全部回落到西文的 Noto Sans,衬线和黑体都分不清。
- **样本用到的字体**:宋体(约 4.8 万处)、仿宋、黑体、楷体、方正系列、Times New Roman、Arial。都是商业字体,不能随镜像分发。
- **OLE 嵌入对象**:10 份样本里都没有,所以「内嵌 OLE 的 docx 会让旧版 LibreOffice 崩溃」这一条无法用本批样本验证,留到收集到这类样本时再测。
- **耗时与稳定性**:10 份文件 × 6 种配置,全部转换成功,没有崩溃;单份 0.4~2.0 秒。
### 7.1 OCR(RapidOCR 3.10,PP-OCRv6 small 检测 / 识别模型,onnxruntime CPU,Apple Silicon)
### 1.2 真值
- **挑页**:沿用文字层 v5 的扫描页规则,整页识别 80 页;图片占比 ≥ 0.15 的文字页只识别图片区域(跳过小于页面 5% 的小图),22 页。和文字层已有文字重叠的 OCR 行去掉。
- **速度**:200 dpi 渲染 + 识别,102 页 61 秒(约 0.6 秒 / 页,横放的报表页 1.5~3 秒)。按这个速度,300 页全扫描约 3 分钟,满足 10 分钟目标。
- **转正**:第 18、19 页的资产负债表是横放扫描,0° 识别出大量竖长框,试 90° / 270° 取「字数 × 平均置信度」最高者,判为 270°;框换算回原页坐标后画回去全部对上。
- **字准(合成扫描件)**:文字页渲染成图片,分三档退化(干净;灰度 + 倾斜 1° + 模糊 + 噪点 + JPEG 60;降采样 + 倾斜 2° + 更模糊 + JPEG 35),以文字层为真值:
| 来源 | 覆盖 | 说明 |
|---|---|---|
| 旧版 DOC 里 WPS 保存时记录的页数 | S07(79 页)、S09(73 页) | OLE SummaryInformation |
| DOCX 的 `docProps/app.xml` 页数 | **没有** | 8 份 DOCX 都是 ONLYOFFICE 7.2 生成的(苏采云平台导出),不写页数 |
| DOCX 目录里缓存的页码(PAGEREF) | S03、S04、S06 | 生成文档时排版写入;比较「各章标题之间隔了几页」,消除页码起始值的影响 |
| 文件 | 页 | 字数 | 字符差(不看顺序) | 按顺序的错误率 |
|---|---|---|---|---|
| 国动招标文件 | 5–24 | 12,806 | 0.31% / 0.41% / 0.32% | 1.2% / 1.4% / 1.3% |
| 国动投标文件 | 35–60 | 15,436 | 0.15% / 0.09% / 1.09% | 约 31%(表格多,阅读顺序和文字层不同,不是认错字) |
**发现**:平台导出的 DOCX 没有「Word 里显示的页数」可以对照。用户在 Word 或 WPS 里看到的分页,取决于他们自己装的软件和字体。所以「出处页码以规范化 PDF 为准」这条设计是必需的,不是权宜之计。
退化对字准影响很小。真实扫描件上没有真值,用视觉模型的交叉校验和人工抽查代替(§7.2)。
- **红章压字**:资产负债表「核算单位」被红章盖住,原图只认出「南京」「信息技术有限公司」两段。
- 按红色像素阈值抹掉印章:章下面的黑字也一起抹掉,更差。
- **只取红色通道当灰度图**(红章变浅、黑字不变):认出「核算单位:南京会信息技术有限公司」(错一字),肉眼可读出「南京长卿信息技术有限公司」。
- 但整页都用红色通道时,23 页有变化,有的变好(p21、p142、p162),有的变差(p16、p163)。**结论:只对红章附近的区域用红色通道重读,其余保留原图结果。**
- **图表**:技术方案里的 22 页架构图、流程图、界面截图,图里的文字全部读出(例如第 61 页系统逻辑架构图 26 行,四层的每个模块名都在)。这些文字以前不在文字层里,查标「出处没能核对」里架构图那几条(`check-eval.md` §14)就是因为这个。
### 1.3 严重问题:WPS 旧版 DOC 转出来正文是空白
### 7.2 视觉模型(DeepSeek Flash,`deepseek-chat` 不思考,`json_object`)
- **现象**:S07 默认转换后,正文渲染成空白,抽出的文字全是「第第第第」;S07 只有 61 页,真值是 79 页。
- **原因**:WPS 在字体表里把「宋体」的字符集标成了 `02`(SYMBOL,符号字符集)。LibreOffice 据此把正文当成符号,换成了 OpenSymbol 字体;转成 DOCX 后,这些字也变成了 `<w:sym>` 符号字符,不是普通文本。
- **修复**:先转 DOCX,把中文字体名被标成 SYMBOL 的字符集改成 GB2312(`86`),再转 PDF。修复后 S07 正文正常,**80 页**。
- **影响**:
- 转换前必须加这一步预处理。
- 用 DOCX 做交叉校验时,读文本要同时读 `<w:t>` 和 `<w:sym>`。
- 只要规范化 PDF 里出现大段 OpenSymbol 字体、或抽出的文字大量重复同一个字,就判定为「转换异常」:不扣点,提示用户。
- **做法**:每页图片(长边 1600 像素,JPEG 85)+ 带编号的 OCR 行一起发;输出页面类型、是否续页、标题、字段(必须引用 OCR 行号)、印章 / 签名有无、图表概述。字段值归一化后在所引行里找;只有数字一致算「近似」;对不上记「不一致」。
- **速度和成本**:102 页并发 6,23 秒;输入 199,863 token、输出 9,324 token,按 §4.3 的高峰价约 0.47 元,每页约 0.005 元。
- **页面分类**:劳动合同 35、业务合同 27、系统界面截图 9、信用查询截图 8、架构图 8、财务报表 4、流程图 4、纳税证明 2、其他图表 2、营业执照 1、授权书 1、其他 1。按「不是续页」的标记数,3 份业务合同(第 104、119、123 页起)、5 份劳动合同(第 135、142、149、156、163 页起,每份 7 页)的起始页都对,和页面下方的文字说明一致;没有逐页人工核对。第 21 页「登记通知书」归到「其他」,合理。
- **字段**:86 个,70 个和所引 OCR 行一致。16 个不一致:
### 1.4 字体配置对比(页数)
| 原因 | 个数 | 处理 |
|---|---|---|
| 值跨两行(住所、所属期间、合同期限、长合同名) | 10 | 允许引用多行,按拼接后的文字核对 |
| OCR 被红章或下划线切碎(「签订日期:20251」) | 4 | 红章附近用红色通道重读 |
| OCR 读错、模型读对(手写「2025」OCR 读成 2015) | 1 | 交叉校验按设计拦下,进待确认 |
| 模型读错(「长卿」读成「长顺」,还引错了行) | 1 | 交叉校验按设计拦下 |
| 配置 | 说明 |
|---|---|
| A-default | Gotenberg 默认,原文件直接转 |
| B-alias | 加 fontconfig 规则:宋体 / 仿宋 / 楷体 / 方正系列 → Noto Serif CJK SC,黑体 / 雅黑 → Noto Sans CJK SC |
| A-fixed / B-fixed | 同上,但先做 §1.3 的字符集修正 |
| **C10-fixed** | 字符集修正 + 用 fontTools 克隆 Noto CJK,**字形不变,只把行高改成 1.0em**(和宋体一致,上 0.86 / 下 0.14),改名 BD Song / BD Hei,替换规则同 B |
| C13-fixed | 同 C10,行高 1.3em |
**校验拦不住的**:
- 语义错:第 145 页「用人单位 = 甲方」「合同期限 = 1 种工时制度」,值确实在所引行里。要按字段类型加格式校验(单位名要像单位名,期限要有日期)。
- 手写:第 169 页乙方手写「2025 年 11 月 22 日」,OCR 和模型都读成「1 月」,两边一致但都错。手写区域即使两边一致也按低可信处理,不出致命级。
- 半截值:第 18 页「单位名称」取了 OCR 认出的半截「信息技术有限公司」,校验通过。被章挡住的值要标「可能不完整」。
- **印章 / 签名(S6 初测)**:判「有章」44 页、「看不清」6 页;手写签名 9 页。抽查:第 106 页右边缘的浅色骑缝章判成「无」(漏),第 131 页只露一截的骑缝章判「看不清」(合理)。签章检查只看指定签章位,骑缝章影响不大,但要加红色像素初筛补漏。没有标注,准确率没算。
- **图表概述**:架构图、流程图的概述准确(第 61 页把四层和每层的模块全部列对),适合在覆盖范围或出处卡片里作「图片说明(AI 生成,非原文)」。
| 样本 | 真值 | A-default | B-alias | A-fixed | B-fixed | **C10-fixed** | C13-fixed |
|---|---|---|---|---|---|---|---|
| S07(WPS) | 79 | 61(正文空白) | 61(正文空白) | 80 | 80 | **79** | 80 |
| S09(WPS) | 73 | 89 | 90 | 91 | 92 | **75** | 87 |
| S01 | — | 93 | 95 | 93 | 95 | 81 | 90 |
| S03 | — | 145 | 145 | 145 | 145 | 104 | 131 |
| S06 | — | 198 | 199 | 198 | 199 | 166 | 190 |
### 7.3 证书识别(资质库上传识别,vision-plan 第 2 步)
目录页码真值(标题之间的页数跨度误差,括号里是最大单点偏差):
> 样本:用户提供的 7 张网上公开证书图片(不进 git):人员证书 4 张(软考、职业技能等级 ×2、培训证书,其中 2 张姓名 / 编号打了马赛克)、软著 2 张(1 张低清、红章压日期)、一张照片里挂着两张软件产品证书(反光)。每张再转 90°、180°、270° 各做一份,共 28 次。标准答案由 Claude 对着图录(`spikes/s5-ocr/out/certs/gold.json`,不进 git,用户未复核)。代码 `spikes/s5-ocr/certs.py`。
| 样本 | 目录项 | A-fixed | C10-fixed | C13-fixed |
|---|---|---|---|---|
| S03 | 7 | +36.7%(29 页) | **-1.3%(1 页)** | +24.1%(19 页) |
| S04 | 8 | +32.3%(20 页) | **0.0%(1 页)** | +22.6%(14 页) |
| S06 | 6 | +17.3%(26 页) | **-2.2%(11 页)**¹ | +11.5%(26 页) |
- **流程**:图片按 EXIF 转正 → OCR 服务(转正、红章重读)→ 转正后的图 + 带编号的 OCR 行交给 DeepSeek Flash,按证书逐张输出类别和字段(每个字段引用 OCR 行)→ 校验。
- **转正**:90° / 270° 原来就能认;**180° 原来认不出**(逐行识别时 RapidOCR 自己翻正,字认得出,但整页图是倒的,模型把「评估机构」当成了「发证机构」、日期读错)。加了整页倒置检测:挑最多 30 个长行交给 RapidOCR 的方向分类模型,过半判 180° 就整页翻过来重识别。之后 16 种「图 × 角度」全部转对,倒置检测每页多 0.2~0.4 秒。
- **打码**:马赛克轻的地方 OCR 会「读」出字(培训证书的姓名、编号),模型照抄。两层处理:提示词要求被打码的字段不输出、写进 masked;服务端看所引 OCR 行的置信度,低于 0.9 标「识别不确定」,不自动填。透过马赛克读出的行置信度 0.69、0.88,正常行在 0.95 以上。
- **结果**(提示词改了两轮之后):200 个字段对 200,漏 0;打码字段 16 次全部没给值或标了识别不确定;一图两证两张都拆对。字段校验 192 个一致、8 个识别不确定(都是打码字段)、9 个不一致(值是对的,OCR 那行认错或值由两行拼成,会以「识别结果不一致,请核对」给用户)。
- **速度和成本**:每张 OCR 约 2 秒(含转正),模型约 1.5 秒;每张输入约 1,400 token、输出约 220 token,不到 0.005 元。
- **局限**:提示词是对着这 7 张改的(第一轮 50 个字段对 45、打码字段漏了 2 次),满分是调出来的,说明不了泛化。下一批证书不改提示词直接跑,才是正式成绩。样本里没有企业资质证书(CS、ITSS、ISO)和营业执照。
¹ S06 只匹配上 4 个目录项,最大偏差里有标题匹配不准的成分。
### 7.4 这份文件上能多查出什么
**结论**:
- 分页偏差的主因是**行高**,不是衬线还是黑体:Noto CJK 的行高约 1.45em,宋体是 1.0em,同样的「单倍行距」在 Noto 下每行高出 45%。
- 克隆字体的行高改成 1.0em 后,5 个有真值的数据点都落在 ±3% 以内,单点偏差大多在 1 页内。
- **字体许可**:Noto CJK 是 OFL 1.1,允许修改后再分发;改名后的字体仍按 OFL 分发,许可证文件要随镜像带上。
- **仍然存在的风险**:
- 这 5 个数据点都以宋体为主。仿宋、楷体为主的文件(S01、S02、S08)没有真值,偏差未知。
- 克隆字体只调了行高,西文字宽和宋体的半角宽度不同。表格密集、中英混排多的文件可能仍有偏差。
只是看结果做的推演,产品还没实现:
## 2. S2 格式识别(斜体 / 下划线 / 加粗)
- **主体名称不一致(D14)**:营业执照(第 16 页)是「南京长卿科技有限公司」,统一社会信用代码 91320114MA27H0P5X5;利润表、资产负债表、现金流量表(第 17、18、20 页)的单位名称,以及第三份业务合同(第 123–124 页)的乙方,都是「南京长卿信息技术有限公司」;资产负债表上的纳税人识别号和营业执照一致。多半是曾用名,但投标文件里没看到更名证明,值得提示用户核对。
- **证明材料**:第二十二条要的营业执照、财务报表、纳税、信用记录都能按页面类型定位到具体页,不用再出「请人工核对」。
- **评分项**:扫描页里只有营业执照、财务报表、纳税证明、信用报告、3 份业务合同、5 份劳动合同,没有软著、人员证书、国产化证明,「软件自主研发」「团队专业能力」「国产化适配」三条可以直接说「投标文件里没有找到这类材料」,不再说「可能在扫描件里」。
- **业绩**:3 份业务合同的金额(4 万、8 万、17 万)、甲乙方、签订日期都读得出,D15 的时间窗口核对有了数据。
### 2.1 方法
### 7.5 对计划的修改
- **银标准**:DOCX 原文件里「斜体且下划线」的文字。解析 XML 时完整处理样式继承:文档默认 → 段落样式链 → 字符样式链 → 直接格式。注意 python-docx 的 `paragraphs` 不包含表格里的段落,直接用它会漏掉大半。
- **PDF 侧**:
- 斜体:字体名含 Italic,或字形矩阵有倾斜(中文没有斜体字形,LibreOffice 合成斜体时倾斜量是 0.35);
- 下划线:字符底边附近有一条横线覆盖该字;
- 加粗:字体名含 Bold。
- 下划线的判定窗口要包含「字符框内侧」:克隆字体的下行部分变小后,下划线会落进字符框里。
### 2.2 结果(规范化 PDF = C10-fixed)
| 样本 | DOCX 斜体下划线字数 | PDF 识别字数 | 按字符一致 | 片段召回 | 片段精确率 |
|---|---|---|---|---|---|
| S06 | 14209 | 14209 | **100%** | 0.993 | 0.871² |
| S08 | 1088 | 1088 | **100%** | 1.000 | 1.000 |
| S09 | 70 | 70 | **100%** | 1.000 | 1.000 |
| S03 | 98 | 98 | **100%** | 1.000 | 1.000 |
² S06 的片段精确率偏低,是因为 PDF 按阅读顺序把相邻表格单元格的片段连在了一起,按片段匹配就对不上;按字符计数两边完全一致。默认字体配置(A-fixed)下结果相同,说明格式识别不依赖字体选择。
### 2.3 Docling 对比(S06)
| 输入 | 耗时 | 保留斜体下划线 | 页码和坐标 | 表格识别 |
|---|---|---|---|---|
| DOCX 原文件 | 2.1 秒 | **100%**(14209 字) | **没有** | 31 个 |
| 规范化 PDF | 96.2 秒(CPU) | **0** | 有 | 73 个 |
- `docling-serve-cpu` 有 arm64 镜像,约 7.2GB,本机拉取约 5 分钟。版本:docling-serve 1.38.2、docling 2.142.1。
- **结论**:Docling 做不到「格式 + 坐标」同时具备;我们自己从规范化 PDF 提取,两样都有,而且 4 份文件合计只要约 6 秒。Docling **不作为主解析器**。它的 PDF 表格识别可以作为候选,用来解决 S3 的表格切句问题,要再评估。
## 3. S3 原句级坐标与高亮
### 3.1 方法
- 从规范化 PDF 取逐字坐标,按行聚类;同一行里字间空隙大于 1.5 个字号时断开,得到「行片段」。
- 在 。!?; 处断句;段落末行或表格单元格结束时也断句。句子不跨页。
- 编号格式:`<文档>:p<页>:s<页内序号>`。规范化 PDF 不再重新生成,所以编号稳定。
- 每句生成 quads:按行合并成矩形。
- 校验分两种:
- **几何回读**:用 quads 裁剪原页重新取字,和句子比对;
- **文本保真**:句子能在 DOCX 原文里找到,不算 Word 自动编号和页码域。
### 3.2 结果
| 指标 | 50 句(种子 20261103) | 300 句(种子 7) |
|---|---|---|
| 10 份文件总句数 | 24020 | 24020 |
| 跨行句子占比 | 23 / 50 | 118 / 300 |
| **几何回读正确** | **50 / 50** | **300 / 300** |
| 文本保真 | 49 / 50(98%) | 269 / 300(89.7%) |
300 句按位置分类的文本保真率:
| 位置 | 文本保真 | 失败原因 |
|---|---|---|
| 正文 | **196 / 201 = 97.5%** | 个别行内拼接 |
| 表格内 | 71 / 91 = 78.0% | 相邻单元格(序号列、分值列)的文字被拼进同一句 |
| 页眉页脚带 | 2 / 8 = 25.0% | 页眉文字混进了正文句 |
- 高亮图在 `spikes/s3-citation/out/highlight-*.png`(8 张),样式是设计规范的蓝铅笔浅底加蓝铅笔描边。人工看过两张:跨 3 行的句子在句号处结束,同一行后面的下一句没有被带进来。
- **要改进的两点**:
1. 切句前先识别表格单元格,用 PDF 的表格线,或者参考 Docling 的表格结构,按单元格切;
2. 识别每页重复出现的页眉页脚带,单独处理,不并入正文句。
- 自动编号(「60.」「24.」)由 Word 渲染时生成,规范化 PDF 里有、DOCX 文字里没有。出处高亮以 PDF 为准,所以不影响高亮;只是做 DOCX 交叉校验时要容忍这一点。
## 4. S4 大模型抽取实质性条款
### 4.1 方法
- **输入**:S3 的句子,带格式标记(`<iu>` 斜体且下划线、`<u>` 下划线、`<i>` 斜体)。每个分块约 6000 字,10 份文件共 150 块。每个分块前附上从全文摘出的「标注规则说明」句。
- **银标准**(实质性条款句):
- ★ 句:排除说明句和「★号条款」这类引用句;
- 斜体下划线句:只在文件自己声明这种标注方式时才算(S06、S08、S09),否则它常常只是模板里的填空处。
- S03 正文的 ★ 句**正好 14 条**,和文件自述的「★ 项共 14 条」一致。
- **提示词**:`spikes/s4-llm/prompts/extract_substantive/`,有 v1、v2 两个版本。要求只能引用句子编号,引文必须逐字复制。
- **三道校验**:
1. 编号必须在本分块里;
2. 引文必须是原句的子串,并满足最小长度;
3. **依据校验**(v2 新增):模型声称的依据,用确定性信号核对。★ 看原句里有没有 ★,斜体下划线看有没有 `<iu>`,「写明无效」看原句和相邻句里有没有无效类字样。
- 任何一道没通过,条目都进**待确认区**,不丢弃。
### 4.2 结果(10 份文件全量)
| 指标 | v1(无依据校验) | **v2 + 依据校验** |
|---|---|---|
| ★ 召回(严格 / 含相邻句) | 91.3% / 92.4%(84、85 / 92) | **93.5% / 93.5%**(86 / 92) |
| 斜体下划线召回(严格 / 含相邻句) | 91.3% / 99.8% | 91.7% / **99.8%** |
| 采纳条目数 | 1761 | 651 |
| 采纳条目属实(命中银标准,或证据句写明无效) | 36.7% | **95.2%** |
| 进待确认区 | 66 | 283 |
| 证据两道校验通过率 | 95.1% | 93.6% |
| 输入 / 输出 token | 61.1 万 / 11.4 万 | 63.6 万 / 5.2 万 |
| 费用(高峰 / 空闲) | 1.93 / 0.96 元 | **1.49 / 0.74 元** |
- **漏掉的 ★ 句(v2)**:共 6 条,其中 3 条是银标准的噪音:「备注:加★为核心技术参数」「非标★、▲项为一般技术参数」「属于清单中打★品目的」。**真正漏掉的 3 条都是表格里的参数行**。扣除噪音后召回约 **96.6%**(86 / 89)。
- **v1 的主要问题是过度抽取**:合同履约、保密协议、付款等条款都被当成了「写明无效」。S09 有 208 条被标成「斜体下划线」,实际上全文只有 2 句。说明模型会**标错依据**,所以必须有第三道依据校验。
- **证据没通过的原因**:引文过短(少于 8 个字)、引文不是原句子串、编号不在本分块。都被校验拦下进了待确认区,没有一条错误出处进入正式清单。
- **耗时**:10 份文件 8 路并发,约 2 分钟;最大的 S06(199 页、28 块)单独串行累计 142 秒,并发后约 20 秒。
### 4.3 成本(供 D2 定价参考)
价格来源:DeepSeek 官方价目页(https://api-docs.deepseek.com/zh-cn/quick_start/pricing,2026-11-03 查询)。`deepseek-flash`(DeepSeek-V4.1-Flash-1017)每百万 tokens:输入缓存命中 0.04 元、未命中 2 元、输出 8 元(高峰);空闲时段半价。
| 口径 | 每份招标文件 |
|---|---|
| 本次实测(只做「实质性条款」一项抽取,v2) | 输入约 6.4 万 token、输出约 0.5 万 token;**约 0.15 元(高峰)/ 0.07 元(空闲)** |
| 推算:完整 M2 解读(资格、废标条款、评分、日期、参数、摘要等 5~6 项抽取) | 约 0.6~1.0 元(高峰),**推算值,未实测** |
- 换成深度思考模式或 `deepseek-v4-pro`,输入单价是 Flash 的 2.25~4.5 倍,还会多出思考 token。本次没有测,D2 定价前要补测「Pro 或思考模式能把召回提高多少」。
- 价格表里没有 `deepseek-chat` 这个名字,但接口仍然接受,实际由 Flash 提供服务。正式接入时应直接用 `deepseek-flash`,并把接口返回的 model 字段记进调用流水账(架构 §3.6)。
### 4.4 建议
1. **标注类条款用规则保召回**:★、*、文件声明了的斜体下划线,都能从规范化 PDF 上确定性地识别出来(S2)。所有这类句子都必须被某个条目覆盖;模型没覆盖的,系统自动生成一条「待确认」。模型负责归并、概括和判断依据,召回不再完全依赖模型。按 S2 的结果,这一类的召回可以做到接近 100%。
2. **「写明无效」类靠模型加依据校验**:这一类没有银标准,召回率还没测,需要人工标注 2~3 份文件。可以和样本缺口里的「人工标注 S03 / S06」一起做。
3. **数量核对**:文件写明了实质性条款数量的(S03「共 14 条」),和抽到的数量对比,不一致就提示(FR-M2-05 已有要求)。
4. 引文最小长度从 8 个字放宽到「不少于 6 个字,或整句」:表格单元格常常很短,「引文过短」是证据被拒的首要原因。
## 5. 对需求目标值的建议
| 需求 | 建议目标值 | 依据 |
|---|---|---|
| FR-M2-05 ★ / 标注类实质性条款召回 | **≥ 99%**(规则兜底 + 模型) | S2 格式识别 100%;S4 模型单独约 96.6% |
| FR-M2-05 「写明无效」类召回 | 先定 **≥ 90%**,人工标注后校准 | 尚无银标准 |
| FR-M2-05 采纳条目准确率(进正式清单的条目属实) | **≥ 95%** | S4 v2 实测 95.2% |
| FR-M2-06 出处页码正确率 | **100%** | 出处由句子编号决定,页码随编号而来;编号和引文都经过校验 |
| FR-M2-06 原句高亮准确率(抽查 50 条) | 正文 **≥ 98%**,表格 **≥ 95%** | 实测正文 97.5%、表格 78%,表格切句改进后再验收 |
| FR-M2-02 解析耗时(300 页) | 维持 10 分钟目标 | 转换 ≤ 2 秒,文字层约 2 秒 / 100 页,单项抽取并发后约 20 秒;完整解读按 5~6 项推算在 2~3 分钟内 |
## 6. 未覆盖的事项
- **S1**:内嵌 OLE 对象的 docx(本批样本里没有);以仿宋、楷体为主的文件的分页真值。
- **S3**:扫描件 OCR 页的坐标(S5 的范围)。
- **S4**:深度思考模式和 Pro 模型的对比;「写明无效」类的召回;资格、评分、日期等其他抽取项。
- S5(OCR)、S6(签章)、S7(任务队列)按 §10 的计划另做。
见 `vision-plan.md` v0.3:多行引用、字段格式校验、红章局部重读、手写低可信、半截值标记、签章位红色初筛;招标文件里的图片按重要程度分流(用户要求)。