9b449051926f0dd71eb794983edf8a8044735e74
Profeto — 先知
给 LLM 提供结构化数据,让 LLM 预测足球比分。
架构
┌─────────────────────────────────────────────────────┐
│ 前端 (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
快速开始
前置条件
- Python >= 3.11
- Docker (运行 PostgreSQL)
- LLM API Key (OpenAI / Deepseek / Ollama 等)
1. 安装
# 克隆
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. 启动数据库
docker compose up -d postgres
3. 启动服务
# 后端 (终端 1)
uvicorn src.api.app:app --reload
# 前端 (终端 2)
cd frontend && npm install && npm run dev
后端运行在 http://localhost:8000,前端在 http://localhost:5173。
使用流程
1. 采集数据
# 采集 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"}'
# 回填 understat xG
curl -X POST http://localhost:8000/api/v1/ingest/understat \
-H "Content-Type: application/json" \
-d '{"league":"E0","season":2026}'
# 采集伤停
curl -X POST http://localhost:8000/api/v1/ingest/injuries \
-H "Content-Type: application/json" \
-d '{"date":"2026-09-09"}'
2. 查询比赛
curl "http://localhost:8000/api/v1/matches?league=E0&status=scheduled"
3. LLM 预测
# 多 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. 评估
# 赛后回填实际比分
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
项目结构
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
核心模块
| 模块 | 作用 |
|---|---|
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 |
测试
pytest
数据库迁移
生产环境建议使用 Alembic:
alembic upgrade head
License
个人研究项目,预测结果不构成投注建议。
Languages
Python
58.3%
TypeScript
40.7%
CSS
0.6%
JavaScript
0.2%