跳到主要内容

双世界理论

在介绍这套理论之前,我们需要理解相关背景。

背景

冯诺依曼架构的核心是内存、状态、指令、状态变迁。内存是空间,数据存储在地址里,程序是对空间的读写操作。程序本质上描述的是:某个时刻,内存里有什么东西。

这套模型非常强大,其本质上是一种空间隐喻

面向对象继承了这套世界观,并把它封装得更精致:类、对象、继承、组合。对象是有名字的空间,方法是对这个空间的操作。OOP 几乎完全是空间隐喻的体现——包含、嵌套、层级、结构——却几乎没有时间隐喻——事件、演化、裁决、因果。

然而随着软件工程的不断发展,其最大的工程复杂度几乎全部来自时间:并发编程,分布式,一致性,事务,消息,超时,同步。

在面向对象的世界观中:

世界=当前状态\text{世界} = \text{当前状态}

世界的变化实际上就是:

状态1状态2状态3\text{状态}_1 \rightarrow \text{状态}_2 \rightarrow \text{状态}_3

因果被私有化、分散化。每个对象都持有自己的状态(空间的切片),用自己的方法修改自己的状态或者用回调方法去修改其他对象的状态(空间内容的变更)。历史被切碎成无数碎片,散落在无数对象的私有空间中,没有统一的因果叙事在守护身份连续性。

这是一种隐藏得非常之深的耦合,本质是空间建模的方式耦合时间维度。


双世界理论

双世界理论主张:对于持续存在的系统,必须在建模上明确区分世界事实如何形成,以及世界如何被感知和呈现

前提:

任何在时间中持续存在、并且必须不断与外部交换信息的复杂系统,都同时面临两个要求:

  1. 它必须保持自身。
  2. 它必须适应环境。

这两个要求可以用一个表达式来体现:

World(t+1)=Ft(World(t),Event)World(t+1) = F_t(World(t), Event)

为什么系统必须适应环境?

因为外部变化不会停止,只要系统一直持续存在,就必须与外部交互。

如果系统完全忽略 EventEvent,它的演化就会退化为:

World(t+1)=Ft(World(t))World(t+1) = F_t(World(t))

导致完全僵化,越来越脱离外部世界,最终失去存在能力。

所以,适应环境的本质是:外部变化必须影响未来。

为什么系统必须保持自身?

因为持续存在的系统不能每一刻都从零开始。

如果未来只由新事件决定,那么系统实际上是在不断“重生”:

World(t+1)=Ft(Event)World(t+1) = F_t(Event)

每次遇到新变化,都会变成一个全新的系统,历史、身份和上下文都会断裂。这意味着没有历史,也没有身份连续性。

所以,保持自身的本质是:过去决定现在,当下决定未来。

于是,系统会逐渐分化出两套相互协作的机制:

  • 因果层:负责维护历史、事实和身份连续性。知道过去发生了什么,现在的状态是什么,未来的推演基于什么。它对应的是时间维度——事件的不可逆、因果的单向性。
  • 感知层:负责感知环境、处理变化和形成体验。接触外部世界,把外部变化翻译成系统可以消费的信息。它对应的是空间维度——多元感官的同时展开、多种呈现方式的并行存在。

系统里并非只允许存在这两层,但是:对于长期存在的系统,这两类职责必须被清楚地区分出来。

两者通过持续反馈形成闭环。

参与者 → 感知层检测 → 上报事件 → 因果层裁决

参与者 ← 感知层呈现 ← 消费事实 ← 发布新状态

外部环境产生输入。感知层检测这些输入,把它们切割成离散的事件,上报给因果层。因果层裁决,产生新的事实版本——系统更新。这个新事实发布给感知层。感知层消费这个事实,并行呈现,展示给外部环境。外部环境看到这个呈现,做出反应,产生新的输入,循环往复。

有一些值得注意的地方:

  1. 在不改变因果事实的前提下,感知层可以高度自治,只需要在关键裁决点与因果层对齐。
  2. 任何要成为事实的新事件一旦进入世界,就必须被纳入既有的因果结构,不能够绕开因果层直接改写世界。
  3. 因果层的事件才是事实,感知层所呈现的永远只是投影。

因果层的本质是可解释

回到之前的公式

World(t+1)=Ft(World(t),Event)World(t+1) = F_t(World(t), Event)

其中:

  • WorldWorld 是系统在时刻 tt 的世界状态,可进一步分解为 事实(Facts)因果结构(Causality) 两部分,即 World=(Facts,Causality)World = (Facts, Causality)
  • EventEvent 是进入系统的新变化
  • FtF_t 是当前世界的解释规则,也称为解释函数或裁决机制

