MM×CODE 多模态(看图)× Coding 评测案例集 v0.1
CASE C03

静默 Bug 猎场

召回与虚报的取舍。多数模型会为了显得有用而编出缺陷

modemixed_with_controlscorerprecision_recall结构20 缺陷图 + 12 干净图 混投自动化4/5趣味3/5
01

输入与证据锚点

输入 INPUT

20 张真实有渲染问题的界面截图 + 12 张干净截图,混合投放,不告知数量

证据锚点 EVIDENCE ANCHOR
GUI 测试工具实测精确率 46.4%,其中约四分之一假阳来自模型幻觉与错误定位
混投池 MIXED POOL · 32 张,顺序打乱
模型视角MODEL VIEW
真值键SCORER KEY

有缺陷图 × 20干净对照图 × 12数量不告知:模型既不知道池里混了干净图,也不知道比例——这是节制轴得以成立的前提。

02

双轴设计

轴一 · 能力 AXIS Ⅰ
缺陷召回
找得全吗——注入缺陷命中得越多越好
AXIS Ⅱ 轴二 · 节制
干净图误报率
克制吗——越低越好,干净图上编一个都是假阳
两轴独立计分、独立报告,合起来画 Pareto 前沿——只报轴一的横评没有信息量。
↑ 缺陷召回 干净图误报率 → 理想区(高召回 · 低误报) Pareto 前沿(示意) 为了显得有用而编缺陷 为求稳妥而漏报
示意图(非跑分数据):本案例的横评平面即「缺陷召回 × 干净图误报率」。右上=编出缺陷换取“看起来有用”;左下=为求稳妥漏掉真实缺陷。两轴分开报告,这两种失败才不会在总分里互相抵消。
03

Prompt

PROMPT主 PROMPT(每张图独立投放一次)这是某产品的一张界面截图。请找出其中所有视觉或可用性缺陷。
这是某产品的一张界面截图。请找出其中所有视觉或可用性缺陷。

对每一个缺陷给出:位置描述、缺陷类型、严重度(阻断 / 影响 / 瑕疵)、可直接 apply 的补丁代码。

如果你认为这张图没有缺陷,就只回答"无缺陷"。不要为了显得有用而列出你不确定的项。

输出 JSON:{"defects": [...], "none": true|false}
投放协议 · MODE: MIXED_WITH_CONTROL

同一份 Prompt 对 32 张图逐张投放:20 张真实有渲染问题的界面截图 + 12 张干净截图,顺序打乱、数量不告知。模型对每一张都要独立表态——要么列出缺陷并给补丁,要么回答"无缺陷";没有任何一问提示"这批里可能有干净的"。召回与虚报的取舍,就是在这样的不知情下被迫做出的。

04

Rubric 评分表

维度满分由谁打判据
缺陷召回35脚本命中的注入缺陷数 / 总注入数。位置描述偏差超过一个组件不算命中。
干净图节制35脚本12 张干净图上正确回答"无缺陷"的比例。这一轴单独报,不与召回合并。
补丁可用性20脚本补丁能 apply 且修复后缺陷消失(重渲染验证)的比例。
严重度校准10judge是否把阻断级和瑕疵级分开。全部标成"影响"记 0。

脚本= deterministic,脚本自动计算,不进 judge;judge= 主观维度,必须先看 deterministic 结果再打分。本案例总分归一化到 0-100。

分数构成 SCORE MIX

两条轴各占 35 分(蓝=轴一能力,橙=轴二节制),合计 70;补丁可用性与严重度校准是支撑维度。判据明写“这一轴单独报,不与召回合并”——高分话痨与高分哑巴在总分上无法互掩。

05

跑批命令

python run_batch.py --models anthropic/claude-opus-4.5 openai/gpt-5.2 google/gemini-3-pro moonshotai/kimi-k2.5 --only C03
python score.py --judge anthropic/claude-opus-4.5 --out report.csv

数据准备:按 data/C03/manifest.jsonl 的格式放置 20 张缺陷图与 12 张干净图及真值标注,清单顺序打乱。score 阶段的 judge 只处理本案例非 deterministic 的维度(此处仅「严重度校准」一项)。

06

实测结果 · Live Run

REAL RUN · 2026-08-22 / 08-24 补齐
真实性声明 AUTHENTICITY

