一个 AI agent 用浏览器自动化工具点开了评测平台某次运行的「查看」按钮,把页面的可访问性树原样吐了回来:18000 字符的纯文本回显,没有截图、没有文档、没有源码。这篇做一次取证式阅读——只凭这一页回显,能把这套评测系统的设计世界观拆到什么程度?答案是:几乎全部。好的系统会在每一页 UI 里泄露它的信念;这页证物泄露的,是一整套关于”分数怎样才可信”的立场。
先交代证物来源:这是我参与的一个 LLM 网关 + 在线路由 + 评测平台(细节已匿名化,与《解剖一份单机高可用 ADR》是同一个项目)。页面展示一次代码评审能力的验收运行:12 个样本、模型是某低成本 flash 档配置(下文记 flash@acceptance-v1)、打分器 code_review_rubric@v1、12/12 通过。
案情概述:这一页上有什么
每个样本区块的结构完全一致,五类信息:
| 区块 | 内容 |
|---|---|
| INPUT | 5 字段 JSON:tools[](给评审者的工具面板)、change.diff(被评审的代码变更)等 |
| ORACLE | 4 字段 JSON:mustFind[]、mustNotClaim[]、minimumScore、schemaVersion |
| SOURCE TRACE | fixture-code-review-001 ~ 012,指回样本的出生地 |
| 逐样本指标 | 分数 100%、成本未知、Token 1,616–5,080、延迟 11,306–35,773 ms |
| INSPECT SAMPLE REF | 每个样本一个短 ID,供下钻 |
页尾还有两样东西:一个 Langfuse span 瀑布区(标注”仅展示时间、层级、模型、usage 与 latency”),和一个 RESULT SUMMARY(model、scorer、totalSamples: 12、promptProfile: sample-input@builtin-v1、datasetContentHash: 1d5fc291…)。
下面按线索逐条取证。每条给:回显里的原始痕迹 → 它暴露的设计决定 → 源头论文。
线索一:样本自带工具面板——评测的是「调查」,不是「问答」
每个 INPUT 里都有一个 tools 字段:trace_callees(“检查 process 生命周期”)、read_query(“检查分页 SQL”)、inspect_allowlist(“检查 URL allowlist”)……工具的 description 直接编码了这道题期望的调查路径。
这暴露了一个立场:评测对象不是”看一段 diff 说感想”的静态问答,而是带工具的评审任务——模型可以(也应该)沿工具去查上下文。这正是 agent 时代样本格式的共识走向:τ-bench(arXiv 2406.12045)给 agent 配 API 工具和领域政策、拿数据库终态当判据;SWE-bench(arXiv 2310.06770)干脆把整个仓库当环境、拿 fail-to-pass 测试当判据(本站有单独深读)。样本格式从 (prompt, answer) 进化成 (环境, 任务, 判据),这页回显里的 tools + diff + oracle 三件套就是它的代码评审版。
线索二:双向 Oracle——mustFind 钉漏报,mustNotClaim 钉误报
这是整页证物里最值钱的设计。抄三对下来(内部约定已做泛化处理):
| fixture | mustFind(必须抓到) | mustNotClaim(不许指控) |
|---|---|---|
| 010 | CancelledError 路径未 terminate/kill 并 wait,可能遗留子进程 | ”asyncio 任务取消会自动终止所有子进程” |
| 008 | 返回 items.length 使 total 退化为当前页数量 | ”getManyAndCount 无法和分页一起使用” |
| 001 | projectId 过滤被移除导致跨项目读取 | ”Like 本身必然造成 SQL 注入” |
mustFind 是召回下限:埋进 diff 的缺陷必须被点名。mustNotClaim 是误报上限:那些”听起来专业、实际是错的”的指控,说了就扣分。注意 mustNotClaim 的条目全是似是而非的行业误区——这正是 TruthfulQA(arXiv 2109.07958)所谓 imitative falsehoods(模仿性谬误)的代码评审版:817 问、38 类,专收”人类语料里高频出现的错误信念”,当年最好的模型只有 58% 真实率(人类 94%),而且模型越大越不真实——因为谬误就是从语料里学来的。把每条误区显式写进 oracle,等于给每个样本配了一个微型 TruthfulQA 陷阱。
为什么必须双向?CriticGPT(LLM Critics Help Catch LLM Bugs, arXiv 2407.00215)给了实证:训练 LLM 评审员抓代码 bug,模型评语在 63% 的情况下被人类偏好于人类评语、抓的 bug 比外包人工还多——但代价是幻觉 bug 和吹毛求疵(nitpicks)随全面性一起上升,论文不得不专门造了 FSBS 采样来在”抓得全”和”少瞎说”之间调节。这就是目标函数即命运:只考核召回的评审员,会被优化成永远拉响警报的惊弓之鸟——反正多说不扣分。mustNotClaim 把 CriticGPT 论文里那个采样期才能调的权衡,前移成了每个样本的合同条款。
清单式打分本身也有论文背书:TICK(arXiv 2410.03608)证明把”打个总分”分解成逐条 YES/NO 清单,judge 与人类的完全一致率从 46.4% 升到 52.2%;HealthBench(arXiv 2505.08775)更是把这套做到工业规模——262 名医生为 5000 段对话手写了 48,562 条 rubric 条款,平均每例 11.4 条,而且约三成条款是负向的(69.3% 为正向,其余就是医疗版的 mustNotClaim)。这页回显里的 oracle,就是 HealthBench 方法论的代码评审移植:逐样本、专家手写、正负双向。
线索三:及格线不是常数——minimumScore 按风险定价
九个可见样本的 minimumScore 不是一个全局配置,而是逐样本浮动:SSRF 校验缺失和把授权码/访问凭据写进日志的样本要求 0.85,事务并发和幂等投递类 0.80,前端状态清理类 0.75。
这是把门禁决策地图那条”门禁强度对齐不可逆性”的定律用到了及格线上:安全类缺陷漏检的代价(数据出境、凭据泄露)远高于一个前端旧状态请求,所以召回门槛也理应更高。HealthBench 给 rubric 条款配权重、业务评测覆盖地图给十个格子分收敛度,都是同一个动作:拒绝用一个标量描述所有风险——这也是上一篇 ADR 解剖里「指标向量化定律」的评测版。
线索四:溯源与封印——每个分数都能走回出生地
两处痕迹合在一起看。其一,每个样本都有 SOURCE TRACE: fixture-code-review-XXX——分数不是孤立的,失败时可以沿指针走回手写的原始金样本,判断是模型错了还是题出错了(覆盖地图里”分歧样本回流”的前置条件就是这条指针存在)。fixture 内容也确实是业务切片的:迁移表名要带项目约定前缀、评测样本表的建表规范——这些题在任何公开 benchmark 里都不存在,也永远不该公开,否则下一代模型的训练语料里就有答案了(数据污染,见 lm-eval Trenches, arXiv 2405.14782)。
其二,RESULT SUMMARY 里的四元组:model@v1 × scorer@v1 × promptProfile@builtin-v1 × datasetContentHash。Trenches 论文用三年 lm-eval-harness 的维护经验反复敲打同一件事:模型分数对评测 setup 极度敏感,不钉死配置的分数没有可比性。这页 UI 把四个自由度全部钉死了——连打分器也带版本号,因为 judge 自己会漂移、自己有偏置(MT-Bench, arXiv 2306.05685 记录在案的位置偏置、冗长偏置、自我偏好,本站深读);datasetContentHash 则是数据的 lockfile——内容寻址,改一个字哈希就变。一个没有坐标的分数只是传闻;这个四元组就是分数的坐标系。这也是 HELM(arXiv 2211.09110)“先画格子再填数”传统的落地端:格子画好之后,每个格子里的数还得可复现才算数。
线索五:数字取证——「未知」是显式空格,延迟列另有真身
三处数字痕迹,都是亲手算过的(方法随算)。
成本一栏印着”未知”而不是留白。 这个细节呼应覆盖地图的「显式空格」定律:未接价格表 ≠ 免费,把”不知道”印出来,比默默省略诚实得多。成本本该是第一等评测轴(FrugalGPT, arXiv 2305.05176),这里的空格等于在 UI 上挂了一张待办工单。
延迟列其实是”输出长度列”的化身。 九个可见样本的 延迟÷Token 比值:7.50、6.17、6.49、6.54、6.09、7.00、7.04、6.56、5.95 ms/token——极差不过 ±12%,均值 6.59 ms/token(约 152 token/s)。比值如此稳定,说明延迟差异几乎全部由生成长度解释:同一条解码路径、无重试、无排队异常。(注意:若 Token 列含输入 token,则 152 token/s 只是解码速度的下界;但”比值稳定 ⇒ 服务路径均质”的推断不受影响。)
样本 ID 里藏着数据生命周期。 样本 ID 第三段以 7 开头——是 UUIDv7,前 48 位就是 Unix 毫秒时间戳。解码九个可见样本:全部落在 73 毫秒内,相邻间隔 7–11ms、单调递增——典型的一次循环批量落库;而 run 的 ID 解码出来比样本晚 20.5 分钟。也就是说:数据集先物化,运行后发生——样本不是运行时现造的,这正是 datasetContentHash 存在的前提(数据先冻结、取哈希,运行只是引用它)。猜测是(未验证):同一哈希的数据集可以被多次运行复用,20 分钟的间隔可能是上一次配置调试留下的。一页只读回显,连数据管道的时序都能取证出来——ID 方案本身就是日志。
线索六:12/12 通过值多少——acceptance 是门禁,不是榜单
运行名里带 acceptance,12 个样本全过、全部 100%。先泼一盆统计冷水:n=12 全部通过,按三分法则(rule of three),真实失败率的 95% 置信上界是 3/12 = 25%。反过来算:如果单样本通过率只有 80%,一次性 12 连过的概率也还有 0.8¹² ≈ 6.9%。12 个样本买不来质量置信,买的是接线置信——模型接得通、scorer 解析得动、rubric 每条路径都执行过、证据链每环都写得进去。
所以这次运行的正确读法是 CI 冒烟测试,不是能力榜单——这是把《评测即新 PRD》里”评测进 CI”的主张落到了产品语义上:acceptance 挡的是”配置改坏了”,真正的能力测量属于更大的金样本集和覆盖地图的十个格子。我认为它还有第二重身份(这是我的推断,回显无法证实):拿一个已知应该全过的便宜模型定期跑这套 fixture,等于在给评测管线自身做金丝雀——scorer 版本升级、prompt profile 变更之后,12/12 变 11/12 报的往往不是模型退化,而是管线坏了。这对应覆盖地图里「judge 有效性」那个格子:评测系统自己也需要被评测。
全链一图
flowchart LR
F["fixture-code-review-*<br>手写金样本<br>业务切片"] --> D["数据集<br>contentHash 封印<br>先物化"]
D --> R["运行<br>model@v × scorer@v<br>× promptProfile@v"]
R --> V{"逐样本判定<br>mustFind 命中?<br>mustNotClaim 触雷?<br>score ≥ minimumScore?"}
V -->|"12/12 通过"| G["acceptance 门禁放行"]
V -->|"任一失败"| T["沿 SOURCE TRACE<br>回溯 fixture"]
R -.元数据.-> O["Langfuse spans<br>只看时间 用量 延迟"]
Langfuse 那格顺带交代了最后一个痕迹:span 瀑布明说”仅展示时间、层级、模型、usage 与 latency”——观测层只碰元数据、不碰内容,这是网关解剖篇「元数据边界定律」在评测 UI 上的又一次现身。
元规律:双向 Oracle 定律
把六条线索拧成一句:
评审型打分器的成熟度,不看它奖励什么,看它禁止什么。 单向清单(只有 mustFind)量的是”它能发现什么”,是能力题;双向合同(加上 mustNotClaim)量的是”它敢不说什么”,是可信题。只考核召回的批评家必然 Goodhart 成噪音制造机——CriticGPT 用实验证明了这条权衡曲线存在,mustNotClaim 把它写成了逐样本的合同条款。
这条定律(我的提炼,非文献原文)向外推广也成立:幻觉评测里”该拒答时拒答”是 mustNotClaim;安全评测里”不过度拒答”(over-refusal)是反向的 mustNotClaim;覆盖地图里每个 ⚠️ 格子背后,几乎都缺一份”不许说什么”的负向合同。
还有一条页面语法值得带走:这页证物上名词皆有版本,数字皆有出处——模型、打分器、prompt、schema 各带 @v,数据带哈希,分数带 SOURCE TRACE,连”未知”都被显式印出来。一页 UI 能做到这两句话,它背后的评测系统就大概率可信。
自检清单:你的评测证据页答得出这六问吗
- 样本里有没有环境(工具、上下文),还是只有一问一答?
- Oracle 是单向还是双向——有没有一条”说了就扣分”的负向条款?
- 及格线是全局常数,还是按风险逐样本定价?
- 任何一个分数,能不能两跳之内走回它的原始金样本?
- 复现这次运行需要的全部坐标(模型/打分器/prompt/数据)是否都被版本或哈希钉死?
- 页面上有没有显式的”未知”——还是所有不知道的东西都被静默省略了?
诚实的提醒
本文的证据分级:ms/token 比值、UUIDv7 时间戳解码、三分法则与 0.8¹² 的算术是亲手算的(一次性脚本验算过);CriticGPT 的 63%、HealthBench 的 48,562 条/69.3% 正向、TICK 的 46.4%→52.2%、TruthfulQA 的 58% vs 94% 均来自当场核实的论文原文,我未复现;“acceptance 兼任管线金丝雀”与”数据集按哈希复用”是标注过的推断。
最低成本的亲手验证(一杯咖啡的价钱):从你自己仓库的历史里挑 3 个修过的 bug,把修复前的 diff 当被评审对象,每个手写一份四字段 oracle——mustFind 填那个 bug 的一句话描述,mustNotClaim 填一条相邻的似是而非指控(比如”这里用了字符串拼接所以必然注入”),minimumScore 按风险给 0.75–0.85。用便宜模型每题跑 3 次,人工对照 9 份输出:mustFind 的命中率是能力,mustNotClaim 的触雷次数是可信。触雷一次,你就亲眼见到了 CriticGPT 那条权衡曲线。
参考来源
arXiv 论文(均于发文当日核实):
- LLM Critics Help Catch LLM Bugs (CriticGPT), arXiv 2407.00215
- TruthfulQA, arXiv 2109.07958
- HealthBench, arXiv 2505.08775
- TICKing All the Boxes (TICK), arXiv 2410.03608
- τ-bench, arXiv 2406.12045
- SWE-bench, arXiv 2310.06770
- Lessons from the Trenches on Reproducible Evaluation, arXiv 2405.14782
- Judging LLM-as-a-Judge with MT-Bench and Chatbot Arena, arXiv 2306.05685
- HELM, arXiv 2211.09110
- FrugalGPT, arXiv 2305.05176
本站关联:业务评测覆盖地图 · 门禁决策地图 · 单机 HA ADR 解剖 · 网关栈解剖 · 评测即新 PRD · LLM-as-Judge 深读 · SWE-bench 深读