简介:围绕规则引擎「决策池」机制整理的操作型文档,面向正在使用 Visual Rules Solution 旗正规则引擎、需要积累可复用规则的开发者与业务规则设计人员,重点解决规则重复编写、复用顺序难以控制、批量验证缺乏方法等问题。内容以「基本工程2」规则包为主线,依次讲解规则包创建、变量定义与规则编写,再延伸到把规则包引入决策池、设置全局变量、按引用先后顺序执行全部复用规则;后半部分说明批量测试的添加方式、测试用例设计与执行结果解读,形成从搭建到校验的完整流程。压缩包仅含 1 个 docx 文件,约 1.19MB,图文对照、篇幅紧凑,适合作为随时查阅的操作参考。目前已有 458 人学习,可作为熟悉决策树之后,进一步理解决策池差异、复用规则组织方式与测试验证思路的实践材料。
1. 规则引擎里的决策池:为什么它比“复制规则”更值得拆
规则引擎里最容易被低估的模块,是决策池。某业务系统三个流程规则都要做同一组字段加工,最初靠复制规则包,改一处漏三处;后来把公共规则抽成独立规则包,再在决策池里按引用顺序拉起,问题才收住。决策池解决的是规则复用:它把被引用的规则全部执行,顺序跟引用先后一致,不做条件分支。适合规则包多、公共逻辑反复出现、执行顺序明确的场景;需要互斥分支或条件选择的,应该用决策树或决策表,不要硬塞进决策池。这份资源把规则包创建、变量定义、规则编写、决策池引用和批量测试串成一条可复现链路,新手能照着搭,熟手能看清边界。值不值得下,看你能不能接受“先复用、后验证”这套工程习惯。
2. 规则包与变量:把复用单元拆成可运行的最小闭环
2.1 规则包不是普通文件夹,而是可编译的复用单元
拆这套规则引擎资源时,最先要建立的认知是:规则包不是拿来装文件的目录,而是独立保存、独立编译、能被决策池引用的最小复用单元。基础规则包 A 负责放公共规则,决策池规则包 B 负责编排引用,两个包各自有变量声明和规则逻辑,边界清楚,后面改一处才不会牵动整条流程规则。选型上我一般会把“可被多处调用的字段加工、公共校验、固定后处理”放进基础规则包,把“谁先执行、谁后执行”留给决策池规则包。这样规则包 A 不关心调用方是谁,决策池规则包 B 也不重复写业务逻辑,复用才有意义。
| 对象 | 作用 | 本示例命名 | 关键检查 |
|---|---|---|---|
| 规则工程 | 管理多个规则包 | 某规则工程 | 右键能新建规则包 |
| 基础规则包 A | 存放可复用规则 | 基础规则包 A | 变量、方法、规则自包含 |
| 决策池规则包 B | 存放决策池与引用关系 | 决策池规则包 B | 变量与 A 同名同类型 |
| 规则 | 最小逻辑单元 | b 赋值、c 赋值 | 动作明确、能单独测试 |
| 外部调用方法 | 封装常用方法 | 从左截取字符 | 参数顺序固定 |
创建步骤不复杂,但顺序别乱。右键规则工程,选择新建规则包,命名为“基础规则包 A”,确认后先看对象库里变量是不是空的,不要急着写规则。规则包建好后点“全部保存”,消息栏会提示 rpk 与 rsc 的生成结果;如果消息栏没有生成信息,先查规则包是否编译通过,别带着一个没保存成功的包去拖决策池。常见误用是把规则包当文件夹,规则之间跨包引用临时变量,最后决策池一执行就找不到变量。规则包 A 里只放高内聚、可叠加的加工规则,互斥规则不要塞进来,这是后面决策池顺序能稳定的前提。
2.2 变量定义先对齐:传入数据、对象库与外部调用方法
变量定义是决策池复用最容易翻车的地方。基础规则包 A 和决策池规则包 B 都要定义 a、b、c 三个 string 类型变量,来源都放在“传入数据”。为什么两边都定义?决策池执行时以 B 的变量作用域承接输入输出,A 的规则被引用后仍按 A 的变量声明执行,两边名字、类型、来源对不上,拖进去能看见规则,跑起来就报变量找不到。变量表不要凭记忆,落地时逐项填清楚,后面排查才有依据。
| 变量 | 类型 | 来源 | 用途 | 检查点 |
|---|---|---|---|---|
| a | string | 传入数据 | 原始输入 | 决策池入口必须赋值 |
| b | string | 传入数据 | 中间结果 | b 赋值规则写入 |
| c | string | 传入数据 | 截取结果 | c 赋值规则写入 |
操作步骤按这个顺序走:打开基础规则包 A 的对象库,在“传入数据”里新增 a、b、c,类型选 string;再到对象库的“外部调用”里添加“从左截取字符”方法,确认后能在外部调用列表里看到它。这个方法的参数一般就是源字符串和截取长度,参数顺序固定,规则里调用时别写反。决策池规则包 B 也按同样方式定义 a、b、c,类型和来源保持一致;B 里不一定重复添加截取方法,但变量必须同名同类型,否则决策池引用 A 的规则时接不上。
外部调用方法的价值在于把常用逻辑从规则体里抽出来。规则里不要手写重复截取,把“从左截取字符”挂到规则包的外部调用里,规则动作直接调用,参数统一、批量测试好定位。常见误用是只在 A 里加了方法,B 里没定义变量,拖完规则一运行就卡住;还有人在 B 里把 b 定义成整数,A 里 b 是 string,决策池执行到一半类型冲突。变量名、类型、来源三项在 A 和 B 里逐项对一遍,别只看名字一样就放过。
提示:变量定义完先保存全部,确认消息栏生成 rpk 和 rsc,再进下一步。
2.3 规则编写落到赋值动作:b 和 c 怎么从 a 推出来
规则命名建议按动作来,不按结果来。“b 赋值”“c 赋值”比“b 取值”更清楚,后面在决策池里拖规则时一眼能看出谁写哪个变量。基础规则包 A 里放两条规则:b 赋值规则把 a 的值赋给 b;c 赋值规则调用“从左截取字符”,源字符串选 b,长度填 2,结果赋给 c。这里让 c 依赖 b,是为了让决策池的引用顺序有可验证的依赖;如果业务里 c 只依赖 a,顺序影响会弱一些,但规则包边界仍然要清楚。
| 规则名 | 输入 | 动作 | 输出 | 复用价值 |
|---|---|---|---|---|
| b 赋值 | a | b = a | b | 公共字段透传 |
| c 赋值 | b | c = 从左截取(b, 2) | c | 公共截取加工 |
步骤是:右键基础规则包 A,添加规则,命名“b 赋值”,在规则动作里给 b 赋值 a,确认;再添加规则“c 赋值”,调用外部方法“从左截取字符”,源字符串选 b,长度填 2,结果赋给 c,确认;最后点“全部保存”,看消息栏是否生成 rpk 和 rsc。截取长度 2 只是示例参数,换成业务需要的长度;源字符串必须是 string,长度参数是整数。如果截取结果为空,先查源字符串是否为空、长度是否越界、参数顺序是否写反,不要一上来就怀疑决策池。
规则包 A 写完后先单独跑一次 b 赋值和 c 赋值,再进决策池。这个顺序能把这层问题分开:单规则跑不通,是规则体或变量问题;单规则能跑、进决策池才错,才是引用顺序或变量作用域问题。常见误用是把 b 赋值和 c 赋值写成互相依赖,决策池顺序一换就翻车;或者在规则里写死常量,批量测试覆盖不到真实输入。规则包 A 要自包含,B 只做编排,流程规则里调用时才不会把公共逻辑又复制一遍。
注意:规则包 A 保存后先单独验证,别把变量问题和顺序问题混在一起查。
3. 决策池的复用顺序:引用即执行,别把它当条件分支
3.1 决策池和决策树、决策表的边界
决策池最核心的规则只有一句:被引用进来的规则会全部执行,执行顺序跟引用先后一致,不按条件跳过。它和决策树、决策表的差别不在界面,而在执行模型。决策树可以设置复用规则的执行条件和规则间条件,适合互斥分支和分层判断;决策表按条件组合命中行,适合规则矩阵;决策池不设这些条件,适合公共校验、字段加工、固定后处理这类“每一步都要跑”的链条。把互斥规则塞进决策池,后执行的规则会覆盖前面的结果,这不是玄学,是执行模型决定的。
| 维度 | 决策池 | 决策树 | 决策表 |
|---|---|---|---|
| 执行方式 | 按引用顺序全部执行 | 按条件选择分支 | 按条件组合命中 |
| 复用规则条件 | 不设置执行条件 | 可设置复用规则执行条件和规则间条件 | 条件列驱动 |
| 顺序影响 | 强,先后可能覆盖 | 分支内顺序 | 命中行决定 |
| 适用场景 | 公共校验、字段加工、固定后处理 | 互斥分支、分层判断 | 规则矩阵、条件组合 |
| 不适用场景 | 互斥规则、需要条件跳过 | 全量执行 | 顺序依赖强的加工链 |
选型理由要落到维护成本上。公共字段加工如果复制到三个流程规则里,改一次要改三处,漏一处就是血泪经验;抽成基础规则包 A 后,决策池规则包 B 只维护引用顺序,改公共逻辑只动 A。反过来,如果两个规则天然互斥,比如“新客价”和“老客价”只能走一个,就不该放进决策池,应该用决策树或决策表把条件写清楚。决策池不是万能复用器,它只解决“全执行、按序执行”的复用问题。
3.2 新建决策池规则包并拖入复用规则
创建决策池规则包 B 的步骤:右键同一个规则工程,新建规则包,命名“决策池规则包 B”;在对象库的“传入数据”里定义 a、b、c 三个 string 变量;右键规则包 B,添加“决策池”;在决策池属性栏的“所有规则”里找到基础规则包 A;把“b 赋值”和“c 赋值”按顺序拖进决策池;点“全部保存”。拖入顺序就是执行顺序,先拖 b 赋值,再拖 c 赋值,因为 c 依赖 b。
| 顺序 | 被引用规则 | 依赖变量 | 预期动作 | 检查点 |
|---|---|---|---|---|
| 1 | b 赋值 | a 到 b | b = a | b 不为空 |
| 2 | c 赋值 | b 到 c | c = 从左截取(b, 2) | b 已赋值 |
这里有个容易忽略的细节:决策池规则包 B 的变量要先定义,再拖规则。先拖规则后补变量,属性栏里可能看到规则,但变量映射是空的,运行时就找不到输入。拖完后在决策池里核对顺序,别只看规则数量。顺序反了,c 赋值先跑,b 还没值,截取结果自然不对。常见误用是把“所有规则”里的规则一次性全拖进去,结果把互斥规则也带进来,后面排查半天才发现是执行模型用错了。
3.3 引用顺序与变量共享:执行链怎么对齐输入输出
决策池执行时,变量在同一个规则包 B 的作用域里共享。入口只传 a,b 和 c 由规则逐步写入。b 赋值先执行,把 a 写到 b;c 赋值后执行,读 b 做截取,写到 c。这个执行链用一张表就能看清,批量测试的期望值也按这张表填。变量共享不是隐式魔法,谁写谁读要明确,规则名和动作要对得上,否则顺序一变就翻车。
| 步骤 | 输入 a | 执行规则 | 变量 b | 变量 c | 说明 |
|---|---|---|---|---|---|
| 初始 | ABCD | 无 | 未定义 | 未定义 | 入口只传 a |
| 1 | ABCD | b 赋值 | ABCD | 未定义 | b 被写入 |
| 2 | ABCD | c 赋值 | ABCD | AB | c 依赖 b |
| 输出 | ABCD | 完成 | ABCD | AB | 批量测试比对 b 和 c |
对齐输入输出时,先看决策池规则包 B 的变量有没有被入口赋值,再看每条规则写了哪个变量,最后看后续规则读了哪个变量。执行链里不要出现“上一条规则写 x,下一条规则读 y”的错位。流程规则里调用这个决策池时,入口参数也要按 a 传进去,b 和 c 作为输出接出来。常见误用是把决策池当黑匣子,只传一个参数就期望所有变量都有值;变量没赋值就是没赋值,顺序和映射都要在表里写清楚。
提示:决策池的引用顺序变更后,先跑一遍单规则,再跑引用链,别直接全量回归。
4. 批量测试:把“我觉得对”变成可回归的用例表
4.1 批量测试怎么加:用例、期望值与覆盖点
规则逻辑写完后,靠肉眼点一遍不算验证。批量测试的价值是把输入、期望输出、实际输出摆在一起比对,改规则后还能回头跑。操作步骤:选中要测试的规则包,选择“添加批量”;在批量测试下添加测试用例;每个用例填输入变量 a 的值,填期望结果 b 和 c;保存并编译规则包;运行批量测试,比对期望值与实际输出值。期望值不是拍脑袋写的,要按第 3 章的执行链表推导。
| 用例 | 输入 a | 期望 b | 期望 c | 覆盖点 |
|---|---|---|---|---|
| T01 | ABCD | ABCD | AB | 正常两位截取 |
| T02 | 规则引擎 | 规则引擎 | 规则 | 中文输入 |
| T03 | A | A | A | 长度不足边界,按平台实际返回填 |
| T04 | 空字符串 | 空字符串 | 空字符串 | 空值输入 |
| T05 | AB | AB | AB | 恰好两位 |
测试用例不要只写正常值。长度不足、空字符串、恰好等于截取长度,这三类最容易暴露参数边界。T03 的期望值不要猜,先跑一次看截取方法的实际返回,再决定是缺陷还是平台约定;如果是平台约定,就在用例备注里写清楚。批量测试添加完后先保存全部,消息栏确认 rpk 和 rsc 已生成,再运行。测试的是最新编译产物,不是界面上刚改但没保存的草稿。
4.2 测试结果比对与失败定位:先看变量,再看顺序,最后看方法参数
测试结果出来后,先看实际输出值,不要只看通过率。期望 b 和实际 b 不一致,先查入口 a 有没有传进去;b 对了但 c 不对,先查决策池引用顺序是不是 b 赋值在前;b 和 c 都为空,先查决策池规则包 B 的变量有没有定义、类型是不是 string。排查顺序固定下来,能少走很多弯路。失败定位表可以贴在工程旁边,改一次规则就对照一次。
| 现象 | 可能原因 | 检查点 |
|---|---|---|
| b 为空 | a 没传进决策池 | 入口参数、B 的变量定义 |
| c 为空 | b 赋值未执行或顺序反了 | 决策池引用顺序 |
| c 截取结果不对 | 方法参数顺序或长度写错 | 外部调用参数、源字符串 |
| 测试全绿但运行不对 | 跑的是旧编译产物 | 保存全部、rpk/rsc 生成信息 |
批量测试跑通后,别急着把用例删掉。公共规则包 A 以后还会改,决策池引用顺序也可能调整,这批用例就是回归底稿。常见误用是只测一个正常值,发布后遇到空输入就翻车;还有人在测试结果里看到期望值和实际值一样就结束,没有检查测试的是不是最新编译版本。保存、编译、再跑,这个顺序别省。
注意:批量测试的期望值要跟执行链表对齐,不要用“看起来差不多”的结果当基线。
5. 避坑与排查:决策池最容易翻车的五件事
5.1 引用顺序与规则边界上的三个坑
第一个坑是复制规则包代替复用。现象是改了一个公共规则,三个流程输出不一致;原因是每个流程各复制一份规则包,改的时候漏了其中一份;解决是把公共逻辑抽到基础规则包 A,决策池规则包 B 只保留引用关系,改一处、三处生效。排查时打开每个流程规则,看有没有重复的 b 赋值、c 赋值规则,有就收敛到 A。
第二个坑是把互斥规则塞进决策池。现象是决策池结果被后一个规则覆盖,前面算出来的值没了;原因是决策池会按引用顺序全部执行,不判断条件;解决是把互斥规则移到决策树或决策表,决策池只放可叠加的字段加工和公共校验。判断方法很简单:两条规则能不能同时跑?能同时跑才进决策池,只能二选一就别放。
第三个坑是引用顺序反了。现象是 c 输出为空或截取结果不对;原因是 c 赋值依赖 b,但决策池里 c 赋值排在 b 赋值前面;解决是拖动规则时按依赖顺序排,先 b 赋值后 c 赋值,改完顺序重新保存并跑批量测试。排查时看决策池列表顺序,不要只看规则名,顺序就是执行顺序。
5.2 变量、编译与测试上的两个坑
第四个坑是变量只在一边定义。现象是决策池能打开,运行却报变量找不到;原因是决策池规则包 B 没定义 a、b、c,或者 B 里 b 是整数、A 里 b 是 string;解决是 B 里按同名同类型补变量,先定义变量再拖规则,拖完在属性栏核对映射。变量表要跟着规则包走,别靠记忆。
第五个坑是测试跑的是旧编译产物。现象是批量测试全绿,发布后结果不对;原因是改完规则只保存了界面,没点“全部保存”,或者 rpk/rsc 没重新生成;解决是保存全部后看消息栏生成信息,再跑批量测试,把编译产物时间戳作为检查点。这个坑最像后悔药,发布前多看一眼消息栏就能避开。
| 坑 | 现象 | 原因 | 解决 |
|---|---|---|---|
| 复制规则包 | 改一处漏三处 | 没走决策池复用 | 抽基础规则包 A,B 只引用 |
| 互斥规则进池 | 结果被覆盖 | 决策池全执行 | 互斥走决策树或决策表 |
| 引用顺序反了 | c 为空或截取错 | c 依赖 b 但先执行 | 按依赖顺序拖规则 |
| 变量只定义一边 | 运行报变量找不到 | B 缺变量或类型不一致 | 两边同名同类型 |
| 测试旧产物 | 测试绿、发布错 | 未保存全部或未编译 | 看 rpk/rsc 生成信息再跑 |
这五条里,前三条是执行模型问题,后两条是工程习惯问题。执行模型问题靠选型和顺序解决,工程习惯问题靠保存、编译、回归解决。决策池不是玄学,翻车大多是因为把它当成了带条件的规则集合,或者把变量作用域想当然了。
提示:每改一次决策池引用顺序,先把这五条对照一遍,再跑批量测试。
6. 进阶用法:用最小回归集锁住决策池的复用边界
6.1 最小回归集怎么分层
决策池的复用边界不是靠一次全量测试锁住的,而是靠分层回归。我的做法是分三层:单规则层、引用链层、全量层。单规则层只测 b 赋值和 c 赋值各自的动作,改规则体时先跑这一层;引用链层只测决策池里 b 到 c 的顺序,改引用顺序或增删规则时跑这一层;全量层跑所有业务用例,发布前跑。三层分开,失败时能立刻判断是规则体问题、顺序问题,还是业务输入覆盖问题。
| 层级 | 用例范围 | 目的 | 触发时机 |
|---|---|---|---|
| 单规则 | b 赋值、c 赋值各自用例 | 锁住单规则逻辑 | 改规则体 |
| 引用链 | 决策池顺序 b 到 c | 锁住顺序依赖 | 改引用顺序或增删规则 |
| 全量 | 所有批量用例 | 回归业务输出 | 发布前 |
6.2 一个具体技巧:先跑依赖链,再跑全量
每次动决策池,我先跑引用链用例,不直接跑全量。引用链用例只保留一条最短依赖:a 传 ABCD,期望 b 是 ABCD、c 是 AB。这条过了,说明变量传递和顺序没断;再跑全量,失败范围就缩小到具体业务输入。反过来,先跑全量,失败信息混在一起,定位成本高。这个习惯不花哨,但能省掉很多“看起来是决策池问题、实际是某个用例输入特殊”的排查时间。
资源包里我留了规则包模板、变量表和批量测试用例表,拿到后先按第 3 章的引用顺序跑一遍,再对照第 5 章的排查表过一遍,基本能把决策池的复用边界摸清。从那以后我每次改决策池引用顺序,都强制先跑单规则回归再跑引用链,不再直接全量跑。希望帮到你。
本文还有配套的精品资源,点击获取