会照做的,和会看着办的
同一台加热器,两种控制方式。一种是「照着说明书算出该开多大,然后开着不管」,另一种是「不管说明书,看着温度调」。在一切如你所料的时候,它们的表现完全一样——这正是第一种方式的陷阱。
一台加热器,你想把它稳在某个温度(记作 1.0)。你查了说明书,算出功率应该开到 1.0,于是把旋钮拧到 1.0,走人。这叫开环。
结果两件事同时发生了:① 这台机器实际上比说明书说的猛 30%;② 半路有人开了窗,进来一份你完全不知道的热量(相当于 0.3)。
问:最后温度会停在多少?而如果换成一个会看着温度调的闭环控制器(它同样不知道①和②),它会停在多少?
这一题的重点不在算术,在于「不知道」这件事对两种做法意味着什么。
两种活法
面对「我想让某个量等于某个值」这件事,天底下只有两条路。
第一条路:算。建一个模型——「开 x 的功率,温度会到 Kx」——反解出 x,拧到那个位置,收工。这条路的英文名是 open loop,开环,意思是那条把结果送回来的线没接。
第二条路:看。不管模型,测当前温度,和目标比,低了就加、高了就减,一直这么干下去。这条路叫 closed loop,闭环。
# 开环:一条直线,走完就完了
目标 ──▶ [ 反解模型 ] ──▶ [ 设备 ] ──▶ 实际
(没人再看它一眼)
# 闭环:一个圈,永远转下去
目标 ──▶ ⊕ ──▶ [ 控制器 ] ──▶ [ 设备 ] ──┬──▶ 实际
▲(−) │
└───────────── 测量 ◀────────────┘
# 差别只有那一条线。但它买来的东西,比它看起来贵重得多。
开环不是「原始」或「错误」的做法。它有闭环没有的优点:它不可能失稳(没有环,就没有绕圈放大这回事),它不需要传感器(省钱、省地方、少一个故障点),它反应可以极快(不用等误差出现)。微波炉加热三分钟、红绿灯按固定时长切换、你按配方放两勺盐——全是开环,而且非常合理。
开环的问题只有一个,但这个问题是致命的:
开环的精度,完全等于你那个模型的精度。模型错多少,结果就错多少;模型没考虑到的东西,结果就一分不差地承担多少。
而闭环不需要模型是对的。它甚至不需要知道发生了什么。它只知道一件事:「现在比目标低了一点」,然后往上顶。反馈的全部价值,就是对付你不知道的事。
四种情况,同一台机器
下面这个 demo 把四种情况摆在一起。灰色虚线是开环,绿色实线是闭环。它们面对的是同一台设备。
逐条看:
| 情况 | 开环停在 | 开环偏了 | 闭环停在 | 闭环偏了 |
|---|---|---|---|---|
| 一切如你所料 | 1.0000 | 0.0% | 0.99965 | 0.03% |
| 设备比你以为的猛 30% | 1.2999 | 30.0% | 0.99975 | 0.02% |
| 半路有人开了窗 | 1.2979 | 29.8% | 1.00231 | 0.23% |
| 两样一起来 | 1.6873 | 68.7% | 1.00233 | 0.23% |
第一行是这张表里最重要的一行,而它看起来最无聊:两种做法表现得一模一样。
这就是开环的陷阱。它在实验室里、在验收时、在「一切正常」的那一天,和闭环看不出任何区别。它的脆弱只在世界偏离模型的那一刻才暴露出来——而世界一定会偏离模型:设备会老化,室温会变,负载会变,供电电压会变,有人会开窗。
再看最后一行的对比:68.7% 对 0.23%,相差约 300 倍。而闭环控制器没有被告知设备变猛了,也没有被告知有人开窗。它甚至没有能力知道这些事——它的输入只有一个数:当前温度。
为什么闭环能把误差压到那么小?这里有一条一行的算术,第 5 章会正式推它,现在先看结论。
设你的控制器增益是 Kp,设备增益是 K,两者相乘叫回路增益 KpK。那么开环和闭环面对同一份「模型错误 + 未知扰动」,误差之比是:
闭环误差 / 开环误差 = 1 / (1 + Kp K)
回路增益 9,误差变成十分之一;回路增益 99,变成百分之一。反馈不是「消除」了误差,它是把误差除以了一个数,而这个数就是你在这个环上愿意用多大力气。
这自然引出一个问题:那把 Kp 拧到一万不就完事了?——这正是这本书接下来二十章的全部内容。剧透:不行,而且拦住你的东西不是功耗、不是成本、不是执行器上限。
一个不太舒服的推论
如果反馈这么好,为什么不是所有地方都用反馈?
因为反馈要付四笔钱,而且每一笔都不小:
- 你得有一个传感器。而且它测的必须真是你想要的那个量。这一条比听起来难得多——第 23 章会给出一个例子:传感器测的东西只占你真正想要的四成,于是那个环把指标顶上去 90%,同时把你真正想要的东西压下去 24%。
- 你得等误差先发生。反馈是事后的:它必须先看见偏差,才能动手。第 18 章讲怎么用前馈补上这一刀。
- 你引入了失稳的可能。开环再差也只是不准,它不会自己抖起来。闭环可以。这是卷 III 和卷 IV 的全部主题。
- 你把传感器的毛病也接进了环里。传感器上的噪声会被控制器放大成执行器的动作——第 7 章那个 demo 里,加一点微分项,执行器的抖动会涨 11 倍。
所以现实中最常见、也最好的做法,往往是两条路一起走:用开环(前馈)拿到速度和大方向,用闭环兜住模型的错。你的巡航定速就是这么干的——它知道油门开度和车速的大致关系(前馈),也在实时比对当前车速(反馈)。第 18 章会把这个组合拆开给你看:前馈模型哪怕错 50%,配上反馈之后,峰值偏差仍然比纯反馈小一半。
烤箱 vs 电饭煲。普通烤箱基本是开环的:你设 180°C,它按一个粗糙的温控开开关关,实际温度可以差 20 度,所以每个人的烤箱都得「摸脾气」。而电饭煲是闭环的:它盯着锅底温度,水一烧干温度就会突然上蹿,它据此判断「饭好了」——它不需要知道你放了多少米多少水。这就是为什么烤箱要你有经验,而电饭煲不用。
预算 vs 实时竞价。「这个月投放预算 100 万,按去年的转化率分配」是开环——去年的转化率就是那个模型。「按小时看实际 ROI 调整出价」是闭环。前者在市场稳定时更省事,后者在市场变化时不会整月错下去。
固定重试次数 vs 自适应限流。「失败重试 3 次」是开环:不管系统现在是空闲还是快挂了,都重试 3 次。而基于实时延迟调整并发上限(比如 Netflix 的 concurrency-limits、TCP 的拥塞控制)是闭环:它不需要知道下游有多少台机器、跑的什么代码。
《撞墙》讲排队,那本书里的系统全是开环的:活来了就排队,队列本身不会回过头去减少到达率。而这本书讲的是把那条线接上会怎样——《撞墙》第 22 章的 AIMD(TCP 拥塞控制)正是一个闭环,它和本书第 22 章讲的是同一件事的两端。
《打分》(强化学习)问的是:如果你连模型都没有、连该怎么动都不知道,怎么办。那本书里的智能体是在试出一条控制律;这本书假设你大致知道设备的脾气,问的是「怎么设计那条控制律」。两本书是同一个问题的两种起手式。
这一点值得多想一分钟,因为它是反馈最反直觉、也最强大的地方:一个只会做减法的装置,能对付无穷多种它从未被告知的干扰。
这也解释了反馈的一个重要局限:既然它不区分原因,它就不会告诉你哪里出了问题。一个整定良好的闭环,会安安静静地补偿掉一台正在老化的设备,直到有一天它补不动了——那时候故障是突然出现的。反馈会掩盖问题,直到它掩盖不住。所以监控要盯的不只是被控量,还得盯控制量:阀门开度悄悄从 40% 爬到 85%,是比温度更早的告警。(这一条在第 15、24 章还会再出现。)
C开环停在 1.6873(偏了 68.7%),闭环停在 1.00233(偏了 0.23%)。
开环那个 1.69 是这么来的:你按模型算出功率 1.0,但设备实际增益是 1.3,所以它自己就到了 1.3;再加上开窗那份 0.3 乘以 1.3,又多出 0.39。两笔直接相加,一分不少——这就是开环的定义。
A 「开窗的热量会自己散掉」——不会。稳态就是稳态:加进来的热量必须有个去处,而这个去处只能是更高的温度。开环里没有任何机制去抵消它。 B 「两个都不知道真相,所以一样错」——这是本章要打的靶子。闭环不需要知道真相;它只需要看得见结果。这句话值得记住:看得见结果,比知道原因更有用。 D 「闭环能修一半」——方向对了,量级差远了。修多少不是「一半」这种定性的事,它等于1/(1+KpK)。这个 demo 里回路增益不小,加上积分项之后稳态误差在数学上就是 0(第 6 章会讲为什么),剩下的 0.23% 只是仿真还没跑完的余量。
这一章的一句话
开环的精度上限是你对世界的了解,闭环的精度上限是你的传感器——而后者通常便宜得多。
下一章把那个环拆开,数一数里面到底有几个零件。答案是五个,其中只有三个是你写的代码;而根据我的经验,生产事故有一大半出在剩下那两个上。