Ohhnews

分类导航

$ cd ..
foojay原文

RuleBox 2.0 发布:让业务规则摆脱业务逻辑混乱

#rulebox#boxlang#coldbox#业务规则引擎#规则可视化

Ortus Solutions 今日宣布 RuleBox 2.0.0 正式发布。这是一款面向 BoxLang 和 ColdBox 应用的现代化自然语言规则引擎。它完全使用 BoxLang 重写,并内置规则即数据、声明式规则手册、试运行、审计追踪以及内置的 Rule Visualizer。

每个应用都会逐渐堆积一堆业务决策:谁可以通过审批、适用哪种折扣、哪些商品可以免运费、促销何时结束。它们通常从一个干净的 if 开始,最后变成没人愿意碰的 300 行方法。如果你也经历过这种情况,请继续往下读!

RuleBox 将这一堆决策转化为可阅读、可测试、可审计的具名规则。给定一些事实,当条件成立时,执行相应操作。规则可以用 BoxLang 编写,也可以采用 JSON/YAML/数据库形式,让团队无需重新部署即可修改。

$ shell
box install rulebox

BoxLang 是它如此轻量的原因

规则引擎的成败取决于开发者体验。如果编写一条规则比编写 if 还沉重,就不会有人采用它。而这正是 BoxLang 作为软件开发生产力平台大放异彩之处:

  • Lambda 和闭包就是 DSL。 规则的 when() 和 then() 就是普通的 BoxLang 函数。无需学习单独的规则语言,无需调试解析器,你的 IDE 也已经理解每一行代码。
  • 默认流畅表达。 动态类型和方法链让规则读起来就像业务分析师会写出的句子。
  • 100% Java 互操作。 规则可以调用任意 Java 库,因此你的决策逻辑永远不会被限制住。
  • 自始至终一种语言。 同一门 BoxLang 运行你的规则、ColdBox 处理器、服务和测试。
  • Box 生态负责底层管道。 WireBox 注入规则手册,ColdBox 注册模块及其辅助工具,CommandBox 负责安装,TestBox 负责测试。

RuleBox 2.0 还附带 AGENTS.md 和大量 skills,让 AI 编程代理在编写任何一行相关代码之前就了解该模块的工作方式。减少错误猜测,更快获得结果。

60 秒写一条规则

规则手册是一个继承 rulebox.models.RuleBook 的类。每条规则都有名称、条件,并在触发时执行操作:

class extends="rulebox.models.RuleBook" {

	function defineRules(){
		addRule(
			newRule( "declineLowScores" )
				.withPriority( 20 )
				.when( ( facts ) -> facts.creditScore < 580 )
				.then( ( facts, result ) -> {
    result.setValue( "DECLINED" )
    return false
} )
				.stop()
		)
		addRule(
			newRule( "autoApprove" )
				.when( ( facts ) -> facts.creditScore >= 680 )
				.except( ( facts ) -> facts.requestedAmount > 500000 )
				.then( ( facts, result ) -> {
    result.setValue( "APPROVED" )
    return false
} )
		)
	}

}

从处理器、服务或任何可以调用 getInstance() 的地方运行它:

getInstance( "LoanApproval" )
	.run( { creditScore : 720, requestedAmount : 250000 } )
	.getResult()
	.getValue() // "APPROVED"

注意 -> 箭头。这些规则不需要其事实之外的任何内容,因此它们是 lambda。如果规则需要捕获外部状态,请改用带 => 的闭包。

2.0 有哪些新特性

规则即数据

将很少变化的逻辑保留在 BoxLang 中。把经常变化的阈值移到 JSON、YAML 或数据库表中,并用 loadRules() 加载它们:

ruleBook.registerAction( "decide", ( facts, result, params ) -> result.setValue( params.decision ) )

ruleBook.loadRules( new rulebox.models.JSONRuleSource( "/path/to/loan.json" ) )
$ cat
[
	{
		"name": "autoApprove",
		"when": { "gte": [ "creditScore", 680 ] },
		"except": { "gt": [ "requestedAmount", 500000 ] },
		"then": [ { "action": "decide", "params": { "decision": "APPROVED" } } ]
	}
]

条件使用一种小型声明式语法(eq、lt、gte、in、and、or、not 等),并且不使用 eval。规则定义只能引用你已注册的操作和谓词,因此规则文件或数据库行永远无法运行你未编写的代码。定义会在加载时验证,因此格式错误的规则会在启动时失败,而不是等到某天终于执行到被短路的那个分支时才失败。需要获取某次修改?在决定时机合适时调用 reloadRules()。更多内容请阅读外部规则指南。

声明式规则手册

在配置中为规则手册命名,或将 JSON 和 YAML 文件放入约定文件夹,然后即可在任何地方按名称获取它们:

moduleSettings = {
	rulebox = {
		rulebooks = {
			"credit" : "config/rules/creditscore.yaml"
		}
	}
}
// in any handler, view or layout
ruleBook( "credit" ).run( { creditScore : 650 } ).getResult().getValue()

或者将提供者注入任何类,包括单例。每次 get() 都会返回新的规则手册,因此并发请求永远不会共享状态:

class singleton {

	property name="creditRules" inject="rulebook:credit";

	function decide( score ){
		return creditRules.get().run( { creditScore : score } ).getResult().getValue()
	}

}

试运行与完整审计追踪

在不执行任何操作的情况下,查询一组事实会得到什么结果:

getInstance( "LoanApproval" ).dryRun( { creditScore : 540, requestedAmount : 1 } )
// [ { name : "declineLowScores", wouldExecute : true, wouldStop : true } ]

