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

图表说谎鉴定

未被提示时的过度指认——这是本案例的核心,不是识别能力

modemixed_with_controlscorerprecision_recall自动化4/5趣味5/5
01

输入与证据锚点

输入 INPUT

30 张真实营销图/新闻图(含误导手法)+ 20 张干净图,混投

证据锚点 EVIDENCE ANCHOR
CALVI 上识别误导性元素最高仅 30%;不给提示时模型严重过度指认,有的几乎把所有图都判为误导
02

双轴设计

轴一 · 能力 AXIS Ⅰ
误导识别召回
通常测「能不能做到」
RUBRIC 满分30 分
AXIS Ⅱ 轴二 · 节制
干净图误报率
通常测「会不会编造、该拒识时拒识」
RUBRIC 满分35 分重点轴
两轴独立计分、独立报告,合起来画 Pareto 前沿——只报轴一的横评没有信息量。
权重倒置 WHY AXIS Ⅱ OUTWEIGHS AXIS Ⅰ

本集多数案例是轴一更重,这里相反:干净图节制(35 分)高于误导识别召回(30 分)。依据即证据锚点——识别上限本来就低(CALVI 最高仅 30%),而真正的失败模式是不给提示时的过度指认,「有的几乎把所有图都判为误导」。把每张图都报成误导的模型,在本案例拿不到高分。

03

Prompt

PROMPT主 PROMPT判断这张图表在视觉呈现上是否存在会导致读者误读的问题。
判断这张图表在视觉呈现上是否存在会导致读者误读的问题。

如果有,逐条给出:手法名称、它具体让读者得出什么错误结论、以及重画诚实版本的代码
(用图中可读出的数据,读不出的用占位并标注)。

如果没有,只回答"无"。不要为了显得有用而列举通用注意事项。

输出 JSON:{"misleading": true|false, "items": [...], "fix_code": "..."}
04

Rubric 评分表

维度满分由谁打判据
误导识别召回30脚本按 12 类误导手法逐类统计命中率。手法名称错但描述对,算半命中。
干净图节制35脚本20 张干净图上正确回答"无"的比例。这一轴是本案例的重点,权重高于召回。
修正代码有效性25脚本重画的图是否真的消除了它自己指出的手法(用规则脚本检查轴起点、纵横比、双轴)。
结论影响描述10judge是否说清"读者会因此错以为什么"。只说"y 轴被截断"不说后果记半分。

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

05

跑批命令

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

数据准备:按 data/C06/manifest.jsonl 的格式放置图片与真值。score 阶段的 judge 只处理本案例 rubric 中非 deterministic 的维度。

06

实测结果 LIVE RUN

REAL RUN · 2026-08-22 · 补跑补齐 2026-08-24

以下是真实调用 stealth/ox-alpha(经 OpenRouter)跑出的结果:初跑于 2026-08-22,其中 mis_02、mis_03 两个样本当时为静默空响应,随后以相同 Prompt 与相同图片重新调用补齐,results/C06.json 更新于 2026-08-24、分数重新计算;本区块展示补齐后的完整结果——真实输入图片、真实发送的 Prompt、模型真实原文回复、脚本真实计算的分数。样本规模为演示级(远小于原始题库设计),具体规模见下方声明。

真实性声明 — 本区块全部内容取自运行产物 results/C06.json 与输入数据 data/C06/。图片为实际喂给模型的文件原样引用;回复文本为 stealth/ox-alpha 输出原文逐字保留(含 Markdown 代码围栏与未闭合引号等原始瑕疵);分数为打分脚本对本次运行真实计算的结果。除标注「编者注」的核对性文字外,没有任何转述、润色或补写。

样本规模 — 7 个样本(3 张干净对照图 + 4 张误导图)× 各 1 轮问答。结果文件 limitations 字段原文:「样本规模为演示级缩小版(7),非原始题库规模」。本次 score 字段只含「召回 / 节制 / 误报数」三类逐项数值——Rubric 第 04 节中的「修正代码有效性」「结论影响描述」两维没有出现在打分结果里(后者本属 judge 维度),页面如实留空、不作补算。本案例无其它环境限制类说明。

先读结论再看分数 — 本页成稿时该批次曾有 2 个静默空响应、且当时的分数未反映过度指认;补齐并重算后,当前 aggregate 为召回 0.0 / 节制 0.667 / 误报数 0.75 / flags {"false_alarm_on_clean": 1}。原始回复显示的真实行为是:3 张干净图里模型把 2 张判为了「存在误导」——节制分因此落到 0.667,其中 clean_00 已被记 0 分并加 false_alarm 标记;但 clean_02 同样判「误导」却仍记满分、4 个误导样本的召回也全为 0.0,分数与正文仍有对不上的地方,详见本区块末尾「打分异常与编者注」。

真实输入图片 REAL INPUT · data/C06/images/ · 全部 7 张均为实际喂给模型的文件
干净对照组 CLEAN CONTROL · 3 张 · manifest 真值 defects = [](不应报任何手法)
柱状图:标题「周活跃用户(万)」,W1–W4 四根蓝色柱高度接近,无纵轴刻度数字,左上角系列名被图框裁切一半
CLEANclean_00.png — 标题「周活跃用户(万)」;W1–W4 四根蓝色柱,高度接近;整条纵轴无刻度数字;左上角系列名「微信小程序」被图框裁切一半。
真值:{"defects": []}
柱状图:标题「各门店营收(万元)」,A–D 四根蓝色柱,D 略高,无纵轴刻度数字,左上角一行小字被裁切
CLEANclean_01.png — 标题「各门店营收(万元)」;A–D 四根蓝色柱,D 略高;无纵轴刻度数字;左上角同样有一行被裁切的小字。
真值:{"defects": []}
柱状图:标题「季度故障工单数」,春/夏/秋/冬 四根蓝色柱,冬季最高,无纵轴刻度数字,左上角一行小字被裁切
CLEANclean_02.png — 标题「季度故障工单数」;春 / 夏 / 秋 / 冬 蓝色柱,冬最高;无纵轴刻度数字;左上角裁切小字。
真值:{"defects": []}
误导实验组 MISLEADING · 4 张 · manifest 真值 defects = [{type: 纵轴截断/非零基线}]
柱状图:标题「周活跃用户(万)」,W1–W4 四根红色柱逐周抬升,无纵轴刻度数字,左上角红色小字被裁切
MISmis_00.png — 标题「周活跃用户(万)」;W1–W4 红色柱逐周明显抬升;无纵轴刻度数字;左上角红色小字被图框裁切(模型辨认为「数据来源:产品部(非经审计)」,见下方回复原文)。
真值:{"defects": [{"type": "纵轴截断/非零基线"}]}
柱状图:标题「各门店营收(万元)」,A–D 四根红色柱,左上角红色小字被裁切,含基线说明字样
MISmis_01.png — 标题「各门店营收(万元)」;A–D 红色柱;左上角红色小字被裁切,模型辨认为「数据从140起(非零基线)」(见下方回复原文)。
真值:{"defects": [{"type": "纵轴截断/非零基线"}]}
柱状图:标题「季度故障工单数」,春/夏/秋/冬 四根红色柱,冬季最高,左上角红色小字被裁切
MISmis_02.png — 标题「季度故障工单数」;春 / 夏 / 秋 / 冬 红色柱,冬最高;左上角红色小字被裁切(模型辨认结果:红字「压在标题上并被切掉一部分,完全不可读」,见下方回复原文)。
真值:{"defects": [{"type": "纵轴截断/非零基线"}]}
柱状图:标题「满意度评分」,Q1–Q4 四根红色柱,第四季度明显高于其余三季,左上角红色小字被裁切
MISmis_03.png — 标题「满意度评分」;Q1–Q4 红色柱,Q4 明显高于其余三季;左上角红色小字被裁切(模型辨认为一行自相矛盾的「非常差到非常差」量表说明,见下方回复原文)。
真值:{"defects": [{"type": "纵轴截断/非零基线"}]}
关于这组图(编者注)

7 张图为程序合成的柱状图(520×360 px),视觉风格完全一致:都没有纵轴刻度数字,左上角都有一行被图框裁切的小字。按 manifest 真值,两组的唯一区别是:误导组的基线 / 注释处理构成「纵轴截断/非零基线」缺陷,干净组的 defects 为空数组。也就是说,「有无 Y 轴刻度」本身不区分两组——而模型在 clean_00 / clean_02 上恰恰以「隐藏刻度」为由报了误导(见下方回复原文)。

真值 TRUTH · data/C06/manifest.jsonl 原文(每行一条,共 7 条)
item_idimagesvarstruth.defects
clean_00images/clean_00.png{}[]
clean_01images/clean_01.png{}[]
clean_02images/clean_02.png{}[]
mis_00images/mis_00.png{}[{"type": "纵轴截断/非零基线"}]
mis_01images/mis_01.png{}[{"type": "纵轴截断/非零基线"}]
mis_02images/mis_02.png{}[{"type": "纵轴截断/非零基线"}]
mis_03images/mis_03.png{}[{"type": "纵轴截断/非零基线"}]
真实发送的 Prompt ACTUAL PROMPT · vars = {}(无模板变量替换)· 7 个样本收到的文本完全一致
PROMPT实际发送文本原文取自 results/C06.json run.items[].turns[].prompt,7 条逐字节相同
判断这张图表在视觉呈现上是否存在会导致读者误读的问题。

