feat: add signal tiering

This commit is contained in:
2026-07-15 12:12:48 -04:00
parent 75a2aac1c0
commit 9d19328cc9
2 changed files with 59 additions and 1 deletions
+49
View File
@@ -7,6 +7,8 @@ build_video_records / select_split。
from __future__ import annotations
from dataclasses import dataclass
_EVOLUTION_TARGET = {
"extraction_failure": "tool",
"search_failure": "skill",
@@ -45,3 +47,50 @@ def cell_of(task_type: str, error_type: str) -> tuple[str, str]:
(task_type, error_type) 二元组,作为覆盖计数的格子键。
"""
return (task_type, error_type)
@dataclass(frozen=True)
class SignalLabel:
"""诊断信号分层标签(DiagnosisResult 的确定性投影)。
字段:
tier: 信号层级,取值 T0 / T1 / T2 / uncertain(判据见 score_signal)。
"""
tier: str
def score_signal(*, cause_category: str | None, infra: bool, degraded: bool) -> SignalLabel:
"""把诊断产物投影为信号分层 tier(不发明新分类,是确定性投影)。
分层优先级顺序固定(用早返回表达,不用魔法权重):
先判 INFRA,再判 degraded,然后 defect / lapse,最后兜底 uncertain。
各层判据来源:
T0 — infra=True,即诊断 INFRA 排除(stop_reason ∈ {error, parse_error}),
基础设施失败先于一切判定,排除出可训练主体。
uncertain — degraded=Truejudge 解析失败)或 cause_category 落不到
defect/lapse 上(如为 None),信号不可信,排除出 T2。
T2 — cause_category == "defect",可训练核心,进多样性覆盖与训练主体。
T1 — cause_category == "lapse",低信号(含无解题),接受但不作训练主体。
参数:
cause_category: 诊断的缺陷归因("defect" / "lapse" / None)。
infra: 是否被 INFRA 护栏排除(基础设施失败)。
degraded: judge 是否解析失败导致诊断降级。
返回:
SignalLabel,其 tier 字段为上述四层之一。
实现细节:
关键字参数强制传入,防止 infra / degraded 两个 bool 位置混淆。
"""
if infra:
return SignalLabel(tier="T0")
if degraded:
return SignalLabel(tier="uncertain")
if cause_category == "defect":
return SignalLabel(tier="T2")
if cause_category == "lapse":
return SignalLabel(tier="T1")
return SignalLabel(tier="uncertain")
+10 -1
View File
@@ -1,6 +1,6 @@
import pytest
from app.harness.split_selection import cell_of, evolution_target_of
from app.harness.split_selection import cell_of, evolution_target_of, score_signal
def test_evolution_target_mapping():
@@ -17,3 +17,12 @@ def test_evolution_target_unknown_raises():
def test_cell_is_task_type_x_error_type():
assert cell_of("Counting Problem", "search_failure") == ("Counting Problem", "search_failure")
def test_tiers():
assert score_signal(cause_category="defect", infra=False, degraded=False).tier == "T2"
assert score_signal(cause_category="lapse", infra=False, degraded=False).tier == "T1"
assert (
score_signal(cause_category="defect", infra=True, degraded=False).tier == "T0"
) # INFRA 先判
assert score_signal(cause_category=None, infra=False, degraded=True).tier == "uncertain"