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:
tzt
2026-09-18 23:27:26 +08:00
parent 81b0bc9b9b
commit c072a1a237
10 changed files with 696 additions and 631 deletions
+1 -1
View File
@@ -10,5 +10,5 @@ from router_system.router import build_router
@pytest.fixture()
def router():
"""????????? mock ?????????????"""
"""构建全 mock 链路的 Router 实例(离线可跑,供各测试复用)。"""
return build_router()
+4 -4
View File
@@ -49,9 +49,9 @@ def test_exact_hit():
def test_semantic_hit():
c = RouterCache(semantic_enabled=True, similarity_threshold=0.5)
c.put("?python?????", {"response": "code", "domain": "code"})
# ?????????? L2
hit = c.get("?python????????")
c.put("python 实现快速排序", {"response": "code", "domain": "code"})
# 相似但不完全相同的查询应命中 L2 语义缓存
hit = c.get("python 实现快速排序的算法")
assert hit is not None
assert hit[0] == "semantic"
@@ -60,7 +60,7 @@ def test_promote_to_exact():
c = RouterCache(promote_frequency=3)
result = {"response": "x", "domain": "general"}
c.put("query", result)
# ?????? 3 ? ? ???????
# 语义命中累计 3 次后提升为精确缓存
for _ in range(3):
hit = c.get("query")
assert hit is not None
+2 -2
View File
@@ -1,4 +1,4 @@
"""???????? fastapi + httpx??"""
"""网关集成测试(需 fastapi + httpx,链路全 mock)。"""
import pytest
pytest.importorskip("fastapi")
@@ -23,7 +23,7 @@ def test_health(client):
def test_chat(client):
resp = client.post("/chat", json={"query": "? Python ???????"})
resp = client.post("/chat", json={"query": " Python 写一个快速排序函数"})
assert resp.status_code == 200
data = resp.json()
assert data["response"]