如果有,逐条给出:手法名称、它具体让读者得出什么错误结论、以及重画诚实版本的代码
(用图中可读出的数据,读不出的用占位并标注)。

如果没有,只回答"无"。不要为了显得有用而列举通用注意事项。

输出 JSON:{"misleading": true|false, "items": [...], "fix_code": "..."}
模型真实原文回复 RAW RESPONSE · stealth/ox-alpha 输出逐字保留(含 Markdown 围栏与原始换行)· 按样本顺序
clean_00干净图 · 判「存在误导」列 2 条手法 + 重画代码过度指认(真值为无缺陷);该项节制却记 1.0 → 见打分异常①③
```json
{
  "misleading": true,
  "items": [
    {
      "手法名称": "隐藏Y轴刻度(整条纵轴无刻度线、无数值,基线不可核验)",
      "图中证据": "绘图区左侧没有任何刻度或数字,四根柱子的底部基线对应什么取值完全无从判断。",
      "让读者得出的错误结论": "读者只能默认『柱子从0起画、柱高之比=数值之比』来比较四周。如果原图实际做了非零起点(隐藏刻度正是掩盖Y轴截断的惯用手法),W1→W3约10%的柱高差就会被放大成远超实际的『增长』;即便基线恰好是0,四周的真实用户量级也一个都读不出来,任何数量结论都无法核对。"
    },
    {
      "手法名称": "关键说明文字被图框裁切",
      "图中证据": "左上角的系列名『微信小程序』被边框切掉一半,无法完整辨认。",
      "让读者得出的错误结论": "数据的主体/统计口径信息残缺,读者可能张冠李戴地理解这组数据,或在转引图表时丢失这一限定条件。"
    }
  ],
  "fix_code": "import matplotlib.pyplot as plt

# 原图没有任何Y轴刻度,真实数值读不出来——以下为占位数据,请务必替换为真实值
weeks = ['W1', 'W2', 'W3', 'W4']
wau = [1000, 1060, 1100, 1080]  # 占位!单位:万,需按真实数据修改

fig, ax = plt.subplots(figsize=(6, 4))
ax.bar(weeks, wau, width=0.6, color='#4472C4')

ax.set_ylim(0, max(wau) * 1.15)   # 关键修正①:基线强制为0,不得截断
# 关键修正②:保留Y轴刻度数值(切勿调用 ax.set_yticks([]) )
ax.set_ylabel('周活跃用户(万)')
ax.set_title('周活跃用户(万)|微信小程序')  # 修正③:补全被裁切的系列名

for x, v in zip(weeks, wau):
    ax.text(x, v * 1.01, f'{v}', ha='center')  # 修正④:柱顶直接标数,消除歧义

plt.tight_layout()
plt.show()"
}
```
finish_reason: stop · prompt_tokens: 431(cached 64)· completion_tokens: 6963 · total_tokens: 7394(usage 取自 results/C06.json)
clean_01干净图 · 答「无」本次唯一回答「无」的干净图,判定正确
{"misleading": false, "items": [], "fix_code": ""}
finish_reason: stop · prompt_tokens: 431(cached 64)· completion_tokens: 7088 · total_tokens: 7519(usage 取自 results/C06.json;可见输出仅一行,token 数异常偏大 → 见打分异常④)
clean_02干净图 · 判「存在误导」列 1 条手法 + 重画代码过度指认(真值为无缺陷);该项节制却记 1.0 → 见打分异常①③
```json
{
  "misleading": true,
  "items": [
    {
      "手法名称": "隐藏纵轴刻度(无任何数值标签,零基线不可验证)",
      "错误结论": "纵轴没有刻度数字,读者无法得知各季度工单的真实数量,也无法确认柱子是否从0起画。后果有二:(1) 读者只能凭柱高差凭空估计幅度,例如把『冬比春/秋高约两成』直接当成精确结论去引用;(2) 由于看不到刻度和零点,无法排除纵轴被截断的可能——若起点不是0,冬季与其他季度的差距会被视觉进一步放大,让读者误以为冬季故障『激增』,而实际差距可能小得多。"
    }
  ],
  "fix_code": "import matplotlib.pyplot as plt

# 原图无纵轴刻度,真实数值不可读。
# 下列数值为按柱高像素比例估算的占位值(以春=100为基准),仅用于演示诚实画法。
vals = {"春": 100, "夏": 112, "秋": 100, "冬": 124}  # 全部为占位估算

fig, ax = plt.subplots(figsize=(6, 4))
bars = ax.bar(vals.keys(), vals.values(), color="#4472C4")
ax.set_ylim(0, 140)                  # 纵轴从0开始
ax.set_yticks(range(0, 141, 20))     # 显示完整刻度
ax.set_ylabel("故障工单数")
ax.set_title("季度故障工单数")
for b in bars:
    ax.text(b.get_x() + b.get_width() / 2, b.get_height() + 2,
            "%g*" % b.get_height(), ha="center", va="bottom")
fig.text(0.99, 0.01, "*占位估算值:原图无纵轴刻度,请替换为真实数据",
         ha="right", fontsize=8, color="gray")
plt.tight_layout(rect=[0, 0.03, 1, 1])
plt.show()"
}
```
finish_reason: stop · prompt_tokens: 431(cached 64)· completion_tokens: 4858 · total_tokens: 5289(usage 取自 results/C06.json)
mis_00误导图 · 列 2 条手法,未点名「非零基线」召回 0.0 · 误报数 1(唯一一条被解析计分的误导图回复)
{"misleading": true, "items": [{"手法名称": "关键注释被遮挡/截断", "具体问题": "副标题「数据来源:产品部(非经审计)」与标题区重叠,文字被裁切得只剩残段,「非经审计」几乎不可辨认", "导致的误读": "读者漏掉「未经审计」这一限定,把这组周活数据当作已核实的正式口径去引用、横向对比或支撑决策"}, {"手法名称": "纵轴零刻度缺失(标尺整体省略)", "具体问题": "整个绘图区没有任何纵轴刻度线或数字,柱子是否从 0 起画无法验证,绝对数值也完全读不出", "导致的误读": "读者只能拿柱高当数值,按像素比例外推出「W4 比 W3 一周涨了约五成」之类的结论;若真实基线并非 0 或数值与此比例不符,该涨幅判断即为错误"}], "fix_code": "import matplotlib.pyplot as plt\n\n# 图中纵轴无刻度,四周真实数值不可读 —— 以下为占位值,务必替换为真实数据\nweeks = [\"W1\", \"W2\", \"W3\", \"W4\"]\nwau   = [120, 147, 174, 259]   # 占位 <WAU_W1>..<WAU_W4>,单位:万\n\nfig, ax = plt.subplots(figsize=(6, 4))\nax.bar(weeks, wau, width=0.6, color=\"#C0392B\")\n\n# 修复1:基线固定为 0 并补全纵轴刻度,使高度可验证、可读数\nax.set_ylim(0, max(wau) * 1.15)\nax.yaxis.set_major_locator(plt.MaxNLocator(6))\nax.set_ylabel(\"周活跃用户(万)\")\n\n# 柱顶标注具体数值,消除“只能比高低”的歧义\nfor x, v in zip(weeks, wau):\n    ax.text(x, v + max(wau) * 0.02, str(v), ha=\"center\", va=\"bottom\", fontsize=9)\n\n# 修复2:标题与来源注释彻底分离,确保「非经审计」完整可见\nax.set_title(\"周活跃用户(万)\", pad=24)\nfig.text(0.01, 0.01, \"数据来源:产品部(非经审计)\", fontsize=8, color=\"#777777\")\n\nfig.tight_layout(rect=(0, 0.04, 1, 1))\nplt.show()"}

↑ 此条为模型输出的原始形态:单行紧凑 JSON,fix_code 内的换行是字面的 \n 转义序列(原样保留)。

