feat: export core Hermes skills
This commit is contained in:
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
K/L 分工自检 / K-L Column Separation Check
|
||||
==========================================
|
||||
校区梳理表 Step5 终审必跑:验证 K 列(法律风险) 与 L 列(模版差异) 职责分离。
|
||||
|
||||
· K 列(第 11 列)= 独立法律审查,从合同条款本身起笔,**绝不引模版**
|
||||
→ 不得出现 "模版 / 07模版 / 07-房屋 / 07标准 / 相对模版 / 被放宽 / 被删除 / 被改为"
|
||||
· L 列(第 12 列)= 纯客观文本对比,只陈述 "模版表述为X;本合同表述为Y"
|
||||
→ 不得出现 "风险 / 建议 / 不利 / 详见"(判断词与向 K 列导流的话)
|
||||
|
||||
⚠️ K 列匹配 "07模版 / 07-房屋 / 07标准" 而非裸 "07"——裸 07 会误命中金额数字
|
||||
(如租金 377,507.80 里的 "507"),2026-06-24 跃龙路实证误报,已修正。
|
||||
|
||||
判据·遮模版测试:把"模版怎么写"整个遮住,K 列那条风险论述仍完整成立才算独立审查;
|
||||
遮住就垮 = L 列逻辑混进了 K 列。
|
||||
|
||||
用法:
|
||||
python3 kl-separation-check.py <校区梳理表.xlsx>
|
||||
退出码:0 = 通过;1 = 有违规(需回去拆分 K/L);2 = 用法错误
|
||||
|
||||
注:本脚本只查 K(11)/L(12) 两列的数据行。整体段(合并 A:L,在第 1 列)里
|
||||
"【与07标准模版的文本差异】" 小节合法含"模版/07",不在本脚本检查范围——
|
||||
那是整体段按设计单独成段的客观对比,不是 K 列。
|
||||
"""
|
||||
import sys
|
||||
import re
|
||||
import openpyxl
|
||||
|
||||
K_FORBIDDEN_LITERAL = ["模版", "相对模版", "被放宽", "被删除", "被改为"]
|
||||
K_FORBIDDEN_REGEX = r"07模版|07-?房屋|07标准"
|
||||
L_FORBIDDEN_LITERAL = ["风险", "建议", "不利", "详见"]
|
||||
|
||||
|
||||
def cell_text(cell):
|
||||
"""取单元格纯文本,兼容 CellRichText(可迭代) 与标量。"""
|
||||
v = cell.value
|
||||
if v is None:
|
||||
return ""
|
||||
if isinstance(v, str):
|
||||
return v
|
||||
try:
|
||||
return "".join(getattr(t, "text", str(t)) for t in v)
|
||||
except TypeError:
|
||||
return str(v)
|
||||
|
||||
|
||||
def is_header(text):
|
||||
"""表头行启发式:K 表头='法律风险…'/'风险点…';L 表头='与…模版差异'。"""
|
||||
head = text[:10]
|
||||
if ("法律风险" in head or "风险点" in head) and len(text) < 40:
|
||||
return True
|
||||
if text.startswith("与") and "模版差异" in text and len(text) < 40:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def check(path):
|
||||
wb = openpyxl.load_workbook(path)
|
||||
violations = []
|
||||
for ws in wb.worksheets:
|
||||
for r in range(1, ws.max_row + 1):
|
||||
k = cell_text(ws.cell(r, 11))
|
||||
l = cell_text(ws.cell(r, 12))
|
||||
if k and not is_header(k):
|
||||
kb = [w for w in K_FORBIDDEN_LITERAL if w in k]
|
||||
kb += re.findall(K_FORBIDDEN_REGEX, k)
|
||||
if kb:
|
||||
violations.append((ws.title, f"K{r}", "独立审查不得引模版", kb))
|
||||
if l and not is_header(l):
|
||||
lb = [w for w in L_FORBIDDEN_LITERAL if w in l]
|
||||
if lb:
|
||||
violations.append((ws.title, f"L{r}", "纯客观对比不得下判断", lb))
|
||||
return violations
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) < 2:
|
||||
print("用法: python3 kl-separation-check.py <校区梳理表.xlsx>")
|
||||
sys.exit(2)
|
||||
v = check(sys.argv[1])
|
||||
if not v:
|
||||
print("✅ K/L 分工自检通过:K 列零模版引用、L 列零判断词。")
|
||||
sys.exit(0)
|
||||
print("❌ K/L 分工自检发现违规(需回去拆分):")
|
||||
for sheet, cell, why, hits in v:
|
||||
print(f" [{sheet}] {cell}: {why} — 命中 {hits}")
|
||||
print("\n判据·遮模版测试:把'模版怎么写'遮住,K 列风险论述仍完整成立才算独立。")
|
||||
print("L 列只陈述'模版表述为X;本合同表述为Y',判断与建议归 K 列。")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user