arishem

arishem

高性能DSL规则引擎 加速业务决策流程

Arishem是一款轻量级高性能DSL规则引擎,由字节跳动客服平台架构组开发。它使用JSON兼容语法,支持可视化规则编辑,执行速度可达微秒级。Arishem提供自定义执行顺序、并发执行、丰富的操作符和内置函数等功能,适合需要快速响应业务决策的场景。其JSON兼容设计使非技术人员也能轻松使用,有效提高业务需求响应速度。

Arishem规则引擎JSON语法性能优化可视化配置Github开源项目

Arishem

Arishem是字节跳动客服平台架构组自研的一款轻量、高性能的DSL规则引擎。它旨在将频繁变更的业务决策从应用程序中分离出来,通过可视化界面灵活编写业务决策,提高业务需求的响应速度。

Arishem采用完全兼容的JSON语法格式定义规则语法,通过组合、嵌套方式灵活表达业务规则。使用Arishem可以轻松地将规则可视化,使不具备编程基础的人员也能快速上手。

Arishem在AST解析生成和规则执行方面进行了一系列优化,使单个复杂规则的执行能在微秒级别完成。

Arishem支持自定义规则执行顺序和并发执行粒度,支持运行时下游数据的并发和预测获取

Arishem内置了丰富的操作符和函数。

完全兼容JSON语法

Arishem由条件表达式和目的表达式组成,其最大特点是语法完全兼容JSON语法,同时也能完全兼容IDL(如thrift、protobuf等)。在examples部分提供了使用thrift和protobuf定义规则的示例。

Arishem在可视化场景(如规则配置页面)具有显著优势。在字节跳动的客服平台,几十个涉及规则判断的场景都接入了Arishem,并实现了运营可视化规则配置页面。这使得原本需要研发维护的规则配置场景,变成了运营同学也能进行配置维护,极大地解放了研发资源。

非常快速!

在benchmark测试中,执行单个无网络请求的复杂规则仅需微秒级别的时间!当然,没有最好的性能框架,只有最适合的应用场景。

测试环境:

goos: darwin goarch: amd64 pkg: */arishem/arishem cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz PASS

测试条件样例,共495个AST节点,包含基本的逻辑操作,如字符串正则、数组遍历、数组交集等:

// 实时数据 {"username":"Andrew","usernames":["Jack","Mike","Andrew"],"news":"Jack hanged out with Mike last weekend.","number1":100,"numbers":["10",99.9,0]} // 条件表达式 {"OpLogic":"||","ConditionGroups":[{"OpLogic":"&&","Conditions":[{"Operator":"STRING_START_WITH","Lhs":{"VarExpr":"username"},"Rhs":{"Const":{"StrConst":"Banana"}}},{"Operator":"STRING_END_WITH","Lhs":{"VarExpr":"usernames#1"},"Rhs":{"Const":{"StrConst":"A"}}},{"Operator":"STRING_END_WITH","Lhs":{"VarExpr":"usernames#0"},"Rhs":{"Const":{"StrConst":"hahaha"}}},{"Operator":"CONTAIN_REGULAR","Lhs":{"VarExpr":"usernames#0"},"Rhs":{"Const":{"StrConst":"^M.*"}}}]},{"OpLogic":"and","ConditionGroups":[{"OpLogic":"&&","ConditionGroups":[{"OpLogic":"||","Conditions":[{"Operator":"<=","Lhs":{"Const":{"NumConst":100}},"Rhs":{"Const":{"NumConst":10}}},{"Operator":"<=","Lhs":{"Const":{"NumConst":100}},"Rhs":{"Const":{"NumConst":10}}},{"Operator":"<=","Lhs":{"Const":{"NumConst":100}},"Rhs":{"Const":{"NumConst":10}}},{"Operator":"<=","Lhs":{"Const":{"NumConst":100}},"Rhs":{"Const":{"NumConst":10}}},{"Operator":"<","Lhs":{"Const":{"NumConst":100}},"Rhs":{"Const":{"NumConst":10}}}]}]},{"OpLogic":"&&","Conditions":[{"Operator":"LIST_IN","Lhs":{"VarExpr":"number1"},"Rhs":{"ConstList":[{"NumConst":1},{"NumConst":98},{"NumConst":101},{"NumConst":1.32e-3},{"NumConst":12.234},{"NumConst":-1}]}},{"Operator":"!LIST_IN","Lhs":{"VarExpr":"numbers#0"},"Rhs":{"ConstList":[{"NumConst":1},{"NumConst":99},{"NumConst":999},{"NumConst":1.32e-3},{"NumConst":10},{"NumConst":-1}]}},{"Operator":"LIST_CONTAINS","Lhs":{"VarExpr":"numbers"},"Rhs":{"MathExpr":{"OpMath":"+","ParamList":[{"Const":{"NumConst":6}},{"Const":{"StrConst":"5"}}]}}},{"Operator":"LIST_RETAIN","Lhs":{"VarExpr":"numbers"},"Rhs":{"MathExpr":{"OpMath":"+","ParamList":[{"Const":{"NumConst":6}},{"Const":{"StrConst":"5"}}]}}},{"Operator":"LIST_RETAIN","Lhs":{"VarExpr":"numbers"},"Rhs":{"ConstList":[{"StrConst":"-1"},{"BoolConst":true},{"NumConst":-3.1415926}]}},{"Operator":"!LIST_RETAIN","Lhs":{"VarExpr":"numbers"},"Rhs":{"ConstList":[{"StrConst":"-1"},{"BoolConst":true},{"NumConst":-3.1415926}]}}]}]},{"OpLogic":"&&","Conditions":[{"Operator":"==","Lhs":{"Const":{"NumConst":1}},"Rhs":{"Const":{"NumConst":1}}}]}]} // 目的表达式 {"ActionName":"Greeting2","ParamMap":{"UserAge":{"VarExpr":"user.age"},"TempUsername":{"VarExpr":"user.name"}}}