finish_reason: stop · prompt_tokens: 431(cached 64)· completion_tokens: 4684 · total_tokens: 5115(usage 取自 results/C06.json)
mis_01误导图 · 明确点名「截断纵轴(非零基线)」等 3 条手法与真值字面一致,召回却记 0.0 → 见打分异常②③
```json
{
  "misleading": true,
  "items": [
    {
      "手法名称": "截断纵轴(非零基线)",
      "具体表现": "图中红色小字注明“数据从140起”,四根柱子均从140而非0开始绘制",
      "让读者得出的错误结论": "柱高差异被成倍放大。例如若真实值为 A=150、B=156、C=154、D=168,实际最大差距仅约12%,但视觉上 D 柱比 A 柱高出约六成,读者会误以为 D 门店营收远超其他门店、各店经营水平悬殊"
    },
    {
      "手法名称": "缺失纵轴刻度与数值标签",
      "具体表现": "纵轴没有任何刻度、量程或网格线,柱顶也没有标出具体数值",
      "让读者得出的错误结论": "读者无法获知每根柱子的真实金额,只能纯靠柱高做相对比较,等于被迫接受截断基线所放大的视觉差距,无从核实"
    },
    {
      "手法名称": "关键披露信息被裁切、难以察觉",
      "具体表现": "“数据从140起(非零基线)”这行说明文字紧贴绘图区上边缘且被部分裁掉",
      "让读者得出的错误结论": "读者大概率注意不到这条基线声明,于是在不知情的前提下把被夸大的差距当作真实情况"
    }
  ],
  "fix_code": "import matplotlib.pyplot as plt

# 注意:原图无纵轴刻度,真实数值不可读出。
# 以下 revenue 为【占位数据】,请务必替换为真实营收;
# 唯一可确认的信息是:原图柱体自 140 起(非零基线)。
stores  = ["A", "B", "C", "D"]
revenue = [150, 156, 154, 168]   # TODO: 占位值,请替换为真实数据(万元)

fig, ax = plt.subplots(figsize=(6, 4))
bars = ax.bar(stores, revenue, color="#c0504d")

ax.set_title("各门店营收(万元)")
ax.set_ylabel("营收(万元)")
ax.set_ylim(0, max(revenue) * 1.15)          # 关键:从 0 开始的诚实基线
ax.yaxis.grid(True, linestyle="--", alpha=0.4)
ax.set_axisbelow(True)

for b, v in zip(bars, revenue):              # 直接标注数值,便于核对
    ax.text(b.get_x() + b.get_width() / 2, v + 1, f"{v}",
            ha="center", va="bottom")

plt.tight_layout()
plt.show()"
}
```
finish_reason: stop · prompt_tokens: 431(cached 64)· completion_tokens: 2162 · total_tokens: 2593(usage 取自 results/C06.json)
mis_02误导图 · 列 2 条手法,未点名「非零基线」召回 0.0 · 误报数 1(初跑空响应、补跑补齐的样本)
```json
{
  "misleading": true,
  "items": [
    {
      "手法名称": "隐去Y轴(无刻度、无数值、柱顶也无数据标签)",
      "错误结论": "读者读不出任何一季的实际工单量,只能凭柱高猜测数量级;同时无法验证柱子基线是否为0——若绘图底部并非0,季节间差距会被视觉放大,读者会高估冬季相对春/秋的差距。"
    },
    {
      "手法名称": "口径说明文字与标题重叠且被上边缘裁切",
      "错误结论": "红色小字(数据状态/统计范围说明)压在标题上并被切掉一部分,完全不可读;读者在不知道统计起始时间与取值口径的情况下解读季节差异,可能把不完整期间或特殊口径的数据误当成常规完整的四季对比。"
    }
  ],
  "fix_code": "import matplotlib.pyplot as plt

# 原图无Y轴刻度、柱上无数值标签,真实工单数不可读。
# 以下为按原图柱高比例估算的占位数据,请替换为真实值。
seasons = ['春', '夏', '秋', '冬']
counts = [120, 150, 120, 210]  # 占位值(按柱高比例估算,非真实数据)

fig, ax = plt.subplots(figsize=(6.4, 4.8))
bars = ax.bar(seasons, counts, width=0.55, color='#c0392b')

# 修正1:显示从0开始的Y轴刻度与轴标题,基线可验证为0
ax.set_ylim(0, max(counts) * 1.2)
ax.set_ylabel('故障工单数(件)')

# 修正2:柱顶直接标注数值,读者无需目测
ax.bar_label(bars, padding=3)

# 修正3:主标题与口径说明分层排布,留出间距,不重叠、不裁切
ax.set_title('季度故障工单数', loc='left', fontsize=13, pad=30)
ax.text(0, 1.02,
        '数据状态:04月起(非零整数)〔占位:原注释被遮挡不可读,请按实际口径填写〕',
        transform=ax.transAxes, fontsize=8.5, color='#c0392b', va='bottom')

ax.spines[['top', 'right']].set_visible(False)
fig.tight_layout()
plt.show()"
}
```
finish_reason: stop · prompt_tokens: 431(cached 0)· completion_tokens: 5634 · total_tokens: 6065(usage 取自 results/C06.json;本条为初跑静默空响应后以相同 Prompt 与相同图片补跑所得)
mis_03误导图 · 第 1 条即称「Y轴截断/非零基线嫌疑」,共列 3 条手法点名真值缺陷类型,召回却记 0.0 · 误报数 1 → 见打分异常②(初跑空响应、补跑补齐)
```json
{
  "misleading": true,
  "items": [
    {
      "手法名称": "Y轴截断/非零基线嫌疑(柱底被绘图区底边齐切,看不到基线是否为0)",
      "错误结论": "读者只能按高度比例比较:Q4 约为 Q1/Q3 的 2.5 倍、Q2 的约 1.5 倍,从而得出“满意度在 Q4 翻倍暴增”的结论。若 Y 轴并非从 0 开始(1–5 分制图表常被设为从 1 或 2 起画),实际分差会被成倍放大。"
    },
    {
      "手法名称": "隐去 Y 轴刻度、网格线和数值标签",
      "错误结论": "图上读不出任何绝对分数,读者只能凭柱高“感觉”判断,把“略高一点”误读成“高很多”,也无法验证 Q4 是否接近满分 5 分、Q1/Q3 到底是 2 分还是 4 分。"
    },
    {
      "手法名称": "副标题量表说明自相矛盾且被裁切(写作“非常差到非常差”)",
      "错误结论": "量表两端都写成“非常差”,读者无法确定数值方向(5 代表好还是差),可能把 Q4 的高柱误读为“差评最多”;同时该行红色小字与图区边框重叠被裁切,关键信息基本不可读。"
    }
  ],
  "fix_code": "import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False

quarters = ['Q1', 'Q2', 'Q3', 'Q4']
# 占位数据:原图无任何Y轴刻度,真实分数读不出来。
# 以下数值仅按原图柱高比例(约 97:165:97:245)折算,请替换为真实数据!
scores = [2.0, 3.4, 2.0, 5.0]

fig, ax = plt.subplots(figsize=(6, 4.2))
bars = ax.bar(quarters, scores, color='#c0392b', width=0.6)

ax.set_ylim(0, 5)                      # 诚实基线:从0开始,上限=量表满分
ax.set_yticks([0, 1, 2, 3, 4, 5])
ax.set_ylabel('满意度评分')
# 原副标题不可读且自相矛盾,按常理更正为“1=非常差,5=非常好”;如实际方向相反请调整
ax.set_title('满意度评分(1–5分制:1=非常差,5=非常好)')
ax.grid(axis='y', alpha=0.3)
ax.set_axisbelow(True)

for b, s in zip(bars, scores):         # 直接标注数值,读者无需猜测
    ax.text(b.get_x() + b.get_width() / 2, s + 0.08, f'{s:g}',
            ha='center', va='bottom')

fig.tight_layout()
plt.show()"
}
```
finish_reason: stop · prompt_tokens: 431(cached 0)· completion_tokens: 5031 · total_tokens: 5462(usage 取自 results/C06.json;本条为初跑静默空响应后以相同 Prompt 与相同图片补跑所得)
打分异常与编者注 ANOMALIES(编者注,非模型输出;只陈述可核对的事实)