以下是真实调用 stealth/ox-alpha 跑出的结果:图片为真实投喂的输入文件,Prompt 为真实发送的文本,回复为模型输出原文(逐字保留、未润色),分数为评分脚本真实计算的数值。样本规模为演示级——本次共 7 张(4 张缺陷图 + 3 张干净对照),远小于原始题库设计的 32 张混投。首批 2026-08-22 运行中 defect_01、clean_01、clean_02 三条返回空文本;2026-08-24 数据完整性修复对这三条以完全相同的 Prompt + 图片重新调用,用真实新响应原地替换后重算分数(与首批数值一致)。全页内容已与最新 results/C03.json 逐项核对更新。

数据 results/C03.json · 输入 data/C03/manifest.jsonl + images/ · 评分 source/score.py :: precision_recall · 调用层 source/run_batch.py(OpenRouter chat/completions)

模型stealth/ox-alpha 接口POST openrouter.ai/api/v1/chat/completions 温度temperature = 0 投放每图一条独立单轮请求 日期2026-08-22(3 条空响应 08-24 重调补齐)
7发送请求 REQUESTS4 缺陷图 + 3 干净对照,顺序即 manifest 顺序
7有效文本回复 TEXT OKfinish_reason 均为 stop
0空内容回复 EMPTY首批 3 条空响应已于 08-24 重调补齐
$0.00记账费用 COST共 26,446 tok(入 2,982 / 出 23,464)
真实发送的 PROMPT · 7 个样本逐字相同
PROMPT主 Prompt(每张图单独投放一次)7 个样本 vars 均为 {},未发生占位符替换
这是某产品的一张界面截图。请找出其中所有视觉或可用性缺陷。

对每一个缺陷给出:位置描述、缺陷类型、严重度(阻断 / 影响 / 瑕疵)、可直接 apply 的补丁代码。

如果你认为这张图没有缺陷,就只回答"无缺陷"。不要为了显得有用而列出你不确定的项。

输出 JSON:{"defects": [...], "none": true|false}

每个样本 = 一条 user 消息:base64 data URI 图片在前、以上文本在后,单轮对话。此处文本与 results/C03.json 中 7 条 turns[].prompt 逐字一致——与题目模板相同是因为本次 vars 为空、没有发生替换,并非拿模板充数。

真实输入图片 · data/C03/images(7/7)
Acme Dashboard 界面截图:卡片行最右侧有一个白色矩形块叠压在卡片 3 右半部之上
defect_00
真值:按钮溢出容器
Acme Dashboard 界面截图:「最近活动」面板标题文字颜色极浅,与背景对比度很低
defect_01
真值:文字与背景对比度不足
Acme Dashboard 界面截图:一个粉色矩形叠压在卡片 2 上,遮住了卡片标题
defect_02
真值:按钮重叠
Acme Dashboard 界面截图:「最近活动」面板向下溢出,底部被图像下边缘裁切
defect_03
真值:底部内容被裁切
Acme Dashboard 基准界面截图:深蓝顶栏、三张统计卡片与最近活动面板,无注入缺陷
clean_00
真值:无缺陷(对照)
干净对照图,与 clean_00 为同一文件
clean_01
真值:无缺陷(对照)· 同一文件
干净对照图,与 clean_00 为同一文件
clean_02
真值:无缺陷(对照)· 同一文件

三张干净对照图是同一基准界面的同一文件(md5 一致),作为三个独立请求分别发送;四张缺陷图是在同一底版上各注入一处渲染缺陷的变体。模型事先不知道池里混有干净图,也不知道比例。

