当“规则引擎”变成“规则陷阱”:一次架构重构背后的教训
每个月,都有企业因为“规则引擎”这个词付出代价。
不是规则引擎不好。事实上,它曾被认为是企业级应用的万能药——业务逻辑复杂?扔给规则引擎。流程需要自动化?规则引擎搞定。甚至有人把它当成一个“代码解释器”,想把所有业务规则都塞进去,让它像魔法一样自动运行。
但现实是,当规则引擎被过度使用,它就会从“万能钥匙”变成“万能陷阱”。规则越来越臃肿,维护越来越吃力,新功能上线越来越慢。更糟糕的是,你根本不知道某个规则到底在干什么——因为它可能来自三年前的某个开发人员,而那人早已离职。
这不是危言耸听。就在我们的一个项目中,我们亲身经历了这个陷阱,然后花了大量时间去纠正它。今天,我想把这个过程分享出来——不是为了展示我们犯了多少错误,而是想说明:真正聪明的架构,不是让规则引擎做所有事,而是知道什么时候不该用它。
架构的演进:从“中心化”到“去中心化”
在早期的设计中,我们的系统采用了一种“中心化”的架构思路。所有面板——无论是创建、修复、优化、比较还是识别——都统一调用后端的规则引擎。这听起来很合理:统一管理,统一执行,统一维护。
但问题在于,创建(Create)这个场景和其他场景有着本质的区别。
修复、优化、比较、识别这些操作,本质上是对已存在的数据进行处理。它们有明确的输入(现有数据)和输出(修改后的数据),规则引擎可以很好地胜任。
但创建不同。创建是从无到有的过程。它涉及字段的自动填充、模板的选择、AML(一种对象描述语言)的组装、以及最终向SCSAI(一种对象管理系统)的提交。这个过程更像是一个“组装流水线”,而不是一个“规则判断器”。
更重要的是,在v3.2架构中,我们明确了一个核心原则:前端负责全部业务逻辑,后端只负责数据存取和透明代理。这意味着,创建场景中所有的字段修正、AML组装、SCSAI提交,都应该由前端自主完成,而不是依赖后端的规则引擎。
为什么这个原则如此重要?
想象一下,如果创建场景也依赖后端的规则引擎,会发生什么?
- 1. 每次创建都要发一次网络请求
- 2. 规则引擎成为瓶颈
- 3. 调试困难
- 4. 扩展性受限
所以,v3.2架构做了一个看似“反直觉”的决定:创建场景,前端自己搞定。
五个错误,同一个教训
说起来容易做起来难。即便是我们自己,在从旧架构迁移到新架构的过程中,也犯了不止一次错误。这些错误虽然看起来技术性很强,但背后反映的问题,其实每个企业都会遇到。
错误一:习惯性调用规则引擎
这是最典型的错误。当开发人员在处理创建面板时,看到“规则引擎”这个词,下意识就认为应该调用它。于是,代码里出现了这样的逻辑:
const ruleEngineResp = await fetch('/api/rule-engine/execute/create_pre', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({...}) }) 这段代码看起来没什么问题——调用规则引擎,获取结果,继续处理。但它违背了架构设计。根据v3.2架构,创建场景的调用链应该是:
前端 Create 面板 → 获取对象Schema → 获取模板 → 获取提示词 → 构建 Prompt → 调用大模型 → 前端完成全部业务逻辑(不调用后端规则引擎) → 字段修正 → 分离属性 → 预创建嵌套对象 → 补充默认值 → 前端组装AML → 提交SCSAI 看到区别了吗?整个过程中,没有一步需要调用后端的规则引擎。前端自己就是规则引擎。
错误二:不读文档就改代码
这个错误听起来有点“低级”,但它确实发生了。开发人员在修改代码之前,没有仔细阅读架构文档,尤其是关于创建场景的章节。结果,他们按照旧的习惯去写代码,自然就写错了。
这个错误的教训是:任何修改前,必须先理解当前的架构设计。 文档不是摆设,它是团队智慧的结晶。尤其是当架构发生重大变更时,不读文档就改代码,等于闭着眼睛开车。
错误三:混淆不同面板的职责
另一个常见的错误是,把所有面板都当成一样的。实际上,不同的面板有不同的架构设计:
| 面板 | 架构 | 是否调用规则引擎 | |------|------|-----------------| | 创建 | v3.2 前端自主 | ❌ 不调用 | | 修复 | v3.2 规则引擎 | ✅ 调用 | | 优化 | v3.2 规则引擎 | ✅ 调用 | | 比较 | v3.2 规则引擎 | ✅ 调用 | | 识别 | v3.2 规则引擎 | ✅ 调用 |
创建面板是特殊的。 它不再依赖后端的规则引擎,而是由前端自主完成全部业务逻辑。这个区别如果不搞清楚,就会在错误的地方调用错误的接口。
错误四:把“参考”当成“可执行”
这是最隐蔽的一个错误。在规则引擎中,我们有一个字段叫 action_script,它记录了一些客户端方法的执行逻辑。这个字段的初衷是作为参考文档,帮助开发人员理解某个规则应该做什么。
但有人错误地认为,这个 action_script 可以直接在后端用 new Function() 执行。这就像你拿到一本烹饪书,然后直接把书扔进烤箱,指望它能烤出蛋糕来。
客户端方法与UI深度绑定,不能脱离UI环境直接执行。 action_script 只是规则意图的描述,不是可执行的代码。正确的做法是:分析理解客户端方法,将其转化为规则定义(条件+动作类型+动作配置),然后由前端根据规则定义自己编写对应的逻辑。
错误五:反复犯同一个错误
最让人沮丧的是,同一个错误可能反复出现。第一次,开发人员擅自添加了调用后端规则引擎的代码。被指出后,撤销了。第二次,他们又添加了类似的代码,理由是“架构例外”。第三次,又被指出 action_script 不能直接执行。
根本原因在于,没有真正理解“客户端方法 → 规则定义 → 前端自己实现”这个转化过程。 看到规则引擎API就想调用,而不是思考架构设计意图。这种思维惯性,是很多技术团队都会遇到的问题。
正确的做法是什么?
如果你正在构建一个类似的企业级应用,或者正在考虑是否使用规则引擎,这里有几点建议:
1. 明确规则引擎的职责边界
规则引擎不是万能的。它适合处理那些有明确输入输出、可独立判断的业务规则。对于复杂的组装流程、多步骤操作、前端交互密集的场景,规则引擎可能不是最佳选择。
2. 前端能做的事,不要交给后端
现代前端框架已经足够强大,可以处理复杂的业务逻辑。把业务逻辑放在前端,可以减少网络请求、提升用户体验、降低后端负载。当然,这需要前端代码有良好的架构和测试覆盖。
3. 文档不是摆设,是代码的“说明书”
每次修改代码前,先读文档。如果文档不清楚,先问清楚再动手。不要猜测架构意图,不要假设“这样应该可以”。
4. 区分“参考”和“执行”
不要把注释、文档、参考代码当成可执行代码。action_script 是规则意图的描述,不是可执行的脚本。客户端方法需要分析理解后转化为规则定义,再由前端实现。
5. 建立修改后的验证机制
修改代码后,不仅要验证功能是否正确,还要验证是否符合架构设计。不要擅自添加功能,不要“顺便”改一些看似无关的东西。
从“规则陷阱”到“智能助手”
回到最初的问题:当规则引擎变成“规则陷阱”,我们该怎么办?
答案是:不要让规则引擎成为唯一的决策中心。 相反,让不同的组件各司其职,用最合适的方式处理最合适的事情。
在BossAgents(左帮右臂)智能体公司,我们帮助企业构建的正是这样的系统。我们的智能体不是简单地调用规则引擎,而是:
- 理解业务场景
- 前端自主处理
- 智能规则管理
- 持续优化迭代
我们相信,真正的智能化不是把所有的逻辑都塞进一个“万能引擎”,而是让每个组件都变得聪明,在合适的时间做合适的事情。
如果你也在为规则引擎的维护头疼,或者正在考虑如何优化你的企业应用架构,不妨和我们聊聊。BossAgents(左帮右臂)智能体公司,让每个企业都拥有自己的智能助手,从“规则陷阱”中解脱出来,真正实现智能化的业务管理。
毕竟,企业需要的不是一个会执行所有规则的“机器”,而是一个知道什么时候该执行规则、什么时候该自己思考的“伙伴”。
BossAgents