运行结果:平均不到30微秒

goos: darwin goarch: amd64 pkg: */arishem/arishem cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz BenchmarkSingleComplexRule-12 205094 28959 ns/op 2227 B/op 69 allocs/op BenchmarkSingleComplexRule-12 208012 28637 ns/op 2226 B/op 69 allocs/op BenchmarkSingleComplexRule-12 207696 28614 ns/op 2226 B/op 69 allocs/op PASS

快速开始

请使用v1.0.9及以上版本

go get github.com/bytedance/arishem@{version}

使用前必须先调用Initialize方法,否则执行将导致Arishem执行异常。通常情况下使用默认配置即可,该操作应在init方法中进行。

func init() { arishem.Initialize(arishem.DefaultConfiguration()) }
func main() { condition := ` { "OpLogic": "&&", "Conditions": [ { "Operator": "==", "Lhs": { "Const": { "NumConst": 1 } }, "Rhs": { "Const": { "NumConst": 1 } } } ] } ` pass, err := arishem.JudgeCondition(condition) if err != nil { // 处理错误 // ... println(err.Error()) } if pass { // 业务代码 // ... println("条件通过!") } }

输出结果:

条件通过!
  • 在规则中通过关键字VarExpr获取实时数据进行判断
func main() { condition := ` { "OpLogic": "&&", "Conditions": [ { "Operator": ">", "Lhs": { "VarExpr": "user.age" }, "Rhs": { "VarExpr": "user_ages#1" } } ] } ` pass, err := arishem.JudgeConditionWithFactMeta(condition, ` { "user": { "name": "KJ", "age": 24 }, "user_ages": [ 15, 20, 32 ] } `) if err != nil { // 处理错误 return } if pass { println("KJ的年龄大于20岁!") } }
  • 创建一个规则并进行判断,输出规则目的
func main() { condition := ` { "OpLogic": "&&", "Conditions": [ { "Operator": ">=", "Lhs": { "VarExpr": "user.age" }, "Rhs": { "VarExpr": "user_ages#1" } } ] } ` // 创建一个表达式目的 aim := ` { "Const": { "StrConst": "规则通过!" } } ` rule, err := arishem.NewNoPriorityRule("rule1", condition, aim) if err != nil { // 处理错误 return } dc, err := arishem.DataContext(` { "user": { "name": "KJ", "age": 24 }, "user_ages": [ 20, 18, 32 ] } `) if err != nil { // 处理错误 return } rr := arishem.ExecuteSingleRule(rule, dc) if rr.Passed() { fmt.Printf("%s 通过,输出=>%s", rr.Identifier(), rr.Aim().AsExpr()) } }

输出结果

规则通过!

或者通过内置的builder函数来构建条件表达式和目的表达式

func main() { condGroup := arishem.NewConditionsCondGroup(arishem.OpLogicAnd) cond1 := arishem.NewCondition(operator.Equal) cond1.Lhs = arishem.NewConstExpr(arishem.NewNumConst(1.0)) cond1.Rhs = arishem.NewConstExpr(arishem.NewNumConst(1.0)) condGroup.AddConditions(cond1) expr, _ := condGroup.Build() println(expr) }

输出结果

{"OpLogic":"&&","Conditions":[{"Operator":"==","Lhs":{"Const":{"NumConst":1}},"Rhs":{"Const":{"NumConst":1}}}]}

更多使用方式请参考详细文档

可自定义的规则优先级定义和执行顺序

Arishem的另一个强大功能是支持灵活多变的规则执行顺序。Arishem支持优先级规则执行、非优先级规则执行以及优先级和非优先级混合执行。你甚至可以通过自实现Arishem规则接口,实现动态的优先级计算。相关使用方式请参考详细文档

丰富的操作符支持和内置函数

arishem支持多达20多种操作符,包括常用的值判断、数组判断,字符串判断等,并且arishem的另一个特性就是强大的类型自动转换功能。 在进行判断时,如果左值和右值的类型不一致,arishem将尝试进行类型统一,在进行类型转换时,以右值的类型为标准进行转换。 更多使用方式请参考详细文档

arishem内部集成了一些常见的功能函数,包括日期、数组、map和字符串函数,并且支持将自定义函数注册到arishem中使用!使用函数表达式来调用这些函数。

支持网络数据的并发访问和预取

arishem将实时获取的网络数据定义为一个feature(特征)。arishem在执行规则时通过分批的方式进行规则运算,因此在获取feature时也是按批次进行的。在使用涉及网络数据的场景中,使用FeatureExpr关键字来使用,并实现feature的获取方法。

{ ... "FeatureExpr": { // user是特征名称,username是字段路径 "FeaturePath": "user.username" } }
type MyFeatureFetcher struct{} ... func (m *MyFeatureFetcher) FetchFeature(feat typedef.FeatureParam, dc typedef.DataCtx) (typedef.MetaType, error) { println("准备获取特征=>%s", feat.FeatureName()) // 在此处编写你的代码 return nil, nil } func init() { arishem.Initialize( arishem.DefaultConfiguration(), arishem.WithFeatureFetcherFactory(func() typedef.FeatureFetcher { return &MyFeatureFetcher{} }), ) }

每个feature的获取都在一个异步协程中执行,因此你可以无顾虑地进行网络IO访问。更多使用方式请参考详细文档

灵活的自定义配置和监听回调

arishem支持多项自定义配置,包括规则运算时的缓存实现、批大小的计算方式以及无优先级的最大并发数量等。

在规则运算场景下,我们小组面临最多的问题是排查规则为什么通过/没通过?规则运算过程是否有错误?feature获取的具体过程是怎样的,究竟是哪个数据没有获取到? 因此,感知规则运算的具体过程非常必要,这将为后续排查规则命中详情提供基础能力支持。

arishem支持规则匹配过程中的条件回调和错误回调,并且FeatureFetcher也必须实现observable方法,以便让arishem内部将feature fetch的过程通知给每一个已注册的观察者。

// MyObserver实现了VisitObserver和FeatureFetchObserver接口 type MyObserver {} func (m *MyObserver) OnFeatureFetchStart(feat typedef.FeatureParam) {} func (m *MyObserver) OnFeatureFetchEnd(featureHash string, featureValue typedef.MetaType, err error) {} func (m *MyObserver) OnJudgeNodeVisitEnd(info typedef.JudgeNode, vt typedef.VisitTarget) {} func (m *MyObserver) OnVisitError(node, errMsg string, vt typedef.VisitTarget) {} func main() { arishem.ExecuteSingleRule(rule, dataCtx, WithVisitObserver(myObserver), WithFetchObserver(myObserver)) }

有关自定义配置和监听回调的更多使用方式,请参考详细文档

开源许可

Arishem 基于Apache License 2.0 许可证。

联系&&问题反馈

目前,我们仅支持错误报告,请在此处提交您的问题

编辑推荐精选

Keevx

Keevx

AI数字人视频创作平台

Keevx 一款开箱即用的AI数字人视频创作平台,广泛适用于电商广告、企业培训与社媒宣传,让全球企业与个人创作者无需拍摄剪辑,就能快速生成多语言、高质量的专业视频。

即梦AI

即梦AI

一站式AI创作平台

提供 AI 驱动的图片、视频生成及数字人等功能,助力创意创作

扣子-AI办公

扣子-AI办公

AI办公助手,复杂任务高效处理

AI办公助手,复杂任务高效处理。办公效率低?扣子空间AI助手支持播客生成、PPT制作、网页开发及报告写作,覆盖科研、商业、舆情等领域的专家Agent 7x24小时响应,生活工作无缝切换,提升50%效率!

TRAE编程

TRAE编程

AI辅助编程,代码自动修复

Trae是一种自适应的集成开发环境(IDE),通过自动化和多元协作改变开发流程。利用Trae,团队能够更快速、精确地编写和部署代码,从而提高编程效率和项目交付速度。Trae具备上下文感知和代码自动完成功能,是提升开发效率的理想工具。

AI工具TraeAI IDE协作生产力转型热门
蛙蛙写作

蛙蛙写作

AI小说写作助手,一站式润色、改写、扩写

蛙蛙写作—国内先进的AI写作平台,涵盖小说、学术、社交媒体等多场景。提供续写、改写、润色等功能,助力创作者高效优化写作流程。界面简洁,功能全面,适合各类写作者提升内容品质和工作效率。

AI辅助写作AI工具蛙蛙写作AI写作工具学术助手办公助手营销助手AI助手
问小白

问小白

全能AI智能助手,随时解答生活与工作的多样问题

问小白,由元石科技研发的AI智能助手,快速准确地解答各种生活和工作问题,包括但不限于搜索、规划和社交互动,帮助用户在日常生活中提高效率,轻松管理个人事务。

热门AI助手AI对话AI工具聊天机器人
Transly

Transly

实时语音翻译/同声传译工具

Transly是一个多场景的AI大语言模型驱动的同声传译、专业翻译助手,它拥有超精准的音频识别翻译能力,几乎零延迟的使用体验和支持多国语言可以让你带它走遍全球,无论你是留学生、商务人士、韩剧美剧爱好者,还是出国游玩、多国会议、跨国追星等等,都可以满足你所有需要同传的场景需求,线上线下通用,扫除语言障碍,让全世界的语言交流不再有国界。

讯飞智文

讯飞智文

一键生成PPT和Word,让学习生活更轻松

讯飞智文是一个利用 AI 技术的项目,能够帮助用户生成 PPT 以及各类文档。无论是商业领域的市场分析报告、年度目标制定,还是学生群体的职业生涯规划、实习避坑指南,亦或是活动策划、旅游攻略等内容,它都能提供支持,帮助用户精准表达,轻松呈现各种信息。

AI办公办公工具AI工具讯飞智文AI在线生成PPTAI撰写助手多语种文档生成AI自动配图热门
讯飞星火

讯飞星火

深度推理能力全新升级,全面对标OpenAI o1

科大讯飞的星火大模型,支持语言理解、知识问答和文本创作等多功能,适用于多种文件和业务场景,提升办公和日常生活的效率。讯飞星火是一个提供丰富智能服务的平台,涵盖科技资讯、图像创作、写作辅助、编程解答、科研文献解读等功能,能为不同需求的用户提供便捷高效的帮助,助力用户轻松获取信息、解决问题,满足多样化使用场景。

热门AI开发模型训练AI工具讯飞星火大模型智能问答内容创作多语种支持智慧生活
Spark-TTS

Spark-TTS

一种基于大语言模型的高效单流解耦语音令牌文本到语音合成模型

Spark-TTS 是一个基于 PyTorch 的开源文本到语音合成项目,由多个知名机构联合参与。该项目提供了高效的 LLM(大语言模型)驱动的语音合成方案,支持语音克隆和语音创建功能,可通过命令行界面(CLI)和 Web UI 两种方式使用。用户可以根据需求调整语音的性别、音高、速度等参数,生成高质量的语音。该项目适用于多种场景,如有声读物制作、智能语音助手开发等。

下拉加载更多