{"id":50690892,"url":"https://github.com/sreeb228/gisk","last_synced_at":"2026-06-09T02:35:55.452Z","repository":{"id":236230770,"uuid":"792186313","full_name":"sreeb228/gisk","owner":"sreeb228","description":"go语言风控策略引擎","archived":false,"fork":false,"pushed_at":"2025-01-26T06:57:39.000Z","size":141,"stargazers_count":5,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-01-26T07:25:17.536Z","etag":null,"topics":["decision-engine","flow","risk","risk-management","rule","rules-engine","ruleset"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sreeb228.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-04-26T06:41:24.000Z","updated_at":"2025-01-26T06:57:43.000Z","dependencies_parsed_at":"2024-04-28T10:26:28.539Z","dependency_job_id":null,"html_url":"https://github.com/sreeb228/gisk","commit_stats":null,"previous_names":["sreeb228/gisk"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sreeb228/gisk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sreeb228%2Fgisk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sreeb228%2Fgisk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sreeb228%2Fgisk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sreeb228%2Fgisk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sreeb228","download_url":"https://codeload.github.com/sreeb228/gisk/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sreeb228%2Fgisk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34089328,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-09T02:00:06.510Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["decision-engine","flow","risk","risk-management","rule","rules-engine","ruleset"],"created_at":"2026-06-09T02:35:54.691Z","updated_at":"2026-06-09T02:35:55.437Z","avatar_url":"https://github.com/sreeb228.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"## gisk风控策略引擎\n\ngisk是独立的即插即用的轻量级决策引擎，支持json和yaml格式DSL。支持自定义运算符，自定义函数，自定义动作开放灵活的扩展适用更多的业务场景。\n\n### 功能列表\n- 基础值\n    - 变量\n    - 输入值\n    - 函数\n- 决策（规则）\n- 决策集\n- 决策流\n- 分流决策流\n- 赋值决策流\n- 评分卡\n- 支持数据类型：number, string, bool, array, map\n- 支持运算符号（支持自定义，覆盖默认运算符）：eq, neq, gt, lt, gte, lte, in, notIn, like, notLike\n- 支持函数（支持自定义，函数支持嵌套）：内置函数rand、sum\n- 支持决策动作（支持自定义）：内置动作 赋值,访问url\n- 支持串行并行执行\n- DSL支持历史版本控制（提供获取接口，实现不同介质DSL储存。内置文件存储）\n- DSL支持json和yaml格式\n\n\n## 快速开始\n- 环境准备\n\n  *go version go1.2+*\n\n\n- 安装\n\n```shell\ngo get -u -v github.com/sreeb228/gisk\n```\n- 基础使用  \n\n```go\npackage main\n\nimport (\n  \"fmt\"\n  \"github.com/sreeb228/gisk\"\n)\n\nfunc main() {\n  elementType := gisk.RULES //规则\n  rulesKey := \"rules1\" //规则唯一key\n  version := \"1\" //规则版本\n\n  g := gisk.New() //创建gisk实例\n  g.SetDslFormat(gisk.JSON) //设置dsl格式\n  err := g.Parse(elementType, rulesKey, version) //解析规则\n  if err != nil {\n    //错误处理\n  }\n  //获取所有被初始化的变量值\n  variates := g.GetVariates()\n  fmt.Println(variates)\n}\n\n```\n\n- 注册dsl获取接口\n\n*dsl接口获取器,可以根据提供的类型和key和版本获取dsl字符串。 dsl接口获取器需要实现`gisk.DslGetterInterface`接口，返回dsl字符串。*\n```go\ntype DslGetterInterface interface {\n\tGetDsl(elementType ElementType, key string, version string) (string, error)\n}\n```\n示例：\n```go\ntype fileDslGetter struct {\n}\n\nfunc (getter *fileDslGetter) GetDsl(elementType gisk.ElementType, key string, version string) (string, error) {\n\tpath := \"./dsl/\" + elementType + \"_\" + key + \"_\" + version + \".json\"\n\tbytes, err := os.ReadFile(path)\n\tif err != nil {\n\t\treturn \"\", err\n\t}\n\treturn  string(bytes), nil\n}\n\nfunc main() {\n    //创建gisk实例\n    g := gisk.New()\n    //设置dsl获取器\n    g.SetDslGetter(\u0026fileDslGetter{})\n    //...\n}\n```\n\n\n- 注册比较符\n\n*系统实现默认的比较符 `eq`, `neq`, `gt`, `lt`, `gte`, `lte`,`in`,`notIn`,`like`,`notLike`如果需要自定义比较符，可以调用RegisterOperation方法。自定义比较符优先级高于系统内置的比较符，可以注册和系统同名比较符实现复写。*\n\n```go\npackage main\n\nimport (\n\t\"errors\"\n\t\"github.com/sreeb228/gisk\"\n\t\"regexp\"\n)\n\nfunc main() {\n\t//自定义正则匹配比较符\n\tgisk.RegisterOperation(\"reg\", func(left gisk.Value, operator gisk.Operator, right gisk.Value) (result bool, err error) {\n\t\tif left.ValueType != gisk.STRING || right.ValueType != gisk.STRING {\n\t\t\terr = errors.New(\"left and right must be string\")\n\t\t\treturn\n\t\t}\n\t\t// 正则表达式匹配\n\t\treg := regexp.MustCompile(right.Value.(string))\n\t\tif reg.MatchString(left.Value.(string)) {\n\t\t\tresult = true\n\t\t}\n\t\treturn\n\t})\n\n\tg := gisk.New()\n\t//...\n}\n```\n- 注册函数\n\n系统实现默认的函数 `rand`，`sum`，如果需要自定义函数，可以调用RegisterFunction方法。自定义函数优先级高于系统内置的函数，可以注册和系统同名函数实现复写。*\n```go\npackage main\n\nimport (\n  \"github.com/sreeb228/gisk\"\n  \"github.com/gogf/gf/v2/util/gconv\"\n)\n\nfunc main() {\n    //注册求和函数\n    gisk.RegisterFunc(\"sum\", func(parameters ...gisk.Value) (gisk.Value, error) {\n      var v float64\n      for _, parameter := range parameters {\n        v += gconv.Float64(parameter.Value)\n      }\n      return gisk.Value{ValueType: gisk.NUMBER, Value: v}, nil\n    })\n\t\n    g := gisk.New()\n    //...\n}\n```\n## DSL语法\n\n### 基础值\n\n*基础值包含变量，输入值，函数。在dsl中用字符串表示。基础值*\n\n#### 变量\n\n表示法：`variate_age_1`\n\n解释：`variate`表示为变量类型，`age`表示变量唯一key（key可以有下划线），`1`表示变量版本号。\n\n变量DSL：\n```json\n{\n    \"key\": \"age\",\n    \"name\": \"年龄\",\n    \"desc\": \"用户年龄\",\n    \"version\": \"1\",\n    \"value_type\": \"number\",\n    \"default\": 20,\n    \"is_input\": false\n}\n```\n变量结构体：\n```go\ntype Variate struct {\n\tKey       string      `json:\"key\" yaml:\"key\"`               //唯一标识\n\tName      string      `json:\"name\" yaml:\"name\"`             //变量名称（前端页面使用，不涉及逻辑）\n\tDesc      string      `json:\"desc\" yaml:\"desc\"`             //描述（前端页面使用，不涉及逻辑）\n\tVersion   string      `json:\"version\" yaml:\"version\"`       //版本\n\tValueType ValueType   `json:\"value_type\" yaml:\"value_type\"` //值类型（number：转成float64, string, bool, array:以,分割转成array, map：json字符串转成map）\n\tDefault   interface{} `json:\"default\" yaml:\"default\"`       //默认值\n\tIsInput   bool        `json:\"is_input\" yaml:\"is_input\"`     //是否要从输入值中匹配(true时会从输入值中匹配相同key的值进行赋值)\n}\n```\n\n#### 输入值\n表示法：`input_1_number`\n\n解释：`input`表示为输入值类型，`1`表示输入值，`number`表示输入值数据类型。\n\n输入值没有DSL\n\n#### 函数\n\n表示法：`func_rand(input_1_number,func_sum(input_10_number,input_20_string))`\n\n解释：函数支持嵌套，函数参数只能是基础值。上述表达式解释为：rand(1,sum(10,20))，rand函数两个参数1和sum函数，sum函数两个参数10和20。 注册函数需要实现 `type Func func(parameters ...Value) (Value, error)`类型。\n\n函数无DSL\n\n## 规则（决策）\n\n*规则是基于多个比较条件通过逻辑运算符进行组合，最终得到一个布尔值。可以根据最终布尔值进行后续动作执行，赋值，访问url，发送消息，连接数据库等等操作。规则支持括号运算，支持串行并行执行*\n\n规则dsl\n\n```json\n{\n  \"key\": \"rule1\",   //唯一key\n  \"name\": \"用户筛选\", //规则名称\n  \"desc\": \"用户筛选\", //规则描述\n  \"version\": \"1\",  //规则版本\n  \"parallel\": true, //是否并行执行（并行执行会先并发获取比较条件组所有结果，再用规则表达式进行逻辑运算）\n  \"compares\": {     \n    \"年龄小于40\": {\n      \"left\": \"variate_年龄_1\", //比较条件左边\n      \"operator\": \"lt\", //比较条件运算符\n      \"right\": \"input_40_number\" //比较条件右边\n    },\n    \"性别女\": {\n      \"left\": \"variate_性别_1\",\n      \"operator\": \"eq\",\n      \"right\": \"input_女_string\"\n    },\n    \"身高大于等于170\": {\n      \"left\": \"variate_身高_1\",\n      \"operator\": \"gte\",\n      \"right\": \"input_170_number\"\n    }\n  },  //比较条件组\n  \"expression\": \"年龄小于40 \u0026\u0026 (性别女 || 身高大于等于170)\", //规则表达式\n  \"action_true\": [\n    {\n      \"action_type\": \"assignment\",  //赋值操作\n      \"variate\": \"variate_命中结果_1\", //赋值变量\n      \"value\": \"input_true_bool\" //赋值值\n    },\n    {\n      \"action_type\": \"geturl\", //访问url\n      \"url\": \"https://xxx.com\" //url\n    }\n  ],  //true执行动作\n  \"action_false\": [\n    {\n      \"action_type\": \"assignment\", //赋值操作\n      \"variate\": \"variate_命中结果_1\", //赋值变量\n      \"value\": \"input_false_bool\" //赋值值\n    }\n  ] //false执行动作\n}\n\n```\n上述规则解释为：如果年龄小于40且性别为女或者身高大于等于170，则命中，否则未命中。命中时执行动作：变量命中结果赋值为true时，访问url。未命中时，赋值变量命中结果为false。\n\n\n规则结构体：\n```go\ntype Rule struct {\n\tKey         string              `json:\"key\" yaml:\"key\"`                //唯一标识\n\tName        string              `json:\"name\" yaml:\"name\"`              //名称\n\tDesc        string              `json:\"desc\" yaml:\"desc\"`              //描述\n\tVersion     string              `json:\"version\" yaml:\"version\"`        //版本\n\tParallel    bool                `json:\"parallel\" yaml:\"parallel\"`      //是否并发执行\n\tCompares    map[string]*Compare `json:\"compares\" yaml:\"compares\"`      //比较\n\tExpression  string              `json:\"expression\"  yaml:\"expression\"` //计算公式\n\tActionTrue  []RawMessage        `json:\"action_true\" yaml:\"action_true\"` //命中执行动作\n\tActionFalse []RawMessage        `json:\"action_false\" yaml:\"action_false\"` //未命中执行动作\n}\ntype Compare struct {\n  Left     string   `json:\"left\" yaml:\"left\"`\n  Operator Operator `json:\"operator\" yaml:\"operator\"` // 比较符号(可自定义注册)\n  Right    string   `json:\"right\" yaml:\"right\"`\n}\n```\n\n\n\n## 规则集（决策集）\n\n*规则集是多个规则的集合，支持串行并行执行和中断。并行模式下规则的先后顺序和中断不生效*\n\n规则集dsl:\n```json\n{\n  \"key\": \"ruleset\", //唯一key\n  \"name\": \"决策集1\", //规则集名称\n  \"desc\": \"决策集1\", //规则集描述\n  \"version\": \"1\", //规则集版本\n  \"parallel\": false, //是否并行执行（串行执行：顺序执行规则，中断后不执行后续规则。 并行执行：并发执行规则，不考虑顺序和中断）\n  \"rules\": [ \n    {\n      \"rule_key\": \"rule1\", //规则key\n      \"rule_version\": \"1\", //规则版本\n      \"break_mode\": \"hit_break\" //中断模式:hit_break命中中断，miss_break未命中中断。中断表示不执行后续的规则\n    },\n    {\n      \"rule_key\": \"rule2\",\n      \"rule_version\": \"1\",\n      \"break_mode\": \"miss_break\"\n    },\n    {\n      \"rule_key\": \"rule3\",\n      \"rule_version\": \"1\",\n      \"break_mode\": \"miss_break\"\n    }\n  ]//规则集规则\n}\n```\n\n规则集结构体：\n```go\ntype Ruleset struct {\n\tKey      string         `json:\"key\" yaml:\"key\"`           //唯一标识\n\tName     string         `json:\"name\" yaml:\"name\"`         //名称\n\tDesc     string         `json:\"desc\" yaml:\"desc\"`         //描述\n\tVersion  string         `yaml:\"version\" json:\"version\"`   //版本\n\tParallel bool           `json:\"parallel\" yaml:\"parallel\"` //是否并发执行\n\tRules    []*rulesetRule `json:\"rules\" yaml:\"rules\"`       //规则集规则\n}\n\ntype rulesetRule struct {\n\tRuleKey     string    `json:\"rule_key\" yaml:\"rule_key\"` //规则key\n\tRuleVersion string    `json:\"rule_version\" yaml:\"rule_version\"` //规则版本\n\tBreakMode   BreakMode `json:\"break_mode\" yaml:\"break_mode\"` //中断模式\n}\n```\n\n\n## 决策流\n决策流支持普通节点，分流节点和动作节点\n\n### 普通节点\n*普通节点可以执行一个元素，元素可为规则，规则集等*\n```go\ntype generalFlowNode struct {\n\tNodeKey    string       `json:\"node_key\" yaml:\"node_key\"`               //节点key\n\tNodeType   FlowNodeType `json:\"node_type\" yaml:\"node_type\"`             //节点类型\n\tEleType    ElementType  `json:\"element_type\" yaml:\"element_type\"`       //元素类型\n\tEleKey     string       `json:\"element_key\" yaml:\"element_key\"`         //元素key\n\tEleVersion string       `json:\"element_version\" yaml:\"element_version\"` //元素版本\n\tNextNode   string       `json:\"next_node\" yaml:\"next_node\"`             //下一个节点\n}\n```\n### 分流节点\n*分流节点通过比较条件进行分流*\n```go\ntype branchFlowNode struct {\n\tNodeKey  string       `json:\"node_key\" yaml:\"node_key\"`   //节点key\n\tNodeType FlowNodeType `json:\"node_type\" yaml:\"node_type\"` //节点类型\n\tLeft     string       `json:\"left\" yaml:\"left\"`           //左侧\n\tBranches []struct {\n\t\tOperator Operator `json:\"operator\" yaml:\"operator\"`   // 比较符号\n\t\tRight    string   `json:\"right\" yaml:\"right\"`         // 右侧\n\t\tNextNode string   `json:\"next_node\" yaml:\"next_node\"` // 下一个节点\n\t} `json:\"branches\" yaml:\"branches\"` // 分支\n}\n```\n### 动作节点\n*动作节点执行动作，公用规则动作，可以自定义*\n```go\ntype actionFlowNode struct {\n\tNodeKey  string       `json:\"node_key\" yaml:\"node_key\"`   //节点key\n\tNodeType FlowNodeType `json:\"node_type\" yaml:\"node_type\"` //节点类型\n\tActions  []RawMessage `json:\"actions\" yaml:\"actions\"`     //动作\n\tNextNode string       `json:\"next_node\" yaml:\"next_node\"` //下一个节点\n}\n```\n\n复杂的决策流：\n```json\n{\n    \"key\": \"flow1\",\n    \"name\": \"普通决策流\",\n    \"desc\": \"普通决策流\",\n    \"version\": \"1\",\n    \"nodes\": [\n        {\n            \"node_key\": \"start\",\n            \"node_type\": \"general_flow_node\",\n            \"element_type\": \"ruleset\",\n            \"element_key\": \"ruleset\",\n            \"element_version\": \"1\",\n            \"next_node\": \"branch_node\"\n        },\n        {\n            \"node_key\": \"branch_node\",\n            \"node_type\": \"branch_flow_node\",\n            \"left\": \"func_rand(input_1_number,input_100_number)\",\n            \"branches\": [\n                {\n                    \"operator\": \"lte\",\n                    \"right\": \"input_20_number\",\n                    \"next_node\": \"\"\n                },\n                {\n                    \"operator\": \"gt\",\n                    \"right\": \"input_20_number\",\n                    \"next_node\": \"\"\n                }\n            ]\n        },\n        {\n            \"node_key\": \"branch_node\",\n            \"node_type\": \"branch_flow_node\",\n            \"left\": \"func_rand(input_1_number,input_100_number)\",\n            \"branches\": [\n                {\n                    \"operator\": \"lte\",\n                    \"right\": \"input_20_number\",\n                    \"next_node\": \"action_flow_node1\"\n                },\n                {\n                    \"operator\": \"gt\",\n                    \"right\": \"input_20_number\",\n                    \"next_node\": \"action_flow_node2\"\n                }\n            ]\n        },\n        {\n            \"node_key\": \"action_flow_node1\",\n            \"node_type\": \"action_flow_node\",\n            \"next_node\": \"\",\n            \"actions\": [\n                {\n                    \"action_type\": \"assignment\",\n                    \"variate\": \"variate_决策流分流_1\",\n                    \"value\": \"input_20%_string\"\n                }\n            ]\n        },\n        {\n            \"node_key\": \"action_flow_node2\",\n            \"node_type\": \"action_flow_node\",\n            \"next_node\": \"\",\n            \"actions\": [\n                {\n                    \"action_type\": \"assignment\",\n                    \"variate\": \"variate_决策流分流_1\",\n                    \"value\": \"input_80%_string\"\n                }\n            ]\n        }\n    ]\n}\n\n```\n\n解释为:\n![决策流图](https://github.com/sreeb228/gisk/raw/master/docs/flow.png)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsreeb228%2Fgisk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsreeb228%2Fgisk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsreeb228%2Fgisk/lists"}