2. 规则引擎核心概念:规则、事实、动作、规则集与决策表
规则引擎是风控系统的“大脑”,它将业务决策逻辑从代码中抽离出来,以声明式规则的形式独立运行。要设计出高可用的风控规则引擎 API,首先必须透彻理解其五大核心概念:规则 (Rule)、事实 (Fact)、动作 (Action)、规则集 (RuleSet) 与 决策表 (DecisionTable)。这些概念构成了引擎的元模型,也是 API 数据契约的基础。
2.1 规则 (Rule) —— 最小的决策单元
规则是“条件 + 结论”的二元组,是引擎执行的最小逻辑单元。在风控场景中,一条规则通常表达为:“如果 事实 满足 条件,则执行 动作”。
| 组成部分 | 说明 | 风控示例 |
|---|---|---|
| 条件 (Condition) | 对事实的布尔表达式,支持比较、范围、集合、正则等 | order.amount > 5000 && user.riskLevel == "HIGH" |
| 结论 (Conclusion) | 条件满足时触发的动作描述 | action = "REJECT",reasonCode = "AMOUNT_HIGH_RISK" |
| 优先级 (Salience) | 规则冲突时的执行顺序,数值越大越优先 | salience = 100 |
| 状态 (Status) | 启用/禁用/草稿,控制规则是否参与推理 | status = "ACTIVE" |
API 设计启示: 规则是 API 的核心资源。RESTful 设计中,
/rules 端点应支持 CRUD,且条件表达式建议以结构化 JSON 存储(如 AST 树),而非纯字符串,便于引擎解析与版本对比。
2.2 事实 (Fact) —— 决策的输入数据
事实是引擎进行推理的“原材料”,是风控系统在运行时传入的上下文对象。事实可以是订单信息、用户画像、设备指纹、历史行为等任何结构化数据。
- 临时事实: 单次请求传入,如
orderId、ipAddress、paymentAmount。 - 持久化事实: 从数据库或缓存中拉取,如用户 30 天逾期次数、设备关联黑名单数。
- 派生事实: 由引擎内部函数计算得出,如“距离上次下单时长”、“IP 归属地与收货城市是否一致”。
最佳实践: 事实对象应扁平化、可序列化。API 请求体中,建议将事实统一放在
facts 字段下,引擎自动完成类型推断与校验。
2.3 动作 (Action) —— 决策的输出结果
动作是规则条件满足后引擎执行的操作。在风控规则引擎中,动作不仅是“通过/拒绝”二值结果,而是一组可组合的指令集。
| 动作类型 | 描述 | 典型输出 |
|---|---|---|
| 决策动作 | 直接给出风控结论 | APPROVE / REJECT / REVIEW |
| 赋值动作 | 修改事实或上下文变量 | user.score += 50 |
| 日志动作 | 记录规则命中详情 | log("命中大额高风险规则") |
| 外部动作 | 触发外部系统调用 | sendSms("138xxxx", "您的订单需人工审核") |
2.4 规则集 (RuleSet) —— 规则的逻辑分组
规则集是规则的容器,用于将具有相同业务目标或执行上下文的规则聚合在一起。规则集支持继承、覆盖、优先级排序等高级特性。
API 设计注意: 规则集支持嵌套(子规则集)。在 API 中,建议使用树形结构表示规则集层级,并通过
parentId 字段维护父子关系。避免过深嵌套(建议不超过 5 层),否则影响引擎加载性能。
2.5 决策表 (DecisionTable) —— 多条件矩阵决策
决策表是规则的一种高效可视化表达,特别适合“多条件组合 + 多结果输出”的场景。它将条件与动作组织成二维表格,每一行是一条完整规则,每一列是一个条件或动作属性。
| 条件1:金额范围 | 条件2:用户等级 | 条件3:是否新设备 | 动作:决策结果 | 动作:审核方式 |
|---|---|---|---|---|
| < 1000 | VIP | 否 | APPROVE | 自动通过 |
| 1000 ~ 5000 | 普通 | 否 | APPROVE | 短信验证 |
| 5000 ~ 20000 | 普通 | 是 | REVIEW | 人工审核 |
| > 20000 | 任意 | 任意 | REJECT | 拒绝 + 上报 |
决策表在 API 中的存储方式通常有两种:
- 扁平化 JSON 数组: 每行一个对象,适合行数较少(< 100 行)的场景。
- 列式压缩存储: 条件列去重,适合大规模决策表(如千行级别),减少 API 传输体积。
// 决策表 API 请求体示例(扁平化)
{
"decisionTableId": "dt_risk_level_001",
"rules": [
{ "conditions": { "amount": "<1000", "level": "VIP", "newDevice": false }, "action": "APPROVE", "verify": "NONE" },
{ "conditions": { "amount": "1000-5000", "level": "NORMAL", "newDevice": false }, "action": "APPROVE", "verify": "SMS" },
{ "conditions": { "amount": "5000-20000", "level": "NORMAL", "newDevice": true }, "action": "REVIEW", "verify": "MANUAL" },
{ "conditions": { "amount": ">20000", "level": "*", "newDevice": "*" }, "action": "REJECT", "verify": "REPORT" }
]
}