auto-sync: 2026-05-18 08:24:10
This commit is contained in:
@@ -0,0 +1,326 @@
|
||||
# v2.7 数据模型重新设计:Project → Task → SubTask
|
||||
|
||||
> 日期:2026-05-18
|
||||
> 版本:v1.0(基于 2026-05-18 08:13 ~ 08:21 讨论定稿)
|
||||
> 作者:庞统
|
||||
> 状态:待确认
|
||||
> 前置:回滚 v2.7 Card 层(设计文档 + 代码)
|
||||
|
||||
---
|
||||
|
||||
## 一、概念对齐
|
||||
|
||||
| 层级 | 语义 | 例子 | 谁创建 | 生命周期 |
|
||||
|------|------|------|--------|---------|
|
||||
| **Project** | 仓库/组织 | sanguo_quant_live、sanguo_vnpy | 系统(自动发现)+ 用户 | 长期 |
|
||||
| **Task** | 用户的一条需求/意图/目标 | "动量策略v1"、"下载分钟线"、"v2.7开发" | 用户 / AI | 天~周 |
|
||||
| **SubTask** | Agent 领走执行的原子动作 | 张飞编码、赵云备数据、司马懿评审 | AI(庞统分解)| 小时~天 |
|
||||
|
||||
### 关键认知
|
||||
|
||||
1. **Task 是用户视角的最小单位**:用户说"帮我做动量策略v1",这就是一个 Task
|
||||
2. **SubTask 是 Agent 视角的最小单位**:庞统把 Task 拆解后分发给各将军
|
||||
3. **SubTask 可以跨 Project**:姜维在 sanguo_vnpy 搭回测引擎,服务的是 sanguo_quant_live 的 Task
|
||||
4. **SubTask ≈ Stage**:同一个 Task 的 SubTask 按执行顺序形成 Stage 链
|
||||
5. **Task 间有依赖**:策略编码依赖数据准备,实盘依赖模拟验证
|
||||
|
||||
---
|
||||
|
||||
## 二、回滚范围
|
||||
|
||||
### 回滚 Card 相关代码(开发目录)
|
||||
|
||||
| 文件 | 操作 |
|
||||
|------|------|
|
||||
| `src/blackboard/models.py` | 删除 Card 相关代码(CARD_VALID_STATUSES 等 + Card dataclass) |
|
||||
| `src/blackboard/db.py` | 删除 `_CARDS_SCHEMA`、`_migrate_v27()`、cards 表 DDL;tasks 表移除 `card_id`、`stage` 列 |
|
||||
| `src/blackboard/operations.py` | 删除 CardOps 类(create_card / list_cards / fork_card 等) |
|
||||
| `src/blackboard/queries.py` | 移除 card_id 过滤参数 |
|
||||
| `src/api/card_routes.py` | **删除整个文件** |
|
||||
| `src/api/mail_routes.py` | **删除整个文件**(Mail 后续重新设计) |
|
||||
| `src/blackboard/registry.py` | 保留 ProjectRegistry(不涉及 Card) |
|
||||
| `src/daemon/ticker.py` | 移除 per-card 扫描逻辑,恢复 v2.6 per-project 扫描 |
|
||||
| `src/main.py` | 移除 card_routes、mail_routes 注册;移除 v2.7 迁移调用 |
|
||||
| `tests/test_v27_cards.py` | **删除整个文件** |
|
||||
|
||||
### 回滚设计文档
|
||||
|
||||
| 文件 | 操作 |
|
||||
|------|------|
|
||||
| `docs/design/v2.7-three-tier-hierarchy.md` | 归档到 `docs/design/archive/` |
|
||||
|
||||
### 保留
|
||||
|
||||
| 文件/功能 | 原因 |
|
||||
|-----------|------|
|
||||
| `registry.db` + ProjectRegistry + 自动发现 | Project 管理需要 |
|
||||
| per-project `blackboard.db` | 多项目隔离需要 |
|
||||
| Project API 路由 | 前端项目选择器需要 |
|
||||
| Product 方向备忘录 | 新增,记录未来方向 |
|
||||
|
||||
---
|
||||
|
||||
## 三、新增:SubTask 层
|
||||
|
||||
### 3.1 数据模型
|
||||
|
||||
**SubTask 表**(加到 per-project blackboard.db):
|
||||
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS subtasks (
|
||||
id TEXT PRIMARY KEY, -- 自动生成(如 st-a1b2c3)
|
||||
task_id TEXT NOT NULL REFERENCES tasks(id), -- 所属 Task
|
||||
title TEXT NOT NULL, -- 如 "策略编码"、"数据清洗"
|
||||
description TEXT DEFAULT '',
|
||||
status TEXT NOT NULL DEFAULT 'pending'
|
||||
CHECK (status IN ('pending','claimed','working','review','done','failed','blocked','cancelled')),
|
||||
assignee TEXT, -- 执行 Agent(如 zhangfei-dev)
|
||||
assigned_by TEXT, -- 分配者(通常是 pangtong-fujunshi)
|
||||
stage TEXT DEFAULT NULL, -- 所属 Stage 标签(如 "research"、"coding")
|
||||
stage_order INTEGER DEFAULT 0, -- Stage 内排序
|
||||
depends_on TEXT, -- JSON array of subtask ids(SubTask 间依赖)
|
||||
output_summary TEXT DEFAULT NULL, -- 产出物摘要
|
||||
output_path TEXT DEFAULT NULL, -- 产出物路径
|
||||
parent_project TEXT DEFAULT NULL, -- 实际工作所在 Project(跨项目时用)
|
||||
retry_count INTEGER NOT NULL DEFAULT 0,
|
||||
max_retries INTEGER NOT NULL DEFAULT 2,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
started_at TEXT,
|
||||
completed_at TEXT
|
||||
);
|
||||
CREATE INDEX IF NOT EXISTS idx_subtasks_task ON subtasks(task_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_subtasks_status ON subtasks(status);
|
||||
CREATE INDEX IF NOT EXISTS idx_subtasks_assignee ON subtasks(assignee);
|
||||
CREATE INDEX IF NOT EXISTS idx_subtasks_stage ON subtasks(task_id, stage);
|
||||
```
|
||||
|
||||
### 3.2 Task 表变更
|
||||
|
||||
在现有 tasks 表基础上,新增字段:
|
||||
|
||||
```sql
|
||||
ALTER TABLE tasks ADD COLUMN stages_json TEXT DEFAULT '[]'; -- Stage 定义(AI 生成)
|
||||
ALTER TABLE tasks ADD COLUMN plan_json TEXT DEFAULT NULL; -- 完整分解计划(庞统生成)
|
||||
```
|
||||
|
||||
**`stages_json` 格式**:
|
||||
|
||||
```json
|
||||
[
|
||||
{"id": "research", "label": "因子研究", "order": 1},
|
||||
{"id": "data_prep", "label": "数据准备", "order": 2},
|
||||
{"id": "coding", "label": "策略编码", "order": 3},
|
||||
{"id": "backtest", "label": "历史回测", "order": 4},
|
||||
{"id": "optimize", "label": "参数优化", "order": 5}
|
||||
]
|
||||
```
|
||||
|
||||
**`plan_json` 格式**:
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 1,
|
||||
"created_by": "pangtong-fujunshi",
|
||||
"created_at": "2026-05-18T08:00:00Z",
|
||||
"stages": [...],
|
||||
"subtasks": [
|
||||
{
|
||||
"id": "st-001",
|
||||
"title": "因子研究",
|
||||
"assignee": "zhangfei-dev",
|
||||
"stage": "research",
|
||||
"depends_on": [],
|
||||
"parent_project": null
|
||||
},
|
||||
{
|
||||
"id": "st-002",
|
||||
"title": "分钟线数据下载",
|
||||
"assignee": "zhaoyun-data",
|
||||
"stage": "data_prep",
|
||||
"depends_on": [],
|
||||
"parent_project": null
|
||||
},
|
||||
{
|
||||
"id": "st-003",
|
||||
"title": "策略编码",
|
||||
"assignee": "zhangfei-dev",
|
||||
"stage": "coding",
|
||||
"depends_on": ["st-001", "st-002"],
|
||||
"parent_project": null
|
||||
},
|
||||
{
|
||||
"id": "st-004",
|
||||
"title": "回测引擎搭建",
|
||||
"assignee": "jiangwei-infra",
|
||||
"stage": "backtest",
|
||||
"depends_on": [],
|
||||
"parent_project": "sanguo_vnpy"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 跨项目 SubTask
|
||||
|
||||
**`parent_project` 字段**:
|
||||
|
||||
- `NULL`:SubTask 在当前 Project 内执行
|
||||
- `"sanguo_vnpy"`:SubTask 实际工作在另一个 Project 目录
|
||||
|
||||
跨项目 SubTask 的执行流程:
|
||||
1. 庞统在 Task A(sanguo_quant_live)分解时,识别到需要回测引擎
|
||||
2. 创建 SubTask st-004,`parent_project=sanguo_vnpy`
|
||||
3. Ticker 在 sanguo_vnpy 项目也扫描到这个 SubTask(通过 cross-project 查询)
|
||||
4. 姜维在 sanguo_vnpy 执行完成后,结果写回 Task A 的 SubTask
|
||||
|
||||
**注意**:跨项目执行是复杂场景,v2.7 先做数据模型支持(字段存在),执行逻辑后续迭代。
|
||||
|
||||
### 3.4 现有表关联 SubTask
|
||||
|
||||
以下表新增 `subtask_id` 字段(可选,向后兼容):
|
||||
|
||||
```sql
|
||||
ALTER TABLE events ADD COLUMN subtask_id TEXT;
|
||||
ALTER TABLE comments ADD COLUMN subtask_id TEXT;
|
||||
ALTER TABLE outputs ADD COLUMN subtask_id TEXT;
|
||||
ALTER TABLE task_attempts ADD COLUMN subtask_id TEXT;
|
||||
```
|
||||
|
||||
这样 Events、Comments、Outputs 既可以关联到 Task 级别,也可以精确到 SubTask 级别。
|
||||
|
||||
---
|
||||
|
||||
## 四、Task 状态 = SubTask 状态聚合
|
||||
|
||||
Task 不独立维护复杂状态机,核心状态从 SubTask 推导(类似之前 Card 的聚合逻辑,但语义更自然):
|
||||
|
||||
| Task 状态 | 推导规则 |
|
||||
|-----------|---------|
|
||||
| `pending` | 所有 SubTask 都是 pending,或无 SubTask |
|
||||
| `working` | 有 SubTask 在 working |
|
||||
| `review` | 有 SubTask 在 review |
|
||||
| `done` | 所有 SubTask 都是 done |
|
||||
| `failed` | 有 SubTask failed 且无 active SubTask |
|
||||
| `blocked` | 有 SubTask blocked 且无 active SubTask |
|
||||
| `cancelled` | 用户/AI 取消(手动设置) |
|
||||
|
||||
**额外状态**(不属于聚合,手动设置):
|
||||
- `planning`:庞统正在分解 Task(生成 plan_json)
|
||||
- `challenging`:司马懿正在审核分解方案
|
||||
|
||||
---
|
||||
|
||||
## 五、API 路由
|
||||
|
||||
### 5.1 Task 级(已有,微调)
|
||||
|
||||
```
|
||||
GET /api/projects/{pid}/tasks → Task 列表(含 SubTask 聚合状态)
|
||||
POST /api/projects/{pid}/tasks → 创建 Task(用户需求)
|
||||
GET /api/projects/{pid}/tasks/{tid} → Task 详情 + Stage 进度
|
||||
PATCH /api/projects/{pid}/tasks/{tid} → 更新 Task(如取消、改优先级)
|
||||
DELETE /api/projects/{pid}/tasks/{tid} → 删除 Task
|
||||
```
|
||||
|
||||
### 5.2 SubTask 级(新增)
|
||||
|
||||
```
|
||||
GET /api/projects/{pid}/tasks/{tid}/subtasks → Task 下所有 SubTask(按 Stage 分组)
|
||||
POST /api/projects/{pid}/tasks/{tid}/subtasks → 创建 SubTask(AI/手动)
|
||||
GET /api/projects/{pid}/tasks/{tid}/subtasks/{stid} → SubTask 详情
|
||||
PATCH /api/projects/{pid}/tasks/{tid}/subtasks/{stid} → 更新 SubTask(状态、指派)
|
||||
POST /api/projects/{pid}/tasks/{tid}/subtasks/{stid}/status → 更新状态(Agent 回调)
|
||||
POST /api/projects/{pid}/tasks/{tid}/subtasks/{stid}/outputs → 提交产出
|
||||
```
|
||||
|
||||
### 5.3 便利路由
|
||||
|
||||
```
|
||||
GET /api/projects/{pid}/tasks/{tid}/progress → Stage 进度条数据
|
||||
GET /api/projects/{pid}/subtasks → 项目级所有 SubTask(跨 Task 查询)
|
||||
```
|
||||
|
||||
### 5.4 向后兼容
|
||||
|
||||
- 旧路由 `/api/projects/{pid}/tasks` 保留
|
||||
- 不传 SubTask 相关参数时行为不变
|
||||
- Task 的 status 仍然可用(聚合推导)
|
||||
|
||||
---
|
||||
|
||||
## 六、Ticker 变更
|
||||
|
||||
### 6.1 扫描逻辑
|
||||
|
||||
```python
|
||||
for project in registry.list_projects(status='active'):
|
||||
db_path = data_root / project.id / "blackboard.db"
|
||||
tasks = queries.tasks_by_status(db_path, ['pending', 'working', 'planning'])
|
||||
for task in tasks:
|
||||
# 1. 如果 Task 在 planning → 触发庞统分解
|
||||
if task.status == 'planning':
|
||||
dispatch_planning(task)
|
||||
continue
|
||||
# 2. 扫描 Task 下 pending 的 SubTask
|
||||
pending = queries.pending_subtasks(db_path, task.id)
|
||||
for subtask in pending:
|
||||
if deps_satisfied(subtask):
|
||||
dispatch_subtask(subtask)
|
||||
# 3. 聚合刷新 Task 状态
|
||||
refresh_task_status(db_path, task.id)
|
||||
```
|
||||
|
||||
### 6.2 调度粒度
|
||||
|
||||
- **调度单位**:SubTask(不是 Task)
|
||||
- **状态聚合**:每次 tick 刷新 Task 的聚合状态
|
||||
- **max_dispatch_per_tick**:全局限制(恢复 v2.6 语义)
|
||||
|
||||
---
|
||||
|
||||
## 七、前端改动(最小)
|
||||
|
||||
### 7.1 不改的
|
||||
|
||||
- 整体布局不变(Tab 栏 + 内容区)
|
||||
- 项目选择器保持下拉菜单
|
||||
- EdictBoard(Task 看板)基本不变
|
||||
|
||||
### 7.2 改的
|
||||
|
||||
1. **Task 详情弹窗(TaskModal.tsx)**:
|
||||
- 新增 Stage 进度条(从 stages_json 读取)
|
||||
- SubTask 列表(按 Stage 分组)
|
||||
- 每个 SubTask 显示:标题、Agent、状态、产出
|
||||
|
||||
2. **Task 看板卡片**:
|
||||
- 加 Stage 进度指示器(小进度条)
|
||||
|
||||
3. **Mail Tab**(后续独立实现):
|
||||
- 新增 Tab,列表展示 Sanguo Mail
|
||||
|
||||
### 7.3 暂不做的
|
||||
|
||||
- 独立的 SubTask 看板/管理页面
|
||||
- 跨 Project 的 Product 视图
|
||||
- Card 看板
|
||||
|
||||
---
|
||||
|
||||
## 八、实施计划
|
||||
|
||||
| 序号 | 任务 | 预计 |
|
||||
|------|------|------|
|
||||
| 1 | 回滚 Card 层(代码 + 设计文档归档) | 2h |
|
||||
| 2 | 新增 SubTask 表 + models + operations | 3h |
|
||||
| 3 | Task 表加 stages_json/plan_json + 聚合状态 | 2h |
|
||||
| 4 | SubTask API 路由 | 2h |
|
||||
| 5 | Ticker 适配(per-SubTask 调度 + 状态聚合) | 2h |
|
||||
| 6 | 前端 Task 详情弹窗改造(Stage 进度 + SubTask 列表) | 3h |
|
||||
| 7 | 测试 + 司马懿评审 | 2h |
|
||||
| **合计** | | **~16h** |
|
||||
|
||||
### 优先级
|
||||
|
||||
先回滚(1)→ 再建 SubTask(2-5)→ 前端(6)→ 评审测试(7)
|
||||
Reference in New Issue
Block a user