0. 从一次物理失效说起
2003 年 2 月 1 日,执行 STS-107 任务的哥伦比亚号航天飞机在返回大气层途中解体。
物理链条并不复杂,也不神秘:2003 年 1 月 16 日发射后约 82 秒,外部燃料箱上的一块泡沫绝热材料脱落,撞击到左翼前缘,破坏了该处的热防护结构;16 天后返回时,高温气体从破损处进入机翼内部,结构逐步失效,飞行器最终失去控制。
如果只做到这一层,结论会很简单:修泡沫、加固前缘、增加检测。
但事故调查委员会(CAIB)给出的判断要更重:事故不能只归因于一次技术故障,NASA 的组织实践、沟通方式与决策机制同样构成事故原因。NASA 后来的安全经验总结里,Organizational Silence(组织沉默) 和 Normalization of Deviance(偏差正常化) 被明确列为这次事故的核心文化教训。
对做系统的人来说,这才是真正值得抄进设计文档的部分。因为泡沫是 NASA 的问题,而偏差正常化是所有复杂系统的问题——包括你正在维护的那套告警、审批、限流和权限体系。
真正危险的异常,往往不是第一次出现的异常,而是已经出现很多次、却被系统学会接受的异常。
1. 异常重复发生,为什么反而更容易被放过
直觉上,一种异常出现的次数越多,组织应该越重视它。
复杂系统里的实际曲线常常相反:
-
第一次出现:紧张,全员关注,成立专项;
-
第二次出现:调查,但已经开始有"上次也是这样"的语气;
-
第三次出现:进入"已知问题"列表,排期靠后;
-
第 N 次出现:写进运维手册,成为"预期行为"。
泡沫脱落并不是哥伦比亚号任务的独有现象。此前的航天飞机任务中就观察到过类似情况,而飞行器每次都安全返回了。长期重复且没有立即造成灾难,直接削弱了组织对它的风险感知——NASA 的历史材料把这种心态概括得很直白:以前也发生过,而且我们总能安全着陆。
这里发生的,是一次错误的学习。系统本应学到"异常必须被消除",实际学到的却是"异常似乎可以被接受"。
关键在于:风险并没有因为过去几次没出事而下降。真正变化的,只是组织对风险的心理边界。
工程上说得更准确一点:过去没出事,可能只是意味着失效条件还没有被同时满足——撞击位置不同、能量更低、余量恰好够用、时序恰好错开。这些都是偶然余量,不是设计安全。
历史成功只能证明系统过去幸存过,不能自动证明系统当前是安全的。
2. 偏差正常化不是一次决策,而是一段位移
偏差正常化几乎从来不发生在某次会议上。没有人会明确宣布"从今天起我们接受这个风险"。
它的真实形态是一段缓慢位移:
异常 → 已知问题 → 可接受风险 → 正常现象 → 失去改变执行状态的能力
每一步都有合理解释:这次时间紧、这次影响面小、这次有人工兜底、这次上线窗口不能动。没有一条规则被正式删除,但边界一点点挪走了。
映射到工程系统,这个位移长这样:
-
某条策略冲突每次都由管理员手动放行;
-
某个证据链缺失但流程照常往下走;
-
某个设备状态异常长期被解释为误报;
-
某个临时权限申请了三个月还没回收;
-
某个降级开关常年处于打开状态。
边界没有被正式删除,但系统已经不再真正服从它。
一条边界是否真实,不取决于它有没有写进制度,而取决于它是否会在没人施压的时候依然生效。每一次没有造成后果的绕过,都在削弱它的可信度。到最后,你可能仍然拥有一份完整的安全文档,却已经没有安全文化了。
3. Observation ≠ State:看见事件不等于掌握状态
哥伦比亚号发射后,工程人员通过发射影像发现了泡沫撞击。NASA 的时间线记录得很精确:约 81.7 秒脱落,约 81.9 秒撞击左翼前缘区域。任务期间也有人围绕撞击展开分析,并提出需要获取更清晰的在轨影像来判断左翼是否受损。
也就是说,系统并非对事件一无所知。真正的问题在于:发现事件,和确认状态,中间还隔着很长一段距离。
-
知道泡沫脱落 ≠ 知道机翼是否被击穿;
-
知道发生撞击 ≠ 知道撞击能量;
-
知道过去安全返回 ≠ 知道这次损伤可承受;
-
模型给出"有限损伤"结论 ≠ 真实机翼状态已被验证。
这是所有监控体系都会踩的坑。日志里有那条记录、看板上有那个红点、群里有人 @ 了一句,都属于 Observation。而 State 是系统对自身当前是否安全的已验证判断。前者是原始信号,后者需要证据、需要覆盖范围、需要有人负责收敛。
信号存在,不代表状态已被正确理解;看板变红,不代表系统知道自己出了什么事。
高风险系统的第一条设计约束是:在状态不确定时,不能自动选择最乐观的那个解释。
4. 举证责任一旦倒置,系统天然倾向继续执行
任务期间,关于泡沫撞击是否会造成严重损伤,内部存在不同程度的担忧;部分工程人员希望拿到更高分辨率的在轨影像来直接检查左翼,但相关请求最终没有形成足以改变任务状态的行动。CAIB 报告把沟通路径、管理层对风险的框定、工程信息未能有效进入决策,列为重要组织因素。
这里最值得警惕的,不是"有人故意忽视风险",而是问题本身被悄悄换掉了:
| 命题 | 我们是否已经证明它能安全返回? | 有没有足够证据证明它不能安全返回? |
| 举证责任 | 安全需要被证明 | 危险需要被证明 |
| 证据不足时的默认 | 停止 / 收紧 | 继续 |
两句话读起来很像,工程后果完全相反。
一旦举证责任倒置,"证据不足"就自动变成了通行证。而复杂任务一旦启动,停止的成本永远显性、继续的成本永远隐性:停止意味着承认状态不清楚、重新评估、重排资源、承受进度压力;继续则完全符合原计划,读数大部分正常,过去也没出过事。
于是"继续执行"伪装成了中立选择。但它不中立:
在状态不确定时选择继续,等于已经做出了一个隐含判断——风险仍在可承受范围内。
必须把这一点写死进执行控制:维持原状态也是一次执行裁决。
-
不进入 Safe Mode,是决策;
-
不升级复核,是决策;
-
不收缩权限,是决策;
-
不索取更多证据,同样是决策。
默认继续从来不是"没有动作",它只是最容易被审计漏掉的那个动作。
5. 组织沉默:能说话,不等于能改变结果
NASA 把 Organizational Silence 列为这次事故的文化教训之一。需要注意的是,组织沉默并不意味着所有人都闭嘴,而是指:关键担忧无法以足够强度、足够清晰的方式,进入有权改变执行状态的那一层。
一个工程师确实表达了担忧。但如果这份担忧:
-
只停留在小组内部;
-
没有进入正式风险状态;
-
没有形成明确的 No-Go 条件;
-
没有改变资源调度;
-
没有推动更强的证据获取;
-
没有让最终决策者完整理解不确定性;
那么从系统角度看,它约等于沉默。
所以工程上要区分两件事:表达和进入边界。有人在群里提醒不是边界;有人在评审邮件里反对不是边界;告警出现在仪表盘上更不是边界。只有当一份担忧能够改变系统状态时,它才真正进入了执行控制:暂停、降级、重新验证、收紧权限、要求独立确认、拒绝继续。
真正的安全文化不在于坏消息能不能被说出口,而在于坏消息有没有执行权。
一个可操作的判据:把你团队最近三次"有人提了风险但没改变计划"的案例翻出来,看看当时缺的是勇气,还是缺一条能把风险转成状态的机制路径。多数时候是后者。
6. Unknown ≠ Allow:不确定性应该收紧边界
任务期间的工程分析没有形成足够明确的灾难性结论。但"没有明确结论"存在两种完全不同的解释:
飞行器没有严重损伤;
现有信息和模型不足以判断是否存在严重损伤。
把第二种误当成第一种,就会产生那条经典的危险推理:没有发现问题,所以问题不存在。 而真实情况可能是:没有足够能力看见问题。
高风险系统的默认值必须反过来写:
Unknown ≠ Allow
Missing ≠ Safe
无法验证 ≠ 默认通过
超时未响应 ≠ 健康
这就是 Fail-Secure 的核心。它不是说看到任何不确定性就永远停机——那样系统没法用。它的适用条件是明确的:当执行后果不可逆、风险半径足够大时,信息不足不能被自动解释为安全。
判断是否该套用 Fail-Secure,问三个问题就够了:这个动作可逆吗?错误的爆炸半径有多大?重新获取证据的成本,是否真的高于一次失败的代价?
7. 模型输出不是现实状态
任务期间对撞击损伤的评估依赖工程模型。问题从来不是"用了模型"——没有模型就无法估算撞击能量、预测材料损伤、制定返回方案。
问题是:模型有没有被当成现实本身。
如果模型主要针对小尺寸泡沫撞击标定,如果实验条件与真实撞击存在量级差异,如果输入数据本身不完整,如果这次工况已经跑出了模型的适用域,那么模型输出就只是一种推断,而不是对真实机翼状态的证明。
这一点在今天的 AI 系统里几乎是逐字对应的:
-
模型判断一笔交易安全 ≠ 交易目标地址没有被替换;
-
系统判断设备正常 ≠ 物理机构真的到位了;
-
风险评分低 ≠ 当前动作确实可执行;
-
置信度 0.97 ≠ 现实世界的概率是 0.97。
模型可以参与治理,但最终执行仍然必须落在可验证事实和独立边界上。
工程上的落法很直接:模型输出只能作为判据之一,不能作为唯一放行条件;高危动作的放行必须至少有一条不依赖模型的、可独立采信的证据通道。
8. 工程落地:让异常累积约束,而不是消耗警觉
现实系统里常见一种反向机制:异常发生一次,大家很紧张;发生十次,大家习惯了。高可靠系统必须把这条曲线掰过来——同类异常反复出现,应当累积风险权重,而不是消耗风险感知。
一个可以直接抄进策略引擎的骨架:
# 同类异常的累积效应:次数越多,边界越紧,而不是越松
def on_anomaly(kind, ctx):
n = counter.incr(kind, window="30d")
if n == 1:
record(kind, ctx) # 记录,留证
elif n == 2:
open_investigation(kind) # 扩大调查范围
elif n == 3:
trigger_design_review(kind) # 触发设计复核,而非运维复核
elif n >= THRESHOLD:
policy.tighten(kind) # 自动收紧策略
halt_high_risk_ops(scope=ctx.scope) # 停止该范围内高风险执行
# 人工例外同样要被计数——例外本身就是一种异常
def on_manual_override(actor, rule, ctx):
record_override(actor, rule, ctx)
if override_count(rule, window="90d") >= K:
escalate_to_governance(rule) # 反复例外 = 规则失真,交治理层裁决
配套的几条规则:
-
同类异常连续出现 → 自动收紧策略,而不是提高告警阈值把它压下去;
-
多次人工例外 → 触发治理复核;一条需要频繁例外的规则,要么规则错了,要么系统错了,两种都必须处理;
-
设备/状态反复不一致 → 进入 Safe Mode,而不是把不一致标为"已知误报";
-
证据链多次中断 → 禁止扩大执行范围;
-
同一 Agent 反复触碰边界 → 降低其可用权限,而不是给它加白名单。
注意最后一条的反直觉之处:常见做法恰恰是"这个服务老是被限流,给它开个白名单吧"。这就是偏差正常化的自动化版本。
同时,边界的放宽必须走相反的路径——不能因为"过去没出事"就自动降级限制:
-
某个白名单地址连续执行成功 ≠ 可以取消金额上限;
-
某个 Agent 连续完成任务 ≠ 可以无限扩大工具权限;
-
某个审批人长期判断正确 ≠ 可以绕过双人复核;
-
某个版本长期稳定 ≠ 进入新环境不需要重新验证。
边界的收紧可以自动,边界的放宽必须显式治理。 这条不对称性是整套机制的地基。
9. AI Agent 时代的哥伦比亚号问题
未来的 Agent 系统大概率不会因为一次明显攻击而失控。更可能的路径长这样:
第一次越界,人工放行——任务紧急,情有可原;
第二次越界,仍然放行——上次也没事;
第三次,为了效率,直接写了条例外规则;
例外被记录为"成功任务",进入历史轨迹;
Agent 从历史轨迹中学到:这条路径是标准路径。
权限一点点扩大,人工复核一点点减少,证据要求一点点放宽,Safe Mode 一点点被绕开。没有任何一天,组织正式决定放弃安全;但几个月之后,边界已经完全不是原来那条。
这里有一个新增的严重性:过去是人慢慢习惯异常,速度受限于人的记忆和轮岗;未来是机器直接从历史数据里学习异常,速度受限于训练频率。组织在压力下做出的每一次妥协,都会被自动化系统忠实继承并放大。
偏差正常化正在从一个组织文化问题,升级为一个自动执行问题。
对应的工程要求也很清楚:训练/回放数据中,必须显式标注哪些成功是"正常路径成功",哪些成功是"依靠例外达成的成功"。把两者混在一起喂给系统,就是在教它绕过边界。
10. 没有事故,不是控制有效的唯一证据
安全系统有个天然的悖论:事故没发生时,你很难区分"边界有效"和"风险恰好没来"。
如果只用结果评价:任务成功就是安全,交易完成就是正确,资产没丢就是边界有效,系统没宕就是架构可靠——那么在真正的失效到来之前,一个已经被掏空的系统和一个健壮的系统,指标看起来完全一样。
所以执行控制还必须评价过程:
-
本次执行是否发生了越界?
-
是否依赖了偶然余量?
-
是否存在未经验证的假设?
-
是否有异常被人工压过?
-
是否缺少独立证据?
-
有没有可能只是"运气好没造成损失"?
这也是执行后证明(Post-Execution Proof)的真正价值。它不该只回答"执行成功了",而要回答:这次执行为什么被允许?边界是否完整?有没有依赖未经授权的例外?
一个可以马上加进复盘模板的字段:本次操作是否使用了 override;如果使用了,override 的授权来源、有效期、以及它是否已经被计入该规则的例外计数。
结语
哥伦比亚号事故不应该只被读成"一块泡沫击穿了机翼"。
泡沫解释了飞行器如何失效,但它解释不了:
-
为什么一种已知异常能够长期存在?
-
为什么过去的安全返回,逐渐变成了"风险可接受"的证据?
-
为什么工程担忧没能改变任务状态?
-
为什么信息不足最终被解释成了没有严重危险?
答案是:组织会学习,但组织不一定学到正确的东西。
当异常重复出现却没有造成事故,组织可能不是变得更警惕,而是变得更放心。当边界被越过却没有立即付出代价,系统可能不是修复边界,而是重新定义边界。直到某一天,同样的偏差遇上了不同的现实条件,过去的运气不再出现。
没有造成事故的异常,仍然是异常。 没有立即付出代价的越界,仍然是在削弱边界。
可靠的系统不能让历史成功替风险作证。它必须让异常积累约束而不是积累麻木,让坏消息进入执行状态而不是停在会议纪要里,让每一次偏离都重新接受边界裁决,而不是因为"上次也没事"就自动获得下一次通行权。
当一个组织开始习惯异常,风险就不再需要突破边界了——因为边界已经被组织自己慢慢挪走了。
参考资料
-
Columbia Accident Investigation Board (CAIB) Report, Volume I — NASA
-
NASA Safety Center / SMA: Columbia Lessons Learned(Organizational Silence、Normalization of Deviance)
-
NASA Technical Reports Server: NASA's Understanding of Risk in Apollo and Shuttle
-
NASA Technical Reports Server: Shuttle Columbia, Mission STS-107
-
NASA History: Columbia Chronology
网硕互联帮助中心




评论前必须登录!
注册