AgentEvalTool/.scratch/v0.8/spec.md
sinohqb dd3b9a5e91 refactor(comparison): 评审修复 — 共享 gateway_chat_client、指标元表、对比区块组件化
- analysis/comparison 重复的 _gateway_chat_client 提取为共享 gateway_chat_client
- Campaigns.tsx 周期对比区块抽为 PeriodComparisonSection 组件,指标格式化
  收敛为单一 METRICS 元表(消除三处 metric 分支级联)
- 基线下拉排除无 completed_at 的终态活动(选中必 400)
- spec/issue 03 追认 delta 按好坏着色口径与 GET 生效基线合并口径
2026-08-03 14:26:20 +08:00

7.7 KiB
Raw Permalink Blame History

v0.8 — 周期对比Period Comparison

Problem Statement

运营者用评估活动对同一对象做周期性考察,每期末尾拿到一份智能分析(总体结论、问题诊断、改善建议)。但单期分析是孤立的:这一期的问题到底是新冒出来的、持续未愈的、还是已经消解的?上一期的改善建议落实了吗?要回答这些,人得自己打开两期报告逐条对照自由文本——而这正是平台该替人做的元层研判。

Solution

在相邻两期活动之间提供周期对比:机械 diff 给出两期聚合指标的客观变化(整窗与分场景的通过率/可用性/时延 deltaADR-0004 口径确定性计算LLM 在两期分析结论之上产出结构化演进叙述(趋势判断、问题演化、建议追踪)。报告抽屉内新增「周期对比」区块,与智能分析并列。正式线活动全链自动(活动完成 → 分析 → 对比),加速调试线手动按需。

User Stories

  1. 作为运营者,我希望打开本期活动报告时看到"与上一期相比"的指标变化表(整窗通过率/可用性/时延及分场景 delta以便快速判断走势。
  2. 作为运营者,我希望看到一个趋势徽章(改善/平稳/退化),以便不看数字也能感知方向。
  3. 作为运营者,我希望看到问题演化列表(新增/持续/消解,含涉及场景与说明),以便知道该担心什么、可以放下什么。
  4. 作为运营者,我希望看到上期建议的追踪状态(已落实/部分落实/未落实/新增),以便评估改进动作的有效性。
  5. 作为运营者,我希望正式线活动的对比在分析完成后自动生成,以便零操作拿到结论。
  6. 作为调试者,我希望加速线活动能手动点「生成对比」,以便验证功能而不等完整周期。
  7. 作为运营者,当本期活动计划与历史不一致(无自动基线)时,我希望能手动挑选一个历史活动作基线,以便换计划后仍能对比。
  8. 作为运营者,我希望对比生成失败时看到原因并可重试,以便区分模型问题与数据问题。
  9. 作为运营者,我希望对比叙述与指标 diff 分开呈现(叙述是 LLM 判断、数字是确定性计算),以便知道哪部分可以较真。
  10. 作为管理员,我希望对比复用「分析默认」模型(活动覆盖 ?? 全局默认),以便不引入新的配置面。
  11. 作为运营者,我希望对比中引用的场景是真实存在的(白名单过滤),以便不被模型虚构误导。

Implementation Decisions

配对(计划指纹 + 自动基线)

  • 计划指纹 = 评测对象 + 计划条目集合(场景 id、偏移秒数、次数+ 窗口秒数。指纹相等的正式线活动构成活动串
  • 自动基线 = 同活动串中、完成时间早于本期、且已有 completed 分析的最近一期活动
  • 指纹不一致 → 无自动基线;POST /comparison 接受可选 baseline_campaign_id 手动指定(跨串允许,可比性由用户负责)
  • 基线活动被删或分析被重置 → 视为无基线

产出(混合:机械 diff + LLM 叙述)

  • 机械 diff:纯函数,输入两期 generate_campaign_report 结果,输出整窗 + 分场景的通过率/可用性/时延 delta读时现算不存储
  • LLM 叙述:单次调用(不做两阶段——输入只有两份已消化的分析 JSON + 机械 diff无原始样本输入上限轻量输出结构化 JSON
{
  "trend": "improving | stable | regressing",
  "summary": "总体演进结论",
  "problem_evolution": [{"status": "new | persisting | resolved", "title", "detail", "scenario_ids": []}],
  "suggestion_tracking": [{"text", "status": "addressed | partial | unaddressed | new", "note"}]
}
  • 叙述中的 scenario_ids 落库前过白名单(同 v0.7);非法 trend/status 枚举归一trend→stablestatus→persisting / unaddressed
  • LLM 解析失败 → 行落 failed + error

存储与生命周期

  • 新表 campaign_period_comparisons:当前活动 id 唯一 upsert、baseline_campaign_id、generating/completed/failed、result叙述 JSON、model_config_id 快照、error、triggered_byauto/manual、时间戳——镜像 campaign_analyses 模式
  • 模型解析复用 v0.7 resolve_analysis_model(活动覆盖 ?? 全局分析默认);不可解析 → 自动链静默跳过 / 手动 400 引导
  • 自动链:execute_campaign_analysis 成功落 completed 后,活动为正式线且存在自动基线 → enqueue 对比生成;任一前提不满足静默跳过
  • 重新生成(手动 POST= 同活动 upsert 覆盖,可借此更换基线重算

API

  • GET /api/campaigns/{id}/comparison:无行 → 空态 {"status": "none"};有行 → 机械 diff现算+ 叙述行合并返回;附 baseline_campaign_id 与自动配对结果,前端据此渲染或引导选基线。metric_diff 跟随生效基线:有对比行按行内基线算,否则按自动基线算
  • POST /api/campaigns/{id}/comparisonbody 可选 {"baseline_campaign_id": "..."};非终态活动 400当前活动无 completed 分析 400先生成分析无模型 400 引导;成功 → 后台任务 + {"status": "generating"}
  • 两期都有 completed 分析是生成前提(基线无分析 → 400 提示先生成基线分析)

前端(报告抽屉「周期对比」区块)

  • 位置:「智能分析」区块之下,复用区块状态行范式(生成中 5s 轮询 / 失败重试 / 未生成按钮)
  • 已生成:趋势徽章 + 总结 → 指标变化表(整窗 + 分场景 delta按好坏着色——比率升为绿、时延降为绿反之红→ 问题演化(新增红/持续橙/消解绿 Tag→ 建议追踪(已落实绿/部分橙/未落实灰/新增蓝)
  • 无自动基线:基线选择器(同对象历史终态活动下拉)+ 生成按钮
  • 展示基线活动名与完成时间、所用分析模型名与生成时间

Testing Decisions

好测试只测外部行为,不测实现细节;全部落在既有最高层 seam

  1. 机械 diff 纯函数:手搓两份报告 dict断言 delta 结构与数值、空桶/None 处理(先例如 test_report_render.py
  2. 计划指纹与自动基线:内存 SQLite指纹相等/不等、跳过无分析活动、跳过非正式线、取最近一期(先例如 test_campaign_analysis.py 的仓储测试)
  3. LLM 叙述编排FakeChatClientv0.7 seam覆盖成功编排、解析失败→AnalysisError 式失败、白名单剔除虚构 scenario_ids、非法枚举归一
  4. API 集成:镜像 test_campaign_analysis_api.py——GET 空态、POST 非终态 400、无分析 400、无基线 400、手动指定基线成功、重跑 upsert 不新增行
  5. 自动链spy 对比入口,断言分析完成后正式线自动触发、加速线不触发、无基线不触发(镜像 test_campaign_analysis_auto_trigger.py
  6. 迁移测试:表存在 + campaign_id 唯一约束(先例如 test_campaign_analyses_migration.py

Out of Scope

  • 跨活动对比(多对象横切)——词汇表中另一个轴,本规格不涉及
  • 活动列表趋势标记(↑↓)——后续增强
  • 对比结果纳入 Markdown 导出——看使用情况再定
  • 基线活动的选取 UI 优化(如按指纹分组展示)
  • 三期以上的趋势序列(只对比相邻两期)

Further Notes

  • 设计决策源自 /grill-with-docs 访谈6 问 6 决):配对 A、产出 C 混合、呈现 A 抽屉区块、生命周期 A 新表+联动触发、输入 A 轻量、输出 A 结构化
  • 「周期对比」「正式线/加速调试线」已入 CONTEXT.md 词汇表
  • 对比不重新消化失败样本:样本已被两期分析消化,对比是元层研判