5D Library › 复杂系统相变、临界慢化与生态韧性的非线性动力学 · English
第六章 紧耦合与模块化:常态事故与高可靠性
常态事故
社会学家佩罗在 1984 年出版的《常态事故》中,从 1979 年美国三里岛核电站事故出发,提出一个令人不安的论点:在某些技术系统中,严重的事故不是偶然的失误,而是系统结构的「正常」产物 (Perrow 1984)。
证据
交互复杂性与耦合。 佩罗所说的复杂交互,指子系统相互连通、存在共因连接与反馈回路、有多个相互作用的控制、操作者只能获得间接信息、对系统的理解有限;与之相对的是线性交互:部件按预期的顺序相互作用,出了问题容易看清。紧耦合的特征是:过程不能延迟、顺序不能改变、达到目标只有一种方法、几乎没有余量,缓冲与冗余只能是事先刻意设计好的;与之相对的是松耦合。在他的矩阵中,大坝是线性而紧耦合的;核电站、化工厂与航天任务是复杂而紧耦合的;大学是复杂而松耦合的;装配线生产是线性而松耦合的。复杂而紧耦合的系统最容易发生「系统事故」:几个本身不严重的故障以设计者未曾预料的方式相互作用,紧耦合又使操作者来不及理解和干预 (Perrow 1984)。
佩罗的论点有一个至今仍有争议的推论:在复杂而紧耦合的系统中,增加安全装置与冗余本身可能增加复杂性,带来新的、未曾预料的交互;对其中风险最大的一些技术,他主张放弃或大幅限制,而不是继续加装保护。用第五章的语言,「紧耦合」相当于失效在部件之间传递得比人察觉得更快,「复杂交互」相当于存在设计图上看不到的连接;两者同时存在时,局部的故障最容易变成系统性的级联。
高可靠性组织:另一种看法
证据
高可靠性组织。 拉波特与孔索利尼等伯克利学者研究了三类被要求「不能出错」的组织:美国联邦航空局的空中交通管制、美国海军核动力航空母舰的飞行作业,以及太平洋煤气电力公司的电力调度与发电部门。它们运行着危险、紧耦合、交互复杂的技术,可靠性却远高于组织理论的预期,而且无法依靠试错学习。他们观察到,同一批人会在常规的层级模式、高节奏模式(技能比职级更重要)与按脚本执行的紧急模式之间切换,权威结构随运行的节奏而改变 (La Porte and Consolini 1991)。韦克、萨克利夫与奥布斯特费尔德把这类组织的做法归纳为「集体正念」的五个过程:专注于失败(把每一次差错与未遂事件当作整个系统健康状况的信号);不愿简化解释;对一线运作保持敏感;致力于韧性;结构的「弱规定」(紧急时让决策流向最懂行的人,而不拘泥于职级;韦克与萨克利夫后来的著作把这一条改称「遵从专长」)(Weick et al. 1999)。
证据
一项检验。 萨根用美国核武器指挥与控制系统的历史检验这两种理论:这个有着最高政治优先级、最多资源与最严格纪律的系统,如果高可靠性组织理论是对的,应当很少出现危险事件;他通过档案与访谈整理出许多险情与未遂事故(包括古巴导弹危机期间的几次),认为这个系统的安全记录更多地归功于运气而不是良好的设计,这更符合常态事故理论的悲观预期 (Sagan 1993)。
两种理论并不简单地相互否定。常态事故理论讲结构:交互复杂与紧耦合在多大程度上留给人干预的时间与理解的可能;高可靠性组织理论讲人与组织:在给定的结构中怎样提高察觉与反应的速度、怎样让信息流向懂行的人。前者主张改变结构(松开耦合、简化设计,必要时放弃),后者主张改变组织;对一个具体系统,两种办法往往都需要,而且都不彻底。
模块化:防火墙与它的代价
降低耦合的一种基本办法是模块化:把系统分成内部联系紧密、彼此联系稀疏的部分。西蒙在 1962 年论证,复杂系统往往是「近可分解」的层级结构,并用两位钟表匠的寓言说明,由稳定的中间组件逐级组装的系统更能承受打断 (Simon 1962)。梅、莱文与杉原建议借鉴生态学关于网络结构与稳定性的研究来理解银行系统的系统性风险 (May et al. 2008)。
证据
一项实验。 希拉兰斯等人用跳虫(Folsomia candida)构建模块化程度不同的集合种群网络,在一个节点上制造局部灭绝作为扰动。在高度模块化的网络中,扰动被限制在受扰动的模块之内;但模拟显示,模块化只在有扰动时才有好处,没有扰动时它会妨碍种群的增长 (Gilarranz et al. 2017)。
推导
400 个节点分成 10 个模块(每个 40 个节点),共 1,200 条连接(平均度 6),其中比例为 的连接跨越模块。一次失效从随机的一个节点开始,沿每条连接以 0.3 的概率传递一次(独立级联)。每个 模拟 20 个网络、每个网络 20 个起点。模块化的日常代价用节点之间的平均最短路径长度衡量:路径越长,帮助、物资与信息在平常传得越慢。
推导
# Modularity as a firebreak, and what it costs. 400 nodes in 10 modules of 40; 1,200 links
# (mean degree 6); a share mu of the links joins different modules. A failure starts at one
# random node and passes along each link once with probability beta = 0.3 (independent
# cascade, i.e. bond percolation). 400 runs per mu (20 networks x 20 seeds). Cost of modularity:
# mean shortest-path length between nodes (longer = slower help, slower information).
import random
from collections import deque
rng = random.Random(13)
N, M, LINKS, BETA = 400, 10, 1200, 0.3
def network(mu):
adj = [set() for _ in range(N)]; size = N // M; n = 0
while n < LINKS:
a = rng.randrange(N); home = (a // size) * size
if rng.random() < mu: # a random node in another module
b = (home + size + rng.randrange(N - size)) % N
else: # a random node in the same module
b = home + rng.randrange(size)
if a != b and b not in adj[a]: adj[a].add(b); adj[b].add(a); n += 1
return adj
def spread(adj, seed):
hit, q = {seed}, deque([seed])
while q:
v = q.popleft()
for w in adj[v]:
if w not in hit and rng.random() < BETA: hit.add(w); q.append(w)
return hit
def mean_path(adj, sources=25):
tot = cnt = 0
for s in rng.sample(range(N), sources):
d = {s: 0}; q = deque([s])
while q:
v = q.popleft()
for w in adj[v]:
if w not in d: d[w] = d[v] + 1; q.append(w)
tot += sum(d.values()); cnt += len(d) - 1
return tot / cnt
print(" mu mean failed P(> 1 module hit) modules hit P(> 100 failed) mean path length")
for mu in (0.01, 0.03, 0.05, 0.1, 0.2, 0.5, 0.9):
sizes, multi, mods, paths = [], 0, 0, []
for _ in range(20):
adj = network(mu); paths.append(mean_path(adj))
for _ in range(20):
h = spread(adj, rng.randrange(N))
m = len({v // (N // M) for v in h})
sizes.append(len(h)); multi += m > 1; mods += m
n = len(sizes)
big, path = sum(s > 100 for s in sizes) / n, sum(paths) / len(paths)
print(f" {mu:4.2f} {sum(sizes) / n:6.1f} {multi / n:4.0%}"
f" {mods / n:4.1f} {big:4.0%} {path:4.2f}")
# mu mean failed P(> 1 module hit) modules hit P(> 100 failed) mean path length
# 0.01 34.9 35% 1.6 6% 7.64
# 0.03 84.0 60% 3.7 34% 5.50
# 0.05 136.1 68% 5.6 54% 4.89
# 0.10 199.3 76% 7.4 70% 4.29
# 0.20 201.4 76% 7.3 69% 3.87
# 0.50 212.1 80% 7.6 72% 3.58
# 0.90 218.6 84% 7.8 74% 3.55防火墙的作用是真实的,但只在跨模块的连接很少时才明显。(全网只有约 12 条跨模块连接)时,平均失效 35 个节点,近三分之二(65%)的失效停在起始模块里,超过 100 个节点失效的概率只有 6%。跨模块连接增加到 5%,平均失效升到 136 个,超过 100 个的概率升到 54%;到 10%,与完全随机的网络()已相差不大。几条跨模块的连接就足以把失效带出去。
代价同样明显:平均路径长度从 3.55 增加到 7.64,翻了一倍多。还有一个代价: 时平均失效 35 个节点,已接近一个模块的规模(40 个);在这样的传递概率下,失效一旦开始,起始模块的大部分节点都会失效。模块化保护的是整体,不是被击中的那一块。
注
用于组织时。 「隔舱化」在船舶、电网(解列)、软件(故障隔离)与组织(独立团队、独立供应商)中都有应用。上面的结果提示:隔舱要有效,跨隔舱的连接必须很少或能在故障时迅速切断;隔舱化有日常的效率代价;为隔离而增加的切换装置与规程,本身也可能带来佩罗所说的新的复杂交互。这些是模型的启发,不是对任何具体组织的建议。
本章小结
佩罗认为,交互复杂而紧耦合的系统会「正常地」发生系统事故,增加安全装置也可能增加复杂性。高可靠性组织理论强调人与组织能够在给定的结构中做到很高的可靠性,萨根对核武器系统的检验则更支持常态事故理论的悲观看法。模块化可以把失效挡在一个模块里,但只在跨模块的连接很少时有效,并以平常的效率与被击中模块的全面失效为代价。下一章读几段中国古代关于「防微杜渐」的文字。
参考文献
Fan, Y. (2026). Phase Transitions, Critical Slowing Down and Resilience in Complex Dynamical Systems: From Saddle-Node Bifurcations and Early-Warning Signals to Cascading Failures, Read Beside Classical Chinese Thought on Incipient Change [复杂系统相变、临界慢化与生态韧性的非线性动力学] (Version 1.0.0). 5D Library. https://doi.org/10.5281/zenodo.23770082 · Licensed under Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International (CC BY-NC-ND 4.0).