AgentEvalTool/.scratch/v0.9/spec.md
sinohqb 6340ec503c feat(exploration): stateless patrol API with watermark increments
Resident agents call GET /api/exploration/patrol once per cycle to see
every running production-line campaign that opted into exploration
(seed set present), the new results since the last watermark (reusing
campaign report aggregation), and the remaining exploration budget.
The watermark advances after each call so subsequent calls only report
increments; accelerated and terminal campaigns are excluded.
2026-08-03 18:12:11 +08:00

114 lines
10 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.

# v0.9 规格说明:探索式评测第一期 —— 周期活动内嵌虚拟用户探索
**状态**: ready-for-agent
**日期**: 2026-08-03
**决策依据**: ADR-0003 v2 修订2026-08-03、CONTEXT.md「探索式评测」章节、grilling 共识清单15 项)
## Problem Statement
平台的评测能力目前全部建立在"固定场景(考纲)"之上:预设题目、预设规则、统计通过率。这能回答"考纲过了多少",回答不了"真实用户会踩到什么"——真实用户不按考纲出牌,他们会中途改主意、追问、被绕晕、放弃。被评智能体在面对这类复杂拟真行为时的表现(问题诊断与优化建议)目前没有任何评测手段。
## Solution
引入与固定场景并行的**探索式评测**模式OpenClaw 作为**虚拟用户**,按活动配置的种子人设 × 种子目标自主与被评对象对话,产出**体验记录**目标达成、卡点、被误导处judge 岗位抽样复核两条证据线汇入活动报告、v0.7 分析与 Markdown 导出。
第一期形态为**周期活动内嵌探索**:现有活动骨架不变(静态计划照常执行),全局一个常驻巡检代理(跑在已集成的 AI 助手上heartbeat/cron 唤醒按节拍巡检进行中的正式线活动在预算内派发探索会话。OpenClaw 停摆只暂停探索,固定计划照常完成——耐久性归平台,自主性归代理。
## User Stories
1. As an 评测平台用户, I want 创建活动时配置该活动的种子集(种子人设 + 种子目标), so that 虚拟用户的行动有据可依,且同种子集的活动跨期可比
2. As an 评测平台用户, I want 创建活动时调整探索预算(或使用平台默认值), so that 探索行为的规模与负载在我的掌控之内
3. As an 平台运维者, I want 部署时 AI 助手注册一个全局常驻巡检作业, so that 所有进行中的正式线活动被自动巡检,无需逐活动配置
4. As an 常驻代理, I want 每次巡检唤醒时调平台巡检 API 拿到进行中活动、上次巡检以来的新结果与预算余量, so that 我能无状态地自主决定"继续观察 / 派探索会话"
5. As an 常驻代理, I want 通过 API 创建探索会话(指定活动、人设、目标、种子出处), so that 我能以虚拟用户身份开始行动
6. As an 常驻代理, I want 通过会话 API 发消息并收到被评对象的回复, so that 我能按人设自主决定追问、等待、放弃
7. As an 常驻代理, I want 在会话结束时提交结构化体验记录, so that 我的第一手判定(达成/卡点/被误导)被平台留痕
8. As an 常驻代理, I want 超出预算时收到 API 明确的 409 拒绝与原因, so that 拒绝本身成为反馈信号,我及时收敛
9. As an 常驻代理, I want 在预算内从种子衍生变体(同目标换表达、同人设换追问策略)并被标记衍生出处, so that 行为多样性与留痕兼得
10. As an 评测平台用户, I want 在活动报告抽屉看到"探索发现"区块(会话数、目标达成率、问题清单), so that 我知道真实用户遭遇了什么
11. As an 评测平台用户, I want 点开单个探索会话查看完整对话与体验记录, so that 每个"问题"都能下钻到原文证据
12. As an 分析岗位模型, I want 生成活动分析时收到探索摘要(问题清单 + 达成统计,非全量对话), so that "固定场景成绩"与"真实用户遭遇"两条证据线合成一份结论
13. As an judge 岗位模型, I want 对抽样的探索对话做独立复核, so that 体验判定之外有客观质量维度(态度、专业性、幻觉)
14. As an 报告导出用户, I want Markdown 导出在存在探索数据时追加"探索发现"区块, so that 离线分享材料完整;无探索数据时导出与旧版一致
15. As an 加速调试线用户, I want 手动触发探索会话, so that 我能调试探索流程;同时加速线不被自动巡检打扰(时间压缩与拟真冲突)
16. As an 平台, I want OpenClaw 停摆时活动的固定计划照常走完, so that 探索是增强层而非单点故障
17. As an 平台, I want 活动窗口结束时仍未关闭的探索会话被妥善结算(标记状态、不再接受消息), so that 不留悬挂会话
18. As an 评测平台用户, I want 探索会话与固定场景的子 Run 在报告里清楚区分, so that 通过率口径ADR-0002不被探索数据污染
## Implementation Decisions
### 数据模型
- 新增**探索会话**独立实体不并入评测运行归属活动、指向评测对象、人设JSON、目标、种子出处可空 = 衍生变体须回溯到种子、状态机running / completed / failed / expired、触发来源auto / manual、体验记录 JSON、judge 复核 JSON、轮次计数、时间戳
- 新增会话轮次表role、content、latency_ms、created_at与评测运行的 turns 表平行,不复用
- 活动实体新增两个 JSON 配置字段(与 `plan` 同构地位):**种子集**(种子人设数组 + 种子目标数组)、**探索预算**(最大会话数 / 单会话最大轮数 / 会话最小间隔,空则取平台默认)
- 活动实体新增 `last_patrolled_at`(巡检 API 每次读取后更新,支撑"上次巡检以来的新结果"语义)
- 三个变更各走一个 Alembic 迁移batch mode
### API 契约(全部 X-API-Key 鉴权,沿用 `require_api_key`
- `GET /api/exploration/patrol`返回进行中的正式线活动time_scale == 1清单每项含活动 id/名称/对象、自 `last_patrolled_at` 以来的新结果摘要(复用 `build_campaign_report` 聚合口径)、探索预算余量;响应生成后更新各活动 `last_patrolled_at`
- `POST /api/exploration/sessions`body = campaign_id、persona、goal、seed_ref可空平台硬校验活动存在且 running、正式线仅接受 auto 或 manual 触发;加速线仅接受 manual预算余量→ 创建 running 会话;超限 409 + 原因
- `POST /api/exploration/sessions/{id}/messages`body = content平台转发到目标的通道复用 ChannelFactory、持久化双方轮次、返回回复与延迟单会话轮数超限 409会话非 running 状态 409
- `POST /api/exploration/sessions/{id}/close`body = 体验记录goal_achieved: bool、blockers[]、misled[]、emotion、notes结构校验 + 非法值归一(沿 v0.7 白名单经验);会话转 completed
- `GET /api/campaigns/{id}/exploration`:会话列表 + 探索发现聚合(会话数、达成率、问题清单)
- 活动窗口 finalize 时:仍 running 的会话转 expired不再接受消息`resolve_finalize` 同处挂接)
### 护栏(平台硬执行,不信任客户端自律)
- 平台默认≤8 会话/窗口、≤12 轮/会话、相邻会话 ≥30min正式线真实时间活动级预算覆盖
- 预算计数是平台账本:创建/发消息/关闭均实时校验,超限一律 409
### 判定双证据线
- 体验判定close 接口收结构化自报,为第一手证据
- judge 抽样复核:会话结束后平台对对话抽样(默认 ≤3 段,控 token经 judge 岗位模型产出质量维度复核ChatClient 可注入(沿 v0.7 分析 seam异步后台执行失败落错误不阻塞
### 报告 / 分析 / 导出
- 活动报告聚合新增"探索发现"维度(会话数、目标达成率、问题清单来自体验记录聚合);周期对比口径不变(探索数据不参与)
- v0.7 分析输入追加探索**摘要**(问题清单 + 达成统计,非全量对话)
- Markdown 导出:存在探索数据时追加「探索发现」附录(缺则无痕),附录顺序:智能分析 → 周期对比 → 探索发现
### 前端
- 活动创建表单:种子集与预算配置输入(种子可留空 = 该活动不参与探索)
- 报告抽屉新增「探索发现」区块(模式沿 v0.7 智能分析区块):达成率、问题清单、会话列表;会话点开查看完整对话 + 体验记录
- 不建新顶级页面
### AI 助手侧(不在平台代码仓内的行为,契约即平台 API
- 现有已集成 OpenClawAI 助手菜单、openclaw-eval 容器)上扩展巡检/探索 skill走部署脚本既有 skill 同步管线
- 注册一个全局常驻 heartbeat/cron 巡检作业(节拍默认 1h巡检 API 本身与节拍无关
### 档位
- 正式线time_scale == 1自动巡检 + 自动派发
- 加速调试线:仅手动触发会话,不参与自动巡检
## Testing Decisions
- 好测试只测外部行为API 契约、状态机迁移、护栏拒绝、聚合口径、渲染产物;不测内部编排细节
- **集成测试TestClient主力接缝**:会话生命周期(创建→对话→关闭)、护栏 409 各分支(超会话数/超轮数/间隔不足/加速线 auto 拒绝)、巡检 API 内容与 last_patrolled_at 推进、finalize 结算 expired、报告/导出纳入。先例:`test_campaigns_api.py`、`test_campaign_comparison_api.py`
- **纯函数单测**:探索发现聚合 + Markdown 渲染dict 进 string 出)。先例:`test_report_render.py`
- **假客户端测试**judge 抽样复核与分析输入扩展,注入假 ChatClient。先例`test_campaign_analysis.py`
- 前端仅 `tsc --noEmit`(无 vitest沿用现状
- AI 助手 skill 行为不进自动化测试,靠部署后端到端验证(与 v0.4 以来 agenteval-run skill 验收方式一致)
## Out of Scope
- 双轨之二「探索活动」独立活动类型OpenClaw 全权接管生命周期)——后续里程碑
- 周期对比扩展(探索数据跨期对照)——待种子集指纹与达成率口径稳定
- 计划条目重排(原 ADR-0003 v2 字面意义的"自适应重规划")——本期代理只派发探索会话,不改写静态计划
- 全局种子库/人设库(活动级配置已够,复用需求出现再提取)
- 事件驱动唤醒(纯 heartbeat/cron 巡检)
- 前端测试基线vitest
- volcengine-102 同步
## Further Notes
- 词汇表与 ADR 已先行落地commit c35159fCONTEXT.md「探索式评测」章节、ADR-0003 v2 修订
- 巡检 API 的"新结果摘要"复用 `build_campaign_report` 聚合口径,不重算新指标
- OpenClaw heartbeat/cron 事实依据:作业持久化 SQLite、重启不丢、瞬态错误重试、连续 10 次失败自动禁用——天然熔断,与"决策点不可用则跳过"的可靠性边界吻合
- 里程碑目录 `.scratch/v0.9/`,票据由 `/to-tickets` 生成于 `issues/`