feat(v1): 架构与算法优化二轮——共享 LLM 客户端去重、语义缓存 O(1) 提升/淘汰、分类器热路径清理
- 新增 router_system/llm_client.py:OpenAICompatClient 统一 experts/judge/fallback
三处复制的懒建 AsyncClient + /chat/completions + choices/usage 解析(~60 行去重);
密钥解析统一走 config.get_api_key(激活原死代码,顺带消除 experts 默认环境名不一致)
- 语义缓存 L2:条目容器 list→OrderedDict(提升/淘汰 O(n)→O(1)),按 query 天然去重;
n-gram 向量 lru_cache 复用(同一次 miss 的 get/put 免重复分词);
A/B:淘汰路径 0.040→0.034s,miss→put 往返 9.41→8.57s(-9%)
- RuleJudge 覆盖度:response.lower() 提出逐词循环(原 O(terms×len) 重复复制)
- extract_content_terms 纯函数 lru_cache 化(专家与 Judge 对同一查询免重复分词),返回 tuple
- RuleClassifier:_score 去掉败者领域白建的命中词 list(胜出后单独收集);
修复 code 规则 ("api",0.7) 重复登记(原命中计 1.4 分)
- difficulty:正则模块级预编译
- tests:恢复上一轮引入的乱码中文 docstring;网关测试输入串恢复为可判 code 的中文查询
This commit is contained in:
+15
-10
@@ -33,7 +33,7 @@ DOMAIN_RULES: Dict[str, List[Tuple[str, float]]] = {
|
||||
("algorithm", 0.8), ("sort", 0.7), ("array", 0.7), ("regex", 0.8),
|
||||
("import", 0.7), ("loop", 0.7), ("recursion", 0.8), ("refactor", 0.8),
|
||||
("deploy", 0.8), ("docker", 0.8), ("kubernetes", 0.8),
|
||||
("async", 0.7), ("flask", 0.7), ("django", 0.7), ("api", 0.7),
|
||||
("async", 0.7), ("flask", 0.7), ("django", 0.7),
|
||||
("索引", 0.8), ("优化", 0.7), ("查询", 0.6),
|
||||
],
|
||||
"math": [
|
||||
@@ -98,24 +98,29 @@ class RuleClassifier(BaseClassifier):
|
||||
self.confidence_floor = confidence_floor
|
||||
self.rules = DOMAIN_RULES
|
||||
|
||||
def _score(self, query: str) -> Tuple[Dict[str, float], Dict[str, List[str]]]:
|
||||
q = query.lower()
|
||||
def _score(self, q: str) -> Dict[str, float]:
|
||||
"""对已 lowercase 的查询按领域规则打分,返回有命中的领域分数。
|
||||
|
||||
命中词列表只对最终胜出领域有意义(classify 的唯一消费点),
|
||||
故不在各领域上白建 list——胜出后由 _matched_rules 单独收集。
|
||||
"""
|
||||
scores: Dict[str, float] = {}
|
||||
matched: Dict[str, List[str]] = {}
|
||||
for domain, rules in self.rules.items():
|
||||
s = 0.0
|
||||
hits = []
|
||||
for kw, w in rules:
|
||||
if kw in q:
|
||||
s += w
|
||||
hits.append(kw)
|
||||
if s > 0:
|
||||
scores[domain] = s
|
||||
matched[domain] = hits
|
||||
return scores, matched
|
||||
return scores
|
||||
|
||||
def _matched_rules(self, q: str, domain: str) -> List[str]:
|
||||
"""收集指定领域命中的关键词(保持登记顺序)。"""
|
||||
return [kw for kw, _w in self.rules.get(domain, ()) if kw in q]
|
||||
|
||||
def classify(self, query: str) -> Classification:
|
||||
raw, matched = self._score(query)
|
||||
q = query.lower()
|
||||
raw = self._score(q)
|
||||
if not raw:
|
||||
# 完全无命中 -> general,低置信度
|
||||
diff, ds = estimate_difficulty(query)
|
||||
@@ -150,7 +155,7 @@ class RuleClassifier(BaseClassifier):
|
||||
difficulty=diff,
|
||||
difficulty_score=ds,
|
||||
raw_scores={k: round(v, 3) for k, v in raw.items()},
|
||||
matched_rules=matched.get(best_domain, []),
|
||||
matched_rules=self._matched_rules(q, best_domain),
|
||||
)
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user