AgentEvalTool/docs/adr/0004-cross-run-aggregation-cancelled-excluded.md
sinohqb 782916a283 refactor(metrics): type Run summary and converge cross-run aggregation
Give EvalRun.summary a typed RunSummary value (unified RunError, lenient
legacy parsing) so readers stop reaching into a schemaless dict, and route
every cross-run rollup — dashboard, scenario ranking, trend, campaign
report — through one aggregate_runs seam. Fixes the divergence where
stats averaged pass_rate over completed-only runs while the campaign
report counted faults as 0.0. Cross-run rule (ADR-0004): genuine faults
count 0.0, user-cancelled runs are excluded from both denominators.
2026-07-31 01:57:56 +08:00

21 lines
2.2 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.

# 跨 Run 通过率聚合:故障计零、用户取消排除
ADR-0002 定义了单次 Run 内的通过率口径(用例级、含执行失败),但没有覆盖**跨 Run 聚合**(仪表盘总览、场景排行、趋势、活动周期报告)。实际代码里长出了两个矛盾口径:仪表盘对"仅已完成的 Run"求均值(故障 Run 被排除出分母),活动报告把失败 Run 计 0.0(除以全部)。决定统一为一个聚合规则,由单一函数实现,所有跨 Run 读者共用:
- **执行故障的 Run 计 0.0**——延续 ADR-0002 的服务视角:整个 Run 挂了,等价于该 Run 的所有用例都不达标;
- **用户手动取消的 Run 排除出分母**(含通过率与可用性)——取消是用户操作,不是被评对象的质量或可用性信号,计 0.0 会诬陷对象,计 1.0 会粉饰,排除是唯一诚实的处理;
- 取消与故障通过 `RunSummary.error.code == "cancelled_by_user"` 区分(取消 Run 的持久化状态仍是 failed
## Considered Options
- **仅对已完成 Run 求均值(仪表盘现状)** — 被否:故障期间仪表盘显示"质量正常",与 ADR-0002 的动机直接冲突;同一个 pass_rate 键在两处得出不同数字,无从解释。
- **非 completed 一律计 0.0(活动现状,单一规则最简)** — 被否:用户自己停掉的 Run 拉低质量分,指标不诚实;长期会让人不敢取消 Run。
- **保留两种聚合、显式命名service_pass_rate / completed_pass_rate** — 被否:两个函数就是两个口径,仪表盘与活动报告的数字依旧不可互相印证,分歧只是换了名字。
## Consequences
- 仪表盘 / 场景排行 / 趋势的数字会变:故障 Run 并入分母(数字下降),取消 Run 排除(略回升)。这是修正,不是回归。
- 活动周期报告的口径同步细化:用户取消的子 Run 不再计 0.0(此前极少发生,现有报告几乎不变)。
- 聚合逻辑必须收敛在一个函数里;任何新读者(未来的对比视图、导出)禁止自行读 `summary["pass_rate"]` 重新聚合。
- 取消的判别依赖统一的 `error.code`——错误形状(此前字符串/对象混用)必须随之统一。