# -*- coding: utf-8 -*- """四份交付文档 · 跨文档一致性自检。仅读取,不改文件。""" import re from pathlib import Path D = Path(r"D:\桌面\金融\客服agent") OUT = Path(r"D:\桌面\金融\_consistency.txt") FILES = { "需求": D / "D2.2-客服Agent需求文档.html", "计划": D / "D2.3-客服Agent开发计划.html", "Todo": D / "D2.1-客服Agent执行Todolist.md", "知识库": D / "D2.4-客服Agent知识库设计方案.html", } texts = {} lines = [] lines.append("== 一、文件基本情况 ==") for name, p in FILES.items(): if p.exists(): t = p.read_text(encoding="utf-8") texts[name] = t lines.append(f" {name:4s} {p.name} {t.count(chr(10)) + 1} 行 / {len(t)} 字符") else: lines.append(f" [MISSING] {p}") lines.append("") lines.append("== 二、关键事实在各文档中的出现次数(0 = 遗漏)==") FACTS = [ ("功能需求 48 条", r"48 条"), ("FR-CS-048", r"FR-CS-048"), ("非功能需求 21 条", r"21 条"), ("NFR-CS-021", r"NFR-CS-021"), ("51 项", r"51 项"), ("7 批次 / 7 个批次", r"7 个?批次"), ("12 步", r"12 步"), ("6 文件 / 六文件", r"(六文件|6 个?文件)"), ("组 2 四文件", r"组 2|组2"), ("三集合", r"三集合"), ("阈值 0.75", r"0\.75"), ("阈值 0.70", r"0\.70"), ("阈值 0.65", r"0\.65"), ("over-fetch", r"over-fetch"), ("不变量", r"不变量"), ("actor.py", r"actor\.py"), ("knowledge_tier.py", r"knowledge_tier\.py"), ("三条红线", r"三条红线"), ("subject_type", r"subject_type"), ("零 DDL", r"零 ?DDL"), ] hdr = " " + "事实".ljust(26) + "".join(n.center(8) for n in FILES) lines.append(hdr) for label, pat in FACTS: row = " " + label.ljust(26) for name in FILES: t = texts.get(name, "") row += str(len(re.findall(pat, t))).center(8) lines.append(row) lines.append("") lines.append("== 三、投顾残留检查(应全部出现在「已清除/作废」语境)==") for name, t in texts.items(): if name == "知识库": continue hits = [m.start() for m in re.finditer("投顾", t)] bad = [] for h in hits: ctx = t[max(0, h - 60): h + 60].replace("\n", " ") if not re.search(r"已(整体)?清除|作废|不再|已删除|清除后|已移除|已下架|原|投顾模块已", ctx): bad.append(ctx) lines.append(f" {name}: 命中 {len(hits)} 处,其中疑似「仍在依赖」{len(bad)} 处") for b in bad[:5]: lines.append(f" ⚠ …{b}…") lines.append("") lines.append("== 四、HTML 锚点自检(TOC href vs 正文 id)==") for name in ("需求", "计划", "知识库"): t = texts.get(name, "") hrefs = set(re.findall(r'class="toc-item" href="#([^"]+)"', t)) ids = set(re.findall(r'