① 过度指认大部分兑现进了节制分,但仍有一处没兑现。3 张干净图里,模型把 clean_00、clean_02 两张明确判为 "misleading": true 并各列出手法(原文见上)——这正是本案例要探的失败模式。clean_00 的节制得分已相应记 0.0 并加 false_alarm_on_clean 标记;但 clean_02 同样判「误导」(含 1 条手法),节制得分仍是 1.0、无任何标记。两条回复同为 ```json 围栏形态,为何一扣一免,结果文件没有任何解释。

② mis_01 点名了真值缺陷,召回却记 0;补跑补齐的 mis_03 也一样。mis_01 第一条手法是「截断纵轴(非零基线)」,mis_03 第一条是「Y轴截断/非零基线嫌疑」,都与真值缺陷类型 纵轴截断/非零基线 字面高度一致;score 里 4 个误导样本的召回仍然全部为 0.0。

③ 初跑成稿时「围栏导致按空回复计分」的推测,不被补齐后的数据支持。当时 7 条里只有 5 条有正文,曾观察到「计分对得上的都是裸 JSON」的现象并据此怀疑围栏回复被当空回复处理;现在全部 7 条都有分数:围栏回复 clean_00 被正常扣分加标,mis_02 / mis_03 的多余手法也被计入误报数——围栏显然没有被当成空回复。目前仍未解释的是上面①②两组不一致,要得到严谨结论应检查打分脚本的手法匹配逻辑后重跑 score。

④ completion_tokens 与可见输出长度明显不符。clean_01 的可见输出仅一行短 JSON,usage 却记 completion_tokens = 7088;补跑所得的 mis_02(5634)与 mis_03(5031)同样远大于各自可见输出,且三条的 completion_tokens_details.reasoning_tokens 均记 0。结果文件未解释此差异,可能存在未随响应返回的隐藏推理或计数异常。

⑤ 运行历史披露。本批次初跑(2026-08-22)时 mis_02、mis_03 为静默空响应(response.text 为 null、usage 为空对象 {}、结果文件未记录任何错误原因);随后以相同 Prompt 与相同图片重新调用补齐,结果文件于 2026-08-24 重新生成、分数重新计算,本页已整体换用补齐后的内容。初跑时的空响应现象在当前结果文件中已不复存在,上述①–④均基于补齐后的现状陈述。

脚本打分 SCORE · results/C06.json 的 score 字段原值(未做任何修饰)
样本真值 defects模型判定(编者摘自上方原文)score 行原值
clean_00[]misleading = true(2 条手法){"节制": 0.0, "召回": null, "flags": ["false_alarm_on_clean"]}
clean_01[]misleading = false(答「无」){"节制": 1.0, "召回": null, "flags": []}
clean_02[]misleading = true(1 条手法){"节制": 1.0, "召回": null, "flags": []}
mis_00[纵轴截断/非零基线]misleading = true(2 条,均未提非零基线){"召回": 0.0, "节制": null, "误报数": 1, "flags": []}
mis_01[纵轴截断/非零基线]misleading = true(3 条,第 1 条即「截断纵轴(非零基线)」){"召回": 0.0, "节制": null, "误报数": 0, "flags": []}
mis_02[纵轴截断/非零基线]misleading = true(2 条,均未提非零基线){"召回": 0.0, "节制": null, "误报数": 1, "flags": []}
mis_03[纵轴截断/非零基线]misleading = true(3 条,第 1 条称「Y轴截断/非零基线嫌疑」){"召回": 0.0, "节制": null, "误报数": 1, "flags": []}
聚合维度(双轴)aggregate 原值(归一化 0–1)说明
召回
轴一 · 能力
0.0
对应 Rubric 维度「误导识别召回」。4 个误导样本行值全为 0.0——其中 mis_01 第 1 条直接点名「截断纵轴(非零基线)」、mis_03 第 1 条称「Y轴截断/非零基线嫌疑」(异常②),此 0.0 与正文可核对的内容不符,主要反映打分管道的处理结果,不能直接读作「模型完全没识别能力」。
节制
轴二 · 节制
0.667
对应 Rubric 维度「干净图节制」。3 个干净样本行值为 (0 + 1 + 1) / 3:clean_00 判「误导」被记 0 分并加 false_alarm_on_clean 标记;clean_01 答「无」记 1.0;clean_02 同样判「误导」却仍记 1.0(异常①)。按上方原文的实际判定,3 张里只有 clean_01 答「无」,故当前 0.667 高估了实际的节制表现。
误报数(辅助计数)0.754 个误导样本行值的算术均值:(1 + 0 + 1 + 1) / 4。三个 1 分别来自 mis_00、mis_02、mis_03 在真值之外多指认的手法行值;mis_01 列了 3 条手法反而记 0——脚本如何把「真值之外的手法」计数,本页不推断,只呈现行值。

aggregate 其余字段原文:flags {"false_alarm_on_clean": 1}(落在 clean_00 行)· n = 7。score 字段中的「召回 / 节制」与第 04 节 Rubric 的「误导识别召回(30 分)/ 干净图节制(35 分)」两轴对应;「修正代码有效性」「结论影响描述」两维未出现在本次 score 中(后者属 judge 维度),页面如实留空、不作补算。

怎么读这个结果 HOW TO READ

补齐后的本次 Live Run 能确认的事实有三件:其一,未被提示时的过度指认在本模型上真实出现了——3 张干净图判了 2 张「误导」,且手法描述本身写得相当具体(隐藏刻度、注释被裁切),这与案例证据锚点「不给提示时严重过度指认」的方向一致,且这次已部分兑现成分数(clean_00 记 0.0 并加 false_alarm 标记);其二,对真正做了非零基线的 mis_01 与 mis_03,模型其实都点名了;其三,分数与正文仍有两处对不上——clean_02 判「误导」却记满分、4 条召回全为 0.0(异常①②),因此当前 aggregate(召回 0.0 / 节制 0.667 / 误报数 0.75)仍是真实行为与打分不一致的混合体。要得到 C06 的有效基准数据,应核查打分脚本的手法匹配逻辑后重跑 score。

三模型同题对比 THREE-MODEL COMPARISON · 同一套图片与 Prompt · REAL RUN · 2026-08-23

对比范围与真实性 — 本小节新增另外两次真实运行:z-ai/glm-5v-turbo(产物 results/z-ai__glm-5v-turbo/C06.json)与 moonshotai/kimi-k3(产物 results/moonshotai__kimi-k3/C06.json)。经核对,三个结果文件中的 turns[].prompt 逐字节相同,images 与真值字段也一致,因此输入图片与 Prompt 沿用上方已有展示、不重复贴三份;两个新模型的回复原文与分数逐字取自各自结果文件。配色沿用 site/compare.html 图例:蓝=stealth/ox-alpha、橙=z-ai/glm-5v-turbo、青绿=moonshotai/kimi-k3。

方法论局限(化用 compare.html 原句) — 三个模型的调用方式相同(同一套 OpenRouter chat/completions 调用),但 stealth/ox-alpha 是强制深度推理的 stealth 模型,glm-5v-turbo 与 kimi-k3 的推理行为未特别配置——输出风格与推理深度可能天然不同。这是解读本小节对比时要注意的局限,不是哪一方「作弊」。两个新结果文件的 limitations 字段与 ox-alpha 相同:「样本规模为演示级缩小版(7),非原始题库规模」。

数据时点编者注 — 本小节涉及的三个结果文件在成稿后经历过更新:ox-alpha 初跑(2026-08-22)中 mis_02 / mis_03 为静默空响应,kimi-k3 初跑(2026-08-23)中 clean_00 / clean_02 为失败(正文 null、finish_reason 记 error)。这些轮次随后均以相同 Prompt 与相同图片重新调用补齐,results/C06.json 与 results/moonshotai__kimi-k3/C06.json 均于 2026-08-24 重新生成、分数重新计算(ox-alpha 的误报数 aggregate 由 0.25 变为 0.75,节制与 flags 不变;kimi-k3 的节制 1.0 由「仅 5/7 有效回复支撑」变为全部基于真实回复);glm-5v-turbo 文件未再生成。本页全站分数与回复原文现一律按三个结果文件的当前原值展示。

stealth/ox-alphaz-ai/glm-5v-turbomoonshotai/kimi-k3
召回轴一 · 能力

误导识别召回 · 归一化 0–1 · 三模型 aggregate 均为 0.0。注意:三方正文中其实都点名过非零基线/截断类手法(见下方原文分组),与本页上文异常②③同类,此维度当前度量的是打分管道的处理而非能力差异。

ox-alpha
0.0
glm-5v-turbo
0.0
kimi-k3
0.0
节制轴二 · 重点轴

干净图节制 · 归一化 0–1 · 差异真实可见的一轴:glm-5v-turbo 把 3 张干净图全部判「存在误导」(0.333,flags 计 false_alarm_on_clean = 2);ox-alpha 判了 2/3(0.667,flags 计 1,但其中 clean_02 判「误导」却未被扣分,见上方异常①);kimi-k3 的 3 张干净图全部答「无」(1.0)——其 clean_00 / clean_02 为初跑失败后补跑补齐的真实回复,该 1.0 现建立在 7/7 有效回复上。

ox-alpha
0.667
glm-5v-turbo
0.333
kimi-k3
1.0
误报数辅助计数

4 个误导样本行值的算术均值:ox-alpha 0.75(mis_00 / mis_02 / mis_03 三行记 1)、glm-5v-turbo 0.25(仅 mis_01 行记 1)、kimi-k3 1(4 个误导样本行值均记 1)。计分脚本如何把「真值之外的手法」计数,本页不推断,只呈现行值。

ox-alpha
0.75
glm-5v-turbo
0.25
kimi-k3
1
逐样本分数与判定 PER-ITEM SCORE · score.rows[] 原值 + 判定摘自各方原文
样本真值 defects stealth/ox-alpha z-ai/glm-5v-turbo moonshotai/kimi-k3
clean_00[]判「存在误导」(2 条手法)
{"节制": 0.0, "召回": null, "flags": ["false_alarm_on_clean"]}
判「存在误导」(称「截断Y轴」)
{"节制": 0.0, "召回": null, "flags": ["false_alarm_on_clean"]}
答「无」(初跑失败、补跑补齐)
{"节制": 1.0, "召回": null, "flags": []}
clean_01[]答「无」
{"节制": 1.0, "召回": null, "flags": []}
判「存在误导」(称「Y轴截断/缺失刻度」)
{"节制": 0.0, "召回": null, "flags": ["false_alarm_on_clean"]}
答「无」
{"节制": 1.0, "召回": null, "flags": []}
clean_02[]判「存在误导」(1 条手法)
{"节制": 1.0, "召回": null, "flags": []}
判「存在误导」(称「截断纵坐标轴」)
{"节制": 1.0, "召回": null, "flags": []}
答「无」(初跑失败、补跑补齐)
{"节制": 1.0, "召回": null, "flags": []}
mis_00[纵轴截断/非零基线]2 条,均未提非零基线
{"召回": 0.0, "节制": null, "误报数": 1, "flags": []}
1 条,未断言非零基线
{"召回": 0.0, "节制": null, "误报数": 0, "flags": []}
2 条,第 1 条点名非零基线
{"召回": 0.0, "节制": null, "误报数": 1, "flags": []}
mis_01[纵轴截断/非零基线]3 条,第 1 条即「截断纵轴(非零基线)」
{"召回": 0.0, "节制": null, "误报数": 0, "flags": []}
3 条,第 1 条即「Non-zero Baseline」
{"召回": 0.0, "节制": null, "误报数": 1, "flags": []}
2 条,点名非零基线并读出「1149 万元起」
{"召回": 0.0, "节制": null, "误报数": 1, "flags": []}
mis_02[纵轴截断/非零基线]2 条,均未提非零基线(补跑补齐)
{"召回": 0.0, "节制": null, "误报数": 1, "flags": []}
1 条,称「截断Y轴/省略刻度」
{"召回": 0.0, "节制": null, "误报数": 0, "flags": []}
1 条,读出「纵轴从84起」
{"召回": 0.0, "节制": null, "误报数": 1, "flags": []}
mis_03[纵轴截断/非零基线]3 条,第 1 条称「Y轴截断/非零基线嫌疑」(补跑补齐)
{"召回": 0.0, "节制": null, "误报数": 1, "flags": []}
1 条,称「截断纵轴与隐藏刻度」
{"召回": 0.0, "节制": null, "误报数": 0, "flags": []}
1 条,读出「纵轴从40起」
{"召回": 0.0, "节制": null, "误报数": 1, "flags": []}

表中判定文字为本页编者摘自各方原文的概括(原文逐字见下),score 行值为三个结果文件 score.rows[] 原值;aggregate 三行与 results/compare.json 的 C06 条目一致。ox-alpha 的 mis_02 / mis_03 与 kimi-k3 的 clean_00 / clean_02 为初跑失败、补跑补齐所得(见下方各条说明与数据时点编者注)。

三模型真实原文回复 RAW RESPONSES · stealth/ox-alpha 已在上方的「模型真实原文回复」完整展示、此处不重复 · 以下为另外两个模型的逐字原文(按样本顺序)
z-ai/glm-5v-turbo(橙)· 7/7 样本均有正文 · 全部包在 Markdown ```json 围栏里 · finish_reason 均为 stop
clean_00干净图 · 判「存在误导」,称「截断Y轴(Non-zero Baseline)」过度指认(真值为无缺陷);该项节制记 0.0 并带 false_alarm 标记
```json
{
  "misleading": true,
  "items": [
    {
      "technique": "截断Y轴(Non-zero Baseline / Truncated Y-Axis)",
      "misconception": "使读者误以为周活跃用户在W1至W3期间出现了**大幅度**的显著增长(视觉上柱高差异明显),且W4出现明显回落;而实际上各周之间的绝对数值差异可能非常微小(例如仅2%-5%的波动),在完整尺度下几乎持平。",
      "detail": "图表Y轴起始值明显高于0(从柱形占据绝大部分绘图区可推断),导致微小差异被视觉放大数倍,违反了柱状图应从原点开始以准确表达数量级关系的原则。"
    }
  ],
  "fix_code": "import matplotlib.pyplot as plt
import numpy as np

# 图中可读出的相对趋势:W1 < W2 < W3,W4略低于W3但高于W2
# 具体数值无法读取,以下为符合视觉比例的占位数据(单位:万)
weeks = ['W1', 'W2', 'W3', 'W4']
values = [102.0, 105.5, 108.2, 106.8]  # 占位数据,保持 W1<W2<W3 且 W3>W4>W2 的关系

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

# 左图:诚实版本(Y轴从0开始)
bars1 = ax1.bar(weeks, values, color='#4472C4', width=0.6)
ax1.set_title('诚实版本:Y轴从0开始', fontsize=12, fontweight='bold')
ax1.set_ylabel('周活跃用户(万)')
ax1.set_ylim(0, max(values) * 1.25)  # 关键修复:强制从0开始
ax1.axhline(y=0, color='black', linewidth=0.8)
ax1.grid(axis='y', alpha=0.3, linestyle='--')

# 添加数据标签以消除歧义
for bar in bars1:
    height = bar.get_height()
    ax1.text(bar.get_x() + bar.get_width()/2., height,
             f'{height:.1f}', ha='center', va='bottom', fontsize=10)

# 右图:原图问题示意(Y轴截断,仅作对比参考)
bars2 = ax2.bar(weeks, values, color='#4472C4', width=0.6)
ax2.set_title('问题版本:Y轴截断(误导性)', fontsize=12, fontweight='bold', color='red')
ax2.set_ylabel('周活跃用户(万)')
ax2.set_ylim(min(values) * 0.95, max(values) * 1.05)  # 模拟截断效果
ax2.grid(axis='y', alpha=0.3, linestyle='--')

plt.tight_layout()
plt.show()"
}
```
finish_reason: stop · prompt_tokens: 342 · completion_tokens: 2007(reasoning 1299) · total_tokens: 2349 · cost: $0.0084384 · usage 取自 results/z-ai__glm-5v-turbo/C06.json
clean_01干净图 · 判「存在误导」,称「Y轴截断 / 缺失坐标轴刻度」并附目测估算金额过度指认(真值为无缺陷);该项节制记 0.0 并带 false_alarm 标记
```json
{
  "misleading": true,
  "items": [
    {
      "technique": "Y轴截断(Truncated Y-axis)/ 缺失坐标轴刻度",
      "misconception": "读者无法获取各门店的具体营收数值,只能进行粗略的相对比较;若Y轴实际起始值非零(图表未明确标注原点),会严重放大门店间的营收差异(例如将10%的差异视觉化为30-50%),导致对业绩差距产生错误判断;同时因无刻度线,无法验证柱高与数值的对应关系。",
      "estimated_data": {
        "note": "以下为根据柱状图相对高度目测的估算值,实际数值应以原始数据为准",
        "A": "~80万元",
        "B": "~95万元", 
        "C": "~88万元",
        "D": "~105万元"
      }
    }
  ],
  "fix_code": "import matplotlib.pyplot as plt
import numpy as np

# 设置中文字体(根据系统调整,如 SimHei, Arial Unicode MS 等)
plt.rcParams['font.sans-serif'] = ['SimHei', 'DejaVu Sans']
plt.rcParams['axes.unicode_minus'] = False

# 数据(基于目测估算的占位值,实际使用时请替换为真实数据)
stores = ['A', 'B', 'C', 'D']
revenues = [80, 95, 88, 105]  # 单位:万元,[请替换为真实数值]

# 创建图形
fig, ax = plt.subplots(figsize=(8, 6))

# 绘制柱状图,确保颜色与原图接近
bars = ax.bar(stores, revenues, color='#4472C4', width=0.6, edgecolor='black', linewidth=0.5)

# 关键修正1:Y轴必须从0开始,避免截断误导
ax.set_ylim(0, max(revenues) * 1.25)

# 关键修正2:添加清晰的Y轴刻度和网格线
ax.set_ylabel('营收(万元)', fontsize=12)
ax.set_title('各门店营收(万元)', fontsize=14, fontweight='bold')
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda x, p: f'{x:.0f}'))
ax.grid(axis='y', alpha=0.3, linestyle='--')

# 关键修正3:添加数据标签,消除歧义
for bar in bars:
    height = bar.get_height()
    ax.text(bar.get_x() + bar.get_width()/2., height + 1,
            f'{height}',
            ha='center', va='bottom', fontsize=11)

# 移除顶部和右侧边框,保持简洁
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

plt.tight_layout()
plt.show()"
}
```
finish_reason: stop · prompt_tokens: 342 · completion_tokens: 2229(reasoning 1561) · total_tokens: 2571 · cost: $0.0093264 · usage 取自 results/z-ai__glm-5v-turbo/C06.json
clean_02干净图 · 判「存在误导」,称「截断纵坐标轴」过度指认(真值为无缺陷);该项节制却记 1.0、无标记
```json
{
  "misleading": true,
  "items": [
    {
      "technique": "截断纵坐标轴(Non-zero Baseline / Truncated Y-Axis)",
      "effect": "夸大季度间的差异幅度。使读者误认为冬季故障工单数较其他季节呈“爆发式”增长(如误以为冬季是春季的2倍以上),而实际绝对数值差异可能仅为15%-20%左右;同时掩盖了春夏秋三季数值相近的事实。",
      "data_note": "原图无具体刻度值,以下为基于柱高比例的估算占位值:春≈60,夏≈72,秋≈62,冬≈85(单位:个)"
    }
  ],
  "fix_code": "import matplotlib.pyplot as plt
import numpy as np

# 占位数据(请替换为实际数值)
quarters = ['春', '夏', '秋', '冬']
values = [60, 72, 62, 85]  # 基于目测比例的示例值

fig, ax = plt.subplots(figsize=(8, 5))
bars = ax.bar(quarters, values, color='#4472C4', width=0.6)

# 关键修正1:强制Y轴从0开始,消除视觉夸大
ax.set_ylim(0, max(values) * 1.25)

# 关键修正2:添加数据标签,确保精确读取
for bar in bars:
    height = bar.get_height()
    ax.annotate(f'{height}',
                xy=(bar.get_x() + bar.get_width() / 2, height),
                xytext=(0, 3),
                textcoords="offset points",
                ha='center', va='bottom',
                fontsize=11)

ax.set_ylabel('故障工单数(个)', fontsize=12)
ax.set_title('季度故障工单数', fontsize=14, fontweight='bold')
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.tick_params(axis='both', labelsize=11)

# 添加网格线辅助读数(仅Y轴)
ax.yaxis.grid(True, linestyle='--', alpha=0.7)
ax.set_axisbelow(True)

plt.tight_layout()
plt.show()"
}
```
finish_reason: stop · prompt_tokens: 342 · completion_tokens: 1957(reasoning 1422) · total_tokens: 2299 · cost: $0.0082384 · usage 取自 results/z-ai__glm-5v-turbo/C06.json
mis_00误导图 · 称「省略Y轴刻度与基线」,未断言非零基线召回 0.0 · 误报数 0
```json
{
  "misleading": true,
  "items": [
    {
      "technique": "省略Y轴刻度与基线(Truncated/Hidden Axis)",
      "misconception": "读者无法验证‘提升70%+’的真实性,且极易凭视觉高估增长幅度(例如将70%的增长感知为100%以上的翻倍增长),同时完全无法获知各周具体的活跃用户规模(绝对值)。",
      "description": "图表未提供Y轴任何刻度线、数值或数据标签,仅保留相对柱高。这种做法既隐藏了数据基准(是否从0开始未知),也使文字宣称的‘70%+’增长无法被视觉核验,属于通过信息不对称引导读者接受预设结论的手法。"
    }
  ],
  "fix_code": "import matplotlib.pyplot as plt
import numpy as np

# 图中可读出的时间维度
weeks = ['W1', 'W2', 'W3', 'W4']
# 因原图无刻度,此处用占位符表示待填充的真实数值(单位:万)
# 建议根据实际数据替换,若遵循'提升70%+'且视觉比例大致吻合,示例假设如下:
values = [w1_val, w2_val, w3_val, w4_val]  # 请替换为实际数值

fig, ax = plt.subplots(figsize=(8, 5))
bars = ax.bar(weeks, values, color='#B84C4C', width=0.6, edgecolor='black', linewidth=0.8)

# 修正1:强制Y轴从0开始,避免截断夸大比例
ax.set_ylim(0, max(values) * 1.15)

# 修正2:添加清晰的Y轴刻度与网格线
ax.set_ylabel('周活跃用户(万)', fontsize=12)
ax.yaxis.grid(True, linestyle='--', alpha=0.7)
ax.set_axisbelow(True)

# 修正3:添加数据标签,确保透明度
for bar in bars:
    height = bar.get_height()
    ax.annotate(f'{height}',
                xy=(bar.get_x() + bar.get_width() / 2, height),
                xytext=(0, 3), textcoords="offset points",
                ha='center', va='bottom', fontsize=10)

# 修正4:将注释移至不遮挡数据的位置,并明确说明计算方式
ax.text(0.02, 0.98, '环比增长:70%+(注:非考勤数,统计口径需注明)', 
        transform=ax.transAxes, fontsize=9, verticalalignment='top',
        bbox=dict(boxstyle='round', facecolor='wheat', alpha=0.5))

plt.title('周活跃用户(万)', fontsize=14, loc='left', pad=20)
plt.tight_layout()
plt.show()"
}
```
finish_reason: stop · prompt_tokens: 342 · completion_tokens: 1902(reasoning 1232) · total_tokens: 2244 · cost: $0.0080184 · usage 取自 results/z-ai__glm-5v-turbo/C06.json
mis_01误导图 · 第 1 条手法即「Non-zero Baseline」,共列 3 条召回 0.0 · 误报数 1
```json
{
  "misleading": true,
  "items": [
    {
      "technique": "截断纵坐标轴(Non-zero Baseline / Truncated Y-axis)",
      "effect": "纵坐标轴未从原点(0)开始,导致柱体高度差异被视觉放大。读者会误认为D店营收是A店的2倍以上(或差异极其悬殊),而实际数值差异可能仅有30%-50%;同时B店与C店的细微差距也被不成比例地拉大。",
      "severity": "high"
    },
    {
      "technique": "省略坐标轴刻度(Missing Axis Ticks/Labels)",
      "effect": "Y轴完全无刻度标记和网格线,读者无法读取任何门店的具体营收数值(万元),也无法验证柱高是否按真实比例绘制,剥夺了读者对数据真实性的核查能力。",
      "severity": "medium"
    },
    {
      "technique": "冗余/错误注释干扰",
      "effect": "顶部标注“数据共14座(非零售类型)”与图表主题“各门店营收”语义矛盾且位置突兀,可能让读者困惑该统计口径是否适用于当前四家门店,或误以为这是累计数据而非单店数据。",
      "severity": "low"
    }
  ],
  "fix_code": "import matplotlib.pyplot as plt
import numpy as np

# 图中可读出的相对比例数据(具体数值需替换为实际值)
# 根据目测像素高度估算的比例关系(假设单位:万元)
stores = ['A店', 'B店', 'C店', 'D店']
# 占位说明:此处为根据柱高比例的估算值,实际应用中请填入真实数据
revenue = [62, 74, 69, 98]  # 示例数据,请替换为 [A_实际值, B_实际值, C_实际值, D_实际值]

fig, ax = plt.subplots(figsize=(8, 5))

# 绘制标准柱状图:确保y轴从0开始(关键修复)
bars = ax.bar(stores, revenue, color='#C94F4F', width=0.6, edgecolor='black', linewidth=0.8)

# 添加数据标签(修复“无刻度”问题)
for bar, val in zip(bars, revenue):
    height = bar.get_height()
    ax.text(bar.get_x() + bar.get_width()/2., height,
            f'{val}',
            ha='center', va='bottom', fontsize=11, fontweight='bold')

# 设置坐标轴(诚实呈现)
ax.set_ylabel('营收(万元)', fontsize=12)
ax.set_title('各门店营收(万元)', fontsize=14, fontweight='bold', pad=15)
ax.set_ylim(0, max(revenue) * 1.2)  # 强制Y轴从0开始,并留出20%顶部空间显示标签
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)
ax.grid(axis='y', alpha=0.3, linestyle='--')

# 移除错误的注释文本
plt.tight_layout()
plt.show()"
}
```
finish_reason: stop · prompt_tokens: 342 · completion_tokens: 1819(reasoning 1078) · total_tokens: 2161 · cost: $0.0076864 · usage 取自 results/z-ai__glm-5v-turbo/C06.json
mis_02误导图 · 称「截断Y轴 / 省略坐标轴刻度」召回 0.0 · 误报数 0
```json
{
  "misleading": true,
  "items": [
    {
      "technique": "截断Y轴 / 省略坐标轴刻度 (Truncated Y-axis & Missing Scale)",
      "error_conclusion": "读者无法得知各季度故障工单的具体数量及真实比例;若Y轴实际非零起点(从视觉压缩程度推测极有可能),会严重夸大季度间差异(例如误以为冬季故障数是春季的1.8-2.0倍,而实际可能仅为1.2-1.3倍),导致对季节性风险程度的错误评估。",
      "details": "图表完全缺失Y轴刻度线、数值标签及单位,违反了柱状图面积/长度应与数值成比例的基本原则。"
    }
  ],
  "fix_code": "import matplotlib.pyplot as plt
import numpy as np

# 季度标签
quarters = ['春', '夏', '秋', '冬']

# 数值占位符(请根据原始数据源替换以下数值)
# 目测相对比例:设春为基准100,则夏≈125,秋≈98,冬≈158
values = [100, 125, 98, 158]  # TODO: 替换为实际故障工单数

# 创建图形
fig, ax = plt.subplots(figsize=(8, 6))
bars = ax.bar(quarters, values, color='#B84C4C', width=0.6, edgecolor='black', linewidth=0.5)

# 【关键修正1】Y轴必须从0开始,确保柱高比例真实反映数据差异
ax.set_ylim(0, max(values) * 1.2)

# 【关键修正2】添加完整的Y轴刻度和标签(原图缺失)
ax.set_ylabel('故障工单数(单)', fontsize=12)
ax.set_title('季度故障工单数', fontsize=14, fontweight='bold', pad=15)

# 【关键修正3】在柱顶添加精确数值标签,消除读数歧义
for bar in bars:
    height = bar.get_height()
    ax.annotate(f'{int(height)}',
                xy=(bar.get_x() + bar.get_width() / 2, height),
                xytext=(0, 5),
                textcoords="offset points",
                ha='center', va='bottom',
                fontsize=11, fontweight='bold')

# 辅助元素:添加水平网格线辅助估读(透明度低以免喧宾夺主)
ax.yaxis.grid(True, linestyle='--', alpha=0.3)
ax.set_axisbelow(True)  # 网格线置于柱状图下层

# 移除不必要的边框(简洁化)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

plt.tight_layout()
plt.show()"
}
```
finish_reason: stop · prompt_tokens: 342 · completion_tokens: 2324(reasoning 1658) · total_tokens: 2666 · cost: $0.0097064 · usage 取自 results/z-ai__glm-5v-turbo/C06.json
mis_03误导图 · 称「截断纵轴与隐藏坐标轴刻度」召回 0.0 · 误报数 0
```json
{
  "misleading": true,
  "items": [
    {
      "technique": "截断纵轴(Truncated Y-Axis / Non-zero Baseline)与隐藏坐标轴刻度",
      "effect": "使读者误判Q4相对于Q1的满意度提升幅度。例如,读者可能得出'Q4满意度是Q1的2倍以上'或'Q4出现爆发式增长'的错误结论,而实际绝对分值差异可能仅为10%-20%(例如从3.5分升至4.2分)。",
      "detail": "图表Y轴既无刻度标注,也无零基线标识,通过压缩Y轴可视区间人为放大了柱体间的高度比率,违反了面积/长度编码应与数值成比例的原则。"
    }
  ],
  "fix_code": "import matplotlib.pyplot as plt
import numpy as np

# 占位数据(根据原图视觉比例估算,实际应用需替换为真实值)
quarters = ['Q1', 'Q2', 'Q3', 'Q4']
# 示例:假设实际满意度评分为1-5分制,原图因截断导致视觉失真
values = [3.5, 4.2, 3.6, 4.8]  # 请替换为 [Q1_val, Q2_val, Q3_val, Q4_val]

fig, ax = plt.subplots(figsize=(8, 5))
bars = ax.bar(quarters, values, color='#B83A3E', width=0.6)

# 关键修正:强制Y轴从0开始,恢复真实比例
ax.set_ylim(0, max(values) * 1.2)
ax.set_ylabel('满意度评分', fontsize=12)
ax.set_title('满意度评分', fontsize=14, fontweight='bold', loc='left')

# 添加网格线辅助读数(可选,增强可读性)
ax.yaxis.grid(True, linestyle='--', alpha=0.7)
ax.set_axisbelow(True)

# 添加数据标签(弥补原信息缺失)
for bar in bars:
    height = bar.get_height()
    ax.annotate(f'{height}',
                xy=(bar.get_x() + bar.get_width() / 2, height),
                xytext=(0, 3), textcoords="offset points",
                ha='center', va='bottom', fontsize=10)

# 移除顶部和右侧边框(简洁化)
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

plt.tight_layout()
plt.show()"
}
```
finish_reason: stop · prompt_tokens: 342 · completion_tokens: 1864(reasoning 1268) · total_tokens: 2206 · cost: $0.0078664 · usage 取自 results/z-ai__glm-5v-turbo/C06.json
moonshotai/kimi-k3(青绿)· 7/7 样本均有正文 · finish_reason 均为 stop · 其中 clean_00 / clean_02 为初跑失败后补跑补齐(初跑正文 null、finish_reason 记 error)
clean_00干净图 · 答「无」(单行紧凑 JSON)判定正确,节制 1.0(初跑失败、补跑补齐的样本)
{"misleading":false,"items":[],"fix_code":""}
finish_reason: stop · prompt_tokens: 430 · completion_tokens: 690(reasoning 938) · total_tokens: 1120 · cost: $0.0114672 · usage 取自 results/moonshotai__kimi-k3/C06.json;本条为初跑失败后以相同 Prompt 与相同图片补跑所得
clean_01干净图 · 答「无」(单行紧凑 JSON)本次唯一有正文的干净图回复,判定正确;节制 1.0
{"misleading":false,"items":[],"fix_code":""}
finish_reason: stop · prompt_tokens: 434 · completion_tokens: 1695(reasoning 2148) · total_tokens: 2129 · cost: $0.02539065 · usage 取自 results/moonshotai__kimi-k3/C06.json
clean_02干净图 · 答「无」(带空格的单行 JSON)判定正确,节制 1.0(初跑失败、补跑补齐的样本)
{"misleading": false, "items": [], "fix_code": ""}
finish_reason: stop · prompt_tokens: 430 · completion_tokens: 1542(reasoning 2087) · total_tokens: 1972 · cost: $0.0242472 · usage 取自 results/moonshotai__kimi-k3/C06.json;本条为初跑失败后以相同 Prompt 与相同图片补跑所得
mis_00误导图 · 点名「截断纵轴/非零基线」等 2 条手法召回 0.0 · 误报数 1
{"misleading":true,"items":[{"technique":"截断纵轴/非零基线用于柱状图(小字标注不足以抵消)","false_conclusion":"读者会把柱高比例误当真实用户量比例:按柱高估计会得出 W4 约为 W1 的 1.9–2.0 倍、W3 约为 1.5 倍、W2 约为 1.25 倍;但纵轴不从 0 开始,真实倍数必然更小,且起点数值未给出,读者无法校正。"},{"technique":"省略纵轴刻度、网格线与数据标签","false_conclusion":"读者无法读出 W1-W4 的具体万数、相邻周差值或百分比,只能凭红色柱高猜测;这会把视觉上的巨大落差当成实际绝对增长,或使人意识不到轴已被截断。"}],"fix_code":"import matplotlib.pyplot as plt\n\n# 图中可读出的只有:类别 W1-W4、指标名“周活跃用户”、单位“万”;具体数值和纵轴起点未标出。\n# 请将 None 替换为原始数据(单位:万)。不要从被截断的柱高反推数值。\nvalues = {'W1': None, 'W2': None, 'W3': None, 'W4': None}\nassert all(v is not None for v in values.values()), '请填入真实数值后再绘图'\n\nlabels = list(values.keys())\ny = [values[k] for k in labels]\n\nfig, ax = plt.subplots(figsize=(6, 4))\nbars = ax.bar(labels, y, color='#c0392b')\nax.set_ylim(0, max(y) * 1.15)  # 柱状图必须使用零基线\nax.set_ylabel('周活跃用户(万)')\nax.set_title('周活跃用户(万)')\nax.grid(axis='y', alpha=0.3)\nax.bar_label(bars, fmt='%.1f')\n\n# 如需强调变化,用真实差值/百分比在标题或注释中说明,而不是截断柱高:\n# pct = [(y[i] / y[i-1] - 1) * 100 for i in range(1, len(y))]\nplt.tight_layout()\nplt.show()"}

