feat(v1): T-R3 采纳 llmrouter 词边界与失败安全——难度英文标记整词命中 + HF 分类器两级回落
- difficulty:标记表编译拆分——英文标记改词边界正则(修真实误判:'int' 子串 命中 'print'/'point'、'log' 命中 'logic'、'list' 命中 'listen'),中文标记 保持子串语义;命中行为对合法用例不变(整词出现照常计数) - classifier:HuggingFaceClassifier 推理期异常回落内置 RuleClassifier(单次 推理异常不打垮路由);build_classifier 的 hf 分支构造失败(ML 依赖缺失/ 模型加载失败)打印提示并回落规则分类器(外置规则照常合并) - 新增 tests/test_failsafe.py 5 项;全量 43 passed(38+5)
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
"""失败安全与词边界单元测试(T-R3,采纳 llmrouter 设计)。"""
|
||||
from router_system.classifier import RuleClassifier, build_classifier
|
||||
from router_system.difficulty import estimate_difficulty
|
||||
|
||||
|
||||
def test_word_boundary_stops_substring_false_positive():
|
||||
"""英文标记整词命中:'int' 不再被 'print'/'point' 误触发 hard。"""
|
||||
diff, score = estimate_difficulty("如何用 print 函数打印结果")
|
||||
# 旧实现 'int' 误命中 print 叠加 如何 -> hard;现在应为 medium 以下
|
||||
assert diff in ("easy", "medium")
|
||||
|
||||
diff2, _ = estimate_difficulty("请总结这段逻辑代码的思路")
|
||||
# 'sum' 不被 'summary/总结' 类场景误判:'逻辑' 含 'log' 也不再整词误命中
|
||||
assert diff2 in ("easy", "medium")
|
||||
|
||||
|
||||
def test_word_boundary_still_counts_whole_words():
|
||||
"""整词出现照常计数:int/log 作为真词仍触发 hard 信号。"""
|
||||
diff, _ = estimate_difficulty("explain how to implement int overflow and log parsing in depth")
|
||||
assert diff in ("medium", "hard")
|
||||
|
||||
|
||||
def test_chinese_markers_keep_substring_semantics():
|
||||
"""中文标记保持子串语义:'证明' 命中 '证明费马大定理'。"""
|
||||
diff, _ = estimate_difficulty("证明费马大定理并推导其推论,给出详细步骤")
|
||||
assert diff in ("medium", "hard")
|
||||
|
||||
|
||||
def test_build_hf_falls_back_when_unavailable(monkeypatch):
|
||||
"""HF 分类器构造失败(依赖缺失/模型加载失败)安全回落规则分类器。"""
|
||||
def _boom(self, *a, **k):
|
||||
raise RuntimeError("HuggingFaceClassifier 需要安装 ML 依赖")
|
||||
import router_system.classifier as C
|
||||
monkeypatch.setattr(C.HuggingFaceClassifier, "__init__", _boom)
|
||||
clf = build_classifier({"type": "hf", "model": "whatever"})
|
||||
assert isinstance(clf, RuleClassifier)
|
||||
assert clf.classify("用 Python 写一个快速排序函数").domain == "code"
|
||||
|
||||
|
||||
def test_hf_runtime_failure_falls_back_to_rules():
|
||||
"""推理期异常(torch 缺失/tokenizer 损坏)回落内置规则分类器。"""
|
||||
from router_system.classifier import HuggingFaceClassifier
|
||||
hf = HuggingFaceClassifier.__new__(HuggingFaceClassifier)
|
||||
hf.labels = ["code", "math", "legal", "medical", "general"]
|
||||
hf.confidence_floor = 0.55
|
||||
hf._rule_fallback = RuleClassifier(confidence_floor=0.55)
|
||||
r = hf.classify("用 Python 写一个快速排序函数") # 本环境无 torch/tokenizer -> 必走回落
|
||||
assert r.domain == "code"
|
||||
Reference in New Issue
Block a user