Bohea

工业可靠性:换掉分母

2026年7月15日

我当时在做一台力控工业机器人的操作员界面——一条机械臂,以设定的力把一个带动力的工具压在工件上,沿路径移动。客户问了我这些年被问过的最好的问题:"车间里真正打到我们的问题,一定是我们没想到的那些——'没想到'就是这个意思。可我们每一个可靠性估算,用的分母都是'我们想到的东西'。那你到底怎么保证工业可靠性?"

安全关键运动控制可靠性HMI / PLC

为什么"再审仔细点"永远收敛不了

审查能找出你想象得到的 bug。而伤到你的 bug,按定义,正是你想象不到的那些。于是你再审一遍——第二遍又找出几个想象得到的,第三遍更少。这个数列不收敛到零;它收敛到"我能想象的一切",而那根本是另一回事。那个项目上,我已经跑了五轮审查,自己的加上几轮独立的冷眼复审,每一轮都还在找出真实缺陷。这不说明代码格外烂——它说明"再审仔细点"是一台跑步机。如果第五轮还在找出 bug,第六轮也会,而你永远没法站在一台正在动的机器前说"没有了"。

数 bug 是一场必输的游戏:分母无限且不可知。出路不是数得更准——而是换掉你数的东西。

换掉分母

整个想法一句话:别再试图保证"我的软件没有 bug";改为保证"即使我的软件彻底地、任意地错了,后果也是有界的"。前者不可能。后者可做到——因为它把一个无限的分母换成了一个有限的。你没法枚举你的 bug,但你枚举一个 bug 能造成的伤害种类。对这样一台机器,所有坏结果的空间装进五个桶里:

你有多少 bug、多离奇,都无所谓——它们造成的伤害必然落在这五个之一。没有第六种坏日子。于是问题从"我想到了多少 bug?"(分母 ∞,永远做不完)变成"对五个后果类中的每一个,我有没有一个不依赖我自己代码正确的兜底?"(分母 5,有限、可核验、做得完)。最后那句是承重的:一个和 bug 写在同一套代码库里的兜底,是同一个作者给自己的考卷打分。保证必须落到一个有 bug 的软件无法编写也无法削弱的层里。

向我证明这一点的那个发现

在后面一个阶段,界面会把操作员选定的参数——力、速度、路径次数——下发给机器人的运动控制器。承载这个的是厂商随平台模板附带的样板代码。它从第一天就躺在代码树里,没被用过。五轮审查从它上面滑过去了——而且是对的,因为它还没在执行;逐行看,没有哪里"错"。然后我停止审查,改问后果问题:假设这段传输被攻陷——它最坏能干什么,什么拦得住它?

这段样板代码构造发给控制器的消息的方式,是把参数当作文本,粘进一段控制器随后会执行的程序中间——指望一个标准序列化器把它们兜住。可那个序列化器转义了某些引号字符、却漏了另一些。这意味着一个含有特定字符的参数值,可以提前闭合那个带引号的字符串,把它自身剩下的部分变成给机器人的实时指令。顺着路径走:那些参数里有一个是名称——一个操作员敲进去的标签,更糟的是,一个搭着从 U 盘导入的备份文件进来的标签。一个 U 盘上的不可信文件 → 一条末端转着动力工具的工业机械臂上的任意运动。

那个缺陷对五轮逐行审查是隐形的——不是因为审查者粗心,而是因为按"这一行对吗?"的标准,这一行确实对,而且它压根没在运行。而当我从"找 bug"切换到"假设它被攻陷;兜底在哪?"的那一刻,它立刻现形了。没有兜底。一个不可信文件和一台运动机器之间,唯一挡着的,是我自己的代码完美无缺——而那恰是我刚花五轮证明了我无法承诺的那件事。

兜底具体长什么样

这才是工业可靠性真正的样子。不是"机器不会出问题"。而是:当机器出了问题——它一定会——那问题浮现在半空、在工件上方、工具已关闭,没有人受伤。

没人明说、但该说的那部分

这是我认为每一个卖"会动的东西"的诚实供应商都该愿意说的一句话:我们不是朝着"没有 bug"去建。我们知道会有 bug——包括我们永远找不到的。我们建的,是让一个 bug 触发时,它被接住、被兜住、或在物理上根本不可能变成伤害。这听起来像承认软弱;恰恰相反。承诺无 bug 软件的人,要么天真,要么在推销。而给你看那些闸、两道独立钳位、和机械臂出不去的那个盒子的人,已经想过它出错的那一天——那是唯一要紧的一天。"无 bug"是个营销词;"后果有界"是一种设计。

写自一次真实的力控机器人集成;所有客户、厂商、产品细节均已抹去。方法是通用的——它适用于任何"软件失败会带来物理或不可逆后果"的场景,从运动控制到支付,到部署。

这套东西的出处

这些都不是我的发明——它是安全工程里成熟的学科,只是换成了大白话:

这套论证有一个可运行的公开实现。后果分类、每类的硬前置条件、运动过程中持续复检的看门狗,以及一个八场景 harness——每次都试图让机器出错,每次都失败。可以用 MQTT 指挥它,也可以点浏览器里的 HMI。  代码 →

如果你造的机器需要一套界面、一个设备连接,或者数据必须落到别处去——告诉我它现在正让你付出什么代价。你会得到一个诚实的判断:能不能解;通常还会收到一个能跑的东西。从这里开始 →

← 全部笔记