↑ 此条为模型输出的原始形态:单行紧凑 JSON,fix_code 内的换行是字面的 \n 转义序列(原样保留)。

finish_reason: stop · prompt_tokens: 433 · completion_tokens: 3267(reasoning 2754) · total_tokens: 3700 · cost: $0.050304 · usage 取自 results/moonshotai__kimi-k3/C06.json
mis_01误导图 · 读出红字「1149 万元起」,点名非零基线召回 0.0 · 误报数 1
{
  "misleading": true,
  "items": [
    {
      "technique": "非零基线/截断纵轴的柱状图",
      "wrong_conclusion": "读者会把柱高比例当成营收比例:图上 D 柱约为 A 柱的 1.6 倍、D 也明显高于 B/C,从而得出“D 营收约比 A 多六成、门店差距很大”的结论。但图中红字可读纵轴从 1149 万元起,柱高只编码“超过 1149 的部分”;真实营收比应是 (1149+d_D)/(1149+d_A),必然小于柱高比,且在差额相对 1149 不大时会接近 1。"
    },
    {
      "technique": "只标注截断起点,不提供纵轴刻度/终点和数据标签",
      "wrong_conclusion": "读者无法把“1149 起”转换成可量化校正,容易仍把 x 轴当 0,或无法判断 D 比 A 实际多多少万元/百分比。图中可读出的只有门店 A/B/C/D、单位万元和起点 1149;各店真实营收读不出。"
    }
  ],
  "fix_code": "import matplotlib.pyplot as plt\n\nstores = ['A', 'B', 'C', 'D']\nunit = '万元'\naxis_start_read_from_chart = 1149  # 图中红字可读;只用于偏差说明,不得作为营收柱的 y 轴下限\nrevenue = {'A': None, 'B': None, 'C': None, 'D': None}  # PLACEHOLDER: 图中读不出真实营收,请用原始数据替换;不要由柱高反推\nbar_height_px_audit_only = {'A': 130, 'B': 152, 'C': 141, 'D': 207}  # 仅记录图像像素,不是营收\n\nif any(revenue[s] is None for s in stores):\n    raise ValueError('真实营收在图中读不出;请填充 revenue 后再画。诚实图不能用像素柱高或 1149 起点反推营收。')\n\nvals = [revenue[s] for s in stores]\nfig, ax = plt.subplots(figsize=(7, 4))\nbars = ax.bar(stores, vals, color='#C44536')\nax.set_ylim(0, max(vals) * 1.15)\nax.set_ylabel('营收(' + unit + ')')\nax.set_title('各门店营收(' + unit + ')')\nax.bar_label(bars, fmt='%.0f')\nax.grid(axis='y', alpha=0.25)\nax.set_axisbelow(True)\nfig.text(0.01, 0.01, '诚实版本:营收柱 y 轴从 0 开始;1149 仅为原图截断起点。', ha='left')\nplt.tight_layout(rect=[0, 0.04, 1, 1])\nplt.show()\n\n# 如分析重点是相对 1149 的差额,应单独画偏差图,且不得把它叫作营收:\n# dev = [v - axis_start_read_from_chart for v in vals]\n# fig2, ax2 = plt.subplots(figsize=(7, 3))\n# b2 = ax2.bar(stores, dev, color='#4C78A8')\n# ax2.axhline(0, color='black', linewidth=0.8)\n# ax2.set_ylabel('营收 - 1149(' + unit + ')')\n# ax2.set_title('相对 1149 ' + unit + ' 的差额(非营收本身)')\n# ax2.bar_label(b2, fmt='%.0f')\n# plt.tight_layout()\n# plt.show()"
}
finish_reason: stop · prompt_tokens: 433 · completion_tokens: 4162(reasoning 3768) · total_tokens: 4595 · cost: $0.0594804 · usage 取自 results/moonshotai__kimi-k3/C06.json
mis_02误导图 · 读出红字「纵轴从84起」,点名非零基线召回 0.0 · 误报数 1
{"misleading": true, "items": [{"technique": "柱状图纵轴截断(非零基线,图中红字自承'纵轴从84起')", "wrong_conclusion": "柱形图用长度编码数值,纵轴从84而非0开始后,读者会按柱子高度直觉比较:春季与秋季看起来相近、冬季柱子约为春/秋的1.7倍,从而得出'冬季故障工单数比春/秋季多约七成、季度间波动很大'的错误结论;按柱高反推,若春≈98、冬≈108,则截断轴把(108-84)/(98-84)=24/14≈1.71的视觉差异放大,而真实差异108/98仅约+10%。图上小字标注并不能消除该误导,因为读者仍用柱长做判断。"}], "fix_code": "import matplotlib.pyplot as plt\n\nquarters = ['春', '夏', '秋', '冬']\n# 图中唯一可读的数值信息:原图纵轴从 84 起(红字);四个季度的真实工单数没有 y 轴刻度/数据标签,读不出。\n# 下列 counts 为按柱高相对比例反推的 PLACEHOLDER 估计(满足 春≈秋<夏<冬,且在基线 84 下 (v-84) 的比接近原图柱高比),发布前必须替换为真实工单数。\nORIGINAL_TRUNCATED_BASELINE = 84  # 原图可读:非零基线\ncounts = [98, 101, 98, 108]  # PLACEHOLDER/估计:真实值图中不可读,勿直接用于结论\n\nfig, ax = plt.subplots(figsize=(6, 4))\nbars = ax.bar(quarters, counts, color='#C0392B')\nax.set_ylim(0, max(counts) * 1.18)  # 诚实做法:柱状图纵轴必须从 0 开始\nax.set_title('季度故障工单数')\nax.set_ylabel('故障工单数(件)')\nfor b, v in zip(bars, counts):\n    ax.text(b.get_x() + b.get_width() / 2, v, str(v), ha='center', va='bottom', fontsize=10)\n# 不画被截断的基线;如确需展示与目标阈值的关系,用水平参考线而非截断 y 轴。\nplt.tight_layout()\nplt.show()"}

