做仿真推演系统的第一天,几乎每个团队都会面对同一个诱惑:把规则写死在代码里,最快。
税率调整影响消费?一行 if。管控升级影响出行?再加一个分支。开头很顺,三个月后就不是那么回事了——规则散落在几十个函数里,一次推演到底应用了哪些前提,没人说得清,包括写代码的人自己。
做 CONE 引擎的时候,我们给自己立了条规矩:凡是会影响推演结果的规则,必须从代码里拿出来,单独写成一份规则文档。
规则文档长什么样
它不是代码,是规则的陈述,每条写清四件事:
- 什么时候生效(适用条件);
- 管谁(哪类居民、哪个区域);
- 起了什么作用(改变了哪个变量、方向和量级);
- 依据是什么(经验参数、文献来源,还是校准结果)。
推演启动前,引擎先加载这组规则;推演过程中居民 agent 的每一次决策,引用的都是文档里写明的条款,不是某个函数里藏着的魔法数字。
代价是真实的
这么做更慢、更麻烦,这点不用回避。
引擎要额外做解析、校验和冲突检测;新增一类规则时,不能只写逻辑,还得写清楚它的声明式描述。开发量大约多三成。
还有些极其特殊的规则,硬套文档结构也别扭。我们允许它们以"扩展算子"的形式存在,但必须在文档里登记:接管了哪个环节、输入输出是什么。可以特殊,但不能隐身。
换回来的是什么
第一,规则可以审。客户的行业专家不用读代码,直接读规则文档,就能确认"你们设定的政策是不是我理解的那个政策"。争论从"你们代码是不是写错了"变成"这条假设合不合理"——后者才是有价值的争论。
第二,改动可以归因。两次推演结果不同,对比规则版本就知道差在哪。参数调了 0.1 和整条规则换掉,是两种性质完全不同的变化,记录里也分得很清。
第三,组合成为可能。规则是结构化的,就能复用、组合、做敏感性分析——把某条规则的参数扫一遍,看结论在哪翻转。黑盒系统做不了这件事。
最后
把规则写成文档,说到底是把"系统的行为"从"程序员的理解"里拿出来,变成一份各方都能审阅、质疑、修订的公共文件。
我们理解的白盒就是这个意思:不是把源码贴出来给人看,而是每一段因果链条都指得出名字、读得懂含义、追得到来源。
下一篇写另一件事:推演产生的每一条变动,为什么只增不改。