docs: 统一文档与代码一致性

- 修复所有 confidence → subjective_confidence 残留(03-api, 04-agents, 05-data, 07-development)
- 修复 5 张表 → 6 张表残留(06-deployment)
- 同步 API schema 示例与实际模型一致
- 更新 predictions 表结构文档(新增 status/cutoff/input_hash 字段)

code: 修复 API 异常处理(eval/predict)和 context_builder stats 时间过滤
This commit is contained in:
shangfangjian
2026-09-15 02:27:48 +08:00
parent 0980c2242a
commit 60e4b89822
8 changed files with 37 additions and 15 deletions
+9 -1
View File
@@ -1,12 +1,16 @@
"""评估路由。"""
from __future__ import annotations
import logging
from fastapi import APIRouter, Depends, HTTPException
from src.api.schemas import EvalSummaryOut, SettleRequest
from src.db.base import AsyncSession, get_db, get_db_read
from src.llm.eval import get_eval_summary, settle_prediction
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/v1", tags=["eval"])
@@ -17,7 +21,11 @@ async def settle(req: SettleRequest, db: AsyncSession = Depends(get_db)):
pred = await settle_prediction(req.prediction_id, req.home_goals, req.away_goals)
return {"id": pred.id, "settled": pred.settled}
except ValueError as e:
raise HTTPException(404, str(e))
logger.warning("settle failed: %s", e)
raise HTTPException(404, "预测记录不存在")
except Exception as e:
logger.exception("settle error")
raise HTTPException(500, "回填失败,请查看服务器日志")
@router.get("/eval/summary", response_model=EvalSummaryOut)
+11 -2
View File
@@ -1,6 +1,8 @@
"""预测路由。"""
from __future__ import annotations
import logging
from fastapi import APIRouter, Depends, HTTPException, Query
from sqlalchemy import select
from sqlalchemy.orm import selectinload
@@ -10,6 +12,8 @@ from src.db.base import AsyncSession, get_db, get_db_read
from src.db.models import Prediction
from src.llm.predict import predict_match, PredictResult
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/api/v1", tags=["predict"])
@@ -24,9 +28,14 @@ async def predict(req: PredictRequest, db: AsyncSession = Depends(get_db)):
mode=req.mode,
)
except ValueError as e:
raise HTTPException(404, str(e))
logger.warning("predict validation error: %s", e)
raise HTTPException(404, "比赛不存在")
except RuntimeError as e:
raise HTTPException(502, str(e))
logger.error("predict LLM error: %s", e)
raise HTTPException(502, "LLM 预测失败,请查看服务器日志")
except Exception as e:
logger.exception("predict unexpected error")
raise HTTPException(500, "预测失败,请查看服务器日志")
# single / multi 两种结果统一映射
return PredictOut(
+1 -1
View File
@@ -142,7 +142,7 @@ async def form_slice(header: MatchHeader, *, limit: int = 5, before=None) -> str
else: losses += 1
score = f"{fm.home_goals}-{fm.away_goals}" if fm.home_goals is not None else "vs"
xg = ""
if fm.stats and fm.stats.home_xg is not None:
if fm.stats and _is_stats_available(fm.stats, before) and fm.stats.home_xg is not None:
own = fm.stats.home_xg if side == "home" else fm.stats.away_xg
xg = f" (xG {own:.1f})"
opp = fm.away_team.name if side == "home" else fm.home_team.name