↑ 此条为模型输出的原始形态:单行紧凑 JSON,fix_code 内的换行是字面的 \n 转义序列(原样保留)。

finish_reason: stop · prompt_tokens: 430 · completion_tokens: 2636(reasoning 2075) · total_tokens: 3066 · cost: $0.04083 · usage 取自 results/moonshotai__kimi-k3/C06.json
mis_03误导图 · 读出红字「纵轴从40起」,点名非零基线召回 0.0 · 误报数 1
{"misleading":true,"items":[{"technique":"柱状图截断纵轴/非零基线(图上小字自称“纵轴从40起”)","wrong_conclusion":"读者会把柱高当成从零开始的完整长度,从而按视觉高度比读出错误倍数:Q4 看起来约为 Q1/Q3 的 2.2 倍、Q2 约为 Q1/Q3 的 1.4 倍;实际上基线被设为 40,柱高只代表“超过 40 的部分”,真实满意度倍数必须用原始数值相对零基线或直接用数值标注判断,不能按截断后的柱高比较。原图没有可读纵轴刻度,具体数值读不出,因此代码中使用 None 占位并强制先填真实值。"}],"fix_code":"import matplotlib.pyplot as plt\n\nlabels = ['Q1', 'Q2', 'Q3', 'Q4']\nvalues = [None, None, None, None]  # 占位:原图只能读出 Q1-Q4;纵轴无刻度,真实满意度值读不出\n\nif any(v is None for v in values):\n    raise ValueError('原图缺少可读纵轴刻度,无法从像素恢复真实数值;请把 values 替换为真实的 [Q1, Q2, Q3, Q4] 后再绘制。')\n\nfig, ax = plt.subplots(figsize=(6, 4))\nbars = ax.bar(labels, values, color='#C04A3B')\nax.set_ylim(0, max(values) * 1.15)  # 诚实版本:柱状图必须从 0 开始\nax.set_ylabel('满意度评分')\nax.set_title('满意度评分(零基线)')\nax.spines['top'].set_visible(False)\nax.spines['right'].set_visible(False)\n\nfor bar, v in zip(bars, values):\n    ax.annotate(f'{v:.1f}', xy=(bar.get_x() + bar.get_width() / 2, v), xytext=(0, 3), textcoords='offset points', ha='center', va='bottom')\n\nplt.tight_layout()\nplt.show()"}

