feat(sense): T-X5 云端评判晋升表×conformal 双闸门——本地档自动接管(采纳 cortiq promotion)
- gateway/sense/promotion.py:PromotionTable 状态机(candidate/promoted/demoted)
* 晋升门:n_total>=n_min 且 通过率>=promote_lb 且 soak 浸泡期满足
* 退化:promoted 期间通过率<demote_lb 自动降级;降级后可凭数据恢复
* 一票否决:tier=T3 观察不进通过率统计,已晋升者立即降级
* 持久化 sense_promotion 表(CREATE IF NOT EXISTS 幂等)
- grader:live 模式对已晋升标签的 T2 决策(无 T3 信号/非 fallback)升级 T1,
hard_gates.promotion_applied 如实标注;T1/T3/fallback 路径不受影响
- 回填链路:T1 审计抽样带 promo:<label> 标签 -> 人工 verdict approve=ok
经 /review/{id} 提交时回填晋升表(失败不影响审核主流程)
- 双闸门语义:conformal 阈值保证单条决策风险率,晋升表保证标签级接管节奏;
collect 数据不足(n_min 未满)不晋升,全部迁移可经 T-X4 留痕审计
pytest 474 passed(T-X4 后 466 + 8)
This commit is contained in:
+17
-2
@@ -21,6 +21,7 @@ from gateway.sense.decision_cache import DecisionCache
|
||||
from gateway.sense.embedder import embed
|
||||
from gateway.sense.errors import EmbedderDown
|
||||
from gateway.sense.features import gate
|
||||
from gateway.sense.promotion import promotion_label
|
||||
from gateway.sense.store import json_dumps
|
||||
|
||||
|
||||
@@ -99,10 +100,11 @@ def _rejected_tiers(fallback: bool, probs: Dict[str, float],
|
||||
class Grader:
|
||||
"""决策器(持有 active 工件缓存;工件/阈值切换后调 invalidate)。"""
|
||||
|
||||
def __init__(self, cfg: SenseConfig, store, observer=None):
|
||||
def __init__(self, cfg: SenseConfig, store, observer=None, promotion=None):
|
||||
self.cfg = cfg
|
||||
self.store = store
|
||||
self.observer = observer
|
||||
self._promotion = promotion # T-X5:晋升表(可 None)
|
||||
self._head: Optional[LinearHead] = None
|
||||
self._head_loaded = False
|
||||
self._thresholds: Optional[Dict[str, Any]] = None
|
||||
@@ -194,6 +196,18 @@ class Grader:
|
||||
else:
|
||||
tier = "T2"
|
||||
|
||||
# ---- 晋升表应用(T-X5:conformal 之外的统计闸门;仅 live)----
|
||||
# 仅对 T2 决策且无任何 T3 信号时,允许已晋升标签升级 T1;
|
||||
# T1/T3 决策与 fallback 路径不受晋升表影响。
|
||||
promotion_applied = False
|
||||
if (self._promotion is not None and self.cfg.mode == "live"
|
||||
and not fallback and tier == "T2"
|
||||
and not feats.repo_signals
|
||||
and probs.get("t3", 0.0) < float(th.get("t3", 0.9))):
|
||||
if self._promotion.is_promoted(promotion_label(consumer, domain)):
|
||||
tier = "T1"
|
||||
promotion_applied = True
|
||||
|
||||
# ---- mode 裁剪(D-G7)----
|
||||
if self.cfg.mode == "live":
|
||||
executed = tier # live:决策即执行
|
||||
@@ -208,7 +222,8 @@ class Grader:
|
||||
"intent_blocked": feats.intent_blocked,
|
||||
"repo_signals": feats.repo_signals,
|
||||
"over_length": feats.over_length,
|
||||
"t1_hard_ok": feats.t1_hard_ok},
|
||||
"t1_hard_ok": feats.t1_hard_ok,
|
||||
"promotion_applied": promotion_applied},
|
||||
thresholds_version=th_version, head_version=head_version,
|
||||
mode=self.cfg.mode, fallback=fallback,
|
||||
executed_tier=executed)
|
||||
|
||||
Reference in New Issue
Block a user