> 检查工具的噪声按「来源文件」折叠,不按条目截断

Research Tools Beginner 2026-10-08 05:57 2026-10-08
#tooling #evaluation #signal-to-noise #provenance #latex

一个检查工具报了几百条,先别急着调阈值或者只显示前 20 条。 按「这条发现来自哪个文件」分组数一遍,噪声通常压倒性地来自一两个来源。

// TABLE_OF_CONTENTS

结论先行

一个检查工具报了几百条,先别急着调阈值或者只显示前 20 条。 按「这条发现来自哪个文件」分组数一遍,噪声通常压倒性地来自一两个来源。

实测一篇论文:符号一致性检查报 474 条,其中

来源 条数 作者能处理吗
会场模板自带的 math_commands.tex 419 ❌ 不是他写的,也不该改
作者自己的导言区 + 正文 55 ✅

按来源折叠之后 474 → 59,44 条真问题从此在第一屏。

判据不是「条数太多」,是「这条发现的接收者能不能动它」。 动不了的东西报多少条都是零。

为什么

那个模板文件定义 430 个宏,论文用到 14 个。 剩下 416 个各报一条「宏定义了但没用到」——单看每一条都成立, 合起来却把同一篇论文里 44 条真问题埋掉了。

三种常见的错误处理方式,都不解决问题:

  • 调阈值:这 416 条本身没有「严重度」可调,它们是事实。
  • 只显示前 N 条:排序不变的话,前 N 条还是那 416 条里的。
  • 加文件名黑名单:math_commands.tex 只是这个会场的名字, 换个模板换个名字,同[[self-checks-must-enumerate-not-list|清单式自检]]一样跟不上。

有效的判据是结构性的:一个文件定义 ≥20 个宏、而论文用到的不足 20%, 就判定为「模板宏库」,出一条汇总说明,不再逐条列。 作者自己导言区里真正没用上的宏(这篇有 3 个)仍然逐条报——那是要清理的,那 416 个不是。 改完在另外 30 篇论文上复跑,条数落在 19–39,没有把真信号一起吃掉。

顺带一件事:在接上运行遥测之前,「这个工具很吵」只是印象。 遥测把每次调用的发现数记下来之后,同一个工具在不同论文上是 474 / 66 / 0, 一眼就能看出问题不在工具的规则,而在某一篇的某一个文件。

怎么用

分诊三步,顺序不能换:

  1. 按来源分组(定义它的文件、产生它的规则、命中的目录),先看分布再看内容。
    collections.Counter(i["file"] for i in findings).most_common(5)
    collections.Counter(i["type"] for i in findings).most_common(5)
    
  2. 对每个大头问一句:接收者能动它吗? 动不了的(第三方 vendored 代码、会场模板、生成产物)折叠成一条,说明为什么不列。
  3. 折叠规则用结构判据,别用文件名。 「定义量大 + 使用率低」「路径在 third_party/ 下」「有 UPSTREAM-SOURCE.txt」 这类判据换个项目还成立,硬编码的文件名不成立。

折叠之后那一条汇总必须留在报告里,不能静默丢弃—— 读者要能看见「这里有 416 个未使用宏,来自模板,我没列」, 否则就变成了 最危险的工具故障是"静默少做"——技能在、后端不在 的另一种形态。

出处

  • ~/Tools/notation-check/notation_check.py,MACRO_LIBRARY 分支(2026-09-06)
  • 触发它的论文:~/Projects/edgecloud-reasoning/paper/probml2026(ICLR/ProbML 模板)
  • 遥测:~/Tools/<tool>/feedback/runs.jsonl,feedback.py runs --all