决策引擎系统,是构建于规则引擎和流程引擎基础上,满足复杂业务决策的一套系统,可用于反欺诈、信用评估、风险决策、推荐系统、精准营销、内容审核、数据清洗等领域场景。
目前流行的“智能风控”,即是以决策引擎为核心驱动,以机器学习 / AI 为大脑,在大数据基础上构建的通用风控能力。而决策引擎作为风控的核心系统,承担着复杂规则和多样化决策需求,今天要介绍的这款开源的“天网决策引擎”即满足了这样的诉求。
规则、决策
规则集
决策树
决策表
决策矩阵
评分卡
决策流
冠军挑战者
条件分流
支持特征类型:int、string、bool、date、array、map
支持多种操作:==、!=、>、<、>=、<=、like、in、contain、before、after
环境准备:go version go1.13 +
代码下载:
https://github.com/skyhackvip/risk_engine
Make 编译启动
cd risk_engine/#编译make build#启动make run#停止make stop
Golang 编译启动
cd risk_engine/mkdir -p dist/conf dist/bincp cmd/risk_engine/config.yaml dist/confcp demo dist/demo -rGO111MODULE=on CGO_ENABLED=0 go build -o dist/bin/risk_engine cmd/risk_engine/engine.go#启动cd dist/nohup bin/risk_engine -c conf/config.yaml >nohup.out 2>nohup.out &#停止pkill -f bin/risk_engine
cd risk_engine/#制作镜像docker build -t risk_engine:v1 .#启动镜像docker run -d --name risk_engine -p 8889:8889 risk_engine:v1#进入容器docker exec -it risk_engine /bin/sh#停止容器docker stop risk_engine
查看当前决策流列表
curl http://localhost:8889/engine/list
{"code": 200,"error": "","result": [{"key": "flow_ruleset","version": "1.0","md5": "46ef45be94e2f3c1ca23cc4ce9fe8947"}, {"key": "flow_abtest","version": "1.0","md5": "886ac3943749e9cf27b5033aad84a9b9"}, {"key": "flow_conditional","version": "1.0","md5": "df7a8a9431e38f1729d8d6788987df23"}, {"key": "flow_matrix","version": "1.0","md5": "37a47768ccb2b48d8585a16693d2279f"}]}
请求执行决策流
curl -XPOST http://localhost:8889/engine/run -d '{"key":"flow_abtest", "version":"1.0", "req_id":"123456", "uid":1,"features":{"feature_1":5,"feature_2":3,"feature_3":55,"feature_4":32,"feature_5":33,"feature_6":231,"feature_7":2,"feature_8":4}}'请求参数
| 参数名 | 必选 | 类型 | 说明 |
| key | true | string | 决策流唯一标识 |
| version | true | string | 决策流版本 |
| req_id | true | string | 本次请求 id |
| uid | true | string | 用户 id |
| features | true | json | 依赖特征值列表 {"feature_1":5,"feature_2":3,"feature_3":55} |
返回结果
*****成功*****{"code":200,"error":"","result":{"key": "flow_ruleset","req_id": "123456789","uid": 1,"features": [{"isDefault": false,"name": "feature_2","value": true}, {"isDefault": false,"name": "feature_y","value": "yyy"}, {"isDefault": false,"name": "feature_x","value": "xxx"}, {"isDefault": false,"name": "feature_3","value": "a"}, {"isDefault": false,"name": "feature_1","value": 55}],"tracks": [{"index": 1,"label": "","name": "start_1"}, {"index": 2,"label": "规则集1","name": "ruleset_1"}],"hit_rules": [{"id": "2","label": "规则2","name": "rule_2"}, {"id": "1","label": "规则1","name": "rule_1"}],"node_results": [{"IsBlock": true,"Kind": "ruleset","Score": 101,"Value": "reject","id": 1,"label": "规则集1","name": "ruleset_1","tag": "internal"}, {"IsBlock": false,"Kind": "start","Score": 0,"Value": null,"id": 0,"label": "","name": "start_1","tag": ""}],"start_time": "2022-08-27 21:54:04","end_time": "2022-08-27 21:54:04","run_time": 0}}****失败****{"code":400,"error":"入参错误","result":""}
features 所有特征值,包括执行过程中产生的衍生特征和赋值特征 hit_rules 命中的规则列表
tracks 流执行轨迹
node_results 各节点执行情况和产生值
条件分流+规则集案例
yaml 源文件: demo/flow_conditional key: flow_conditional
version: 1.0

