Some checks failed
CI / test (push) Failing after 46s
.scratch/v0.6/spec.md:评估活动 v1(静态地基)规格——单对象、可配服务 周期窗口、耐久调度、双主轴周期报告、time_scale 时间倍速。5 张 tracer- bullet 票(持久化/API → 调度决策+派生 → 耐久回路+恢复 → 双轴报告 → 前端页),依赖边 ①→②→③、②→④、①③④→⑤。
93 lines
9.5 KiB
Markdown
93 lines
9.5 KiB
Markdown
# v0.6 Spec — 评估活动(Campaign)v1 静态地基
|
||
|
||
**状态**: ready-for-agent
|
||
**领域词汇**: 见 CONTEXT.md「周期评估」章节(评估活动 / 服务周期窗口 / 活动计划)
|
||
**关键决策**: ADR-0003(分期:v1 静态地基、v2 自适应回路;OpenClaw 进调度热回路的取舍)
|
||
|
||
## Problem Statement
|
||
|
||
被评智能体(AI 数字员工 / AI 助手)提供的是 7×24 的持续服务,但现有平台只能做「一个对象 × 一个场景」的单次评测(Run)。用户拿不到「这个智能体在一个完整服务周期内,服务质量如何随时间波动」的画像——夜间是否降级、高峰是否变慢、凌晨无人值守时表现如何,这些只有跨时段持续采样才能暴露。用户需要一种能在一个可配置长度的服务周期窗口内、按计划持续对同一对象施加多场景评测、并汇总成周期报告的能力。
|
||
|
||
## Solution
|
||
|
||
引入**评估活动(Campaign)**:针对单个评测对象、跨一个服务周期窗口(可配 6/12/24/48/72 小时)的评估聚合。用户定义一份**静态活动计划**(在窗口的哪些时间点、对哪个场景、跑几次),平台的**耐久调度器**在窗口内按计划持续派生普通 Run,最后聚合成**双主轴周期报告**(时间趋势 + 能力汇总)。活动状态入库、抗重启:服务重启后调度器从数据库恢复,继续未完成的窗口。多对象通过并行多个活动 + 跨活动对比实现(跨活动对比可后续迭代)。
|
||
|
||
v1 计划是静态的(手工定义,或后续由 OpenClaw 在启动时一次性生成);OpenClaw 在窗口内依结果自适应重规划的能力是 v2(ADR-0003)。
|
||
|
||
活动支持**可配时间倍速**:正式线用真实墙钟(24h 活动真的持续 24h,采到真实的凌晨/高峰表现);开发线可设压缩倍速(如把 24h 压成几分钟)快速验证调度与聚合,不改变任何判定语义。
|
||
|
||
## User Stories
|
||
|
||
1. 作为质量负责人,我想对一个数字员工发起一个 24 小时评估活动,以便看到它一整天的服务质量画像。
|
||
2. 作为质量负责人,我想自定义活动窗口长度(6/12/24/48/72h),以便匹配不同的服务周期考察需求。
|
||
3. 作为质量负责人,我想在活动计划里指定"哪些时段跑哪个场景、各跑几次",以便模拟真实用户在一天里不同时间的不同诉求。
|
||
4. 作为质量负责人,我想让活动只针对单个评测对象,以便活动身份清晰、报告维度单纯。
|
||
5. 作为质量负责人,我想在活动进行中查看它的实时进度(已派生多少 Run、当前窗口位置、已完成时段的通过率),以便掌握活动健康度。
|
||
6. 作为质量负责人,我想在活动结束后得到一份周期报告,主轴一是**时间趋势**(通过率/可用性/时延随时段的曲线),以便发现质量随时间的波动。
|
||
7. 作为质量负责人,我想周期报告的主轴二是**能力汇总**(按场景/能力维度聚合的整窗表现),以便看到这一周期里哪些能力强、哪些弱。
|
||
8. 作为质量负责人,我想活动派生的每个 Run 仍是标准 Run(可单独打开看逐轮对话与判定),以便下钻排查具体失败。
|
||
9. 作为运维,我想活动在服务重启后能自动恢复继续跑,以便长窗口活动不因一次部署而中断作废。
|
||
10. 作为运维,我想中途取消一个进行中的活动,以便及时止损;已完成的子 Run 结果保留。
|
||
11. 作为开发者,我想在开发线用时间压缩倍速把 24h 活动压成几分钟跑完,以便快速验证调度与报告聚合。
|
||
12. 作为质量负责人,我想活动列表能看到每个活动的对象、窗口、状态(计划中/进行中/已完成/已取消/失败)、整窗通过率,以便一览管理。
|
||
13. 作为质量负责人,我想活动的通过率口径与单 Run 一致(用例级、含执行失败,ADR-0002),以便跨层数字可比。
|
||
14. 作为质量负责人,当某个时段的 Run 因通道故障失败时,我想它照常计入周期报告(失败也是质量信号),以便报告反映真实可用性。
|
||
15. 作为质量负责人,我想活动报告能导出(复用现有导出能力),以便存档与分享。
|
||
|
||
## Implementation Decisions
|
||
|
||
### 领域与聚合
|
||
- **评估活动是 Run 之上的新聚合**,不是巨型长命 Run。活动按计划派生多个普通 Run(每个仍是"一个对象 × 一个场景 × 一个时段"),完整复用现有引擎、规则、判定(judgement)、单 Run 报告。
|
||
- **单对象**:一个活动绑定一个 `target_id` + 一份计划(计划条目引用若干 `scenario_id`)。多对象=并行多个活动。
|
||
- 子 Run 通过一个新的可空外键 `campaign_id` 归属到活动;非活动派生的手动 Run 该字段为空。子 Run 复用现有 `EvalEngine.run(existing_run=...)` 派生路径。
|
||
|
||
### 活动计划(静态)
|
||
- 计划是一组条目,每条描述:目标场景、在窗口内的触发时间点(相对窗口起点的偏移)、重复次数/强度。存为活动记录上的 JSON(仿现有 cases 的 JSON 列存取),不新建计划子表。
|
||
- 计划由用户创建活动时提供;v1 不含 OpenClaw 生成/自适应(ADR-0003)。
|
||
|
||
### 耐久调度器
|
||
- 平台新建一个耐久调度子系统,生命周期挂在 Web 应用 lifespan:启动时从数据库加载所有"进行中"的活动并恢复推进,关闭时优雅停止。
|
||
- **调度决策是纯函数**:给定活动计划 + 当前活动时钟位置,算出"此刻应派生哪些 Run / 活动是否已达窗口终点"。外层是薄的异步循环 + 派生 Run 的副作用壳。这是主要的新可测接缝,仿 v0.5 的 `combine_case_outcome`。
|
||
- **抗重启**:活动状态(窗口起止、已完成/已派生进度)入库;进程内不持有权威状态。重启后调度器据库恢复。沿用 `mark_orphans_failed` 的思路处理重启时正在跑的子 Run。
|
||
- **时间倍速**:活动记录带 `time_scale`(默认 1.0=真实墙钟)。活动时钟 = (真实经过时间 × time_scale) 映射到窗口位置。倍速只影响"何时派生 Run",不影响任何判定/报告口径。开发线可设大倍速加速;正式线用 1.0。
|
||
|
||
### 报告聚合(双主轴)
|
||
- 新增活动报告聚合纯函数:消费该活动全部子 Run 的 summary,产出两轴:
|
||
- **时间趋势轴**:按时段桶聚合通过率/可用性/时延(仿 stats.py 的 trend 按时间分桶取均值)。
|
||
- **能力汇总轴**:按场景/能力维度聚合整窗表现(仿 stats.py 的 dashboard 分组取均值)。
|
||
- 通过率口径沿用单 Run 的用例级、含执行失败(ADR-0002),保证跨层可比。
|
||
- 报告导出复用现有 report 渲染/导出能力。
|
||
|
||
### API 与前端
|
||
- 新增活动 API:创建 / 列表 / 详情(含进度)/ 报告 / 取消,形状与命名沿用现有 `runsApi` 风格。
|
||
- 前端新增「评估活动」页(keep-alive tab,仿现有页面注册方式):活动列表 + 创建 + 进度 + 双主轴报告视图。`api.ts` 新增 `campaignsApi` 与 `Campaign`/`CampaignReport` 类型。
|
||
|
||
### 持久化与迁移
|
||
- 新增活动表(含窗口、状态、计划 JSON、time_scale、时间戳);`EvalRunDB` 加可空 `campaign_id`。
|
||
- Alembic batch mode 迁移(SQLite),沿用现有迁移链与 `render_as_batch=True` 约定;`init_db` 的 create_all 覆盖全新库。
|
||
|
||
## Testing Decisions
|
||
|
||
- **好测试只验外部行为**:断言 API 契约、调度决策的输出、报告聚合的数值,不耦合内部实现细节。
|
||
- **三接缝**(已与用户确认):
|
||
1. **API 集成接缝**:`POST/GET /api/campaigns`、`GET /api/campaigns/{id}/report`、取消——用 `test_runs_api.py` 同款 httpx AsyncClient + MockChannel + monkeypatch get_session 端到端测。
|
||
2. **调度决策纯函数接缝**:`due_entries(plan, clock) -> 待派生条目`,注入任意时钟/倍速,无需真实定时器,仿 `test_orphan_runs.py` 的纯 `db_session` 风格。
|
||
3. **活动聚合纯函数接缝**:`generate_campaign_report`,用 `_seed_run × N` 构造多子 Run 后断言两轴数值,仿 `test_report.py`。
|
||
- **时间压缩用于测试**:调度决策纯函数吃注入时钟,测试可瞬间推进整个窗口,无需等待。
|
||
- **抗重启测试**:构造"进行中"活动 + 部分子 Run,模拟重启后调度恢复,断言不重复派生、不丢进度。
|
||
- 现有 `conftest.py` 的 `db_session`/TestClient 夹具与显式模型 import 列表需加入新活动模型。
|
||
|
||
## Out of Scope
|
||
|
||
- **OpenClaw 生成/自适应计划**(v2,ADR-0003):v1 计划静态、执行期不依赖 OpenClaw。
|
||
- **Layer 2 逐轮自由漫游**:时段内对话仍由现有动态用例生成器产出,不做 OpenClaw 逐轮即兴。
|
||
- **跨活动对比视图**:多对象对比留待后续迭代;v1 先把单活动闭环。
|
||
- **人设(persona)深度建模**:v1 计划条目可带轻量人设标签,但不强制影响生成;深度人设留待 v2。
|
||
- **告警/通知**:活动异常主动通知不在 v1。
|
||
|
||
## Further Notes
|
||
|
||
- 与既有决策的一致性:单对象聚合 + 通过率用例级含故障,均与 ADR-0001/0002 对齐。
|
||
- 风险点:耐久调度器是全新子系统,长窗口 + 重启恢复是主要复杂度来源;建议 to-tickets 时把「调度决策纯函数 + 持久化 + 恢复」作为最早的 tracer-bullet,先立稳地基再叠 API/前端/报告。
|
||
- 时间倍速是把双刃剑:务必保证它只影响派生时机,绝不渗入判定/报告口径,否则开发线与正式线数字不可比。
|