Files
Profeto/docs/03-api.md
T
shangfangjian 0a27b18c27 feat: 足球 LLM 预测服务初始提交
Profeto — 给 LLM 提供数据,让 LLM 预测足球比分。

核心模块:
- FastAPI 后端 + PostgreSQL (SQLAlchemy async)
- 多 Agent LLM 预测 (5 专家 + 终裁)
- 数据采集 (bzzoiro / understat / injuries)
- React 前端 (Vite + Tailwind)

包含:
- 数据源抽象 (DataSource 协议 + 注册表)
- Alembic 数据库迁移
- Prompt 模板 (单/多 Agent)
- 核心路径单元测试
2026-09-09 02:10:47 +08:00

190 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 03 · API 参考
Base URL: `http://localhost:8000` · 交互式文档: `/docs`(Swagger)与 `/redoc`
所有数据端点返回 JSON。错误统一为 `{"detail": "<message>"}` + 对应 HTTP 状态码。
---
## 数据查询
### `GET /api/v1/leagues`
列出已入库联赛。
```json
[{"id": 1, "code": "E0", "name": "Premier League", "country": "England"}]
```
### `GET /api/v1/matches`
比赛列表,游标分页。
| 参数 | 说明 |
|---|---|
| `league` | 联赛代码,如 `E0` / `SP1` / `D1` / `I1` / `F1` |
| `status` | `scheduled` / `finished`(不传 = 全部) |
| `date` | `YYYY-MM-DD`,当天比赛 |
| `cursor` | 上一页返回的 `next_cursor` |
| `limit` | 1100,默认 50 |
响应(倒序,含双方中文名与 xG):
```json
{
"items": [
{"id": 42, "league_code": "E0", "season": "2026-2027",
"home_team": "Arsenal", "away_team": "Manchester United",
"home_team_zh": null, "away_team_zh": null,
"match_date": "2026-09-15T19:00:00Z", "match_status": "scheduled",
"home_goals": null, "away_goals": null,
"match_stage": "第 5 轮", "home_xg": null, "away_xg": null}
],
"next_cursor": "2026-09-15T19:00:00+00:00|41",
"has_more": true
}
```
### `GET /api/v1/matches/{id}`
单场比赛详情,字段同上。
---
## 预测
### `POST /api/v1/predict`
对一场比赛做 LLM 预测。**核心端点。**
请求:
```json
{
"match_id": 42,
"mode": "multi",
"model": "gpt-4o",
"prompt_version": "v1"
}
```
| 字段 | 默认 | 说明 |
|---|---|---|
| `match_id` | 必填 | 比赛 ID |
| `mode` | `multi` | `multi` = 5 专家 + 终裁;`single` = 单次调用 |
| `model` | 配置值 | 覆盖本次模型(single 模式下生效) |
| `prompt_version` | `v1` | prompt 版本(multi 模式即 agent prompt 版本) |
响应(multi 模式):
```json
{
"prediction_id": 7,
"provider": "openai",
"model": "gpt-4o",
"prompt_version": "multi_v1",
"mode": "multi",
"pred_home_goals": 2.1,
"pred_away_goals": 1.0,
"pred_1x2": "1",
"confidence": 0.68,
"reasoning": "综合 xg 报告的进球期望 2.1-1.0 与 form 报告的三连胜势头……",
"agent_outputs": [
{"agent": "h2h", "status": "ok", "data_sufficiency": "medium",
"analysis": "近 5 次交锋主队 3 胜……", "home_edge": 0.4,
"confidence": 0.7, "key_evidence": ["近5次交锋主队3胜", "主场交锋3连胜"],
"exp_home_goals": null, "exp_away_goals": null, "probable_score": null,
"model": "gpt-4o-mini", "latency_ms": 2100,
"prompt_tokens": 380, "completion_tokens": 120},
{"agent": "injuries", "status": "no_data", "data_sufficiency": "none",
"analysis": "该维度无数据,跳过分析。", "home_edge": null, "confidence": null,
"key_evidence": [], "exp_home_goals": null, "exp_away_goals": null,
"probable_score": null, "model": "", "latency_ms": null,
"prompt_tokens": null, "completion_tokens": null}
],
"agent_weights": {"form": 0.9, "stats": 0.8, "home_away": 0.7, "injuries": 0.0, "h2h": 0.8},
"context": "[5 份报告的 JSON 串]",
"latency_ms": 9800
}
```
`agent.status` 取值:`ok` / `no_data`(维度无数据,已跳过 LLM)/ `error`(调用失败,fail-open 不阻断)/ `parse_error`
错误:404 比赛不存在;502 LLM 调用失败(终裁失败时整体失败,专家失败不会)。
### `GET /api/v1/predictions?match_id=&limit=`
预测历史(倒序),含 `settled` 与实际比分回填状态。
### `GET /api/v1/predictions/{id}`
单条预测详情(含完整 `agent_outputs`)。
---
## 数据采集
### `POST /api/v1/ingest/bzzoiro`
从 bzzoiro 采集赛果/赛程并入库(幂等,重复跑安全)。
```json
{"leagues": ["E0", "SP1"], "date_from": "2025-08-01", "date_to": "2026-09-08", "status": "finished"}
```
- `status` 还可传 `scheduled` 拉未来赛程
- 响应含每联赛 `inserted`/`updated`/`errors` 统计
### `POST /api/v1/ingest/understat`
回填 xG(只补空字段,不创建比赛):
```json
{"league": "E0", "season": 2025}
```
`season=2025` 表示 2025-2026 赛季。仅支持五大联赛。
### `POST /api/v1/ingest/injuries`
采集伤停(需 `API_FOOTBALL_KEY`,当前只返回计数,尚未接入 context):
```json
{"date": "2026-09-10"}
```
---
## 评估
### `POST /api/v1/eval/settle`
赛后回填实际比分:
```json
{"prediction_id": 7, "home_goals": 2, "away_goals": 1}
```
### `GET /api/v1/eval/summary`
`provider × model` 聚合已结算预测:
```json
{"summary": [
{"provider": "openai", "model": "gpt-4o", "total": 12,
"accuracy_1x2": 58.3, "avg_score_rmse": 1.21, "avg_confidence": 0.65}
]}
```
> 提示:multi 模式存的 `model` 是终裁模型、`prompt_version` 是 `multi_v1`,
> 因此 summary 里天然可对比 multi vs single、以及不同 prompt 版本的效果。
---
## 基础
| 端点 | 说明 |
|---|---|
| `GET /health` | 存活检查 |
| `GET /docs` | Swagger UI |