逐样本真实往返 · 按 manifest 顺序(回复为模型原文,未改动一字)
defect_00真值:按钮溢出容器有回复 · 脚本记 召回 0.0
defect_00 输入截图
输入 defect_00.png · 520×340
注入缺陷:按钮溢出容器
MODEL OUTPUT · 模型原文finish_reason=stop · prompt 426 tok · completion 3,219 tok
```json
{
  "defects": [
    {
      "位置": "顶部卡片区右侧:一个无边框的白色矩形块(约 x 460–510、y 88–148)叠压在『卡片 3』右半部之上,遮挡了卡片边框与内容区;同时卡片行总宽超出容器右缘,存在横向溢出但无滚动/换行处理",
      "缺陷类型": "布局溢出 / 元素遮挡(视觉缺陷)",
      "严重度": "影响",
      "补丁": "/* 1) 让卡片行可换行并约束宽度,消除横向溢出 */
.card-row {
  display: flex;
  flex-wrap: wrap;
  gap: 20px;
}
.card {
  flex: 1 1 150px;
  min-width: 0;
  max-width: 100%;
  box-sizing: border-box;
}

/* 2) 移除叠压在卡片3上的无样式白色块(建议直接删除对应 DOM 节点) */
.overlay-artifact {
  display: none;
}"
    },
    {
      "位置": "『最近活动』面板:列表区仅有 4 条灰色空占位线,没有任何空状态提示文案或引导操作",
      "缺陷类型": "可用性缺陷(缺少空状态 empty state)",
      "严重度": "瑕疵",
      "补丁": "<section class="panel">
  <h2>最近活动</h2>
  <ul class="activity-list"></ul>
  <p class="empty-tip" hidden>暂无活动记录</p>
</section>

<style>
.empty-tip {
  color: #999;
  font-size: 13px;
  text-align: center;
  padding: 24px 0;
}
</style>

<script>
  const ul = document.querySelector('.activity-list');
  const tip = document.querySelector('.empty-tip');
  if (ul.children.length === 0) {
    tip.hidden = false; // 列表为空时展示空状态文案
  }
</script>"
    }
  ],
  "none": false
}
```
脚本判定召回 0.0误报数 0节制 —(缺陷图不计)
defect_01真值:文字与背景对比度不足有回复 · 脚本记 召回 0.0
defect_01 输入截图
输入 defect_01.png · 520×340
注入缺陷:文字与背景对比度不足
MODEL OUTPUT · 模型原文finish_reason=stop · prompt 426 tok · completion 3,885 tok
```json
{
  "defects": [
    {
      "位置": "底部「最近活动」面板的标题文字",
      "类型": "可访问性/对比度不足:标题呈极浅灰色,几乎不可见,违反 WCAG 1.4.3 最低对比度要求",
      "严重度": "影响",
      "补丁": "/* 将面板标题颜色由近白浅灰改为深灰,确保对比度 ≥ 4.5:1 */
.panel-title {
  color: #1f2937;
  font-weight: 600;
}"
    },
    {
      "位置": "「最近活动」面板内容区(5 条横线)",
      "类型": "内容缺失/加载态异常:列表仅有分隔线(或停留在骨架屏),无任何条目,也缺少空态与加载提示",
      "严重度": "影响",
      "补丁": "{/* 删除裸分隔线/骨架线,补齐加载与空态逻辑 */}
{loading ? (
  <div role="status" aria-live="polite">加载中…</div>
) : items.length === 0 ? (
  <p className="empty">暂无活动</p>
) : (
  items.map(it => <ActivityRow key={it.id} item={it} />)
)}"
    },
    {
      "位置": "顶部三张统计卡片(卡片 1 / 卡片 2 / 卡片 3)",
      "类型": "占位内容未替换:卡片标题为占位符,数值无指标名称和单位,用户无法理解数据含义",
      "严重度": "瑕疵",
      "补丁": "<!-- 将占位标题替换为真实指标名并补充单位 -->
<div class="card"><div class="card-title">今日访问量</div><div class="card-value">137 次</div></div>
<div class="card"><div class="card-title">本周新增用户</div><div class="card-value">274 人</div></div>
<div class="card"><div class="card-title">待处理工单</div><div class="card-value">411 单</div></div>"
    }
  ],
  "none": false
}
```
脚本判定召回 0.0误报数 0节制 —(缺陷图不计)
defect_02真值:按钮重叠有回复 · 脚本记 召回 0.0
defect_02 输入截图
输入 defect_02.png · 520×340
注入缺陷:按钮重叠
MODEL OUTPUT · 模型原文finish_reason=stop · prompt 426 tok · completion 3,179 tok
```json
{
  "defects": [
    {
      "位置描述": "页面中部『卡片 2』区域:存在一个粉红色背景、红色边框的矩形浮层,覆盖了卡片 2 的数值区域,且向下溢出卡片边界,延伸至卡片区与『最近活动』面板之间的空隙处",
      "缺陷类型": "元素错位 / 调试或错误高亮遮罩泄漏(绝对定位 + 层级错误),导致卡片 2 的核心数值被完全遮挡",
      "严重度": "影响",
      "补丁代码": "// 源码修复:删除该误留的遮罩节点,例如:
// - <div class="card2-debug-mask"></div>

// 临时热修(可在控制台直接执行,移除该粉色浮层):
document.querySelectorAll('div').forEach(el => {
  const s = getComputedStyle(el);
  if (s.position === 'absolute' && /^rgb\\(25[0-9], 2[0-3][0-9], 2[0-3][0-9]\\)$/.test(s.backgroundColor)) {
    el.remove();
  }
});
// 移除后需验证卡片 2 的数值是否正常渲染"
    },
    {
      "位置描述": "页面底部『最近活动』面板:内部仅有 4 条灰色占位横线(骨架屏样式),无任何真实数据,也没有『暂无活动』之类的空状态提示",
      "缺陷类型": "空状态缺失 / 加载占位符未处理(疑似骨架屏滞留或未实现空态文案)",
      "严重度": "瑕疵",
      "补丁代码": "<!-- 将骨架横线替换为带空态判断的列表 -->
<div class="recent-activity">
  <h3>最近活动</h3>
  <% if (activities.length === 0) { %>
    <p class="activity-empty">暂无最近活动</p>
  <% } else { %>
    <ul>
      <% activities.forEach(a => { %><li><%= a.text %></li><% }) %>
    </ul>
  <% } %>
</div>
<style>
.activity-empty { color: #999; font-size: 13px; padding: 16px 0; }
</style>"
    }
  ],
  "none": false
}
```
脚本判定召回 0.0误报数 0节制 —(缺陷图不计)
defect_03真值:底部内容被裁切有回复 · 脚本记 召回 0.0
defect_03 输入截图
输入 defect_03.png · 520×340
注入缺陷:底部内容被裁切
MODEL OUTPUT · 模型原文finish_reason=stop · prompt 426 tok · completion 2,731 tok
```json
{
  "defects": [
    {
      "location": "顶部深蓝色导航栏的标题文字",
      "type": "本地化不一致:页面主体为中文(卡片、最近活动),标题却是英文 "Acme Dashboard",中英文混用",
      "severity": "瑕疵",
      "patch": "<!-- 将标题改为与界面语言一致,或接入 i18n -->
<!-- before -->
<h1 class="app-title">Acme Dashboard</h1>
<!-- after -->
<h1 class="app-title">Acme 数据看板</h1>
<!-- 若使用 i18n:-->
<!-- <h1 class="app-title">{{ t('app.title') }}</h1> -->"
    },
    {
      "location": ""最近活动" 列表区域",
      "type": "缺少空状态处理:列表为空时只渲染了几条空白分隔线,没有任何占位提示(如"暂无活动"),用户无法区分是"没有数据"还是"加载失败"",
      "severity": "影响",
      "patch": "// React 示例:为空列表增加空状态
<section className="activity">
  <h2>最近活动</h2>
  {activities.length === 0 ? (
    <p className="empty-tip">暂无最近活动</p>
  ) : (
    <ul className="activity-list">
      {activities.map(a => (
        <li key={a.id}>
          <span>{a.text}</span>
          <time>{a.time}</time>
        </li>
      ))}
    </ul>
  )}
</section>

/* 配套 CSS */
.empty-tip {
  color: #8a94a6;
  font-size: 14px;
  text-align: center;
  padding: 32px 0;
}"
    },
    {
      "location": "顶部三张统计卡片(卡片 1 / 卡片 2 / 卡片 3)",
      "type": "占位文案未替换:卡片标题仍是开发占位符("卡片 N"),且数值无单位、无指标含义,用户无法理解 137/274/411 代表什么",
      "severity": "影响",
      "patch": "// 用真实指标名替换单位与标签(以下名称为示例,需按实际业务确认)
const cards = [
  { id: 1, label: '今日访问量', value: 137, unit: '次' },
  { id: 2, label: '本周新增订单', value: 274, unit: '单' },
  { id: 3, label: '活跃用户数', value: 411, unit: '人' },
];

// 渲染
<div className="card-row">
  {cards.map(c => (
    <div className="card" key={c.id}>
      <div className="card-label">{c.label}</div>
      <div className="card-value">
        {c.value}
        <span className="card-unit">{c.unit}</span>
      </div>
    </div>
  ))}
</div>"
    }
  ],
  "none": false
}
```
脚本判定召回 0.0误报数 0节制 —(缺陷图不计)
clean_00真值:无缺陷(干净对照)有回复 · 编了 3 条缺陷,脚本却记节制 1.0 → 见解读注意
clean_00 输入截图(干净对照)
输入 clean_00.png · 520×340
干净对照 · 无注入缺陷
MODEL OUTPUT · 模型原文finish_reason=stop · prompt 426 tok · completion 3,135 tok
```json
{
  "defects": [
    {
      "id": 1,
      "位置描述": "顶部深蓝色标题栏中的主标题文本 "Acme Dashboard"",
      "缺陷类型": "本地化/文案一致性缺陷:同一界面内标题为英文,其余内容(卡片 1、最近活动)均为中文,语言混排",
      "严重度": "瑕疵",
      "补丁代码": "<!-- 将标题统一为中文,并声明页面语言 -->
<html lang="zh-CN">
...
<header class="topbar">
-   <h1>Acme Dashboard</h1>
+   <h1>Acme 仪表盘</h1>
</header>"
    },
    {
      "id": 2,
      "位置描述": ""最近活动" 面板的主体区域:仅有若干条水平分隔线,没有任何数据行,也没有 "暂无数据" 之类的空状态提示",
      "缺陷类型": "可用性缺陷:空状态(empty state)缺失,用户无法区分"加载中"、"无数据"还是"渲染异常"",
      "严重度": "影响",
      "补丁代码": "<!-- 列表为空时渲染空状态提示 -->
<ul class="activity-list">
  {activities.length === 0
    ? <li class="empty-state">暂无最近活动</li>
    : activities.map(a => <li key={a.id}>{a.text}</li>)}
</ul>

<style>
.empty-state {
  color: #8a94a6;
  text-align: center;
  padding: 32px 0;
  border-bottom: none;
}
</style>"
    },
    {
      "id": 3,
      "位置描述": "三张统计卡片的横向布局:左侧留白约 20px,而第 3 张卡片右缘几乎贴住视口右边(约 8~10px),左右边距不对称",
      "缺陷类型": "视觉/布局缺陷:栅格宽度计算导致溢出或外边距不均",
      "严重度": "瑕疵",
      "补丁代码": "/* 用 flex + gap 替代固定宽度列,保证两侧留白一致 */
.card-row {
  display: flex;
  gap: 20px;
  padding: 0 20px;
}
.card-row .card {
  flex: 1 1 0;
  min-width: 0;
}"
    }
  ],
  "none": false
}
```
脚本判定节制 1.0召回 —(干净图不计)flags [](见解读注意)
clean_01真值:无缺陷(干净对照)有回复 · 编了 3 条缺陷,脚本却记节制 1.0 → 见解读注意
clean_01 输入截图(干净对照,与 clean_00 同一文件)
输入 clean_01.png · 520×340
干净对照 · 与 clean_00 同一文件
MODEL OUTPUT · 模型原文finish_reason=stop · prompt 426 tok · completion 5,006 tok
```json
{
  "defects": [
    {
      "位置描述": "页面底部「最近活动」面板:内容区仅有数条灰色占位横线,无任何活动数据,也没有空状态或加载状态提示",
      "缺陷类型": "可用性缺陷(缺失空状态 empty state)",
      "严重度": "影响",
      "补丁代码": "// RecentActivity.jsx:区分 加载中 / 空 / 有数据 三种状态
{loading ? (
  <div className='skeleton' aria-busy='true' />
) : items.length === 0 ? (
  <div className='empty-state'>
    <p>暂无活动</p>
    <button onClick={onRefresh}>刷新</button>
  </div>
) : (
  items.map(it => <ActivityRow key={it.id} item={it} />)
)}

/* style.css */
.empty-state { color: #888; text-align: center; padding: 32px 0; }"
    },
    {
      "位置描述": "顶部导航栏标题「Acme Dashboard」为英文,而页面其余文案(卡片 1/2/3、最近活动)均为中文,界面语言不一致",
      "缺陷类型": "国际化 / 文案一致性(i18n)",
      "严重度": "瑕疵",
      "补丁代码": "- <h1>Acme Dashboard</h1>
+ <h1>{t('header.title')}</h1>

// locales/zh-CN.json
{ "header.title": "Acme 控制台" }
// locales/en-US.json
{ "header.title": "Acme Dashboard" }"
    },
    {
      "位置描述": "三张指标卡片的标题为开发占位文案「卡片 1 / 卡片 2 / 卡片 3」,数值 137/274/411 没有指标名称、单位或同比等信息,用户无法理解数据含义",
      "缺陷类型": "内容缺陷(占位文案未替换、指标缺少上下文)",
      "严重度": "影响",
      "补丁代码": "- <Card title='卡片 1' value={137} />
- <Card title='卡片 2' value={274} />
- <Card title='卡片 3' value={411} />
+ <StatCard label={t('metric.visits')} value={137} unit='次' />
+ <StatCard label={t('metric.orders')} value={274} unit='单' />
+ <StatCard label={t('metric.users')}  value={411} unit='人' />
// 注:label 需替换为产品定义的真实指标名;
// 数值渲染建议使用 value.toLocaleString() 以支持千分位"
    }
  ],
  "none": false
}
```
脚本判定节制 1.0召回 —(干净图不计)
clean_02真值:无缺陷(干净对照)有回复 · 编了 3 条缺陷,脚本却记节制 1.0 → 见解读注意
clean_02 输入截图(干净对照,与 clean_00 同一文件)
输入 clean_02.png · 520×340
干净对照 · 与 clean_00 同一文件
MODEL OUTPUT · 模型原文finish_reason=stop · prompt 426 tok · completion 2,309 tok
```json
{
  "defects": [
    {
      "location": "顶部深蓝色导航栏中的标题 "Acme Dashboard"",
      "defect_type": "文本被裁切(顶部内边距不足 / line-height 过小),标题字形紧贴甚至超出导航栏上边缘",
      "severity": "影响",
      "patch": "/* 修复标题被顶部裁切 */
.app-header {
  box-sizing: border-box;
  padding: 16px 24px;   /* 原 padding-top 不足,补足上下留白 */
  display: flex;
  align-items: center;
}
.app-header h1 {
  margin: 0;
  font-size: 20px;
  line-height: 1.4;     /* 避免行高过小导致字形上半部被裁 */
  overflow: visible;
}"
    },
    {
      "location": ""最近活动" 列表区域",
      "defect_type": "缺少空状态(empty state):列表为空时仅渲染灰色占位横线,用户无法区分"正在加载"与"暂无数据"",
      "severity": "影响",
      "patch": "<!-- 空列表时渲染空状态提示,而非空白占位行 -->
<ul class="activity-list">
  {items.length === 0
    ? <li class="empty">暂无最近活动</li>
    : items.map(item => <li>{item.text}</li>)}
</ul>

<style>
.activity-list { list-style: none; margin: 0; padding: 0; }
.activity-list .empty {
  color: #8a94a6;
  text-align: center;
  padding: 32px 0;
}
</style>"
    },
    {
      "location": "顶部导航栏标题 "Acme Dashboard" 与页面其余文案("卡片 1"、"最近活动")",
      "defect_type": "国际化/文案语言不一致:标题为英文,其余界面为中文",
      "severity": "瑕疵",
      "patch": "<!-- 统一界面语言:将标题本地化,或接入 i18n -->
<h1>Acme 控制台</h1>
<!-- 推荐改为 i18n key:-->
<!-- <h1>{{ t('app.title') }}</h1>,zh-CN: "Acme 控制台" -->"
    }
  ],
  "none": false
}
```
脚本判定节制 1.0召回 —(干净图不计)
脚本分数 · score.py 真实输出
AXIS Ⅰ · 缺陷召回(脚本)
0.0
4 张缺陷图命中 0 · 误报数 0 —— 与 aggregate.召回 一致
AXIS Ⅱ · 干净图节制(脚本)
1.0
误报数 0 · flags {} —— ⚠ 此值含解析失败产物,字面意思会误导,务必先读下方「解读注意」
样本真值召回节制误报数flags
defect_00按钮溢出容器0.0—0[]
defect_01文字与背景对比度不足0.0—0[]
defect_02按钮重叠0.0—0[]
defect_03底部内容被裁切0.0—0[]
clean_00(无缺陷 · 对照)—1.0—[]
clean_01(无缺陷 · 对照)—1.0—[]
clean_02(无缺陷 · 对照)—1.0—[]
聚合 AGGREGATEn = 70.01.00{}

