- 资质库(FR-M6-08):增删改、证书扫描件(PDF/JPG/PNG,企业级密钥加密、签名下载)、 late_for 按进行中项目的投标截止日提醒、审计;前端资质库页和对话框,侧栏入口 - 资质匹配(FR-M3-05):证书类别词表(16 类,产品证书、人员证书不进匹配), QUAL.EXPIRED / LEVEL_LOW / NOT_COVERED;投标文字层按清单项定级,只有资质库记录的降一级, 出处显示「依据:资质库记录」(查标页、报告模板 v2);一类证书一个问题;评分项不逐条找响应的也查 - 响应错位规则不再把资质表的证书名称格当成照抄的要求 - 评测:qual_defects.py 派生资质情况表,D12 3/3、D18 2/2、规矩的资质表 0 误报;开发集不退化 - 决策 QL1–QL7;方案和落地记录 docs/architecture/qualification-plan.md,评测 check-eval.md §13 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
19 KiB
资质库和资质匹配实现方案 v0.1(2026-11-04)
范围:查标实现计划(
m3-plan.md)第 4 步,即 FR-M6-08 最小资质库 + FR-M3-05 资质匹配检查。 依据:03-functional-requirements.md、05-it-integration-domain.mdR07 / R08、决策 G4 / C10 / DM4、data-model.md(qualificationqualification_file)、openapi.yaml(/qualifications)、原型qualifications.html和results.html的 f6、评测规范evals/check/GUIDELINES.mdD11 / D12 / D14 / D15。 状态:QL1–QL7 已全部按建议确认(2026-11-04,docs/decisions.md)。
0. 结论速览
- 表、接口、原型都已经有了。基线迁移里已建
qualification和qualification_file两张表;openapi.yaml里已定义 7 个操作;原型资质库页的交互也已定稿。资质库本身是一个普通的增删改模块,工作量主要在前端页面和附件。 - 难点在匹配,不在资质库。从样本看(§1),企业资质在政府采购项目里多数是评分项,不是资格条件;而且大量「证书」要求是产品证书(节能认证、CCC、商用密码)或人员证书,资质库管不了,必须先排除。
- 匹配不调模型:按 IT 集成常见证书建一张类别词表,招标侧的要求、投标文字层、资质库三方都映射到类别再比较。认不出类别的,不做判断,写进检查覆盖范围。
- 证据有两个来源,可信度不同:投标文字层(比如投标文件里的「资质情况表」)上读到的有效期和等级,有原文出处,按清单项定级;只有资质库记录、投标文件那边是扫描件或没写日期时,降一级,说明里写明「按资质库记录」。
- 资质库是空的就不做资质库核对,只在覆盖范围里写一句。不能因为用户没录,就报一片「未覆盖」。
1. 样本里的资质要求长什么样
在 S01–S10 读标结果里筛出和证书有关的清单项(evals/out/runs/fix3),分成四种:
| 种类 | 例子 | 清单类别 | 资质库能不能管 |
|---|---|---|---|
| 企业资质(资格条件) | 电子与智能化工程专业承包资质、《安全生产许可证》(S01) | 资格条件 + 无效 | 能,致命 |
| 企业资质(评分项) | ISO 27001 / 9001 / 20000(S09)、CCRC 信息安全服务资质一级、CCIA 一级(S01) | 评分 | 能,重要 |
| 软件著作权(评分项) | 「虚拟化云平台软件计算机软件著作权登记证书(1 分)」、「软件著作权证书(3 分)」 | 评分 | 部分:软著长期有效、没有等级,只能看有没有 |
| 产品证书 | 节能产品认证、CCC、商用密码产品认证、IPv6 Ready、网络安全专用产品检测证书 | 技术参数 / 无效 | 不能:证书是厂商的、跟着产品走 |
| 人员证书 | 「虚拟化维护人员具有虚拟化认证证书」 | 技术参数 | 不能:人员库是 V1 |
结论:
- 政府采购项目不能把和项目无关的资质设为资格条件,所以企业资质出现在资格条件里的少(10 份里只有 S01),多数在评分项里。这样一来,资质问题大多是「重要」,不是「致命」。
- 产品证书和人员证书必须先排除,否则资质库会对它们报「未覆盖」,造成大量误报。
- 真实投标文件里的证书基本都是盖章扫描件。不少 IT 投标文件另附一张文字的「企业资质情况表」,列出证书名称、编号和有效期,这是投标文字层上唯一能读到有效期的地方。
2. 资质库(FR-M6-08)
2.1 数据
用基线里已有的两张表,不加列、不加迁移:
qualification:名称、类型(资质证书 / 体系认证 / 软件著作权 / 其他)、等级、证书编号、发证机构、有效期起止(「有效期至」为空表示长期有效)。qualification_file:附件。对象键t/<tenant>/q/<qualification>/<file>,用企业级数据密钥加密(DM4)。
证书类别(§3.1)在用到时从名称和类型算出来,不存库。词表改了以后,旧记录不用迁移。
2.2 接口
按 openapi.yaml 现有的 7 个操作实现:列表(可按类型筛)、新增、修改、删除(连同附件)、挂附件(走现有的分片上传,purpose = qualification_file)、附件下载地址、删除附件。只加两处:
Qualification响应加一个字段late_for:进行中的项目里,投标截止日晚于这张证书「有效期至」的项目(项目编号、名称、截止日)。原型里的「N 张证书会在进行中项目的投标截止前到期」提醒就靠这个字段。「进行中」指状态是跟进中、编制中、已检查,且截止日不早于今天。- 列表接口加关键词参数
q,按名称、编号、发证机构搜索。
权限点用已有的 qualification.edit。增删改和附件操作都写审计:qualification.create / update / delete、qualification_file.attach / delete,修改记录前后的值。不扣额度。
2.3 校验
- 名称必填;「有效期至」必须晚于「有效期起」。
- 证书编号、「有效期至」:原型要求必填(长期有效的打开开关),界面按原型必填,接口保持可空,因为以后从投标文件批量导入时不一定读得全。
- 附件:PDF / JPG / PNG,单个不超过 20 MB,一条资质可以挂多个附件。
2.4 删除
删除是硬删:同时删行、删对象、写审计。原型在确认框之外还有「撤销」提示,这一步不做撤销(QL6):要撤销就得软删除,而软删除和「彻底删除」(G10)冲突;确认框已经够了。已导出的报告不受影响,因为报告里存的是生成时的快照。
企业注销时按 data-model.md §6.1 的顺序删资质库,企业级密钥一并销毁。
2.5 前端
照原型 qualifications.html 实现:侧栏「资质库」(图标 award)、类型分段筛选、关键词搜索、按「有效期至」排序(长期有效的排最后)、到期提醒条、新增 / 编辑对话框(日期选择器上标出进行中项目的截止日)、附件上传和预览、删除确认。页面底部注明「业绩、人员、历史标书等资产库在 V1 提供」。
3. 资质匹配(FR-M3-05)
3.1 证书类别词表
check/qualification.py 里放一张词表,规则集版本跟着升(2026.11-r4)。每个类别包括:别名(含国标等同写法)、等级写法,以及等级怎么比(数字越大越高,还是「一级」最高)。初版覆盖 IT 集成常见的企业资质:
| 类别 | 别名例子 | 等级 |
|---|---|---|
| ISO 9001 质量 | GB/T 19001 | 无 |
| ISO 14001 环境 | GB/T 24001 | 无 |
| ISO 45001 职业健康安全 | OHSAS 18001、GB/T 45001、GB/T 28001 | 无 |
| ISO 27001 信息安全 | GB/T 22080 | 无 |
| ISO 20000 IT 服务 | GB/T 24405 | 无 |
| ISO 22301 业务连续性 | GB/T 30146 | 无 |
| CMMI | 能力成熟度模型集成 | 1–5,大为高 |
| 信息系统建设和服务能力 | CS、CS1–CS5 | 1–5,大为高 |
| ITSS 运维 | 信息技术服务标准、运行维护 | 一级最高 |
| CCRC 信息安全服务资质 | 中国网络安全审查技术与认证中心;子类:安全集成、风险评估、应急处理、软件安全开发等 | 一级最高 |
| CCIA 信息系统业务安全服务资质 | 中国网络安全产业联盟 | 一级最高 |
| 电子与智能化工程专业承包 | 建筑业企业资质 | 一级 > 二级 |
| 建筑智能化系统设计专项 | 工程设计资质 | 甲 > 乙 |
| 涉密信息系统集成 | 涉密资质 | 甲 > 乙 |
| 安全生产许可证 | 无 | |
| 软件著作权 | 计算机软件著作权登记证书、软著 | 无,长期有效 |
排除词:要求里出现「产品」「设备」「所投」「厂商」「制造商」「节能」「环境标志」「CCC」「3C」「商用密码产品」「人员」「工程师」「项目经理」这类主体时,判定为产品证书或人员证书,不进资质匹配,仍按现在的流程处理(找响应、扫描件兜底)。
认不出类别、但清单类别是资格条件或评分项、文字里又有「证书 / 资质 / 认证」字样的,计入覆盖范围:「N 条资质要求没认出是哪类证书,有效期和等级没有核对」。
3.2 三方怎么对上
对每条进入资质匹配的清单项(类别是资格条件或评分项,且认出了证书类别):
- 招标侧:类别、要求的等级(「CS3 级及以上」「一级」)、子类(CCRC 的「安全集成」)。要求原文就是招标侧出处。
- 投标文字层:在响应匹配找到的证据句附近,以及投标文件里写着同一类别的表格行中,读证书编号、等级、有效期(「有效期至」「有效期:A 至 B」「截止日期」)。日期解析复用
rules.py里的写法。只取和这个类别同一行、或同一段落里只有这一张证书的日期;附近出现两张以上证书、日期归属不清时不读。 - 资质库:同一类别的记录。同类有几条(旧证书和换发后的新证书)时取最有利的一条:有效期最晚、等级最高。
有效期比较用项目基本信息里的投标截止日(人工改过的为准),不用今天。「有效期至」当天仍算有效,即 有效期至 < 截止日 才算过期。项目没有截止日时,不比有效期,写进覆盖范围。
3.3 规则和定级
「按清单项定级」:资格条件 → 致命,评分项 → 重要(沿用 findings.severity)。
| 规则 | 什么时候报 | 证据来源 | 级别 |
|---|---|---|---|
QUAL.EXPIRED |
证书在投标截止日已过期 | 投标文字层 | 按清单项 |
| 只有资质库 | 降一级(致命 → 重要,重要不变) | ||
QUAL.LEVEL_LOW |
等级能比较,且低于要求 | 投标文字层 | 按清单项 |
| 只有资质库 | 降一级 | ||
QUAL.NOT_COVERED |
投标文字层没找到(结论是「未找到」或「扫描件」),而且资质库有记录但没有这一类 | 资质库 | 重要(不给致命:资质库可能没录全) |
| (不报问题) | 资质库里有、而且有效、等级够 | 扫描件兜底那条「请人工核对」保留,说明里补一句:资质库里有《X》(编号…,有效期至…),请核对扫描件里附的是这一张 |
规定:
- 投标文字层和资质库冲突时,以投标文件为准。投标文件里的日期已过期、资质库里有换发后的新证书时,仍按投标文字层报
QUAL.EXPIRED,说明里写「资质库里有有效期至 … 的新证书,投标文件附的可能是旧证书」。评审看的是投标文件。 - 一条清单项只出一个资质问题。资质问题比扫描件兜底的「请人工核对」更具体,有资质问题时代替那一条;投标文件是文字版且确实没找到(「未找到响应」,致命)时,保留原问题,只在说明里补资质库的情况(「资质库里有这张证书,可能忘了附」)。
- 软件著作权不查有效期和等级,只在扫描件兜底说明里补「资质库里有 N 件软件著作权」。要求里写了具体软件名的,也不按名称硬配:软件名的写法太散。
- CCRC 子类:要求写了子类(安全集成),资质库记录的名称里没有这个子类,按
QUAL.NOT_COVERED报,说明写「资质库里的 CCRC 证书没写服务类别,请核对是不是『安全集成』」,级别是提示。 - 资质库是空的:所有资质库规则都不跑,覆盖范围写「资质库还没有录入资质,有效期和等级没有按资质库核对」。查标页在覆盖范围旁边放一个去资质库的链接。
- 说明只写事实,不写整改建议。原型 f6 里「请上传换发后的证书」这一句去掉,改成「按资质库记录,有效期至 2026年11月15日,早于投标截止日 11月20日」。
3.4 问题的存法和出处
finding.type = qualification,detector = rule,rule_code是上面的编号,checklist_item_id填对应清单项,match_key = rule:QUAL.EXPIRED:<清单项>,复查沿用按现有机制走。detail里存:kind(过期 / 等级不足 / 未覆盖)、source(bid_text/library)、截止日、要求的等级,以及用到的资质库记录的快照(编号、名称、等级、有效期、记录 id)。资质库记录以后改了、删了,旧检查的问题和报告不变。- 出处:招标侧照常挂清单项的原文出处;投标文字层来源的挂投标侧句子;资质库来源的没有投标侧出处,界面和报告显示「依据:资质库记录」块(名称、编号、有效期,能点开那条记录和附件)。这一点要你确认(QL2)。
- 覆盖范围加一节「资质核对」:资质库有几条、本次核对了几条资质要求、几条按资质库判断、几条没认出类别、产品证书和人员证书各排除了几条。
3.5 在流水线里的位置
放在 runner.py 的响应匹配和扫描件兜底之后、rules.run 之前,读一次本企业的资质库,不调模型、不计费。复查时重新算:资质库可能改过,结果不复用。
4. 不在这一步做的
| 不做 | 原因 |
|---|---|
| D14 证书主体和投标人不一致(子公司、曾用名) | 不在 FR-M3-05 的三种预警里;证书主体只在扫描件上;资质库挂在企业主体下,主体本来就一致。等 OCR(S5)后再看 |
| D15 业绩 / 人员证明的时间窗口 | 业绩库、人员库是 V1 |
| 产品证书核对 | 厂商的证书,不是用户的资质(红线 5:不从外部补数据) |
| 从投标文件或附件里自动识别、批量导入资质 | 要 OCR / 多模态;MVP 只手工录入(01-scope-roles:「手工录入 + 有效期」) |
| 读标清单上显示「资质库:ISO 9001 有效期至 …」 | 并入第 6 步前端补齐 |
| 软著按软件名称配对、按件数核对评分 | 写法太散,认不准的不报 |
5. 评测
- 类别识别:把 S01–S10 读标结果里和证书有关的清单项全部人工标注(企业资质 / 软著 / 产品证书 / 人员证书 / 无关,再加类别和等级),约几十条,作为词表的单元测试。读标留出集的 S03、S06、S09 不在开发里看,词表写完后跑一次,只用来报数字。
- 规则:每条规则配正例和反例单元测试:截止日当天到期不报;同类有新证书也有旧证书取新的;等级写法认不出时不比较;产品证书不进匹配;资质库空不报。
- 评测集:生成器现在不生成证书文字。给风格 A / B 的规矩投标文件加一张「企业资质情况表」(虚构的证书、编号、有效期),注入 D12(有效期早于截止日;整张表的证书都过期)和「等级不足」两类问题,按 GUIDELINES 的流程请 Fable 复核、你抽查。资质库那一侧在评测里用虚构的资质库模拟,分「空 / 全 / 缺一类 / 有过期」四档。
- 局限:评测集里的证书表是看着词表生成的,分数说明不了泛化。国动的真实投标文件到了以后,请你按自己公司的真实证书录资质库,再跑一次,这才是这一步真正的检验。
6. 工作量和顺序
- 后端
qualification模块:增删改、附件、late_for、审计,集成测试(含行级安全、企业级密钥)。约半天。 - 前端资质库页。约半天。
- 类别词表、标注样本、
check/qualification.py、接入流水线、覆盖范围、问题渲染和报告。约 1 天。 - 评测集加证书表和注入,复核。约半天。
7. 待确认事项
| 编号 | 事项 | 建议 |
|---|---|---|
| QL1 | 匹配方式 | 规则 + 证书类别词表,不调模型。认不出的不判断、写进覆盖范围。理由:资质名称是有限集合,规则可解释,不花钱 |
| QL2 | 只有资质库记录、没有投标侧出处时能不能出问题 | 能出,降一级,出处显示「依据:资质库记录」。资质库是用户自己录的数据,不是 AI 结论,和红线 2「AI 结论要能回溯原文」不冲突;如果不出,扫描件为主的真实投标文件就基本查不出过期 |
| QL3 | 「未覆盖」怎么报 | 资质库有记录但没有这一类时报「重要」;资质库是空的不报,只写覆盖范围 |
| QL4 | 投标文件和资质库冲突时 | 以投标文件为准,说明里提一句资质库里有新证书 |
| QL5 | 免费版能不能用资质库 | 能用。01-scope-roles 把资质库写在专业版下,但它不花额度、没有成本;免费版只有 1 个项目,用来试用完整的查标链路,缺了资质库体验就不完整 |
| QL6 | 删除要不要撤销 | 不要,只留确认框;撤销需要软删除,和「彻底删除」冲突 |
| QL7 | D14(主体不一致)、D15(时间窗口) | 不在这一步做,评测规范里这两类的实现阶段改为「OCR 之后 / V1」 |
8. 落地记录(2026-11-04)
和上文设计不一致、或实现时补的,记在这里:
- 一类证书一个问题(改 §3.3「一条清单项只出一个资质问题」):一条评分项常写几类证书(S07「ITSS 三级得 1 分;CS3 及以上得 2 分」),一张过期、一张等级不够是两件事,合成一条时规则编号只能取一个。改为每条清单项里每类证书出一个问题,标题写证书名(「证书等级低于要求:信息系统建设和服务能力等级」),
match_key = rule:QUAL.*:<清单项>:<证书类别>。 - 评分项不逐条找响应的也查:applicability 把没写「提供……证书」的评分项跳过了(「评分标准本身」),而企业资质多数就在评分项里。资质匹配改为看所投包里的全部清单项;这类条目没有响应结论,投标文字层和资质库的过期、等级照常提示,「未覆盖」不报(不知道投标人报不报这一项分)。
- 等级按证书各读各的:要求里属于这一类证书的那一段(从它的名称到下一类证书的名称)里读等级;投标侧先看短的格子(等级栏),证书编号里常带等级字样(「CS3-3201-…」);大写数字(「贰级」)也认。
- 响应错位规则收窄(
check/deviation.py):资质情况表的名称格(「安全生产许可证」,比要求短、以证书名结尾)不算「照抄的要求格」,右边的编号、有效期不算「响应对不上」。端到端测试里发现的。 - 营业执照、法人证书、联合体的资质认定规则不算「没认出类别的资质要求」,不进覆盖范围的计数。
- 出处:资质问题挂清单项自己的招标侧出处(
Hit.tender_refs);问题接口的rule改为规则问题都带(原来挂了清单项就不带);报告模板 v2 在问题明细里写「依据:资质库记录《…》」。 - 前端:资质库页和对话框(日期可直接键入,接受 2026/11/20、2026年11月20日等写法;日历弹层留到第 6 步);查标页资质问题显示「依据:资质库记录」块,墨色(用户录入的数据,不用 AI 出处的蓝铅笔色)。
- 评测见
check-eval.md§13。