feat(sense): T-G0 语义分析器骨架(包结构/DDL/灰度门控挂载)
- gateway/sense/:config(SenseConfig:mode 灰度三态/特征门/conformal/consumers 档位映射,mode 非法回落 collect)、errors(EmbedderDown/ArtifactMissing,D-G4 降级)、 store(tier_observations + sense_artifacts DDL,WAL;观察写入/标签回填/ labeled 查询/180d 清理/工件登记与 active 切换)、routes(/sense/health 透出灰度状态) - settings DEFAULTS 增 sense 段(enabled 默认 False,mode 默认 collect——D-G7) - api.py include_router 门控(装配失败不拖垮主应用) - 测试 +5:门控 404/DDL 幂等/配置缺省与 mode 回落/独立挂载 health/ 观察写入-回填-计数-清理链路,全量 375 passed
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
"""SenseConfig:从 settings 的 sense 段构建语义分析器配置(T-G0)。
|
||||
|
||||
灰度纪律(D-G7):
|
||||
- enabled 默认 False(总开关,关闭时不注册任何 /sense 或 /v1/route 路由);
|
||||
- mode 默认 "collect"(只记不决策);collect 攒满 min_labels 前禁止 live
|
||||
(晋升校验在 grader/admin,配置层不阻止写值——但 admin promote 会复核)。
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass, field
|
||||
from typing import Any, Dict
|
||||
|
||||
MODES = ("collect", "shadow", "live")
|
||||
|
||||
|
||||
@dataclass
|
||||
class EmbedderCfg:
|
||||
base_url: str = "http://127.0.0.1:8902/v1"
|
||||
model: str = "bge-m3-Q4_K_M"
|
||||
timeout_s: float = 5.0
|
||||
dim: int = 1024
|
||||
|
||||
|
||||
@dataclass
|
||||
class SenseConfig:
|
||||
enabled: bool = False
|
||||
mode: str = "collect" # collect | shadow | live
|
||||
db_path: str = "data/sense.sqlite3"
|
||||
admin_key: str = ""
|
||||
embedder: EmbedderCfg = field(default_factory=EmbedderCfg)
|
||||
t1_max_tokens: int = 512
|
||||
t1_max_turns: int = 2
|
||||
intent_blacklist: tuple = ("重构", "脚手架", "迁移", "实现", "多文件", "项目")
|
||||
code_t1_kinds: tuple = ("解释", "补全")
|
||||
alpha: float = 0.05
|
||||
min_labels: int = 500
|
||||
t2_prefer_local_when_idle: bool = True
|
||||
consumers: Dict[str, Dict[str, str]] = field(default_factory=lambda: {
|
||||
"proxy": {"t1": "local-small", "t2": "budget", "t3": "premium"}})
|
||||
models_dir: str = "data/sense_models"
|
||||
retention_days: int = 180
|
||||
|
||||
def tier_pool_hint(self, consumer: str, tier: str) -> str:
|
||||
"""消费方×档位 -> model_pool 档位名(§5 consumers;缺省兜底 local/budget/premium)。"""
|
||||
m = self.consumers.get(consumer) or {}
|
||||
return m.get(tier) or {"t1": "local", "t2": "budget",
|
||||
"t3": "premium"}.get(tier, "budget")
|
||||
|
||||
|
||||
def build_sense_config(settings_dict: Dict[str, Any]) -> SenseConfig:
|
||||
"""从 settings.to_dict() 的 sense 段构建(缺省兜底;mode 非法回落 collect)。"""
|
||||
raw = settings_dict.get("sense") or {}
|
||||
if not isinstance(raw, dict):
|
||||
raw = {}
|
||||
emb = raw.get("embedder") or {}
|
||||
if not isinstance(emb, dict):
|
||||
emb = {}
|
||||
feats = raw.get("features") or {}
|
||||
if not isinstance(feats, dict):
|
||||
feats = {}
|
||||
policy = raw.get("policy") or {}
|
||||
if not isinstance(policy, dict):
|
||||
policy = {}
|
||||
consumers = raw.get("consumers") or {}
|
||||
if not isinstance(consumers, dict):
|
||||
consumers = {}
|
||||
mode = str(raw.get("mode", "collect") or "collect")
|
||||
if mode not in MODES:
|
||||
mode = "collect"
|
||||
return SenseConfig(
|
||||
enabled=bool(raw.get("enabled", False)),
|
||||
mode=mode,
|
||||
db_path=str(raw.get("db_path") or "data/sense.sqlite3"),
|
||||
admin_key=str(raw.get("admin_key") or ""),
|
||||
embedder=EmbedderCfg(
|
||||
base_url=str(emb.get("base_url") or "http://127.0.0.1:8902/v1"),
|
||||
model=str(emb.get("model") or "bge-m3-Q4_K_M"),
|
||||
timeout_s=float(emb.get("timeout_s", 5) or 5),
|
||||
dim=int(emb.get("dim", 1024) or 1024),
|
||||
),
|
||||
t1_max_tokens=int(feats.get("t1_max_tokens", 512) or 512),
|
||||
t1_max_turns=int(feats.get("t1_max_turns", 2) or 2),
|
||||
intent_blacklist=tuple(feats.get("intent_blacklist")
|
||||
or ("重构", "脚手架", "迁移", "实现", "多文件", "项目")),
|
||||
code_t1_kinds=tuple(feats.get("code_t1_kinds") or ("解释", "补全")),
|
||||
alpha=float(policy.get("alpha", 0.05) or 0.05),
|
||||
min_labels=int(policy.get("min_labels", 500) or 500),
|
||||
t2_prefer_local_when_idle=bool(policy.get("t2_prefer_local_when_idle", True)),
|
||||
consumers=consumers or SenseConfig().consumers,
|
||||
)
|
||||
Reference in New Issue
Block a user