2. 规则引擎基础
在融合决策流中,规则引擎承担“可解释、可配置、可快速变更”的决策职责。理解规则引擎,不能停留在“写 if-else”的层面,而要掌握它如何把业务策略抽象为规则、如何匹配事实、如何在多条规则同时命中时做出选择。本章围绕规则、条件、动作、优先级、冲突消解、Rete 算法与常见引擎展开,为后续评分模型融合打下工程基础。
一、核心原理:规则引擎到底在做什么
规则引擎的本质是一个“事实驱动的推理机”。它把业务知识拆成若干条规则,每条规则由条件(Condition)和动作(Action)组成。运行时,引擎将输入数据作为事实(Fact)放入工作内存(Working Memory),通过模式匹配找出所有条件成立的规则,再按冲突消解策略选择执行顺序,最终触发动作并可能修改事实,形成链式推理。
- 规则(Rule):一条独立的业务判断单元,通常包含名称、条件、动作、优先级和元数据。
- 条件(Condition):对事实的约束,如“用户等级为黄金且订单金额大于 500”。
- 动作(Action):条件满足后执行的操作,如“发放优惠券”“标记风险等级”“拒绝授信”。
- 优先级(Salience):数值越大越先执行,用于表达业务上的强弱顺序。
- 冲突消解(Conflict Resolution):当多条规则同时命中时,决定先执行哪一条的策略集合。
二、方法流程:从规则定义到执行
一个典型的规则引擎执行流程可以概括为:加载规则、插入事实、模式匹配、冲突集排序、触发动作、更新事实、循环直至无规则可触发。下面用一段伪代码展示核心循环:
// 规则定义示例(DRL 风格)
rule "黄金会员大额订单折扣"
salience 100
when
$u: User(level == "GOLD")
$o: Order(amount > 500, userId == $u.id)
then
$o.setDiscount(0.15);
update($o);
end
// 执行循环
while (conflictSet.notEmpty()) {
Rule r = conflictSet.selectByStrategy();
r.fire();
conflictSet.rebuild();
}
其中“冲突集重建”是关键:动作可能修改事实,导致原本不成立的规则变为成立,或已成立的规则失效。因此规则引擎通常采用“匹配—选择—执行—再匹配”的循环,而不是一次性匹配后顺序执行。
三、冲突消解策略与优先级设计
当多条规则同时命中,引擎必须决定执行顺序。常见策略包括:优先级数值、最近使用、最具体条件优先、规则定义顺序、随机或轮询。工程上最常用的是“显式优先级 + 条件具体度”组合。
| 策略 | 说明 | 适用场景 | 风险 |
|---|---|---|---|
| Salience 优先级 | 数值大者先执行 | 风控拦截优先于营销 | 优先级膨胀,难以维护 |
| 具体度优先 | 条件更具体的规则先执行 | 特例覆盖通用规则 | 具体度难以量化 |
| 定义顺序 | 按加载顺序执行 | 简单流程 | 隐式依赖,易被覆盖 |
| 最近使用 | 优先复用最近命中的规则 | 性能优化 | 行为不稳定 |
四、Rete 算法:为什么规则引擎能跑得快
如果每次循环都遍历所有规则的所有条件,复杂度会随规则数量线性甚至指数上升。Rete 算法通过构建有向无环图,把条件拆成节点,共享相同模式,缓存中间匹配结果,从而在事实变化时只重新计算受影响的部分。
Rete 网络主要包含:Alpha 节点(单事实条件过滤)、Beta 节点(多事实连接)、Join 节点(连接匹配)、Terminal 节点(规则命中)。当新事实插入时,它沿网络传播,只有相关分支被激活。
五、常见规则引擎与选型对比
不同引擎在表达方式、执行模型和生态上差异明显。选型时要关注:规则语言是否易读、是否支持热更新、是否可嵌入现有服务、是否有审计与调试工具。
- Drools:Java 生态成熟,支持 DRL、决策表、CEP,适合复杂企业级规则。
- Easy Rules:轻量级 Java 引擎,API 简单,适合中小规模规则。
- NRules:.NET 平台,基于 Rete,适合 C# 服务。
- JSON Logic / 自研表达式引擎:规则以 JSON 描述,前端可编辑,适合配置化场景。
- Flink CEP / Esper:面向事件流与时间窗口,适合实时风控与监控。
六、案例与复盘:优惠券发放规则
场景:电商大促期间,需要根据用户等级、订单金额、历史退款率和库存状态决定是否发放优惠券。规则如下:
rule "高退款用户拦截"
salience 300
when
$u: User(refundRate > 0.3)
then
reject("高退款用户不发放");
end
rule "黄金会员大额券"
salience 200
when
$u: User(level == "GOLD", refundRate <= 0.3)
$o: Order(amount >= 800)
then
grantCoupon($u, 50);
end
rule "普通用户满减券"
salience 100
when
$u: User(level == "NORMAL")
$o: Order(amount >= 300)
then
grantCoupon($u, 10);
end
复盘时常见误区有三类:其一,优先级设置过粗,导致拦截规则被营销规则覆盖;其二,动作中修改事实后未重新匹配,造成重复发券;其三,规则条件之间隐含依赖,却没有显式声明,导致新增规则时行为漂移。
掌握规则、条件、动作、优先级、冲突消解与 Rete 之后,下一步才能把规则引擎的输出与评分模型结果进行融合。规则负责硬约束与可解释分支,模型负责概率与排序,两者在决策流中各有边界,不能互相替代。