docs: 完善 README 文档
This commit is contained in:
@@ -1,81 +1,237 @@
|
||||
# Profeto — 足球 LLM 预测服务
|
||||
|
||||
**给 LLM 提供数据,让 LLM 预测足球比分。**
|
||||
> 给 LLM 提供结构化数据,让 LLM 预测足球比分。
|
||||
|
||||
与旧项目 `MatchPro`(自研统计模型预测引擎)完全不同:
|
||||
- MatchPro: 160 个 Python 文件,7 套 ML 模型,OOF/校准/Promotion Gate,6 容器
|
||||
- **Profeto**: ~25 个文件,5 张表,LLM 做预测,2 容器(api + postgres)
|
||||
与旧项目 [MatchPro](https://github.com)(自研统计模型预测引擎)完全不同:
|
||||
|
||||
| | MatchPro | Profeto |
|
||||
|---|---|---|
|
||||
| 代码量 | 160 个 Python 文件 | ~30 个文件 |
|
||||
| 预测方式 | 7 套 ML 模型 + OOF/校准/Promotion Gate | LLM 推理 |
|
||||
| 架构 | 6 容器 | 2 容器 (api + postgres) |
|
||||
| 数据 | 多源 + 特征工程 | 5 张表 + 数据切片 |
|
||||
|
||||
## 架构
|
||||
|
||||
```
|
||||
前端(单页) → FastAPI → PostgreSQL
|
||||
↑
|
||||
LLM (OpenAI-compatible)
|
||||
↑
|
||||
bzzoiro / understat
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ 前端 (React + Vite + Tailwind) │
|
||||
│ http://localhost:5173 │
|
||||
└──────────────────────┬──────────────────────────────┘
|
||||
│ REST API
|
||||
┌──────────────────────▼──────────────────────────────┐
|
||||
│ FastAPI │
|
||||
│ ├── /api/v1/matches 比赛查询 │
|
||||
│ ├── /api/v1/predict LLM 预测 (单/多 Agent) │
|
||||
│ ├── /api/v1/ingest/* 数据采集 │
|
||||
│ └── /api/v1/eval/* 评估回填 │
|
||||
└──────────┬─────────────────────────────┬────────────┘
|
||||
│ │
|
||||
┌──────────▼──────────┐ ┌─────────────▼────────────┐
|
||||
│ PostgreSQL │ │ LLM (OpenAI-compatible) │
|
||||
│ 5 张表 │ │ OpenAI / Deepseek / │
|
||||
│ leagues/teams/ │ │ Ollama / 任意网关 │
|
||||
│ matches/match_ │ └──────────────────────────┘
|
||||
│ stats/predictions/ │
|
||||
│ injuries │
|
||||
└─────────────────────┘
|
||||
▲
|
||||
│ 采集
|
||||
┌──────────┴─────────────────────────────────────────┐
|
||||
│ 数据源 (DataSource 协议 + 注册表) │
|
||||
│ ├── bzzoiro 比分 / 统计 / xG │
|
||||
│ ├── understat xG 回填 │
|
||||
│ └── injuries 伤停数据 (api-football) │
|
||||
└────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 多 Agent 预测
|
||||
|
||||
默认模式 (`mode=multi`) 采用 **5 专家 + 终裁** 架构:
|
||||
|
||||
```
|
||||
比赛数据 → 切片 ─┬─→ A 近期状态专家 ─┐
|
||||
├─→ B 攻防数据专家 ─┤
|
||||
├─→ C 主客因素专家 ─┼─→ 终裁专家 ─→ 最终预测
|
||||
├─→ D 阵容完整专家 ─┤
|
||||
└─→ E 历史交锋专家 ─┘
|
||||
```
|
||||
|
||||
- 各专家**只看到自己维度的数据切片**,避免信息过载
|
||||
- **fail-open**: 单个专家失败不影响整体
|
||||
- **no_data 门控**: 无数据维度跳过 LLM 调用,省 token 防幻觉
|
||||
- 终裁根据各报告的 `confidence` / `data_sufficiency` 加权输出 `agent_weights`
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 1. 环境
|
||||
### 前置条件
|
||||
|
||||
- Python >= 3.11
|
||||
- Docker (运行 PostgreSQL)
|
||||
- LLM API Key (OpenAI / Deepseek / Ollama 等)
|
||||
|
||||
### 1. 安装
|
||||
|
||||
```bash
|
||||
# 后端
|
||||
pip install -e ".[dev]"
|
||||
cp .env.example .env
|
||||
# 编辑 .env: 填 LLM_API_KEY、BZZOIRO_KEY
|
||||
# 克隆
|
||||
git clone https://git.bilidili.cn/shangfangjian/Profeto.git
|
||||
cd Profeto
|
||||
|
||||
# 数据库
|
||||
# 后端依赖
|
||||
pip install -e ".[dev]"
|
||||
|
||||
# 配置环境变量
|
||||
cp .env.example .env
|
||||
# 编辑 .env,填入 LLM_API_KEY 和 BZZOIRO_KEY
|
||||
```
|
||||
|
||||
### 2. 启动数据库
|
||||
|
||||
```bash
|
||||
docker compose up -d postgres
|
||||
```
|
||||
|
||||
### 2. 启动
|
||||
### 3. 启动服务
|
||||
|
||||
```bash
|
||||
# 后端
|
||||
# 后端 (终端 1)
|
||||
uvicorn src.api.app:app --reload
|
||||
|
||||
# 前端(另一个终端)
|
||||
# 前端 (终端 2)
|
||||
cd frontend && npm install && npm run dev
|
||||
```
|
||||
|
||||
### 3. 使用
|
||||
后端运行在 `http://localhost:8000`,前端在 `http://localhost:5173`。
|
||||
|
||||
## 使用流程
|
||||
|
||||
### 1. 采集数据
|
||||
|
||||
```bash
|
||||
# 采集数据
|
||||
# 采集 bzzoiro 比分与统计
|
||||
curl -X POST http://localhost:8000/api/v1/ingest/bzzoiro \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"leagues":["E0","SP1"],"date_from":"2026-08-01","date_to":"2026-09-06"}'
|
||||
|
||||
# 查比赛
|
||||
curl "http://localhost:8000/api/v1/matches?league=E0&status=scheduled"
|
||||
# 回填 understat xG
|
||||
curl -X POST http://localhost:8000/api/v1/ingest/understat \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"league":"E0","season":2026}'
|
||||
|
||||
# LLM 预测
|
||||
# 采集伤停
|
||||
curl -X POST http://localhost:8000/api/v1/ingest/injuries \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"date":"2026-09-09"}'
|
||||
```
|
||||
|
||||
### 2. 查询比赛
|
||||
|
||||
```bash
|
||||
curl "http://localhost:8000/api/v1/matches?league=E0&status=scheduled"
|
||||
```
|
||||
|
||||
### 3. LLM 预测
|
||||
|
||||
```bash
|
||||
# 多 Agent 预测 (默认)
|
||||
curl -X POST http://localhost:8000/api/v1/predict \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"match_id": 1}'
|
||||
|
||||
# 赛后回填
|
||||
# 单次调用模式
|
||||
curl -X POST http://localhost:8000/api/v1/predict \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"match_id": 1, "mode": "single"}'
|
||||
```
|
||||
|
||||
### 4. 评估
|
||||
|
||||
```bash
|
||||
# 赛后回填实际比分
|
||||
curl -X POST http://localhost:8000/api/v1/eval/settle \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"prediction_id": 1, "home_goals": 2, "away_goals": 1}'
|
||||
|
||||
# 评估汇总
|
||||
# 查看准确率汇总
|
||||
curl http://localhost:8000/api/v1/eval/summary
|
||||
```
|
||||
|
||||
前端访问 `http://localhost:5173`。
|
||||
## 项目结构
|
||||
|
||||
```
|
||||
Profeto/
|
||||
├── src/
|
||||
│ ├── api/ # FastAPI 路由层
|
||||
│ │ ├── app.py # 应用工厂 + lifespan
|
||||
│ │ ├── schemas.py # Pydantic 请求/响应模型
|
||||
│ │ └── routes/
|
||||
│ │ ├── matches.py # 比赛查询
|
||||
│ │ ├── predict.py # 预测入口
|
||||
│ │ ├── ingest.py # 数据采集
|
||||
│ │ └── eval.py # 评估回填
|
||||
│ ├── core/ # 基础设施
|
||||
│ │ ├── config.py # pydantic-settings 配置
|
||||
│ │ └── http_client.py # 共享 httpx 客户端
|
||||
│ ├── data/ # 数据层
|
||||
│ │ ├── sources.py # DataSource 协议 + 注册表
|
||||
│ │ ├── match_lookup.py # 比赛匹配辅助函数
|
||||
│ │ ├── normalize.py # 数据规范化契约
|
||||
│ │ ├── bzzoiro.py # bzzoiro 数据源
|
||||
│ │ ├── understat.py # understat xG 数据源
|
||||
│ │ ├── injuries.py # 伤停数据 (独立领域)
|
||||
│ │ ├── config.py # 联赛映射常量
|
||||
│ │ └── team_names.py # 队名归一化
|
||||
│ ├── db/ # 数据库
|
||||
│ │ ├── base.py # SQLAlchemy async engine
|
||||
│ │ └── models.py # ORM 模型 (5 表)
|
||||
│ └── llm/ # LLM 预测核心
|
||||
│ ├── predict.py # 预测服务 (缓存 + 单/多模式)
|
||||
│ ├── context_builder.py # 数据切片 + 上下文拼接
|
||||
│ ├── eval.py # 评估统计
|
||||
│ ├── provider.py # 多提供商 LLM 抽象
|
||||
│ ├── agents/
|
||||
│ │ ├── base.py # Agent 基础设施 + 解析
|
||||
│ │ └── orchestrator.py # 多 Agent 编排
|
||||
│ └── prompts/ # Prompt 模板
|
||||
│ ├── match_prediction_v1.md
|
||||
│ ├── match_prediction_v2.md
|
||||
│ └── agents/ # 各专家 prompt
|
||||
├── alembic/ # 数据库迁移
|
||||
├── frontend/ # React 前端
|
||||
├── docs/ # 详细文档
|
||||
├── tests/ # 单元测试
|
||||
├── docker-compose.yml
|
||||
├── Dockerfile
|
||||
└── pyproject.toml
|
||||
```
|
||||
|
||||
## 核心模块
|
||||
|
||||
| 文件 | 作用 |
|
||||
| 模块 | 作用 |
|
||||
|---|---|
|
||||
| `src/llm/context_builder.py` | **最重要**: 拼 LLM 看到的上下文 |
|
||||
| `src/llm/prompts/match_prediction.md` | prompt 模板(迭代最频繁) |
|
||||
| `src/llm/provider.py` | 多提供商抽象 |
|
||||
| `src/data/bzzoiro.py` | 数据采集(迁移自旧项目) |
|
||||
| `src/data/normalize.py` | 数据清洗契约 |
|
||||
| `context_builder.py` | **最重要**: 数据切片 + 拼接 LLM 看到的上下文 |
|
||||
| `prompts/` | Prompt 模板 (迭代最频繁) |
|
||||
| `provider.py` | OpenAI-compatible 多提供商抽象 |
|
||||
| `sources.py` | 数据源协议 + 注册表 |
|
||||
| `normalize.py` | 数据清洗契约 (校验/范围/归一) |
|
||||
| `orchestrator.py` | 多 Agent 编排 (并行专家 + 终裁) |
|
||||
|
||||
## 配置
|
||||
|
||||
通过 `.env` 或环境变量配置:
|
||||
|
||||
| 变量 | 说明 | 默认值 |
|
||||
|---|---|---|
|
||||
| `DATABASE_URL` | PostgreSQL 连接 | `postgresql+asyncpg://football:football@localhost:5432/football` |
|
||||
| `LLM_PROVIDER` | 提供商标识 | `openai` |
|
||||
| `LLM_API_KEY` | API 密钥 | *(必填)* |
|
||||
| `LLM_BASE_URL` | API 地址 | `https://api.openai.com/v1` |
|
||||
| `LLM_MODEL` | 模型名 | `gpt-4o` |
|
||||
| `LLM_SPECIALIST_MODEL` | 专家模型 (空=回落 LLM_MODEL) | |
|
||||
| `LLM_AGGREGATOR_MODEL` | 终裁模型 (空=回落 LLM_MODEL) | |
|
||||
| `BZZOIRO_KEY` | bzzoiro API Key | *(必填)* |
|
||||
| `API_FOOTBALL_KEY` | api-football Key (伤停) | |
|
||||
| `CORS_ORIGINS` | 允许的跨域来源 | `http://localhost:5173` |
|
||||
|
||||
## 测试
|
||||
|
||||
@@ -83,6 +239,14 @@ curl http://localhost:8000/api/v1/eval/summary
|
||||
pytest
|
||||
```
|
||||
|
||||
## 数据库迁移
|
||||
|
||||
生产环境建议使用 Alembic:
|
||||
|
||||
```bash
|
||||
alembic upgrade head
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
个人研究项目,预测结果不构成投注建议。
|
||||
|
||||
Reference in New Issue
Block a user