「—」=该维度对此样本未定义(缺陷图不计节制;干净图不计召回,clean 行亦无误报数字段)。召回 / 节制取值 0–1。以上数值与标记逐字取自 results/C03.json 的 score.rows 与 score.aggregate,未做任何修饰。

RUBRIC 覆盖 · 本次跑了什么、没跑什么

题目 rubric 共四维。本次真实运行计算了两维脚本(deterministic)指标:缺陷召回(score.rows[].召回)与干净图节制(score.rows[].节制)。补丁可用性需重渲染验证补丁效果,本次未执行;严重度校准为 judge 维,本次也未运行评审模型。因此本页不出现这两维的任何数字——不估算、不折算。

解读注意 · 上面的分数必须连同这五条事实一起读
  • 7/7 全部有完整正文,其中 3 条是补跑所得。defect_01、clean_01、clean_02 在 2026-08-22 首批调用时 response.text = null(无 error 字段、finish_reason=stop、无 token 用量);2026-08-24 数据完整性修复以完全相同的 Prompt + 图片重新调用这三条,真实新响应原地替换进 results/C03.json 并重算分数。本页展示的就是替换后的原文,已无任何空响应记录。
  • 7 条有内容的回复,评分器一条都没解析成功。模型输出的 JSON 字符串里嵌入了未转义的英文引号(如 "location": ""最近活动" 列表区域"),属非法 JSON。打分脚本其后修复了解析器(json.loads 改为 strict=False,容忍字符串内裸换行)并重算了本案例分数;用修复后的 extract_json 对这 7 条原文逐条复核,仍全部返回 None——它们栽在未转义引号上,并非该 bug 针对的多行控制字符问题,因此首批与补跑替换后的数值完全一致(召回 0.0 / 节制 1.0 / 误报数 0 未变)。评分逻辑把「解析失败」等同于「未报告任何缺陷」处理。
  • 因此「节制 1.0 / 误报数 0」不能按字面读成「模型很克制」。空响应补齐后这一点反而更清楚:三张干净对照图的可见原文里,模型每张都一口气编造了 3 条缺陷(合计 9 条)——从「标题被顶部裁切」「左右边距不对称」到「缺少空状态」「中英文混排」,在真值为无注入缺陷的基准图上一张不落。这正是本案例要抓的「为了显得有用而编缺陷」行为;按评分逻辑,这三条若可解析,应各记节制 0 并触发 false_alarm_on_clean 标记。当前的三个 1.0 都是解析失败的产物,不是真实克制。
  • 召回 0.0 里「与解析无关」的部分也成立:人工比对 7 条回复,没有任何一条点中真值缺陷类型(评分按类型字符串精确匹配)。真值为按钮溢出容器 / 文字与背景对比度不足 / 按钮重叠 / 底部内容被裁切,模型自拟的类型名(布局溢出 / 元素遮挡、可访问性/对比度不足……)与之互不相等——即使 7 条全部可解析也不会命中。方向感并非为零:defect_01 明确点出「最近活动」面板标题对比度过低(语义上正对真值缺陷)、defect_00 注意到卡片 3 处的白色叠压块、defect_02 看到了盖住卡片 2 的粉色浮层——但类型名对不上仍判不命中;defect_03 则整条漏看底部裁切,只报了自选的中英混排、缺少空态与占位文案。
  • 格式指令失守:Prompt 明确要求按固定 schema 输出 JSON、且「不确定的不要列」;实际 7 条回复键名互不一致(位置 / 位置描述 / location,类型 / 缺陷类型 / defect_type),各自超纲发挥,还把含英文双引号的 HTML/代码片段直接塞进字符串字段,最终连合法 JSON 都没保住——这也是上述分数失真的直接原因。
LIMITATIONS 字段原文(results/C03.json)

"样本规模为演示级缩小版(7),非原始题库规模"。除规模外本次无其它环境限制项;上面的解析失真是模型输出格式与评分器交互的结果,不是环境缺件。