Files
bid-doctor/docs/architecture/vision-plan.md
YANG JIANKUAN 3344f09563 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>
2026-11-05 17:50:13 +08:00

244 lines
26 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 扫描件与图片识别计划 v0.3(OCR + 视觉模型)
> 2026-11-05。起因:国动真实投标文件查标时,扫描页上的内容一律成了「请人工核对」。本文盘点现状,回答「要不要视觉模型」,列出全系统里要识别图片的地方,给出分步计划。VS1–VS9 已确认(§7,`docs/decisions.md`);v0.2 按用户决定把视觉模型改为 DeepSeek Flash(VS2)。v0.3 按国动投标文件上的初测(`tech-validation.md` §7)补了校验规则,招标文件里的图片按重要程度分流(§3.1,用户要求)。
## 进度
| 步 | 状态 | 说明 |
|---|---|---|
| 0 验证 | 基本完成 | 国动投标文件的 OCR 和视觉初测(`tech-validation.md` §7.1、§7.2);用户的 7 张证书(§7.3,提示词对着这 7 张改过,满分说明不了泛化)。还差签章标注 |
| 1 OCR 进文字层 | **已完成**(2026-11-05) | 架构 §13 SK15;国动端到端见 `check-eval.md` §16。规则检查不看扫描附件和插图上的识别文字(第一次跑报出 21 个附件噪音后改的) |
| 2 资质库识别 | **已完成**(2026-11-05) | 架构 §13 SK16。按用户要求简化(VS11、VS12):一张图按一张证书处理;不单设识别入口,「添加资质」对话框最上面传证书照片,识别后填进下面的表单。产品接口上 7 张证书实测见下 |
| 3–5 | 未开始 | |
### 第 2 步落地记录(2026-11-05)
- **流程**:传照片(PDF / JPG / PNG / WEBP)→ `POST /qualification-scans` 排队 → worker 任务 `recognize_qualification`(`qualification/recognize.py`):每页图片按 EXIF 转正 → OCR 服务 → 转正后的图 + 带编号的 OCR 行交给 DeepSeek Flash(提示词 `vision.cert_fields` v1)→ 逐字段校验 → 前端轮询拿结果、填表。PDF 只识别前 10 页;不扣额度,每个企业每天 100 次;没开 OCR 时直接说明,可以手动填。
- **校验**:所引 OCR 行拼起来要包含字段值(日期按年月日比);所引行置信度低于 0.9 标「识别不确定」;对不上标「不一致」;「甲方」「本公司」这类不当证书主体。只有一致的才预填,其余只给建议、点「采用」才填。被打码的字段写「被遮挡,请手动填写」。
- **辅助**:名称写成「证书标题(软件名或专业)」;软著取登记号当证书编号、默认长期有效;只写了「有效期:五年」时给「按发证日期推算」;有效期起没写时给「发证日期 填入」;证书主体和企业名称不一致(曾用名、子公司)、人员证书、产品证书都提醒;编号和已有记录相同时可以「改为更新它」(换证)。
- **留痕**:保存时识别值记在 `qualification.ai_values`,识别用的照片挂成附件;没保存的识别 24 小时后删除(建下一次识别时顺手清)。迁移 0014。
- **产品接口实测**(真实 OCR + DeepSeek,7 张证书):每张 2~4 秒,全部识别成功,结果和 `tech-validation.md` §7.3 一致。**局限**:培训证书的编号中间几位打了码,OCR 这次跳过了打码的字、置信度不低,读成「FRX11032897」并预填了,两层防护都没拦住。所以界面要求逐项核对,识别出的值不能当确定值。
## 0. 结论
- **OCR 和视觉模型都还没有接。** 架构里写的是「PaddleOCR 独立服务 + 多模态大模型补充」(架构 §1、§3.5、AR1),技术验证 S5(OCR)、S6(签章检测)一直排在 M3 之后(C10),没有做。
- **要用视觉模型,但它不能代替 OCR。** OCR 给文字和坐标,保证原句高亮、出处可查(红线 2);视觉模型负责「理解」:这页扫描件是什么材料、证书上的字段、签章有没有、图里的表格。视觉模型的结论要能对上同一页的 OCR 文字,对不上的进待确认区。
- **视觉模型用 DeepSeek Flash,不另加供应商**(VS2)。v0.1 以为 DeepSeek 不收图片,实测是错的:`/models` 返回 `deepseek-flash`(DeepSeek-V4.1-Flash)的 `input_modalities` 是 `text`、`image`,`deepseek-chat` 直接收 OpenAI 格式的 `image_url`。见 §2.1。
- 除了读标、查标、资质库,还有一处 P0 缺口:**签章有无(FR-M3-04)完全没做**,`rules.py` 把它列在「还没查」里。它也要靠视觉。
## 1. 现状
| 地方 | 现在怎么做 | 代码 |
|---|---|---|
| 判断扫描页 | 每页记图片占比(文字层 v5),字少、图多的页算 `empty` | `document/pipeline/text_layer.py` `Page.text_source` |
| 流水线的 OCR 阶段 | 只有阶段名,不做事;招标文件超过一半是扫描页就报 `ocr_required` 失败 | `normalize.py`、`runner.py` 的 TODO(S5) |
| 整份扫描的招标文件、补遗 | 解析失败:「扫描件识别还没有上线」 | `core/errors.py` `ocr_required` |
| 整份扫描的投标文件 | 检查失败:`bid_text_missing` | `check/runner.py:148` |
| 投标文件里的扫描页 | C10 兜底:要附证明材料而文字部分没找到,出提示级「第 X–Y 页是扫描件……请人工核对」;覆盖范围列出扫描页 | `check/match.py`、`check/findings.py` |
| 资质匹配 | 证书多在扫描页上,只能靠资质库记录(QL2,降一级);主体不一致(D14)、业绩时间窗口(D15)留到「OCR 之后」 | `check/qualification.py` |
| 招标文件正文里的图片 | **没有处理,也没有告诉用户**:截图的评分表、参数表、资格要求不会进清单 | — |
| 签章有无 | 没做 | `check/rules.py` `RULES_NOT_YET` |
| 资质库 | 手工录入,扫描件只当附件存着 | `qualification/` |
| 模型调用 | 提示词可以声明 `capability: vision`,但 `openai_compat.py` 只发文字消息(模型本身收图片,§2.1) | `ai/providers/openai_compat.py` |
国动那份投标文件(`check-eval.md` §14、§15):183 页里约 82 页是扫描件(资格证明、合同、劳动合同),12 条「请人工核对」只有 4 条有用。
## 2. OCR 和视觉模型怎么分工
| | OCR(自部署) | 视觉模型(DeepSeek Flash,私有化可选) |
|---|---|---|
| 产出 | 每行文字 + 坐标框 + 置信度 | 结构化理解:页面是什么材料、证书字段、签章有无、图片类型 |
| 出处 | 能高亮原句,满足红线 2 | 给不出可靠坐标,**不能单独当出处** |
| 风险 | 错字(红章压字、手写、低清、旋转) | 会「顺手改正」或编出没写的值,日期、编号尤其危险 |
| 成本 | CPU 上跑,按算力算 | 按 token 计费,逐页调用较贵 |
| 私有化 | 镜像自带模型,离线可用 | 客户要有 GPU 部署多模态模型,没有就降级 |
**组合方式:先 OCR,再把「页面图片 + 带编号的 OCR 行」一起交给视觉模型。** 视觉模型输出的每个字段都要引用 OCR 行号,服务端沿用三道校验:
1. 编号校验:引用的行号在这一页上;
2. 原文校验:字段值(日期、编号按规则归一化后)出现在所引的 OCR 行里;
3. 不一致处理:视觉模型读出的值和 OCR 行对不上(例如 OCR 把 2028 认成 2026),**不采信任何一边**,标「识别结果不一致」,进待确认 / 要用户填写。
初测(`tech-validation.md` §7.2)后补的四条:
4. **可以引用多行**:住所、合同期限、长合同名常跨两行(初测 16 个不一致里占 10 个),按所引各行拼接后的文字核对。
5. **字段格式校验**:值在所引行里也可能是错的(「用人单位 = 甲方」「合同期限 = 1 种工时制度」)。按字段类型校验:单位名要以「公司 / 中心 / 局……」结尾,日期能解析,期限有起止日期,编号有字母数字。不合格的进待确认。
6. **半截值**:所引的行挨着印章、或者值明显不完整(单位名没有后缀),标「可能不完整」,不当作确定值比对(例如不拿半截单位名去判主体不一致)。
7. **手写区域低可信**:手写的签订日期,OCR 和模型可能一致但都错(第 169 页手写的「11 月」两边都读成「1 月」)。OCR 置信度低于阈值、或模型标了手写的值,最多出提示级。
这样出处始终落在 OCR 的坐标框上,视觉模型只负责「理解」和交叉校验。没有文字的判断(签章有没有、这是一张拓扑图)只能做提示,不当成原文证据。
### 2.1 DeepSeek Flash 的图片能力(2026-11-05 实测)
| 测试 | 结果 |
|---|---|
| `GET /models` | `deepseek-flash`(DeepSeek-V4.1-Flash):`input_modalities: ["text", "image"]`,上下文 1M |
| `deepseek-chat` / `deepseek-reasoner` 收 `image_url`(base64) | 都返回 200,实际模型都是 `deepseek-flash` |
| 虚构的中文证书图:倾斜 1.5°、模糊、椒盐噪声、JPEG 55 质量、红色圆章,要求输出 8 个字段的 JSON(`json_object` 模式) | 名称、编号、主体、等级、发证机构、发证日期、有效期至、有无印章 **8 / 8 全对**;输入 393 token、输出 72 token |
这只是一张合成图,说明不了真实扫描件上的准确率;坐标框也没测(不打算靠它出坐标,§2)。S5 在扫描评测集上正式测。
**没有理由否决 DeepSeek Flash**:能力够、一张证书不到 500 token,和抽取共用一家供应商,还省掉一套供应商接入、协议(红线 10)和路由。仍要留意的两点:① 合成图上的满分不代表真实扫描件,手写签名、红章压字、低清复印件要在 S5 / S6 里专门测;② 只有一家供应商,DeepSeek 限流或故障时抽取和视觉一起停,降级候选列表(架构 §3.6)以后再配。
## 3. 全系统里要识别图片的地方
按模块挖了一遍,分三档:**P0 缺口**(MVP 范围内,现在没做或做得不够)、**MVP 内的增强**、**以后版本**(按「以后的功能只留结构」的原则,只保证能复用同一层,不展开设计)。
### 3.1 读标(M2)
| # | 场景 | 现在 | 要做的 | 档 |
|---|---|---|---|---|
| R1 | 整份扫描的招标文件(盖章扫描版、纸质转电子) | 解析失败 | OCR 进文字层,抽取照常;扫描页上的斜体下划线标注认不出,覆盖范围写明「实质性条款可能漏,请复核」,★ 按 OCR 常见误认(`*`、`☆`)归一 | P0(FR-M2-01「PDF 扫描版」) |
| R2 | 补遗、更正公告是盖章扫描件 | 解析失败 | 同 R1 | P0(FR-M2-10) |
| R3 | 文字版招标文件里的部分扫描页(盖章页、附件) | 当空页跳过 | 同 R1,逐页补 | P0 |
| R4 | 正文里的截图:评分表、参数表、资格要求的平台截图 | 静默忽略 | 图片区域单独 OCR,按单元格切句进文字层,可引用、可高亮;重要的再交给视觉模型理解(见下面的分流) | P0(重要的一定做) |
| R5 | 正文里的图纸:拓扑图、平面图、效果图、二维码、logo | 静默忽略 | 装饰类(logo、二维码、印章、页眉图标)跳过;重要的图纸交给视觉模型,给出「图片说明(AI 生成,非原文)」,图里的文字(OCR)可引用;不重要的只在覆盖范围列出 | P0(重要的一定做) |
| R6 | 扫描件上的标注格式(下划线、加粗) | — | 视觉模型认标注,作为依据校验的信号 | 以后,跟读标专项(`extract-status.md`)一起做 |
**招标文件里的图片怎么分流**(用户要求:不是每张都做全套,重要的一定做)。OCR 便宜(CPU 约 0.6 秒 / 页),视觉模型按页计费,所以:
1. **都做 OCR**:扫描页整页识别;文字页里面积超过页面 5% 的图片区域都识别。小图(logo、图标)不识别。
2. **判断重不重要**,满足任一条就算重要,交给视觉模型:
- 图片在要求类章节里:资格条件、评分标准、采购需求 / 技术参数、商务要求、报价 / 清单、合同条款、投标文件格式;
- 图片的 OCR 文字像表格(多行多列、有数字、单位、「★」「≥」)或带要求类字眼(「应」「须」「不得」「无效」「分」);
- 整页扫描的页(补遗、盖章的更正页、扫描附件)。
3. **视觉模型做什么**:判断图片类型(表格截图、架构 / 拓扑图、平面图、效果图、装饰);表格截图按行列还原,交给后面的抽取;图纸给一段说明。
4. **不重要的**(章节外的效果图、宣传图)不调视觉模型,覆盖范围列出「第 X 页有 N 张图没有细读」。
### 3.2 查标(M3)
| # | 场景 | 现在 | 要做的 | 档 |
|---|---|---|---|---|
| C1 | 投标文件里的扫描页(资格证明、合同、证书) | C10 兜底「请人工核对」 | OCR 进文字层:文件要在(按标题找)、响应匹配都能用上扫描页上的文字;C10 只留给 OCR 也读不出的页 | P0 |
| C2 | 整份扫描的投标文件(纸质投标扫描、盖章后扫描) | 检查失败 | 同 C1;报价规则在 OCR 文字上跑,数字的处理见 §4.6 | P0 |
| C3 | 扫描页是什么材料 | 分不出 | **附件索引**:视觉模型给每页(或连续几页)分类——营业执照、资质证书、ISO 体系认证、软著、社保缴纳证明、纳税证明、审计报告、信用查询截图、合同、中标通知书、发票、身份证复印件、人员证书、授权书、其他;文件要在、证明材料缺失(D02)按索引判断,不再说「可能在扫描件里」 | P0(FR-M3-05「每条证明材料都要找到」) |
| C4 | 投标文件里的证书字段 | 只能靠资质库 | 证书类页面抽名称、编号、等级、发证机构、有效期、证书主体;资质匹配有了投标侧出处,不再降一级(QL2 只用于真没识别出的情况);主体和投标人不一致(D14)可以做 | P0 |
| C5 | 签章有无 | 没做 | 从文字层找签章位(「(盖章)」「法定代表人(签字或盖章)」「投标人(公章)」),截取附近区域:红色像素做初筛(不调模型),视觉模型判断有没有印章、手写签名、电子签章;只报「有 / 没看到 / 看不清」,界面写明不鉴定真伪(红线 7) | **P0 缺口**(FR-M3-04、S6、G12) |
| C6 | 业绩合同扫描件:合同金额、签订日期、甲方、项目名称 | — | 字段抽取同 C4;按评分项的时间窗口核对(D15) | 结构在 MVP 留好,规则按 QL7 放 V1 |
| C7 | 人员证书、社保证明、学历职称 | — | 页面分类先认出来(C3);人员匹配是 V1 | 以后 |
### 3.3 资质库(M6-08)及其他
| # | 场景 | 现在 | 要做的 | 档 |
|---|---|---|---|---|
| Q1 | 新增资质 | 手工填全部字段,扫描件只作附件 | **添加资质的对话框最上面传证书照片,识别后填进下面的表单**(只有这一个入口,VS12):名称、类型、等级、证书编号、发证机构、证书主体、有效期。识别出的字段标「识别」,鼠标移上去在缩略图上高亮出处;用户核对后保存才入库(人工确认) | MVP 增强(用户要求) |
| Q2 | 证书主体和本企业不一致 | 没有主体字段 | 识别出的主体和企业名称不一致时提示(子公司、曾用名),不阻断 | 随 Q1 |
| Q3 | ~~一份 PDF 里汇编了多张证书~~ | — | **不做**(VS11):一张图按一张证书处理,认出几张时只填第一张并提示 | — |
| Q4 | 换证:传了新证书 | — | 证书编号或名称 + 类别匹配到已有记录时,建议「更新这条」而不是新增,旧附件保留 | 随 Q1 |
| Q5 | 企业主体信息(营业执照:名称、统一社会信用代码) | 注册时手填企业名 | 传营业执照自动填;给 C4、Q2 的主体比对提供依据 | MVP 增强,可选 |
| L1 | M4 资产库:历史标书、业绩合同、人员证书入库 | V1 | 复用同一层 | 以后 |
| L2 | M5 查重:扫描版的历史标书 | V1/V2 | 复用 OCR 文字层 | 以后 |
| L3 | M1 标讯附件是扫描件 | P1/P2 | 复用 R1 | 以后 |
运营后台不看业务内容,不涉及。
## 4. 设计
### 4.1 流水线
现有的 OCR 阶段落实为(读标、查标共用 `normalize.pages`):
```
文字层(不变) → 逐页决定:
扫描页(text_source = empty) → 整页 OCR
文字页里有大图(按图片区域面积和位置) → 只 OCR 图片区域,和已有文字重叠的去掉
其他 → 跳过
→ 渲染(pypdfium2,约 200 dpi)
→ 转正:0° 识别出大量竖长框时试 90° / 270°,取「字数 × 平均置信度」最高者(初测横放报表判对)
→ 红章:先找红章位置,只对章附近的区域取红色通道当灰度图重读,和原图结果按行取优(整页用红色通道有的页变差,§7.1)
→ OCR 服务(独立容器 bid-doctor-ocr,HTTP 接口,worker 并发调用)
→ OCR 行换算回 PDF 坐标,按同样规则切句,并入文字层(text_layer v6)
→ [视觉] 页面分类、证书字段、图片类型(只对需要的页)
```
- **句子编号稳定**:页上原有文字句的编号不变,OCR 句接在后面编号(`p18s3` 之后是 OCR 的 `p18s4`…)。句子带 `source: "ocr"` 和置信度。
- `document_page.text_source` 增加 `ocr`、`mixed`,加 OCR 平均置信度;`empty` 只剩 OCR 也读不出的页。
- 阶段可续跑、幂等,和其他阶段一样;OCR 结果按页缓存(同一份规范化 PDF 不重复识别)。
- 招标文件不再因为扫描件失败;`ocr_required` 只在 OCR 服务不可用时报,按基础设施错误退回额度。
### 4.2 OCR 引擎
**初定 RapidOCR + PP-OCRv6 small 模型(onnxruntime,CPU)**:国动投标文件上 0.6 秒 / 页,合成扫描件字符差 0.1%~1.1%,坐标准(`tech-validation.md` §7.1)。不用装 PaddlePaddle,镜像小。许可证(RapidOCR Apache 2.0,模型随 PaddleOCR 发布)在做镜像时按架构 §6 的策略核实。表格截图(R4)要行列结构:先用 OCR 框的坐标聚成行列,不够再试 PP-StructureV3。
不用云 OCR 接口:私有化用不了,而且多一个处理方。
### 4.3 视觉模型接入
- **模型**:`vision` 能力用 DeepSeek Flash 不思考模式(`deepseek-chat`),和抽取同一个供应商、同一套配置(VS2、M1)。业务代码仍只声明 `capability: vision`,以后要换模型改 `BD_AI_MODELS` 就行,不改代码。
- **消息格式**:`complete_json` 加可选的图片入参(OpenAI 兼容的 `image_url`,用 base64 data URL,不给模型可访问的外链)。图片在 worker 内存里渲染,长边压到模型够用的分辨率,不另存。
- **假模型**:`fake` provider 加视觉任务的确定性输出,测试和 CI 照旧不调真实模型。
- **提示词**(带版本):`vision.page_classify`、`vision.cert_fields`、`vision.signature`、`vision.figure_kind`。输入都带 OCR 行编号,输出要引用行号(§2)。
- `ai_call` 照常记录;图片只记哈希。
### 4.4 资质库识别(Q1–Q4)
- 上传附件后发起识别任务(几秒;PDF 多页的按页分类后逐张抽)。结果存在附件上(`qualification_file.extracted`:识别值、引用的 OCR 行、模型和提示词版本),用户保存时记下最终值——识别值和人工值都留痕,同读标的 `ai_values`。
- `qualification` 加「证书主体」字段(迁移)。
- 前端:资质库新增改成「先传文件」,表单字段带识别标记,扫描件预览可高亮出处;识别不出的字段留空,不填猜测值(红线 5)。
### 4.5 查标的附件索引和签章(C3–C5)
- 附件索引:每个投标分册版本算一次,存进文字层旁边(同版本复用,和 `prepare_bid` 一样)。证明材料类清单项先查索引,找到了就有投标侧出处(页面分类引用的 OCR 标题行)。
- 证书字段(C4)复用资质库识别的提示词和校验,结果进资质匹配,出处是投标文件的页和 OCR 行。
- 签章(C5):签章位来自文字层;红色像素初筛先过一遍,只有初筛拿不准和要找手写签名的位置才调视觉模型。**电子投标的 CA 签章常在加密上传时才加**,投标人检查的那一版往往还没盖章——要用户说明「这一版盖过章了吗」,没盖过的不查签章,只进需人工核对(P2)。
### 4.6 定级和红线
- **OCR 文字当原文用,但界面标「识别文字」**:出处卡片显示 OCR 标记和置信度,高亮框画在扫描图上。
- **低置信度页上的结论降一级**(同 QL2 的思路);整页置信度太低的仍按 C10「请人工核对」。
- **OCR 读出的数字**:大小写金额、合计、超限价这几条规则在 OCR 文字上跑时,只有 OCR 和视觉模型读出的数字一致才保留原级别,否则降为提示「识别的金额可能有误,请核对」。报价仍然只读不生成(红线 6)。
- **不鉴定真伪**:证书、签章都只看「有没有、写了什么」,不去外部系统核验(红线 5、7)。
- **个人信息**:身份证复印件只分类,不抽号码;人员证书在 V1 之前只分类。
- **覆盖范围**:报告和查标页写明 OCR 了哪些页、哪些页置信度低、哪些图片没读、视觉模型没开时哪些检查没做。
### 4.7 计费
不单独计费,沿用现在的扣点(VS5):OCR 和视觉调用并入「解析 1 次 / 检查 N 点」,靠每个任务的页数上限和硬预算控制成本(同查标第五轮的硬预算);成本记进 `ai_call`,S5 实测后回填 D2 的单次成本。资质库识别不扣点,按企业限次(防刷)。额度页的扣点规则说明不用改。
### 4.8 私有化
OCR 容器随离线包交付(模型打进镜像)。客户没有 GPU 部署视觉模型时:OCR 照常,页面分类退化成按 OCR 标题关键词分类,证书字段只用 OCR + 规则抽(准确率低,全部进待确认),签章退回需人工核对。覆盖范围写明。
## 5. 分步计划
| 步 | 内容 | 验收 | 依赖 |
|---|---|---|---|
| **0 验证** | **初测已做**(2026-11-05,国动投标文件,`tech-validation.md` §7):OCR 速度、字准、转正、红章;DeepSeek Flash 页面分类、字段、交叉校验、图表概述、印章初判。**还差**:证书扫描件上的字段准确率(等用户的证书);签章有无的标注和准确率;扫描评测集(开发集投标文件做成「扫描版」,金标准沿用,留出一部分不看) | 选定 OCR 引擎(已初定);证书字段按字段统计准确率;签章按准确率定级 | 证书样本(§8) |
| **1 OCR 进文字层** | OCR 容器、`normalize` 的 OCR 阶段、text_layer v6、`document_page` 迁移、出处卡片的「识别文字」标记、覆盖范围;去掉 `ocr_required` / `bid_text_missing` 的「未上线」失败 | R1–R3、C1、C2 走通;开发集文字版不退化;扫描版开发集的查标召回和文字版差距可量化 | 0 |
| **2 资质库识别** | 模型调用的图片入参、`vision.cert_fields`、附件识别任务、证书主体字段、自动填表、多证拆分、换证合并 | Q1–Q4;字段级准确率(按字段统计,不合格的字段留空而不是填错) | 0(和 1 可以并行) |
| **3 附件索引 + 投标侧证书** | `vision.page_classify`、附件索引、证明材料按索引判断、证书字段进资质匹配、D14 主体不一致 | 国动重跑:12 条「请人工核对」里的噪音消失、有用的 4 条还在;扫描版开发集证明材料缺失(D02)召回 | 1、2 |
| **4 签章有无** | 签章位识别、红色初筛、`vision.signature`、「这一版盖过章了吗」、规则 `FORM.SIGNATURE_MISSING` | 按 S6 准确率定级(G12:不够就降为请核对) | 1、0 的 S6 |
| **5 读标里的图片** | R4 图片区域 OCR、§3.1 的重要程度分流、表格截图还原行列进抽取、R5 图纸说明和覆盖说明、扫描件上 ★ 的归一 | 构造含截图评分表、参数表的虚构招标文件,截图里的要求进清单、出处高亮在图上 | 1 |
| 以后 | R6、C6 的规则、C7、L1–L3 | 只保证复用 | — |
建议顺序 0 → 1 / 2 并行 → 3 → 4 → 5。资质库识别(2)独立、见效快,也是视觉链路的第一个真实用户场景,适合先上线。
## 6. 影响面
- 迁移:`document_page`(text_source 取值、置信度)、`qualification`(证书主体)、`qualification_file`(识别结果)、附件索引的存放(对象存储里和文字层放一起,库里只存键)。
- 接口:资质附件识别(发起 / 取结果)、文字层句子带 `source`、检查的「这一版盖过章了吗」选项;改 `openapi.yaml` 后重新生成客户端。
- 部署:Compose 加 `ocr` 服务;`.env.example` 加 `BD_OCR_URL`;视觉沿用现有的 `BD_AI_*` 配置,`BD_ENV=prod` 时的假模型检查已经覆盖。
- 文字层版本升级:已有的招标文件不自动重解析;投标分册下次检查时按 v6 重抽(和 v5 一样)。
## 7. 决定(2026-11-05 已确认)
VS2 按用户决定,VS5 用户重申不单独计费,其余按建议。
| # | 事项 | 决定 |
|---|---|---|
| VS1 | OCR 怎么部署 | 自部署 PaddleOCR 系(独立容器),SaaS 和私有化同一套;具体模型 S5 定。不用云 OCR 接口 |
| VS2 | 视觉模型 | **DeepSeek Flash**(`deepseek-chat` 不思考模式),和抽取同一家,不另加供应商(实测见 §2.1) |
| VS3 | 视觉模型的结论怎么用 | 字段必须引用同一页的 OCR 行并通过校验,对不上进待确认;没有文字依据的判断(签章、图片类型)只做提示或按 S6 定级 |
| VS4 | OCR 读出的报价数字 | OCR 和视觉读数一致才按原级别报,否则降为提示 |
| VS5 | 计费 | 不单独计费,沿用现在的扣点;按页数上限和硬预算控成本;资质库识别不扣点、按企业限次 |
| VS6 | 签章检查和 CA 签章 | 检查时让用户说明这一版是否已盖章;未盖章的不查签章,只进需人工核对 |
| VS7 | 私有化没有视觉模型 | 允许,降级运行(§4.8),覆盖范围写明 |
| VS8 | 个人信息 | 身份证复印件只分类不抽号码;人员证书 V1 前只分类 |
| VS9 | 顺序 | 0 → 1、2 并行 → 3 → 4 → 5 |
## 8. 需要准备的样本
- ~~真实扫描的招标文件~~:用户说明招标文件通常是文字稿,这次不提供;招标文件里的图片、扫描页照样按 §3.1 处理,评测用构造的虚构样例;
- 本企业的证书扫描件 10–20 张(资质库识别评测,不进 git):用户在找;
- 盖过章的投标文件 1 份(签章检测),最好有对应的未盖章版本。