返回 AICAP-180
B17 · Day 165outcome 指标仪表盘 + A/B

活仪表盘聚合

Day 161 立了 4 指标骨架,Day 162-164 分别把 FPR / SAR 质量 / cost-per-case / p95 四个指标落地。

阶段: B17 · outcome 指标仪表盘 + A/B(Day 161-170) 标签: #dashboard #snapshot #delta-trend #otel-genai

今日导引(由浅入深)

Day 161 立了 4 指标骨架,Day 162-164 分别把 FPR / SAR 质量 / cost-per-case / p95 四个指标落地。

今天 Day 165 把它们合成一个东西——一个 snapshot JSON,并加 delta 字段对比上一次 run,让你一眼看出 FPR 是在降还是在升。

在 B1→B18 曲线上,这是 outcome 度量从「四个孤立数字」收敛成「可追踪趋势的活仪表盘」的一步;明天 Day 166 再把这个 snapshot 渲染成 UI 指标卡。

最小可判定产出:dashboard.ts 聚合四指标成一个 snapshot JSON、加 delta 字段,单测断言 schema 完整(4 指标键齐全 + delta 存在)。

1. 机理精读

为什么要 snapshot + delta,而不只是当前值。

单看「FPR=0.18」无法判断系统在变好还是变坏。

delta = 本次值 − 上次 run 值,方向(在降/在升)往往比绝对值更有决策价值——

一个 FPR=0.18 但每次 run 都在降的系统,比一个 FPR=0.15 但在持续上升的系统更健康。

所以仪表盘的核心不是「快照」,而是「快照 + 与历史的差分」。

delta 的方向语义要按指标极性解读。

这点今天先在数据层埋好、明天 UI 层用:

  • FPR 的 delta 为负(在降)是好事;
  • SAR 质量的 delta 为正(在升)是好事。

同一个「负 delta」对不同指标含义相反。

今天 dashboard 层只负责算出 delta(纯差分),不负责着色;着色按极性是 Day 166 UI 的事。数据层保持中立、只给原始 delta,是正确的分层。

为什么聚合层必须是纯函数 + 接 live 数据。

src/agent/eval/dashboard.ts 的设计原则(头注释):「Pure (takes reports in); the fs reader lives in scripts/build-dashboard.ts so this stays bundler-safe.」

聚合逻辑不读文件系统,只接 reports 数组进来,这样它:

  1. 既能在浏览器构建里安全运行;
  2. 又能被确定性单测。

文件读取(live data)放在 scripts/build-dashboard.ts。这是「纯计算与 IO 分离」的标准分层。

与相邻概念的边界。

今天产出的是「schema + delta 逻辑」这套已测纯函数,外加 cost 项可填真值 $0.0139。

但「含真实 4 指标值的完整 snapshot」是部分待跑的:FPR/SAR 质量/p95 这三项要等 eval run(需 key)才有真值;只有 cost 项有已测真值。

今天不臆造 FPR/质量/p95 的真值,只保证 snapshot 结构与 delta 计算正确。

2. 推导 / 手算 / 代码走读