这里的 World=(Facts,Causality)World = (Facts, Causality) 表示:世界不是一堆孤立事实的简单集合,而是由事实以及把事实组织起来的因果结构共同构成的。

这个公式表达的是:

在一个趋向无序的宇宙中,持续存在的世界必须不断将新的事件纳入已有因果结构,并转化为可解释的事实。

世界不会直接接收事件。世界会依据已有事实和规则解释事件,更新自身。

比如刮风下雨,在现实世界,它必然影响真实因果,但是在游戏世界,一般只会将其用作视觉效果。

所以不能将 WorldWorld 狭隘地理解为状态机。传统意义上的状态机并不区分事实和投影;但在双世界理论中,因果和感知是必须作为第一性原理来进行分层建模的。

FtF_t 可以被称为:

  • 解释函数(Interpretation Function)
  • 裁决机制(Adjudication Mechanism)

它回答的是:新事件如何被纳入已有世界,并转化为新的事实结构。

根据热力学第二定律,外部世界往往趋向于熵增,即无序化。系统观察这些变化并将其纳入自身,这就需要对这些变化进行解释。

操作系统触发 syscall、interrupt,内核就需要解释谁取得了 CPU 的轮询切片,谁占据了事件总线。

两个人同时越过终点,观众本身无法分辨,但是裁判一定会给出谁先谁后的裁决。

两笔区块链交易同时花费同一笔资产,两笔交易都被广播、被矿工看到,但共识机制必须解释:哪笔交易进入历史,哪笔交易失效,哪个区块成为主链。

FPS 游戏中,两个玩家同时开火,游戏服务器必须解释:谁先命中,谁先死亡。

所以因果层不能完全理解为 Event Source。Event Sourcing 通常的前提是:事件已经是事实。但外部变化本身是熵增的、可能冲突的、不可直接信任的,因果层的存在意义是通过 F_t 把这些无序输入解释为可追溯的事实。因果层的本质在于解释。

这就是为什么可解释性如此重要,可解释的本质就是因果可追溯,一个事实如果无法追溯其来源,那事实所对应的状态就无法解释其形成过程。


最终因果一致性

任何需要形成稳定世界的过程,都不能允许“事实长期悬而不决”。

因此,因果层一旦做出裁决,系统就在有限时间内收敛到该裁决所确定的事实版本。这个就是最终因果一致性

它强调的不是“所有东西必须瞬间同步”,而是:

  • 呈现可以滞后
  • 感知可以插值
  • 局部可以暂时不一致

但在有限时间内,所有参与者最终必须面对同一个事实版本。

在双世界理论中,宏观世界永远没有真正意义上的并行

你可以把它理解成:

宏观世界的本质不是"同时发生",而是"因果关系最终可裁决"。

这很关键。因为我们感知中的"同时"——两个人同时挥剑、两颗子弹同时命中、两个线程同时运行——本质上都只是局部观察下暂时无法分辨先后。但只要世界需要给出结果、状态需要收敛、事实需要成立,系统最终就必须形成一个可解释的因果顺序。否则世界无法稳定。

这其实就是裁决为什么不可避免。

比如游戏里的"同时攻击":两个角色同时砍死对方。看起来:

A hit B
B hit A

同时发生。但因果层一定要回答:谁先死亡?死亡后技能还能不能触发?吸血效果是否成立?死亡爆炸是否发生?仇恨归属怎么算?

于是系统必须裁决。哪怕玩家感觉是同时、动画也是同时、特效也是同时——因果层仍然必须裁决

版本控制:多个开发者同时修改同一行代码,Git 会尝试自动合并;如果冲突无法自动解决,就必须有人工裁决。

数据库事务:多个用户同时修改余额。物理世界里 CPU 并行、网络并行、请求并行,但数据库必须裁决先后顺序。否则钱会凭空消失、状态腐化、世界失真。

法律系统:两个人互相指控,但法院最后一定形成一条可叙述的因果链。因为社会秩序和媒体大众都需要一个"事实版本"。


宏观世界这个词非常重要。因为微观层面,可能确实存在:

  • 量子叠加
  • 概率态
  • 真并发
  • 非决定性

但一旦进入宏观层面,世界就必须收敛成可叙述现实

为什么?因为宏观系统需要稳定因果

否则:

  • 无法记忆
  • 无法推理
  • 无法协作
  • 无法预测
  • 无法治理

换句话说:文明本身就是建立在因果关系最终可裁决这一基础之上。


相关阅读