feat(check): 规则检查(报价形式、形式要件、响应表),表格按单元格分行

- check/rules.py(规则集 2026.11-r1,不调模型):大小写金额、分项合计、超最高限价、
  多个报价、别的项目名称、没填的地方、落款日期、投标有效期、附加条件、响应表里的未响应;
  每条挂投标原文,有依据的挂招标侧出处;缺限价、截止时间、有效期要求时写进覆盖范围
- 文字层的句子带上单元格框,表格按单元格上沿分行
- 按 Fable 审读意见收紧致命级:认不准的降为重要或提示
- 评测:score.py 评规则问题;P07 注入记录改为空白处前后原文,剔除注入到人员表的 D10
- 上传页的检查范围文案同步

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
YANG JIANKUAN
2026-11-04 16:44:22 +08:00
parent 47c6a1258e
commit db1b1f6f9f
17 changed files with 1792 additions and 20 deletions

View File

@@ -30,6 +30,10 @@ def main() -> None:
traps: Counter[str] = Counter()
tokens = [0, 0]
findings_clean = items_clean = 0
r_found: Counter[str] = Counter()
r_total: Counter[str] = Counter()
r_fp: Counter[str] = Counter()
r_fp_clean = r_clean = 0
for bid in a.bids:
d = OUT / bid
m = json.loads((d / "manifest.json").read_text())
@@ -43,6 +47,13 @@ def main() -> None:
if "查标" in s["recall"]:
by_style[m["style"]] += s["recall"]["查标"][0]
by_style_tot[m["style"]] += s["recall"]["查标"][1]
rules = s.get("rules") or {}
r_found.update(rules.get("found") or {})
r_total.update(rules.get("total") or {})
r_fp.update(rules.get("fp_by_code") or {})
if m["kind"] == "clean":
r_fp_clean += rules.get("fp", 0)
r_clean += 1
if m["kind"] == "clean":
fp += s["fp"]
ok += s["ok_units"]
@@ -68,6 +79,15 @@ def main() -> None:
f"- 规矩的投标文件里,不需要响应(na / unknown)的要求上报了问题 {other} 个,对不上标注单元的问题 {unmapped} 个",
f"- 干扰项误报:{dict(traps)}",
f"- token:输入 {tokens[0]:,},输出 {tokens[1]:,}({len(a.bids)} 次检查)",
"",
f"## 规则问题:查出 {pct(sum(r_found.values()), sum(r_total.values()))};误报 {sum(r_fp.values())} 个"
f"(其中规矩的投标文件 {r_clean} 份上 {r_fp_clean} 个)",
"",
"| 问题 | 查出 |",
"|---|---|",
*[f"| {k} | {pct(r_found[k], r_total[k])} |" for k in sorted(r_total)],
"",
f"- 误报按规则:{dict(r_fp)}",
]
print("\n".join(lines))