src/agent/eval/dashboard.tsbuilt(63 行,已读)。当前实现走读 + 本日扩展点:

  • buildDashboard(reports)

    • EvalReportLike[],返回 DashboardSnapshot { runs, totalTasks, nsm, leaves, note? }
    • 当前快照是「北极星指标(NSM:task autonomous completion)+ 叶子指标」结构;
    • 叶子含 partial-credit mean / code-check pass / unknown rate / cost (USD/run) / judge-human kappa
  • 空报告守卫reports.length === 0 时返回 nsm.value=nullleaves=[]note: 'no eval reports yet — run \pnpm eval:agent` (needs an API key) to populate live data'`——诚实标注需 key 才有 live data。

  • avg(xs) / num(sel)

    • avg 空数组返回 null;
    • num 只挑出 typeof x === 'number' 的值(过滤掉 null/undefined),保证缺指标项不污染均值。
  • 本日扩展点(与 seed 对应)

    • 要把 161-164 的四 outcome 指标(FPR / SAR 质量 / cost-per-case / p95)作为快照键纳入;
    • 并新增 delta 字段(本次值 − 上次 run 值);
    • 当前 dashboard.ts 已有 leaves 聚合骨架与 cost/kappa 项,但尚无 delta 字段——delta 逻辑是本日要补的纯函数扩展;
    • 单测断言「4 指标键齐全 + delta 存在」。

delta 手算:

上一 run snapshot { fpr: 0.22, sarQuality: 0.78, costPerCase: 0.30, p95: 800 },本次 run { fpr: 0.18, sarQuality: 0.84, costPerCase: 0.28, p95: 720 }

逐项 delta = 本次 − 上次

  1. fpr: 0.18 − 0.22 = −0.04(在降,对 FPR 是好)
  2. sarQuality: 0.84 − 0.78 = +0.06(在升,对质量是好)
  3. costPerCase: 0.28 − 0.30 = −0.02(在降,好)
  4. p95: 720 − 800 = −80(在降,好)

注意上面的 0.18/0.84/0.28/720 都是口径示范的假设值,非真值——真值要等 eval run;唯一能填真值的是 cost 项 $0.0139。

单测只断言 delta 计算正确与 schema 完整,不断言这些示范数字。

3. 今日实战

  1. src/agent/eval/dashboard.ts 把 161-164 四指标(FPR / SAR 质量 / cost-per-case / p95)纳入 snapshot 键。
  2. 新增 delta 字段:对每个指标算 本次值 − 上次 run 值(缺历史时 delta 置 null)。
  3. cost 项可填已测真值 $0.0139;FPR/SAR 质量/p95 留待 eval run 填真值。
  4. 写单测断言 schema 完整(4 指标键齐全 + delta 存在)并断言 delta 计算确定性,跑 pnpm test

4. 今日实测 / 产出

  • dashboard.ts 已 built
  • snapshot schema 完整性单测可跑 pnpm test确定性)。
  • 含真实 4 指标值的完整 snapshot = 部分待跑:FPR / SAR 质量 / p95 需 eval run 填真值,cost 项可填 $0.0139 真值
  • schema 与 delta 逻辑为已测纯函数。不臆造 FPR/质量/p95 真值。

5. 常见误区 / 陷阱

  • 在数据层就按极性着色:dashboard 层只给原始 delta,着色(FPR↓绿、质量↑绿)是 Day 166 UI 的事——分层别越界。
  • 缺历史时硬塞 delta=0:首个 run 没有上一次值,delta 应为 null,不是 0(0 会被误读成「持平」)。
  • 把示范 snapshot 数字当真值:0.18/0.84/720 是口径示范假设值,只有 cost $0.0139 是真值。
  • 聚合层读文件系统:会破坏 bundler-safe,IO 必须留在 scripts/build-dashboard.ts
  • 自造指标名:沿用 OTel gen_ai.* 语义约定,别另起一套命名。

6. 学习资源(每条带 YYYY-MM)

  • OTel GenAI semantic conventions(2026-01/2026-03)——指标/span 命名规范(gen_ai.*),仅借命名、本仓未真接 wiring。
  • Anthropic「Demystifying evals」——metric-tree(NSM + 叶子)评测仪表盘思路(2026-01)。
  • 本仓代码:src/agent/eval/dashboard.tsbuildDashboard 聚合纯函数 + 空报告守卫)、scripts/build-dashboard.ts(fs reader,IO 分离)、src/agent/eval/stats.ts(p95 来源)。

SOTA检查 (2026-06 更新)

  • 当前主流:OTel GenAI 语义约定(2026-01)仍是指标/span 命名 SOTA;NSM + 叶子 + delta 趋势是稳定的仪表盘范式。
  • 过时黑名单:避免自造指标名,沿用 gen_ai.* 约定。
  • gated 现状:实际 OTel wiring 本仓尚未接(attributeMap.ts 注释亦明确「当前不真正上报」),仅借命名规范——不得宣称已接 collector。
  • 下次复查点:随 OTel GenAI spec 升级(agent/framework spans 仍 experimental)复查属性名是否漂移;复查 dashboard.ts snapshot schema 与 AML Copilot 页面引用是否一致(防字段漂移)。

衔接

  • 昨天:Day 164 — M7 cost-per-case + p95(单位经济性两数字)。
  • 今天:把 4 指标聚合成带 delta 的 snapshot JSON,schema/delta 为已测纯函数,cost 填真值、其余待 eval。
  • 明天:Day 166 — 仪表盘可视化(把 snapshot 渲染成按极性着色的 4 张指标卡)。