feat(v2): 架构与算法优化二轮——推理机不变量外提、知识库匹配预编译、协作循环增量索引

- inference.py(/chat/legacy 热路径):kb.match 循环不变量外提(原每步全量重扫+重排序,
  最坏 O(steps×rules×patterns));fired 查重 list→set
- knowledge.py:Rule patterns 注册侧懒缓存小写副本(原每条规则每次匹配重复 lower);
  match() 文本只 lower 一次(原逐规则重复);load() 的 yaml 文件名集合提到循环外
- worker.py:本地端点生成器 httpx.AsyncClient 懒建复用(原每步新建/销毁连接,
  对齐 ArchitectClient 惯用法;协作循环最多 10 次生成免重复建连)
- pipeline.py(协作循环):plan_by_id O(1) 步定义查找;done 集合增量维护
  (原每轮重建 progress+archive 扫描);领域只解析一次(原 _artifact_name 每步
  全领域 kb.match);_deps_done 支持传入预填集合(保持旧签名兼容)
- v2stats.py:回合数分布改增量聚合(sum/max/分桶计数),summary() O(n)→O(1),
  不再持有无界 list(修长时运行内存增长)
- gateway/agent.py + api.py:AgentService 运行计数 O(1) 化(原 register 全量扫描),
  状态迁移收敛到 _transition_state 单一入口(api.py cancel/异常两处绕过点一并接入,
  消除计数与状态脱节隐患);21 项 agent 测试全绿(两轮全量 230 passed 复核)
This commit is contained in:
tzt
2026-09-18 23:45:35 +08:00
parent 0767030f02
commit 8820e8da48
7 changed files with 103 additions and 41 deletions
+19 -6
View File
@@ -2,6 +2,9 @@
T9:每请求 API token 记账;聚合快路径命中率、回合数分布、熔断次数、累计 token/成本。
配合 /metrics 对外透出(论文 E1 token 经济学数据来源之一)。
性能设计(2026-09 优化):回合数分布以"和/最大值/分桶计数"增量维护,
summary() 从每次全量重算 O(n) 降为 O(桶数),且不再持有无界 list。
"""
from __future__ import annotations
@@ -18,7 +21,11 @@ class V2Stats:
self._fast_path = 0
self._breach = 0
self._by_status: Dict[str, int] = {}
self._rounds: List[int] = []
# 回合数增量聚合(等价于全量 list 的 sum/max/histogram,内存 O(桶数)
self._rounds_count = 0
self._rounds_sum = 0
self._rounds_max = 0
self._rounds_hist: Dict[str, int] = {}
self._api_input_tokens = 0
self._api_output_tokens = 0
self._api_cost_usd = 0.0
@@ -33,7 +40,13 @@ class V2Stats:
self._fast_path += 1
status = getattr(result, "status", "?")
self._by_status[status] = self._by_status.get(status, 0) + 1
self._rounds.append(getattr(result, "rounds_used", 0))
rounds = getattr(result, "rounds_used", 0)
self._rounds_count += 1
self._rounds_sum += rounds
if rounds > self._rounds_max:
self._rounds_max = rounds
bucket = str(rounds) if rounds <= 10 else ">10"
self._rounds_hist[bucket] = self._rounds_hist.get(bucket, 0) + 1
if "breach" in " ".join(getattr(result, "route", [])):
self._breach += 1
self._api_input_tokens += getattr(result, "api_input_tokens", 0)
@@ -64,16 +77,16 @@ class V2Stats:
def summary(self) -> Dict[str, Any]:
with self._lock:
total = self._total
rounds = self._rounds
rounds_n = self._rounds_count
return {
"total_requests": total,
"fast_path_rate": round(self._fast_path / total, 4) if total else 0.0,
"status_distribution": dict(self._by_status),
"breach_count": self._breach,
"rounds_used": {
"avg": round(sum(rounds) / len(rounds), 2) if rounds else 0.0,
"max": max(rounds) if rounds else 0,
"distribution": _histogram(rounds),
"avg": round(self._rounds_sum / rounds_n, 2) if rounds_n else 0.0,
"max": self._rounds_max if rounds_n else 0,
"distribution": dict(self._rounds_hist),
},
"api_tokens": {
"input": self._api_input_tokens,