Files
bid-doctor/docs/architecture/check-eval.md
YANG JIANKUAN cb0c2fcafe feat(check): 响应方式识别(C12)和「这条要不要投标人回答」;评测集纠错
- checklist/response_mode.py:按类别(技术 / 商务)识别招标文件的响应方式(逐条响应 / 默认接受),规则优先;
  两种写法冲突按逐条,认不出按逐条并写进覆盖范围。
- check/applicability.py:无效情形(★ / 斜体下划线标注的条款除外)、日期与递交、没要求附材料的评分标准、
  无需提供证明或由采购人查询的资格,不逐条找响应,写进覆盖范围;要求附证明材料按原文判断,中标后才交的不算。
- 默认接受的要求没找到响应:一般要求记 implicit_accepted、不出问题;实质性要求记 implicit_review、提示级
  人工核对;要附证明材料的不免(迁移 0006)。
- match.py:修同一行单元格又是别的条目候选句时的 KeyError(每条清单项单独记候选句,句子从总表里查)。
- 评测集:注入器同一要求的所有表格行一起改;散文、附件、格式文件里也响应了的要求不挂漏响应类问题;
  错位响应必须是另一个参数;复核判不成立的单元不再挂;regen.py 按固定种子重新生成。

开发集 17 份:规矩投标文件报出的问题 639 → 229,误报 21.3 → 12.4 / 100,召回 68% → 65%,致命级 20 → 21 / 32
(docs/architecture/check-eval.md §4)。

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-04 14:25:14 +08:00

137 lines
15 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.