↑ 此条为模型输出的原始形态:单行紧凑 JSON,fix_code 内的换行是字面的 \n 转义序列(原样保留)。

finish_reason: stop · prompt_tokens: 434 · completion_tokens: 2519(reasoning 2387) · total_tokens: 2953 · cost: $0.03713265 · usage 取自 results/moonshotai__kimi-k3/C06.json
三模型对照速读(编者注,只陈述可核对的事实)

① 节制轴上的差异真实可见,glm-5v-turbo 的过度指认最重。它把 3 张干净图全部判为「存在误导」,且每张都给出「Non-zero Baseline / 截断Y轴」类手法名(原文见上)——而那组图的真值是「无缺陷」;ox-alpha 为 2/3 判「误导」(其中 clean_00 已被计 0.0 加标、clean_02 未被扣分);kimi-k3 补跑补齐后的 3 张干净图全部答「无」,节制 1.0 现在建立在 7/7 有效回复上,可与另两家直接比较。

② 四张误导图上,三个模型的正文其实都点名了非零基线/截断纵轴类手法,但三方召回均为 0.0。这与本页上文异常②(mis_01 点名真值手法却记 0)是同一类现象:当前 aggregate 召回 0.0 对三家一体成立,度量的是打分管道的处理,区分不出三家的识别能力。

③ 对被图框裁切的红字的辨认,三方互不相同。同一张 mis_01:ox-alpha 读作「数据从140起」,kimi-k3 读作「纵轴从 1149 万元起」,glm-5v-turbo 读作「数据共14座(非零售类型)」;kimi-k3 在 mis_02 / mis_03 上还分别读出「84」「40」的起点。原图小字确实被裁切,三种读法孰对孰错本页无法裁定,仅并列呈现。

④ 补跑前后的对照(只陈述可核对的事实)。ox-alpha 初跑的 mis_02 / mis_03 与 kimi-k3 初跑的 clean_00 / clean_02 都没有正文(前者 finish_reason 记 stop、usage 为空,后者记 error、completion_tokens 全为 reasoning),初跑失败原因均无日志可查;补跑后四条均正常返回并参与计分。token 计数的方向差异仍在:kimi-k3 各条 reasoning_tokens 普遍大于 completion_tokens,而 ox-alpha 各条 reasoning 恒记 0、completion 远大于可见输出(见上方异常④)。