做仿真推演系统的第一天,几乎每个团队都会面对同一个诱惑:把规则写死在代码里,最快。

税率调整影响消费?一行 if。管控升级影响出行?再加一个分支。开头很顺,三个月后就不是那么回事了——规则散落在几十个函数里,一次推演到底应用了哪些前提,没人说得清,包括写代码的人自己。

做 CONE 引擎的时候,我们给自己立了条规矩:凡是会影响推演结果的规则,必须从代码里拿出来,单独写成一份规则文档。

规则文档长什么样

它不是代码,是规则的陈述,每条写清四件事:

推演启动前,引擎先加载这组规则;推演过程中居民 agent 的每一次决策,引用的都是文档里写明的条款,不是某个函数里藏着的魔法数字。

代价是真实的

这么做更慢、更麻烦,这点不用回避。

引擎要额外做解析、校验和冲突检测;新增一类规则时,不能只写逻辑,还得写清楚它的声明式描述。开发量大约多三成。

还有些极其特殊的规则,硬套文档结构也别扭。我们允许它们以"扩展算子"的形式存在,但必须在文档里登记:接管了哪个环节、输入输出是什么。可以特殊,但不能隐身。

换回来的是什么

第一,规则可以审。客户的行业专家不用读代码,直接读规则文档,就能确认"你们设定的政策是不是我理解的那个政策"。争论从"你们代码是不是写错了"变成"这条假设合不合理"——后者才是有价值的争论。

第二,改动可以归因。两次推演结果不同,对比规则版本就知道差在哪。参数调了 0.1 和整条规则换掉,是两种性质完全不同的变化,记录里也分得很清。

第三,组合成为可能。规则是结构化的,就能复用、组合、做敏感性分析——把某条规则的参数扫一遍,看结论在哪翻转。黑盒系统做不了这件事。

最后

把规则写成文档,说到底是把"系统的行为"从"程序员的理解"里拿出来,变成一份各方都能审阅、质疑、修订的公共文件。

我们理解的白盒就是这个意思:不是把源码贴出来给人看,而是每一段因果链条都指得出名字、读得懂含义、追得到来源。

下一篇写另一件事:推演产生的每一条变动,为什么只增不改。