# 查标评测(2026-11-04 起)
> 评测集规范:`evals/check/GUIDELINES.md`;工具:`evals/check/`;数据和输出在 `evals/out/check/`(不进 git)。
> **读数的前提**:金标准由 Fable 复核、用户抽查 20%(决策 E1),未经全部人工复核;本文的数字都是**开发集**上的,只用于找问题、调实现,不能当效果证据。头条效果以留出集(风格 C)和真实国动投标文件为准,第 3 步冻结代码后才跑。
## 1. 试跑(第 0 步,2026-11-04)
**范围**:开发集 S02、S04、S10 各两份投标文件(规矩 + 马虎),都是风格 A(风格 B 的改写还没做)。查标代码是第 1 步的版本:响应匹配只有「检索 + 模型判断」,规则检查还没有。模型 DeepSeek Flash,提示词 `check.match` v1。
**复核**:马虎的投标文件共注入 82 个要求项问题,Fable 复核通过 70 个、不通过 12 个(S02 10 个:默认接受的文件里注入了漏响应、「暂不支持」套在尺寸和费用这类参数上、要求本身是可选项等)。下面只算通过的。用户抽查 17 条(随机 20%,含 Fable 判不通过的 4 条),**全部同意**(2026-11-04)。
### 1.1 结果
| 投标文件 | 清单条数 | 报出问题 | 查标召回 | 致命级召回 | 规矩响应的要求上误报 | 不需要响应的条目上报了问题 |
|---|---|---|---|---|---|---|
| S02 规矩 | 248 | 104 | — | — | 21 / 56 | 39 |
| S02 马虎 | 248 | 117 | 8 / 16(50%) | 2 / 7 | | |
| S04 规矩 | 264 | 90 | — | — | 11 / 111 | 52 |
| S04 马虎 | 264 | 110 | 11 / 28(39%) | 1 / 4 | | |
| S10 规矩 | 305 | 122 | — | — | 6 / 39 | 75 |
| S10 马虎 | 305 | 142 | 5 / 20(25%) | — | | |
- 合计查标召回 24 / 64(38%)。只检索不调模型的基线召回 0:基线把检索到的第一句都当作已响应,说明现在查出的问题来自模型判断,不是检索。
- 按问题类型:漏响应(D01)9 / 14 较好;写明不支持(D05)5 / 20、负偏离未说明(D06)0 / 7、响应对象错位(D09)0 / 4 很差。
- 每次检查调用模型 31~39 次,输入约 9~11.5 万 token、输出约 1.5~1.7 万 token(约一两毛钱)。
### 1.2 问题出在哪里
1. **不需要投标人响应的条目也被报了「未找到响应」**:三份规矩的投标文件报了 316 个问题,166 个落在根本不需要响应的条目上(无效情形的列举、日期、采购人义务、别的采购包),这是误报的大头。→ C12 的响应方式抽取,加上「这条要不要投标人回答」的判断和按所投采购包过滤(第 2、3 步)。
2. **表格里的「暂不支持」「负偏离」看不见**:表格按单元格切句,检索命中的是投标人照抄要求原文的那一格,同一行里写着「暂不支持」「负偏离」的格子不在模型的输入里。→ 第 3 步把整行交给模型(偏离表直取也是这个思路)。
3. **证明材料和格式文件找不到**:规矩响应的要求上的误报,主要是证明材料(扫描件页没有文字层)和格式文件(声明函、承诺书)报了「未找到响应」,以及让投标人「见附件」的要求被报成「未给出具体值」。→ C10 扫描件兜底;文件要在(presence)的要求按文件在不在判断,不逐条找响应。
4. **级别口径**:S02 的 ★ 是「核心技术参数,负偏离扣分」,不是投标无效条款;标注集记成实质性条款,查标按致命报和真实评审不一致。→ 级别要跟着招标文件对 ★ 的定义走(读标口径 Q2 已有,查标沿用)。
### 1.3 评测集自身的问题(已修 / 待修)
| 问题 | 状态 |
|---|---|
| 分项报价平均摊,一项超过单价上限,规矩的投标文件自带致命问题(S10) | 已修:按分项上限比例分摊 |
| 偏离表有「设备名称」列,按固定列写会错位(S04) | 已修:按表头决定列 |
| 写死的落款日期晚于投标截止日(S04) | 已修:取截止日前 3 天 |
| 同一参数列在两张表里,只删一张表的行不算漏响应(S04) | 已修:漏响应在所有表里都删 |
| 符合性条件响应表的一格被算成 11 个问题 | 已修:按表级问题记一个 |
| 标注集同一要求有两个单元(两个类别、或表格一行拆成几条),一个问题算两次 | 已修:评分按句子重叠合并 |
| 「暂不支持」套在尺寸、费用、打印方式这类参数上,不像真实写法 | 待修:按参数类型选注入方式 |
| 默认接受的文件里注入漏响应(S02 另加了一张逐条的技术规格表,脚本推响应方式时被它带偏) | 待修:响应方式以档案的 modes 为准,不从表格推 |
| 「提供某文件」类要求被当成参数注入偏离 | 待修:推响应方式时识别 presence |
| 风格 B 的改写(截断、同义替换、只写值)还没做;所有数字都是风格 A 的 | 待做 |
## 2. 开发集第一版(2026-11-04)
**范围**:开发集 7 份招标文件各两份投标文件,共 14 份:S02、S05、S08、S10 是 A 规矩 + B 马虎,S01、S04、S07 是 B 规矩 + A 马虎(GUIDELINES §4)。生成器修了试跑的待修项(「暂不支持」不再套在数值参数上、表格响应方式以档案为准、「提供……文件」不注入参数类问题),风格 B 由模型改写、数字对不上的改写丢弃。查标代码仍是第 1 步的版本。
**复核**:注入的要求项问题两批共 222 个,Fable 复核通过 188 个。第二批 140 个里不通过 22 个,其中 14 个在 S07:S07 须知要求逐条标明,格式注又写未列入视作接受,且只有 ★ 项写明未响应无效,非 ★ 参数删一行算不算问题拿不准,金标准从严不算(查标侧仍按 C12 取更严的逐条)。用户抽查第一批 17 条全部同意;第二批抽查 28 条(含 Fable 判不通过的 4 条)也**全部同意**。两批合计抽查 45 条,和 Fable 的判断一致。
### 2.1 结果
| 指标 | 结果 |
|---|---|
| 查标召回(复核通过的问题) | 51 / 128(40%);风格 A 25 / 70(36%),风格 B 26 / 58(45%) |
| 端到端召回(含读标漏抽) | 51 / 132(39%) |
| 致命级召回 | 18 / 37(49%) |
| 不带标志词 / 带标志词 | 40 / 81(49%)/ 11 / 51(22%) |
| 连续一段 / 单点 | 7 / 12(58%)/ 44 / 120(37%) |
| 规矩的投标文件报出的问题 | 清单 2049 条,报出 699 个 |
| 其中规矩响应的要求上的误报 | 153 / 620(每 100 条 24.7) |
| 其中不需要响应的要求上报的 | 334 个(占 48%) |
| 干扰项误报 | 默认接受的要求没复述(T06)39,改写后的要求(T02)20,响应写在别的分册(T01)3 |
| 费用 | 14 次检查输入 150 万 token、输出 25 万 token |
按问题类型:资格证明缺失(D11)9 / 14、评分材料缺失(D13)9 / 12、漏响应(D01)15 / 23 较好;负偏离未说明(D06)0 / 20、响应对象错位(D09)1 / 14、证明材料缺失(D02)2 / 9、写明不支持(D05)11 / 31 很差。
### 2.2 读法
- **试跑的四个判断都成立,而且更清楚了**:「带标志词」的问题(写明不支持、负偏离)召回只有 22%,比不带的还低,正是表格里同一行的响应格、偏离格不在模型输入里;风格 B 反而比 A 高,因为 A 照抄要求原文,检索更容易命中照抄的那一格。规矩的投标文件上近一半的问题落在不需要响应的要求上,默认接受的要求被报了 39 次。
- **第 2、3 步按这个顺序改收益最大**:① 整行上下文 / 偏离表直取(直接对应 D05、D06、D09,51 个问题里的 45 个);② 响应方式和「这条要不要投标人回答」(C12,对应 334 + 39 个误报);③ 扫描件兜底和 presence 判断(证明材料、格式文件类误报)。
### 2.3 评测集还要改的
| 问题 | 状态 |
|---|---|
| 「暂不支持」「可选配置」仍会套在证书、供货清单、服务义务、文档交付这类非功能要求上(两批共 12 条被复核拒掉) | 待修:注入前按「功能类要求」过滤 |
| 同一要求被两个标注单元挂了同一个问题(实质性 + 技术参数、资格 + 符合性,第二批约 20 对);「第二十二条总述」这类伞状单元和具体条目不重叠 | 待修:注入前按 anchor 重叠合并标注单元;伞状单元不挂问题 |
| 条件性要求(「如依法免税则须提供」)被当作必须提供的材料挂 D11 | 待修:按投标人情况排除 |
| 低密度(每份 5~8 个问题)的投标文件还没做 | 待做:选 3 份 |
## 3. 第一轮改进:整行上下文(2026-11-04)
**改了什么**:候选句在表格里时,把同一行的单元格一起交给模型,也可以引用(`check/match.py`);提示词 `check.match` v2 说明怎么读一行(要求格 / 响应格 / 偏离格)。对应 §2.2 的第 ① 项。v2 的规则写法避开了开发集注入词库里的说法(重合的只有「负偏离」「完全响应」,是招标文件格式自带的用语)。
**评测集同时修了 §2.3 的前三项**(「暂不支持」只套功能类要求、伞状单元和条件性要求不挂问题),7 份马虎的投标文件用原来的种子重新生成,另加 3 份低密度的,共 17 份。新目标 55 个由 Fable 复核(通过 54 个),用户抽查 11 个全部同意(三批合计抽查 56 个,全部同意)。因为注入的问题换了一批(「负偏离未说明」多了、「暂不支持」少了),下表的「旧做法」要和同一批投标文件比,不能和 §2 的数字直接比。
| 指标(17 份,复核通过的问题) | 旧做法(v1、不带整行) | 新做法(v2 + 整行) |
|---|---|---|
| 查标召回 | 43 / 145(30%) | **73 / 145(50%)** |
| 致命级召回 | 9 / 31(29%) | **15 / 31(48%)** |
| 带标志词 | 1 / 65(2%) | **35 / 65(54%)** |
| 负偏离未说明 D06 / 写明不支持 D05 / 数值不满足 D03 | 0 / 58、1 / 7、3 / 7 | 28 / 58、7 / 7、6 / 7 |
| 漏响应 D01 / 响应对象错位 D09 | 18 / 27、3 / 14 | **14 / 27、0 / 14**(变差) |
| 规矩的投标文件报出的问题 | 699 | 639 |
| 规矩响应的要求上的误报 | 153 / 620(24.7 / 100) | 132 / 620(21.3 / 100) |
| 不需要响应的要求上报的问题 | 334 | 329 |
| 输入 / 输出 token | 189 万 / 32 万 | 273 万 / 28 万 |
**读法**:整行上下文解决了「看不见响应格、偏离格」的问题,带标志词的问题从几乎查不出到过半;误报略降。代价是输入 token 多 44%。**两处变差**:漏响应(D01)和响应对象错位(D09)。推测是同一行或相邻行的内容让模型更容易「找到点什么就判已响应」:漏掉的那一行不在了,检索命中的是相邻要求的行;错位的那一行响应格写的是另一条参数,模型没比对参数名。下一轮在提示词里要求先核对响应格说的是不是同一个参数 / 设备,并单独看 D01、D09 的漏报明细。不需要响应的要求上的误报(329)没有变化,要靠第 ② 项(C12)。
## 4. 第二轮:评测集纠错 + 响应方式和「要不要回答」(2026-11-04)
**评测集纠错**:§3 里漏响应、响应对象错位「变差」,逐条看漏报后发现多数是**生成器的错**,不是查标的错:读标清单有重复条目、S04 同一参数列在两张表里、技术方案散文也复述了要求,注入器只改了其中一处,别处还留着正确的响应,模型找到它是对的。改为同一要求的所有表格行一起改;在散文、附件、格式文件里也响应了的要求不挂漏响应 / 数值不满足 / 错位;错位响应必须是另一个参数的。马虎的投标文件按原种子重新生成,新目标 45 个由 Fable 复核(通过 40 个),用户抽查 9 个全部同意(四批合计抽查 65 个,全部同意)。
**查标改了什么**(第 2 步的 C12 部分):
- `checklist/response_mode.py`:按类别(技术 / 商务)识别招标文件的响应方式,规则优先;冲突按逐条,认不出按逐条并标明。开发集 7 份的识别结果和档案一致。(还没存进清单、没做清单页的显示和修改。)
- `check/applicability.py`:不需要投标人回答的条目不逐条找响应,写进覆盖范围(无效情形 —— 但 ★ / 斜体下划线标注的条款照常找、日期与递交、没要求附材料的评分标准、无需提供证明或由采购人查询的资格)。要求附证明材料按原文判断(读标的 evidence_required 常常是空的),中标后才交的不算。
- 默认接受的要求没找到响应:一般要求记「按招标文件默认接受」、不出问题;实质性要求出提示级「请人工核对」;要附证明材料的不免(迁移 0006 加了两种结论)。
| 指标(17 份,复核通过的问题) | v1 | v2 + 整行 | + 响应方式和「要不要回答」 |
|---|---|---|---|
| 查标召回 | 48 / 150(32%) | 102 / 150(68%) | 97 / 150(65%) |
| 致命级召回 | 9 / 32 | 20 / 32 | **21 / 32** |
| 规矩的投标文件报出的问题 | 699 | 639 | **229** |
| 规矩响应的要求上的误报 | 24.7 / 100 | 21.3 / 100 | **12.4 / 100** |
| 不需要响应的要求上报的问题 | 334 | 329 | **77** |
| 默认接受的要求被报(T06) | 39 | 35 | **1** |
| 输入 token | 189 万 | 273 万 | 224 万 |
按问题类型(最后一列):漏响应 19 / 24、写明不支持 13 / 14、数值不满足 4 / 4、负偏离未说明 39 / 59、评分材料缺失 9 / 14、错位 6 / 13;**证明材料缺失 1 / 17**。
**读法**:规矩的投标文件上的问题少了三分之二,召回只掉了 3 个点(掉的主要是只在默认接受的文件里、被正确判为「默认接受」的条目,以及证明材料)。证明材料缺失几乎查不出:资格证明、检测报告多是扫描件页,没有文字层,规矩的投标文件上同样报「未找到」——这是下一项(C10 扫描件兜底 + 文件要在的判断)。
**一处要说明的**:调响应方式识别时,打印结果里顺带出现了留出集 S03、S06、S09(招标文件本身,不是投标文件)的识别结果,其中 S03、S09 和规范 §2 的记录不一致。没有据此改任何规则,留到留出集正式评测时再看。
## 5. 下一步
1. 证明材料和格式文件:扫描件兜底(C10)、文件要在(presence)按文件在不在判断。
2. 响应方式存进清单、清单页显示并可改(C12 的人工确认点)。
3. 第 2 步(投标侧结构识别、规则、C12 响应方式抽取)和第 3 步(整行上下文、偏离表直取、presence 判断)按 §2.2 的顺序改,每改一轮在开发集 14 份上重跑对比。
3. 留出集(S03、S06、S09,风格 B + C,封存的词库)和真实国动投标文件,在第 3 步冻结代码后只跑一次。