> 随机占位决策器读起来像一个很弱的系统,不像"模型根本没接上"
一套完整的实验脚本跑完了,结果写进了报告。决策器长这样:
结论先行¶
一套完整的实验脚本跑完了,结果写进了报告。决策器长这样:
def mock_decision_maker(scenario):
"""Mock decision maker - replace with your model"""
actions = ['KEEP_LANE', 'ACCELERATE', 'DECELERATE']
return np.random.choice(actions) # 完全随机
而项目里真正的决策模块是完整实现的——六个文件,场景图编码、推理链、 检索知识库、安全融合全都在——实验脚本一个都没 import。
有完整代码但没运行 = 等于没有。
真正值得记下来的是这些数字的样子:
| 指标 | 实测 | 期望量级 |
|---|---|---|
| Success Rate | 2.4% | 70%+ |
| Collision Rate | 23% | <5% |
| Expert Alignment | 33.8% | >60% |
它们看起来像"一个很差的系统",不像"没有系统"。 于是它们差点被当成"一个很差的结果"写进去。
而那个指纹就在表里:33.8% ≈ 1/3,正好是三选一随机的水平。
为什么¶
"核心模块没接上"这件事之所以能活到写报告那一步,是因为它不触发任何错误:
- 脚手架跑通了,没有异常;
- 产出了完整格式的结果文件;
- 数字落在"合理的坏"的区间里,不是
NaN、不是 0、不是 100%; - 占位函数的 docstring 甚至写着
replace with your model——提示语不是检查。
而识别它的方法是把指标和占位物的随机水平对齐:
| 占位物 | 它会把哪个指标钉在哪 |
|---|---|
| 从 k 个动作里均匀随机 | 任何"选对了吗"的指标 → ≈ 1/k |
| 常数预测(总选多数类) | 准确率 → 多数类占比;AUC → 0.5 |
| 随机打分 | AUC / AP → 0.5 / 正例率 |
| 恒等/复制 baseline | 和输入的相似度 → 1.0 |
凡是某个指标恰好等于一个随机基线的解析值,先怀疑接线,不要怀疑模型。 这个检查是零成本的,而且比"看看结果合不合理"可靠得多, 因为"合不合理"的直觉恰好会被 1/k 这种值满足。
反过来说,这也是为什么随机基线必须作为一条正式的对照跑并报出来: 它既是性能下界,也是"我的模型真的接上了吗"的哨兵。
怎么用¶
- 实验开始前算出每个指标的随机基线解析值,写在表的第一行。 跑出来的数等于它,就是接线问题。
- 占位实现要让流水线失败,不要让它返回值。
raise NotImplementedError("wire the real model")比一个随机返回安全一个数量级。 注释和 docstring 里的 "replace this" 不构成保护。 - 加一条启动期断言:核心模块被实际调用过。 最简单的实现是在真实模块里打一个计数器,实验结束时断言它 > 0。 这和"正则项的代码路径其实没被调用"是同一类检查。
- "代码存在"和"代码被跑过"要分开记账。 项目状态表里写"已实现"而实验里没 import,是两个不同的事实。
- 一个坏结果在被解释之前,先确认它是被测出来的。 "我们的方法表现不佳"和"我们的方法没有参与这次实验"在报告里长得一样。
出处¶
- 自己一个被拒投稿项目的实验脚手架,缺陷分析报告(归档于项目
archive/reports/):mock_decision_maker的实现、三个指标的实测值 (Success Rate 2.4% / Collision Rate 23% / Expert Alignment 33.8%)、 以及"已有但未被 import 的六个核心模块"清单 - 相关:你设计的 workload 必须能让你的机制起作用——否则 ablation 一定是平的、恒为常数的特征在归一化融合里等于不存在——不报错,还会连累依赖它的阈值、 测不出失败的门禁比没有门禁更糟——它在制造信心