52 lines
1.8 KiB
Python
52 lines
1.8 KiB
Python
"""经验条目的判重与归类。桌面端(backend)和中心服务端(server)共用同一套规则,避免两边判重结果不一致。
|
||
|
||
判重按内容而不是按 key:模型每次给同一条知识起的名字都不一样,
|
||
「班级下拉框」和「班级选择控件」实际是一条。阈值来自真实草稿对的标定。
|
||
"""
|
||
|
||
from __future__ import annotations
|
||
|
||
import difflib
|
||
import re
|
||
|
||
LEARNED_CATEGORIES = {"control_tip", "path", "rule", "note"}
|
||
# 只有控件技巧和入口路径能自动生效:它们描述「控件怎么点」,错了顶多多花几步;
|
||
# 系统规则和其他类描述「系统有什么约束」,一条错的会让 Agent 以后一直绕开正确操作,必须人审。
|
||
AUTO_VERIFY_CATEGORIES = {"control_tip", "path"}
|
||
|
||
CATEGORY_LABELS = {
|
||
"control_tip": "控件技巧",
|
||
"path": "入口路径",
|
||
"rule": "系统规则",
|
||
"note": "其他",
|
||
}
|
||
|
||
|
||
def similarity(a: str, b: str) -> float:
|
||
na = re.sub(r"\s+", "", a or "")
|
||
nb = re.sub(r"\s+", "", b or "")
|
||
if not na or not nb:
|
||
return 0.0
|
||
return difflib.SequenceMatcher(None, na, nb).ratio()
|
||
|
||
|
||
def same_knowledge(a_key: str, a_value: str, b_key: str, b_value: str) -> bool:
|
||
"""内容相似度 >= 0.55,或 key 相似度 >= 0.7 且内容 >= 0.45,视为同一条知识。"""
|
||
vs = similarity(a_value, b_value)
|
||
if vs >= 0.55:
|
||
return True
|
||
return similarity(a_key, b_key) >= 0.7 and vs >= 0.45
|
||
|
||
|
||
def pick_category(*cats: str) -> str:
|
||
"""合并两条草稿时取更具体的类别,note 让位。"""
|
||
for c in cats:
|
||
if c in LEARNED_CATEGORIES and c != "note":
|
||
return c
|
||
return "note"
|
||
|
||
|
||
def normalise_category(value: str | None) -> str:
|
||
category = str(value or "note").strip()
|
||
return category if category in LEARNED_CATEGORIES else "note"
|