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:
shangfangjian
2026-09-15 00:14:24 +08:00
parent f3160e3062
commit cb36dc3ef9
14 changed files with 70 additions and 41 deletions
+11 -3
View File
@@ -2,9 +2,11 @@
from __future__ import annotations
import functools
import hashlib
import logging
import time
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from threading import Lock
@@ -64,7 +66,7 @@ class PredictResult:
pred_home_goals: float | None
pred_away_goals: float | None
pred_1x2: str | None
confidence: float | None
subjective_confidence: float | None
reasoning: str | None
context: str
latency_ms: int | None
@@ -112,6 +114,10 @@ async def _predict_single(
# 1. 拼上下文
ctx = await build_context(match_id)
# 1.5 计算快照元数据(用于可复现性)
cutoff_at = ctx.match_dt # 比赛时间 = 数据截止时间
input_hash = hashlib.sha256(ctx.text.encode("utf-8")).hexdigest()
# 2. 拼 prompt(指定版本)
template = _load_prompt_template(version)
user_prompt = template.replace("{{context}}", ctx.text)
@@ -155,9 +161,11 @@ async def _predict_single(
pred_home_goals=validated.pred_home_goals,
pred_away_goals=validated.pred_away_goals,
pred_1x2=validated.pred_1x2,
confidence=validated.confidence,
subjective_confidence=validated.subjective_confidence,
reasoning=validated.reasoning,
raw_response=resp.raw,
cutoff_at=cutoff_at,
input_hash=input_hash,
)
db.add(pred)
await db.commit()
@@ -171,7 +179,7 @@ async def _predict_single(
pred_home_goals=pred.pred_home_goals,
pred_away_goals=pred.pred_away_goals,
pred_1x2=pred.pred_1x2,
confidence=pred.confidence,
subjective_confidence=pred.subjective_confidence,
reasoning=pred.reasoning,
context=ctx.text,
latency_ms=resp.latency_ms,