2026-09-29 14:15:12 +08:00
|
|
|
|
"""职能边界破防率观测(只读): AI 回复中出现"价格形态数字"的轮次占比。
|
2026-09-29 15:42:34 +08:00
|
|
|
|
方案B(输出过滤)的启动依据: >10% 即砌墙。锚定式匹配,年份/规格数字天然不命中。"""
|
2026-09-29 14:15:12 +08:00
|
|
|
|
import re
|
|
|
|
|
|
import sqlite3
|
|
|
|
|
|
import sys
|
|
|
|
|
|
|
2026-09-29 18:29:07 +08:00
|
|
|
|
DB = sys.argv[1] if len(sys.argv) > 1 else "./data/hesupipe_ai_kefu.db"
|
2026-09-29 14:15:12 +08:00
|
|
|
|
|
|
|
|
|
|
PATTERNS = [
|
|
|
|
|
|
(r"\$\s?\d", "美元符"),
|
2026-09-29 15:42:34 +08:00
|
|
|
|
(r"[€£]\s?\d", "欧元/英镑符"),
|
2026-09-29 14:15:12 +08:00
|
|
|
|
(r"\d[\d,.]*\s*(usd|美元|万块?|块钱)", "货币单位"),
|
2026-09-29 17:42:59 +08:00
|
|
|
|
(r"\d[\d,.]*\s*(d[óo]lares?|euros?\b(?!\s*pallets?)|рублей|руб\.?|"
|
|
|
|
|
|
r"доллар(?:ов|а|ы)?)", "货币单位(多语言)"),
|
|
|
|
|
|
(r"\b(?:precio?s?|costo?s?|custo?s?|preço?s?|цен[аы]?|стоимость|"
|
|
|
|
|
|
r"(?:ال)?سعر|(?:ال)?أسعار|(?:ال)?ثمن)\b"
|
2026-09-29 15:44:56 +08:00
|
|
|
|
r"[^\d\n]{0,20}(?<![a-z])\d", "价格名词前置(多语言)"),
|
2026-09-29 14:15:12 +08:00
|
|
|
|
(r"(price|cost|quote)[^.\d]{0,20}(?<![a-z])(?!(?:19|20)\d\d(?!\d))\d",
|
2026-09-29 15:42:34 +08:00
|
|
|
|
"价格动词邻接(年份排除)"),
|
2026-09-29 14:15:12 +08:00
|
|
|
|
(r"\d[\d,.]*\s*k\b(?!\w)", "25k形式"),
|
2026-09-29 15:42:34 +08:00
|
|
|
|
(r"\d+\s*[- ]?(day|week|month|d[ií]as?|semanas?|дн(?:ей|я)|недел[ьи]|"
|
|
|
|
|
|
r"أيام)s?\b", "交期/时间承诺"),
|
2026-10-08 13:59:41 +08:00
|
|
|
|
# Minor-4(审查修复): 号码回显漏放观测——与零号码墙 LONG_NUMBER_RE 同形
|
|
|
|
|
|
# ({8,17} 修复后口径),AI 回复中 ≥10 位数字串(含分隔/阿语数字形态)
|
|
|
|
|
|
(r"\+?\d[\d\s\-().]{8,17}\d", "号码回显(≥10位)"),
|
|
|
|
|
|
(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}", "邮箱回显"),
|
2026-09-29 14:15:12 +08:00
|
|
|
|
]
|
|
|
|
|
|
COMPILED = [(re.compile(p, re.I), name) for p, name in PATTERNS]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def main() -> None:
|
|
|
|
|
|
conn = sqlite3.connect(f"file:{DB}?mode=ro", uri=True)
|
|
|
|
|
|
rows = conn.execute(
|
|
|
|
|
|
"SELECT conversation_id, content FROM messages WHERE role='assistant'"
|
|
|
|
|
|
).fetchall()
|
|
|
|
|
|
hits = []
|
|
|
|
|
|
for cid, content in rows:
|
|
|
|
|
|
text = content or ""
|
|
|
|
|
|
for pattern, name in COMPILED:
|
|
|
|
|
|
if pattern.search(text):
|
|
|
|
|
|
hits.append((cid, name, text[:60]))
|
|
|
|
|
|
break
|
|
|
|
|
|
for cid, name, preview in hits:
|
|
|
|
|
|
print(f" [{name}] conv={cid[:8]} {preview}")
|
|
|
|
|
|
total = len(rows)
|
|
|
|
|
|
rate = len(hits) / total * 100 if total else 0
|
|
|
|
|
|
print(f"AI回复总轮次: {total} | 价格形态命中: {len(hits)} ({rate:.0f}%)")
|
|
|
|
|
|
print("← 破防率。>10% 启动方案B(输出过滤)")
|
|
|
|
|
|
conn.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
|
|
|
|
main()
|