- 新增 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 的中文查询
45 lines
1.0 KiB
Python
45 lines
1.0 KiB
Python
"""网关集成测试(需 fastapi + httpx,链路全 mock)。"""
|
|
import pytest
|
|
|
|
pytest.importorskip("fastapi")
|
|
pytest.importorskip("httpx")
|
|
|
|
from fastapi.testclient import TestClient
|
|
|
|
from gateway.api import app
|
|
|
|
|
|
@pytest.fixture()
|
|
def client():
|
|
return TestClient(app)
|
|
|
|
|
|
def test_health(client):
|
|
resp = client.get("/health")
|
|
assert resp.status_code == 200
|
|
data = resp.json()
|
|
assert data["status"] == "ok"
|
|
assert "code" in data["domains"]
|
|
|
|
|
|
def test_chat(client):
|
|
resp = client.post("/chat", json={"query": "用 Python 写一个快速排序函数"})
|
|
assert resp.status_code == 200
|
|
data = resp.json()
|
|
assert data["response"]
|
|
assert data["domain"] == "code"
|
|
assert "route" in data
|
|
|
|
|
|
def test_chat_empty_query(client):
|
|
resp = client.post("/chat", json={"query": ""})
|
|
assert resp.status_code == 422
|
|
|
|
|
|
def test_metrics(client):
|
|
resp = client.get("/metrics")
|
|
assert resp.status_code == 200
|
|
data = resp.json()
|
|
assert "router" in data
|
|
assert "cache" in data
|