feat: Sprint 2 - 概率语义 + 轻量快照 + 数据库约束
P0-05: confidence → subjective_confidence 改名(15 文件)
LLM 主观置信度与概率分离
P0-02: predictions 增加 cutoff_at + input_hash(轻量快照)
MatchContext 暴露 match_dt
单/多 Agent 路径均记录快照元数据
P2-05: 数据库 CHECK 约束
- pred_home_goals >= 0
- pred_away_goals >= 0
- subjective_confidence 0~1
- pred_1x2 IN (1,X,2)
- mode IN (single,multi)
P2-06: limit 分页约束(ge=1, le=200)
P2-01: 新增 /health/ready 就绪检查
This commit is contained in:
@@ -59,14 +59,14 @@ class TestReportParsing:
|
||||
"data_sufficiency": "high",
|
||||
"analysis": "主队交锋占优",
|
||||
"home_edge": 0.6,
|
||||
"confidence": 0.8,
|
||||
"subjective_confidence": 0.8,
|
||||
"key_evidence": ["近5次交锋主队4胜", "主场交锋3连胜"],
|
||||
}
|
||||
resp = LLMResponse(content="{}", parsed=parsed, prompt_tokens=100, completion_tokens=50, latency_ms=500)
|
||||
r = _parse_report("h2h", parsed, resp, "gpt-4o-mini")
|
||||
assert r.status == "ok"
|
||||
assert r.home_edge == 0.6
|
||||
assert r.confidence == 0.8
|
||||
assert r.subjective_confidence == 0.8
|
||||
assert len(r.key_evidence) == 2
|
||||
assert r.data_sufficiency == "high"
|
||||
|
||||
@@ -78,7 +78,7 @@ class TestReportParsing:
|
||||
"data_sufficiency": "medium",
|
||||
"analysis": "主队火力更强",
|
||||
"home_edge": 0.4,
|
||||
"confidence": 0.7,
|
||||
"subjective_confidence": 0.7,
|
||||
"key_evidence": ["场均xG 2.1"],
|
||||
"exp_home_goals": 2.1,
|
||||
"exp_away_goals": 1.2,
|
||||
@@ -97,7 +97,7 @@ class TestReportParsing:
|
||||
parsed = {
|
||||
"data_sufficiency": "bogus", # 非法 → medium
|
||||
"home_edge": "very strong", # 非法 → None (宽容降级)
|
||||
"confidence": None,
|
||||
"subjective_confidence": None,
|
||||
"key_evidence": "单字符串", # → [str]
|
||||
}
|
||||
resp = LLMResponse(content="{}", parsed=parsed)
|
||||
@@ -109,7 +109,7 @@ class TestReportParsing:
|
||||
assert r.key_evidence == ["单字符串"]
|
||||
|
||||
# 验证范围约束: confidence > 1 会被截断或拒绝
|
||||
parsed2 = {"confidence": 1.5, "home_edge": 2.0}
|
||||
parsed2 = {"subjective_confidence": 1.5, "home_edge": 2.0}
|
||||
r2 = _parse_report("form", parsed2, resp, "m")
|
||||
# Pydantic 会拒绝越界值 → parse_error
|
||||
assert r2.status == "parse_error"
|
||||
@@ -175,7 +175,7 @@ class TestRunAgent:
|
||||
assert "A 2-1 B" in user
|
||||
return LLMResponse(
|
||||
content="{}",
|
||||
parsed={"data_sufficiency": "high", "analysis": "ok", "home_edge": 0.5, "confidence": 0.9},
|
||||
parsed={"data_sufficiency": "high", "analysis": "ok", "home_edge": 0.5, "subjective_confidence": 0.9},
|
||||
prompt_tokens=10, completion_tokens=5, latency_ms=100,
|
||||
)
|
||||
|
||||
@@ -200,7 +200,7 @@ class TestOrchestratorAggregation:
|
||||
import json
|
||||
|
||||
reports = [
|
||||
AgentReport(agent="h2h", status="ok", home_edge=0.5, confidence=0.8, analysis="a"),
|
||||
AgentReport(agent="h2h", status="ok", home_edge=0.5, subjective_confidence=0.8, analysis="a"),
|
||||
AgentReport(agent="injuries", status="no_data", data_sufficiency="none"),
|
||||
]
|
||||
text = _reports_to_json(reports)
|
||||
|
||||
Reference in New Issue
Block a user