在一次真实运行之后,getRuleStatusMap() 会告诉你哪些规则处于 EXECUTED、SKIPPED、STOPPED 或 FAILED 状态。2.0 还会跨运行跟踪每条规则的指标:求值次数、耗时、错误率,以及最近一次错误及其堆栈跟踪。

优先级、停止与时间窗口

withPriority() 可让规则不受插入顺序影响进行排序,stop() 结束规则链,而新增的 active() 可让规则在某个季节或活动期间启用,并自行到期:

newRule( "blackFridayPromo" )
	.active( from : "2026-11-27", until : "2026-11-30" )
	.then( ( facts, result ) -> result.setValue( "BLACK_FRIDAY" ) )

声明事实

规则手册现在可以声明它接收的事实,包括类型、默认值、描述和示例。调用 enforceFacts() 后,错误运行会在任何规则执行之前失败,并给出列出所有问题的消息:

function defineFacts(){
	enforceFacts()
	fact( "creditScore" ).type( "numeric" ).required().example( 680 )
}
RuleBox.InvalidFactsException: RuleBook [] was given invalid facts: Missing required fact [creditScore].

设计上更安全

RuleBox 单例服务(例如 Builder@rulebox)现在是线程安全的。不要在多个请求之间共享 RuleBook;应为每个决策获取一个新实例,如上面的提供者示例所示。抛出异常的 then() 消费者会在异常到达你的代码之前,在审计追踪中记录为 FAILED。审计追踪会在每次 run() 时重置,因此规则链未到达的规则永远不会报告过期状态。并且 given() 上的 overwrite 最终会生效。

规则可视化器

2.0 内置一个管理界面。通过一项设置即可启用:

moduleSettings = {
	rulebox = {
		visualizer = { enabled = true }
	}
}

然后浏览到 /rulebox-visualizer。它默认关闭,在禁用时不会产生任何额外开销,并且 RuleBox 本身不会为其提供安全保护,因此请像对待任何其他管理界面一样,用 cbSecurity 或你自己的认证机制来保护它。

一分钟导览

[LOADING...]

点击图片观看视频。

逐屏了解可视化器

[LOADING...] 仪表盘:每个规则手册,以及失败最多和最慢的规则 [LOADING...] 链视图:按运行顺序排列的规则,显示耗时、错误率和最近一次错误 [LOADING...] 试运行:输入事实,查看哪些规则会触发 [LOADING...] 指标:完成率和错误率,以及每条规则的健康状况 [LOADING...] 错误:每个不同错误只显示一次,并显示次数、原因和抛出位置 [LOADING...] 实时跟踪器:每次求值时实时显示,并展开失败项

用十节短课学会它

第一次接触规则引擎?教程课程会带你从一个简单的 if 语句,逐步实现一个贷款决策:规则放在文件中,在 ColdBox 中运行,并显示在可视化器中。十节短课,一个贯穿始终的示例。

从 1.0.0 迁移

2.0.0 是一次重写,因此升级前请检查以下事项:

  • 在 BoxLang 1.18+ 上运行。 不再支持其他引擎。
  • 将 NONE 替换为 REGISTERED。 已添加但未到达的规则现在的状态是 REGISTERED。更新任何将状态与 "NONE" 比较的代码。
  • 不要依赖过期状态。 getRuleStatusMap() 会在每次 run() 开始时重置。
  • 检查 given() 和 givenAll() 上的 overwrite。 它以前会被忽略。现在 overwrite = false 会保留现有事实。
  • 在调用 run() 之前附加规则。 运行一个从未添加到 RuleBook 的 Rule 会抛出 RuleBox.RuleNotAttachedException。

1.0.0 文档保存在归档中,完整的逐行历史记录见变更日志。

开始使用

要求: BoxLang 1.18+ 和 ColdBox 8+。

$ shell
box install rulebox

有两项功能需要可选的 BoxLang 模块,而 RuleBox 不会替你安装它们:box install bx-yaml 用于 YAML 规则文件,box install bx-sqlite 用于持久化可视化器指标。仅安装 bx-sqlite 并不会启用持久化;你还必须配置 SQLiteMetricsStore@rulebox 并注册其数据源。完整设置请参阅 RuleBox 文档中的可视化器持久化说明。

将规则手册保存为 models/HelloWorld.bx,调用 getInstance( "HelloWorld" ).run( { name : "World" } ),你就在运行规则了。完整演练见入门指南。

加入我们

RuleBox 是基于 Apache 2.0 的开源项目。请在 GitHub 上为仓库加星,提交 issue 和 pull request,并在 Ortus 社区 Slack 或社区论坛告诉我们你接下来希望看到什么。## 资源

别再让业务决策埋没在 if 代码块中了。开始编写规则吧。

分享此页面

链接已复制

发现错误或有内容需要补充?在 GitHub 上编辑此页面

[LOADING...]

作者

Luis Majano

Ortus Solutions 首席执行官 · 工程师 · 作者 · ColdBox HMVC、BoxLang JVM 语言、ContentBox CMS 等产品的创造者

相关文章

BoxLang AI v3 正式发布——多智能体编排、工具链、技能及更多 [LOADING...] Luis Majano · 2026年4月6日 · 1,062 次浏览

TestBox 7:实时反馈、基于浏览器的 IDE,以及 JVM 上的现代测试工作流 [LOADING...] Cristobal Escobar · 2026年3月24日 · 2,709 次浏览

隆重推出 skills.boxlang.io —— 面向 BoxLang 与 Ortus 世界的开放智能体技能生态 [LOADING...] Cristobal Escobar · 2026年5月21日 · 1,539 次浏览

隆重推出 bx-jwt:面向 BoxLang 的企业级 JSON Web Token [LOADING...] Cristobal Escobar · 2026年5月26日 · 1,460 次浏览

分类:AI、BoxLang、GenAI、开发者工具、DevOps、Java

参与讨论