MiMo AI 能力扩展:TAF解读、概率分布解读、异常检测、市场概览

AI 解读字段扩展:
    - 新增 taf_read_zh/en:解读机场预报中影响今日峰值窗口的变化
    - 新增 probability_read_zh/en:描述概率分布形态(最高桶、偏左/偏右)
    - stream max_tokens 900→1200 容纳新输出字段
    - 缓存 key 简化为 METAR原文+观测时间,大幅提升命中率
    - 兜底函数补全 TAF 和概率字段的确定性生成

    异常检测:
    - 纯数学计算,零 AI 延迟:实测温度 vs 全部模型预测上下限
    - 三级告警:breakout_above / breakout_below / deviation

    市场概览:
    - 新增 POST /api/scan/terminal/overview(MiMo 批量解读,缓存10分钟)
    - 前端 MarketOverviewBanner 可折叠横幅(顶栏与标签栏之间)
    - 移动端适配 640px/768px 断点,暗色/亮色双主题

    Scope-risk: MEDIUM — 170 测试通过,TypeScript 零错误,ruff 零告警
    Tested: python -m pytest -q (170 passed), npx tsc --noEmit (0 errors), ruff check .
This commit is contained in:
2569718930@qq.com
2026-05-14 22:41:31 +08:00
parent 6c08a68413
commit 2ee00f8016
13 changed files with 823 additions and 55 deletions
+43
View File
@@ -421,3 +421,46 @@ def build_scan_ai_prompt(payload: Dict[str, Any], *, max_rows: int) -> Dict[str,
"sent_contracts": sent_contracts,
},
}
def _compact_probability_context(probabilities: Any, deb: Any, unit: str) -> dict:
if not isinstance(probabilities, dict):
return {}
dist = probabilities.get("distribution")
if not isinstance(dist, list) or not dist:
return {}
top_buckets = sorted(
[b for b in dist if isinstance(b, dict) and b.get("probability")],
key=lambda b: float(b.get("probability", 0)),
reverse=True,
)[:3]
compact = {
"top_buckets": [
{
"label": b.get("label", ""),
"prob": round(float(b.get("probability", 0)) * 100),
}
for b in top_buckets
],
}
mu = probabilities.get("mu")
if mu is not None:
compact["mu"] = mu
spread = (
round(float(probabilities.get("calibrated_sigma") or 0), 1)
or round(float(probabilities.get("raw_sigma") or 0), 1)
or None
)
if spread is not None:
compact["sigma"] = spread
deb_val = deb.get("prediction") if isinstance(deb, dict) else None
if deb_val is not None and mu is not None:
if deb_val > mu:
compact["skew"] = "right"
elif deb_val < mu:
compact["skew"] = "left"
else:
compact["skew"] = "centered"
if unit:
compact["unit"] = unit
return compact