curl -XPOST http://localhost:8889/engine/run -d '{"key":"flow_conditional", "version":"1.0", "req_id":"123456789", "uid":1,"features":{"feature_1":20,"feature_3":"xyzab","feature_4":55,"feature_5":44,"feature_6":"a","feature_a":false,"feature_b":1}}'{"code": 200,"error": "","result": {"key": "flow_conditional","req_id": "123456789","uid": 1,"features": [{"isDefault": false,"name": "feature_4","value": 55}, {"isDefault": false,"name": "feature_5","value": 44}, {"isDefault": false,"name": "feature_6","value": "a"}, {"isDefault": false,"name": "feature_a","value": false}, {"isDefault": false,"name": "feature_b","value": 1}, {"isDefault": false,"name": "feature_1","value": 20}, {"isDefault": false,"name": "feature_3","value": "xyzab"}],"tracks": [{"index": 1,"label": "","name": "start_1"}, {"index": 2,"label": "分支节点","name": "conditional_1"}, {"index": 3,"label": "规则集3","name": "ruleset_3"}, {"index": 4,"label": "","name": "end_1"}],"hit_rules": [{"id": "5","label": "规则5","name": "rule_5"}],"node_results": [{"IsBlock": true,"Kind": "end","Score": 0,"Value": null,"id": 0,"label": "","name": "end_1","tag": ""}, {"IsBlock": false,"Kind": "start","Score": 0,"Value": null,"id": 0,"label": "","name": "start_1","tag": ""}, {"IsBlock": false,"Kind": "conditional","Score": 0,"Value": "branch_3","id": 1,"label": "分支节点","name": "conditional_1","tag": "ab"}, {"IsBlock": false,"Kind": "ruleset","Score": 1,"Value": "record","id": 3,"label": "规则集3","name": "ruleset_3","tag": "internal"}],"start_time": "2022-08-27 22:04:11","end_time": "2022-08-27 22:04:11","run_time": 1}}
执行过程分析:从开始节点 start_1,执行到条件分流节点 conditional_1,分流节点依赖feature_a(值为 false)、feature_b (值为 1),条件满足分支3,走到规则集3。
规则集3 中有一个规则5,对应 feature_3 (值为 xyzabc)LIKE xyz,满足条件并命中规则。输出 record 值,并记录规则命中列表,未阻断继续执行到结束 end。
更多案例列表可参考:
https://github.com/skyhackvip/risk_engine/blob/master/docs/api.md
▌代码结构
├── api http接口逻辑├── configs 配置文件├── docs 文档├── core 决策引擎解析核心目录├── service 执行逻辑├── cmd 启动文件├── global 全局配置├── demo 测试yaml文件├── internal│ ├── dto 数据传输对象│ ├── errcode 错误异常定义│ ├── util 工具包│ └── operator 操作算子├── test 测试用例
▌DSL 语法详解
规则表述 Rule
type Rule struct {Name string `yaml:"name"`Tag string `yaml:"tag"`label string `yaml:"label"`Conditions []Condition `yaml:"conditions,flow"`Decision Decision `yaml:"decision"`Depends []string `yaml:"depends"`}
- rule:name: rule_4tag: rule_4label: 规则4depends: [feature_2, feature_3]conditions:- condition:name: c4feature: feature_2operator: LTvalue: 8- condition:name: c5feature: feature_3operator: GTvalue: 9decision:depends: [c4, c5]logic: c4 || c5output:name:value: recordkind: stringassign:feat1: aafeat2: bb
如果:feature_2 < 8 || feature_3 > 9那么:输出结果:record变量赋值:feat1 = aa feat2 = bb
特征表述 Feature
type Feature struct {Id int `yaml:"id"`Name string `yaml:"name"`Tag string `yaml:"tag"`Label string `yaml:"label"`Kind string `yaml:"kind"`}
features:- feature:id: 1name: num_featuretag: aalabel: 数值特征kind: int- feature:id: 2name: str_featuretag: aalabel: 字符串特征kind: string- feature:id: 3name: bool_featuretag: aalabel: 布尔特征kind: bool- feature:id: 4name: date_featuretag: aalabel: 日期特征kind: date- feature:id: 5name: array_featuretag: aalabel: 数组特征kind: array- feature:id: 6name: map_featuretag: aalabel: 字典特征kind: map
var OperatorMap = map[string]string{GT: ">",LT: "<",GE: ">=",LE: "<=",EQ: "==",NEQ: "!=",BETWEEN: "between",LIKE: "like",IN: "in",CONTAIN: "contain",BEFORE: "before",AFTER: "after",KEYEXIST: "keyexist",VALUEEXIST: "valueexist",}
数值型支持:> < >= <= == != between in
字符串支持:== != like in 布尔型支持:== != 日期型支持:== != before after between 数组型支持:== != contain in 字典型支持:keyexist valueexist