深色模式
第四章 决策引擎:把数据变成会下判断的模型与规则
4.1 决策引擎总览
一笔信贷申请递进来:申请人 35 岁、月收入 2.5 万、负债率 0.2、历史逾期 0 次。业务方要的不是这一排字段,而是一个结论——"通过还是拒绝,给多少准入分"。把"递进来一个申请、还回去一个决策"这件事标准化、可配置、可上线,就是决策引擎要解决的问题。
决策引擎是风控中台的三大模块之一,用来把中台里的数据资产,变成一套"输入特征、输出决策"的可执行逻辑。 通俗来讲,它像一座"判断力工厂":上游把散落的字段沉淀成标准口径(指标/特征),中间用统计学习模型算出概率、用规则把概率翻译成结论,再把这些逻辑编排成一条链路,最后对外发布成一个能被 HTTP 调用的接口。
决策引擎围绕一条主线搭建,后续每个小节都挂在这条主线的某一环上:
指标 / 特征 → 模型(机器学习 / 评分卡)→ 规则集 → 决策流(编排)→ 发布成对外 API + 在线试调,旁边再挂一个用于比对选型的策略实验室 A/B。
跑通这条主线,用户就"从 0 通了第一个决策服务"。
说明: 决策引擎里出现两个"流",职能不同、切勿混淆——决策流(规则流): 是可视化编排画布,把模型节点、规则节点串成一条有向流程,是决策资产的编排形态;而对外打分服务在实建时,也可以用任务流:(数据开发里的任务开发 + 任务编排)以双 HTTP 调用节点串接实现。前者偏"设计态编排",后者偏"运行态对外发布"。两者会在 4.6、4.7 分别讲清。
是什么 —— 五大核心能力
决策引擎主要提供五大核心能力,对应主线的五环:
- 准备输入——把散字段沉淀成可复用的标准口径(指标/特征),供模型与规则统一取用。
- 算出概率——用离线训练好的机器学习模型,对一笔申请给出一个违约/通过概率。
- 翻译结论——用规则集把概率、负债率、逾期次数等输入,按业务逻辑翻译成分数与"通过/拒绝/人工复核"结论。
- 编排链路——用决策流把"取数 → 跑模型 → 过规则 → 出结论"串成一条可视化流程。
- 对外发布——把编排好的决策发布成平台内部执行端点,再经数据网关放行给第三方,一次 HTTP 调用即拿决策。
产品功能入口
打开侧边导航栏,决策引擎是一个一级目录,它本身不是页面,只把下面五个页面拢成一个分区。五个页面各管一段,先记住它们分别解决什么问题:
| 页面 | 这个页面解决什么问题 |
|---|---|
| 内容管理(内容中心) | 决策资产的总目录树。目录、文件、规则集、规则流、模型全部挂在同一棵树上,共用一套目录、版本、发布、迁移机制。找不到某份资产、要搬家、要从回收站捞回来,都来这里。 |
| 规则集 | 内容树里只看规则集的过滤视图。左选目录、右列规则集,是写评分卡和结论规则的日常入口。 |
| 规则流 | 内容树里只看规则流的过滤视图。产品里说的「决策流」就是规则流,没有另一个叫「决策流」的菜单。 |
| 模型管理 | 内容树里只看机器学习模型的过滤视图,管模型条目的上传解析、建模训练、版本与发布。 |
| 策略实验室 | 沙盒列表。把整棵内容库快照克隆一份出来当隔离环境,在里面挂多组策略跑同一批数据、比分歧。 |
另有两处功能不在这个分区下,但属于本章链路:指标与特征归在数据中台 → 指标引擎里(它是中台数据与决策之间的桥);面向对外发布的任务流在数据中台 → 数据开发下——任务本身在任务开发里建,把任务串成链路在任务编排里画。
说明: 规则集、规则流、模型管理这三个页面看到的是同一棵内容树的不同切片——在内容中心里能做的实体操作(新建 / 编辑 / 移动 / 引用 / 删除),在这三个页面里同样能做,只是列表按类型过滤过。从哪个入口进不影响结果。
使用前的准备
决策引擎的操作受功能操作权限约束,这些权限随角色一并下发给账号。开始前,先确认账号具备下表权限;缺哪一项,对应按钮会置灰或提示无权限。
| 功能权限项 | 资源内容 | 操作类型 |
|---|---|---|
content:entity:list | 内容管理 / 规则集 / 规则流 三个页面 | 打开菜单(缺它这三页在导航里根本不出现) |
content:entity:add / edit / remove / query | 内容实体(目录 / 文件 / 规则集 / 规则流 / 模型) | 新建 / 编辑 / 删除 / 查看 |
content:entity:move / ref / clone / restore / purge | 内容实体 | 移动 / 引用 / 克隆 / 从回收站恢复 / 彻底清除 |
content:ruleset:query / save / publish / test | 规则集 | 详情 / 保存 / 发布 / 测试 |
content:ruleset:version / activate | 规则集版本 | 新建版本 / 激活版本 |
content:ruleflow:query / save / publish / test | 规则流 | 详情 / 保存 / 发布 / 测试 |
content:ruleflow:version / activate | 规则流版本 | 新建版本 / 激活版本 |
content:model:query / save / publish / test | 机器学习模型 | 打开模型管理菜单、查看详情 / 保存 / 发布 / 测试 |
content:model:execute | 模型执行端点 | 发起一次模型调用(「接口」弹窗里点发送请求走的就是它) |
content:model:version / activate | 模型版本 | 新建版本 / 激活版本 |
content:ruleset:seed / content:ruleflow:seed | 规则集 / 规则流 | 生成示例数据 |
lab:sandbox:query / create / remove | 沙盒 | 查看(也是策略实验室菜单本身的权限)/ 创建 / 删除 |
lab:experiment:query / create / remove / run | 实验 | 查看 / 创建 / 删除 / 执行 |
lab:experiment:group:query / create / remove | 实验组 | 查看 / 创建 / 删除 |
lab:dataset:query / create / remove | 实验数据集 | 查看 / 创建 / 删除 |
说明: 对内容实体的操作需要账号持有相应的功能操作权限(由管理员配在角色上,随角色下发);资源层面还叠加 OWNER(可编辑 / 发布)与 READ(仅查看)两级归属权限,只有资源的 OWNER 才能发布该资源。功能权限决定"能不能进这个操作",资源权限决定"能不能动这一份资产",两层都过才放行。
视角说明
不同角色在决策引擎里看到的范围不同:数据工程师 / 建模人员负责建指标、训模型、写规则、编排决策流并发布;策略运营主要在策略实验室做 A/B 比对;应用开发者关心的是"发布后怎么调"——在列表页点接口看文档并在线试调;管理员统管目录树、迁移包与回收站。
4.2 内容中心:决策资产的底座
一个建模同学入职第一天,想找"上个季度那版信贷评分卡放哪了",却发现规则、模型、编排流程散落各处——内容中心就是为了避免这种混乱而存在的"总目录"。
内容中心是决策引擎所有资产的统一实体入口。 通俗来讲,它就是一棵目录树:目录、文件、规则集、规则流、模型全部作为内容实体:(entity,决策引擎里被统一管理的资产单元)挂在同一棵树上,共用同一套目录、版本、发布、迁移机制。先有目录树,才能组织、检索、复用决策资产。
页面为左右布局:左侧目录树 + 右侧内容列表。顶部有面包屑导航指示当前所在层级,工具条提供新建目录 / 新建内容 / 导出当前目录 / 导入迁移包,每行内容还有移动 / 引用 / 编辑 / 导出 / 删除行操作。
新建内容
涉及该操作的功能权限:内容实体的新建(content:entity:add)。
- 在左侧目录树选中目标目录,确定新实体挂在哪一层。
- 点击工具条新建内容按钮,右侧滑出新建抽屉。
- 在抽屉里选择类型,填写名称、排序、扩展元数据与备注。
抽屉里的关键字段如下:
| 参数名称 | 描述 |
|---|---|
| 类型(entityType) | 五选一,创建后不可更改,逐项说明见下表。 |
| 名称 | 同级目录下不允许"同名同类型"实体,保存时前端与后端都会做唯一性校验。 |
| 排序 | 数值越小越靠前,用于人工控制目录树 / 列表的展示次序。 |
| 扩展元数据 / 备注 | 补充说明性信息,不参与执行逻辑。 |
类型逐项说明 —— 类型决定这个实体后面能干什么,选错只能删了重建:
| 类型 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
| 目录 | 纯组织层级,不承载任何执行内容。建出来只有一层归属关系,没有版本、不能发布、不能被调用。 | 给资产分层归类,例如按业务线(信贷 / 反欺诈)、按环境(生产基线 / 试验)分目录。 |
| 文件 | 占位型条目。建出来既不初始化版本,也没有对应的详情页。 | 见下方提示,实际用不上。 |
| 规则集 | 创建时系统自动建一个 1.0 的生效版本,保存后进规则集详情页写规则内容与变量表。 | 要写"命中即返回"的条件规则、要做评分卡时选它。 |
| 规则流 | 创建时同样自动建一个 1.0 的生效版本,保存后进规则流详情页画编排。产品里说的"决策流"就是它。 | 要把多个规则集 / 模型串成一条有向流程时选它。 |
| 模型 | 创建时同样自动建一个 1.0 的生效版本,但这一版是个空壳——既没有模型文件,也没有输入特征。要到模型详情页上传模型文件或跑完一次训练,内容才补齐。 | 要挂离线训好的统计学习模型时选它。 |
注意: "文件"类型名不副实——选了它既不能上传文件,列表里点"打开"也无处可去(系统没有为它准备详情页,也不给它初始化版本)。它只能当目录树里一条说明性条目摆着,不建议用。要挂说明文字,更合适的做法是写在目录或实体的备注里。
说明: 规则集、规则流、模型这三类可执行内容,建出来都自带一个 1.0 生效版本,不需要手工建第一版;区别在于模型那一版是空的。空壳版本可以先存着,但激活或发布时会被拦下:没上传模型文件报"该版本还没有模型文件,无法生效",上传了但没有输入特征报"该版本没有输入特征,无法生效"。碰到这两条提示,说明模型内容还没补齐,不是版本没建出来。
- 点击确定保存。新建保存后,实体即为 ACTIVE(正常) 状态,可直接编辑、发布、引用。
验证: 保存后,回到右侧列表,可见新实体一行,状态标签为 ACTIVE;此时该实体即可被编辑、发布、引用。
注意: 同级目录下同名同类型会被拦下。若确需重名,可在名称后追加字母或数字区分;不同类型(如一个目录与一个规则集)同名则允许。
关于列表里的"状态"列: 内容实体只有一个会出现的状态。
| 状态 | 是什么 / 什么时候出现 |
|---|---|
| ACTIVE(正常) | 实体可编辑、可发布、可被引用。新建保存后立刻就是这个状态,之后一直是。列表和筛选里能看到的就是它。 |
说明: 系统在状态字段上还预留了待激活、失败、删除中三档,但当前版本没有任何操作会把实体置成这三档——删除走的是"软删进回收站"、不改状态。也就是说,在界面上不会遇到 ACTIVE 之外的实体状态,看到状态列全是"正常"属于正常现象,不用去找别的状态。
引用与移动
一份资产在树上出现的位置,由两种关系决定。行操作里的"移动"和"引用"改的就是这两种关系,成对理解:
| 关系类型 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
| 归属(移动改的是它) | 实体本体挂在哪个目录下。一个实体有且只有一条归属关系,所以本体只有一处。点"移动"选一个新目录,本体就整个挪过去,原目录下不再有它。 | 资产分错目录了、或者业务归属变了,要把它真正挪走时。 |
| 引用(点"引用"新增的是它) | 在另一个目录下建一条指向本体的软链接。两个目录都能看到这一行、都指向同一份内容;改任何一处就是改同一份。引用可以建多条。 | 一份资产要在多个业务目录里同时露出时。举例:"信贷评分卡"规则集本体挂在"信贷"目录,再在"风控公共"目录建一个引用,两边都能找到。 |
注意: 引用是软链接,删起来方向别搞反。1. 删除引用只删链接、不删本体——本体还在原目录好好待着;2. 要真正删掉这份资产,必须去本体所在的那个目录删;3. 反过来,如果本体正被别处引用,直接删本体会被拦下,提示"以下实体仍被引用,无法删除"——先把各处引用清掉,再删本体。
搜索、回收站与迁移包
- 搜索: 在内容检索框输入关键字,命中后目录树会自动展开并定位到该实体,省去逐层点开。
- 回收站: 删除的实体先进回收站,可恢复(需
content:entity:restore);在回收站里清空才是彻底删除(需content:entity:purge),不可再恢复。这是一道"软删 → 硬删"的两级闸门,防止误删即失。 - 迁移包: 用于在不同环境间搬运决策资产(如从测试环境搬到生产环境)。点导出当前目录把整个目录打成一个迁移包(扩展名
.dcmx),也可以在单行操作里只导出一个实体;点导入迁移包上传后,系统先做预校验,展示这个包里有多少内容、多少版本、多少条发布记录、多少个文件、是否含模型文件,以及一组 warnings,确认无误再点导入。
说明: 迁移包用系统内置密钥加密,导出和导入页面上都没有密钥输入框,不需要也无法自己设口令;换句话说,包只能被同一套平台读回来,不要指望用压缩工具打开看里面。
导入迁移包时要先定两件事:落点目录和导入模式。
| 参数名称 | 描述 |
|---|---|
| 落点目录 | 在左侧目录树里选中的那个目录。新建模式下它决定内容落在哪一层;覆盖模式下它就是被清空重写的那个目录。 |
| 迁移包文件 | 仅接受 .dcmx 迁移包;导入前必看预校验结果里的 warnings,确认后再继续。 |
| 导入模式 | 两选一,逐项说明见下表。 |
导入模式逐项说明:
| 模式 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
| 新建 | 整包内容当成新实体导入,包里每个实体都重新生成一套标识,不触碰任何已有实体。原来目录里有什么,导完还是有什么,只是多出一批新内容。 | 往一个空目录、或者一个全新环境里搬资产时,一律用这个。 |
| 覆盖 | 先把选中的落点目录清空,再把包内内容按包里原来的标识写进去。执行前必须先在目录树里选中一个正式目录作为覆盖目标:没选目标报"覆盖导入缺少目标实体";选的目标不在正式目录里(比如落在回收站一侧)报"目标实体不在正式目录中,无法覆盖导入"。 | 要用包里这一版整体替换现有目录内容、且确认现有内容不再需要时。 |
重要提示: 覆盖导入不可逆。 它不是"同名的替换、不同名的保留",而是先清空整个目标目录再写入——目录里原有但包里没有的内容,导完就没了,回收站里也不会有。预校验的 warnings 里会明确出现一条"覆盖导入会先清空当前目录 XXX,再重新导入包内容",这一条必须逐字读完再点确认。拿不准就先用新建模式导到一个临时目录,比对完再决定。
验证: 导入完成后,在目标目录下刷新列表,可见迁移包内的实体逐条落位,数量与预校验展示的"内容数"一致,即导入成功。
注意: 彻底清空回收站与覆盖导入都是不可逆操作。1. 清空前确认里面的东西确实不要了;2. 覆盖前确认落点目录选对——覆盖会先清空整个落点目录,清掉的内容不进回收站。
4.3 指标与特征:给决策准备"输入"
模型和规则不会凭空判断,它们吃的是"月收入""负债率""历史逾期次数"这类标准口径。这些口径不能各写各的,否则同一个"负债率"在两处算法不同,决策就失去可信度。指标模块就是把散字段沉淀成可复用、可发布的标准口径,再喂给模型与规则。
说明: 指标虽然在决策链里是最上游的"输入",但功能实现落在数据中台 → 指标引擎里,是中台数据与决策引擎之间的桥。打开侧边导航栏,在数据中台分区下找到指标引擎,内含数据集与指标定义两个子模块。
4.3.1 数据集:指标的取数来源
指标要算"历史逾期次数",得先知道去哪张表、哪个字段上数。数据集干的就是这件事——把取数来源先登记清楚。
数据集是指标计算的数据来源定义。 通俗来讲,就是把一张数仓宽表(例如信贷申请人特征宽表 dws_credit_applicant_feature_df)登记进来、发布之后,指标才能从它身上选字段做聚合。它是整个指标体系的前置。
为什么先建数据集: 统计、衍生、复合三类指标都要先挂到一个"已发布"的数据集上,才能选字段、做试算;没有已发布数据集,新建指标时字段下拉是空的。
涉及该操作的功能权限:数据集的新建与查看。
- 进入数据中台 → 指标引擎 → 数据集,点击列表工具条上的新建数据集按钮,弹出两张卡片,先选一种建法(逐项说明见下表)。
- 按选中的建法把取数来源配清楚:
- 选数据源数据集的:在左侧依次选数据源、库、表,选中数据表就直接进下一步,不需要在页面上写 SQL。
- 选 SQL 数据集的:同样先在左侧选到表,再在右侧编辑器里写查询,点查询预览前 100 / 200 / 500 行(脚本里带
${参数}占位时会先弹框让填参数值);预览出来了才点得动下一步。
- 在下一步的表单里填数据集名等信息并保存。保存后数据集处于未发布;点击发布后变为已发布,该数据集才能被指标选用。
建法逐项说明 —— 列表里的"类型"列显示的就是这一项(彩标:数据源 / SQL):
| 建法 | 是什么 / 选了要做什么 | 什么时候用 |
|---|---|---|
| 数据源数据集 | 直接基于一张物理表生成数据集:选完数据源和表,取数定义就算配完了,系统按整表拉取该表的列及其类型。 | 一张现成的数仓宽表就够用时——常规都用这个,最省事。 |
| SQL 数据集 | 自己写一段查询当取数来源,可以关联多表、先过滤、给列改名;脚本里能用 ${参数} 占位,预览时按提示填值。字段元数据从预览结果里回填。 | 要的口径不是某一张现成表:需要多表关联、需要先筛一遍、需要重命名列时。 |
| 参数名称 | 描述 |
|---|---|
| 数据集名 | 支持中文名与英文名,英文名用于程序引用。 |
| 绑定数据源 + 表 | 指定物理来源;字段元数据从表结构或 SQL 预览结果自动拉取,含列名与类型。 |
| SQL 脚本 | 只有 SQL 建法要填。必须先点查询预览成功,否则下一步走不下去,页面会提示"请先执行 SQL 并预览数据"。 |
| 发布状态 | 两个取值,逐项说明见下表。 |
发布状态逐项说明 —— 界面上显示的是"未发布 / 已发布",接口里对应的枚举值是 UNPUBLISHED / PUBLISHED:
| 发布状态 | 是什么 / 处在这个状态能干什么 |
|---|---|
| 未发布(UNPUBLISHED) | 刚保存出来的状态。数据集本身建好了,但下游指标选不到它——新建统计指标时字段下拉是空的。 |
| 已发布(PUBLISHED) | 点过发布之后的状态,即时生效、不走工单。此时指标才能挂上来选字段、做试算。 |
验证: 发布后回到数据集列表,该行状态由未发布变为已发布;此时新建统计指标时,字段下拉里能选到这个数据集的列,即数据集已生效。
注意: 页面上点按钮发布不用管大小写;但用接口直接传发布状态时必须传大写,传小写 published 会被拒,报"发布状态非法"。这类大小写枚举硬约束在指标、模型、规则集里普遍存在,后文不再赘述。
说明: 只有走过建模流、有模型 / 数据集承载的表才能挂指标;"同步直用"(仅把外部源直接同步进来、未建模)的表挂不上指标——指标要求先有数据集。字段要能做数值聚合,类型须为数字类(如 BIGINT / DECIMAL / DOUBLE / FLOAT / INT),字符类字段做不了 SUM / AVG 这类聚合。
4.3.2 指标定义:统计 / 衍生 / 复合三类
数据集就绪后,就能在它上面定义一个个可复用的口径。
指标是可复用的标准口径或特征,如月收入、负债率、历史逾期次数、偿债能力比、组合逾期率,是模型和规则的直接输入。页面左侧是指标分类类目树,右侧是指标管理表,可按类目筛选(含"全部""未分类"两个虚拟节点),状态用彩色标签标注。类目支持新增 / 编辑 / 删除,用于把指标按业务归类。
新建时,系统先弹出选择指标类型的三张卡片,按加工方式选其一:
| 参数名称 | 描述 |
|---|---|
| 统计指标 | 基础聚合。选一个已发布数据集 + 一个字段 + 一种聚合方式,按主体(如 applicant_id)算出单人值。例:"历史逾期次数"= 对逾期记录做 COUNT。 |
| 衍生指标 | 表达式加工。把多个已有指标用表达式组合计算。例:偿债能力 expression = 月收入 ×(1 − 负债率)÷ 申请金额。 |
| 复合指标 | 脚本扩展。用 SQL 或脚本做更复杂的总体级计算,常用于总体监控。例:组合逾期率按批算总体率。 |
建统计指标(最常用)
涉及该操作的功能权限:指标的新建与查看。
- 在指标定义页点击新建,在弹窗里选统计指标卡片。
- 填写字段并保存,关键参数如下:
| 参数名称 | 描述 |
|---|---|
| 中文名 / 英文名 | 中文用于展示,英文用于程序引用。 |
| 类目 / 资源目录 | 指定所属类目(用于左树筛选)与资源目录归属。 |
| 业务口径负责人 | 该口径的解释与维护责任人。 |
| datasetId / fieldId | 绑定的数据集与参与聚合的字段。 |
| statMethod | 聚合方式,六选一,逐项说明见下表。 |
| nullHandling | 空值处理,两选一,逐项说明见下表。 |
| precision | 结果保留的小数位数。 |
| 维度列表 / 过滤条件 | 维度用于分组;过滤条件通过结构化条件树配置,可层层叠加 AND / OR。 |
| 指标语义 | 口径的文字说明,便于消费方理解。 |
聚合方式逐项说明 —— 下拉里显示的是中文,括号里是接口对应的枚举值:
| 取值 | 算什么 | 什么时候用 |
|---|---|---|
| 计数(COUNT) | 按主体数记录条数(不去重)。 | "历史逾期次数"这类计次口径。 |
| 去重计数(COUNT_DISTINCT) | 去重计数。选了它必须再指定按哪个字段去重(distinctField)。 | "近一年放款机构家数"这类去重计数。 |
| 求和(SUM) | 求和。 | 累计放款金额、累计逾期天数。 |
| 平均值(AVG) | 求平均。 | 近半年月均收入。 |
| 最大值(MAX) | 取最大值。 | 历史最大逾期天数。 |
| 最小值(MIN) | 取最小值。 | 最早一笔账龄。 |
空值处理逐项说明 —— 下拉里同样是中文,这一项选错不会报错,只会让同一个口径算出两个数,务必按业务定义来:
| 取值 | 空值怎么处理 | 什么时候用 |
|---|---|---|
| 忽略空值(IGNORE) | 空值直接不参与计算,也不进分母。 | "有记录的人的平均收入"——没填收入的人不该被算进去。 |
| 空值按 0 处理(ZERO) | 空值当成 0 参与计算,会进分母、会把均值拉低。 | "全体申请人的平均逾期次数"——没有逾期记录就等于 0 次。 |
- 点击预览试算,系统按当前配置跑出几行样例值,用于当场确认口径是否符合预期。
- 保存后回到列表,行操作里点发布,指标才能被下游选用。
说明: 指标定义的发布会提交一张发布工单(METRIC_PUBLISH),需资源方 / 审批人通过后状态才变成已发布、可被下游选用。所以点完发布,列表上那一行仍然显示"未发布",这不是没提交成功,是工单还没批。而 §4.3.1 的数据集发布是即时生效、不走工单,两者别搞混。
验证: 预览试算能跑出几行合理样例值,且发布工单审批通过、列表状态变为已发布,即该指标可被模型、规则或其他指标引用。
建衍生指标
涉及该操作的功能权限:指标的新建与查看。在弹窗里选衍生指标卡片,在 expression 里用已有指标拼表达式(如 月收入 ×(1 − 负债率)÷ 申请金额),保存后发布。它不直接连数据集,而是站在别的指标肩上做二次加工。
建复合指标
涉及该操作的功能权限:指标的新建与查看。在弹窗里选复合指标卡片,用 SQL 或脚本写总体级计算(如按批统计组合逾期率)。复合指标常用于总体监控,可用总体试算接口跑一遍看总体表现。
说明: 统计指标按主体出"单人值"(如某申请人的逾期次数),复合指标出"总体率"(如一批申请的组合逾期率),两者用途不同,别用统计指标去算总体、也别用复合指标去出单人值。
注意: 衍生指标的 expression 只能引用已存在且已发布的指标;引用了未定义或未发布的指标会保存失败或试算报错。建指标前先把它依赖的下层指标建好、发布好。
4.4 机器学习模型:从概率出发
信贷准入里,"这个人会不会违约"很难用几条硬规则说死,更适合让统计学习模型从历史数据里学一个违约概率出来。决策引擎里的机器学习模型,负责的就是这一环:输入特征,输出一个概率。
机器学习模型的运行方式是:离线训练 → 导出标准化模型文件 → 平台上传解析 → 服务端在进程内直接加载执行 → 输入特征、输出概率。 通俗来讲,建模同学在离线环境里用建模脚本训好一个逻辑回归(或其他)模型,导出成一份标准化模型文件:(一种通用的模型描述格式),上传到平台;平台把它解析出来,运行时在服务端进程内直接加载执行,不依赖任何常驻的建模脚本服务。
为什么这么设计: 把统计学习能力接进决策链,而运行时不需要常驻一套建模语言环境——模型描述与执行都在平台内闭环,规则集再消费模型算出的概率做串联决策。
打开侧边导航栏,在决策引擎 → 模型管理里找到模型列表。这个页面解决的是"模型条目放哪、怎么管"的问题:它是内容树里只看模型的过滤视图,左侧选目录、右侧列出该目录下的模型,行操作有打开 / 编辑 / 删除 / 接口。点打开进模型详情页。
模型有两条来路,产出的条目在后续使用上没有区别:一是直接上传一份离线训好的标准化模型文件;二是在详情页的建模训练里训一个,训完自动回写到当前版本。
模型详情页有 6 个 Tab,各管一段:
| Tab | 干什么用 |
|---|---|
| 模型内容 | 上传模型文件、核对输入特征表与输出标签表的绑定关系、导出模型文件。核心操作都在这里。 |
| 建模训练 | 当前生效版本下的训练流程列表,可新建训练流程、打开建模画布、删除。详见本节"在平台里训一个模型"。 |
| 版本控制 | 新建版本、激活某个历史版本、删除版本。用法见 4.10。 |
| 测试 | 建测试组批量跑当前版本,逐样本看输入输出。用法见 4.11。 |
| 基础信息 | 名称、备注、扩展元数据这类实体属性。 |
| 发布历史 | 每一次发布的记录:发布名、版本、执行地址、这一版的输入 / 输出契约。见 4.10。 |
上传并解析模型文件
涉及该操作的功能权限:内容实体的新建 / 编辑;测试需 content:model:test。
- 在内容中心或模型列表点新建,进入模型详情页。
- 点编辑进入编辑态,在"模型内容" Tab 点上传模型文件,选择离线导出的标准化模型文件上传。
- 上传成功后系统自动解析(parse),把模型的输入、输出回填成两张表——输入特征表与输出标签表。
- 逐行核对两张表的绑定关系(见下),确认无误后保存。
输入特征表每行字段:
| 参数名称 | 描述 |
|---|---|
| 顺序 | 特征在模型里的排列次序。 |
| 特征名(featureName) | 必须等于模型文件里的字段名,解析后自动带出。 |
| 绑定变量(bindVarCode) | 该特征在决策链里对应的变量编码,决定上游怎么把值喂进来。 |
| 类型 | 特征的取值类型,四选一(逐项说明见下表)。解析模型文件时自动回填,通常不用手改。 |
| 是否必填 / 默认值 | 必填项缺值会报错;非必填可给默认值兜底。 |
| 说明 / 来源 | 说明性文字;来源可关联血缘,指明特征从哪来。 |
输出标签表每行字段:
| 参数名称 | 描述 |
|---|---|
| 顺序 | 输出的排列次序。 |
| 输出标签(labelName) | 必须等于模型运行时合成的输出名——这是最容易踩的坑,见下方提示。 |
| 绑定变量(bindVarCode) | 输出映射到的下游变量编码,例如把"通过概率"绑到 approveProb。 |
| 类型 | 输出的取值类型,与输入特征表用的是同一套四档类型,逐项说明见下表。 |
| 说明 | 该输出的文字解释,不参与执行。 |
输入 / 输出的类型逐项说明 —— 两张表共用同一套四档类型,它决定平台把值交给模型前怎么转换:
| 类型 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
| 字符 | 按文本处理,不做数值转换。 | 渠道、城市、职业这类文本型特征。 |
| 整数 | 按整数转换后再交给模型。 | 逾期次数、申请笔数这类计数型特征。 |
| 小数 | 按小数转换,概率类输出一律用它。 | 负债率、金额、比率,以及模型输出的通过概率。 |
| 布尔 | 按是 / 否两值处理。 | 黑名单命中、设备风险这类是非型特征。 |
注意: 这四档是解析模型文件时自动回填的,除非解析结果明显不对(例如把一个概率输出识别成了字符),否则不要手工改。类型改错的直接后果是引用这个模型的规则流编译失败,或者数值特征被当文本比较、算出的结果不对却不报错。
- 核对无误后点发布,填写模型发布名,模型即变为在线可执行。也可点导出模型文件把当前模型导出留存。
验证: 发布后进入测试 Tab,填几条用例点测试,若能对每条样本返回一个 0~1 之间的概率,说明模型已在线可执行、输入输出对齐无误。
重要提示: 输出对齐是硬坑。 逻辑回归这类模型,运行时合成的"通过概率"输出名通常形如 probability(1)。若模型文件里没有显式的输出节点,解析会给出 warning、输出标签表为空,此时须手动补一行,把 labelName 填成运行时真实合成的那个名字(如 probability(1)),再把绑定变量指向 approveProb。名字对不上,下游就取不到概率。
注意: 模型文件格式只有一种。 页面上虽然有"模型格式"这一项,但它不是一个可选下拉——平台只接受标准化模型文件格式,留空会被自动补成它,填别的一律被挡下并报错。请用支持导出标准化模型文件的离线建模工具训练,或者直接用平台自带的建模训练画布(它的最后一步就是导出这种格式)。
说明: 模型详情页未做页面缓存,编辑未保存就切菜单会丢失改动——系统已加离开守卫,跳转前会提醒先保存。另外新建版本时,系统会把当前版本的模型文件、输入输出契约、建模训练画布一并复制到新版本上,所以新版本一进去就是旧版的完整副本,不需要手工搬。
在平台里训一个模型:建模训练画布
不是每个团队都有一套现成的离线建模环境;就算有,建模过程散在个人电脑的脚本里,过半年也没人说得清这个模型当初是怎么训出来的。建模训练画布解决的就是这两件事——在平台内部把模型训出来,并且把训练过程本身留痕。
建模训练画布把"取数 → 清洗 → 造特征 → 训练 → 评估 → 导出"拉成一条可视化的算子链,跑完直接把模型文件和输入 / 输出契约写回当前模型版本。 它不替代离线建模,但对信贷评分卡这类结构化建模已经够用。
涉及该操作的功能权限:内容实体的编辑、content:model:save。
- 进模型详情页,切到建模训练 Tab,可以看到当前版本下的训练流程列表(训练流程名 / 算法 / 最近运行 / 更新时间)。
- 点新建建一条训练流程,或对已有的一条点打开进画布。
- 从左侧算子面板往画布上拖算子,按执行顺序连线,点中算子在右侧配参数。
- 跑通后,链路末尾的导出算子会把训好的模型写回本模型条目的"模型内容"。
注意: 1. 建模训练画布只能从模型详情页的这个 Tab 进,它原本的独立菜单已经下线;2. 画布按版本隔离——这里只列当前生效版本下的训练流程,训练产出会直接覆盖当前版本的模型文件;想保住现在这一版,先去版本控制新建一个版本再训(新版本会连带复制这些画布);3. 非编辑态下画布只能看不能改,要改先点编辑。
左侧算子面板按七个类别分组,每个算子的作用如下:
| 类别 | 算子 | 干什么用 / 什么时候用 |
|---|---|---|
| 数据准备 | 读数据表 | 每条训练流程的第一步,指定去哪个数据源、哪张表取样本。 |
| 训练测试集拆分 | 把样本切成训练集和测试集,避免用训练数据评估自己。 | |
| 采样 | 处理正负样本严重不均衡(坏样本占比很低)的情况。 | |
| 预处理 | 缺失值填充 | 把空值补上,否则多数算法直接报错。 |
| 标准化 / 归一化 | 把量纲拉齐,喂给对量纲敏感的算法之前必做。 | |
| One-Hot 编码 | 把类别列展开成一组 0/1 列,让算法能吃。 | |
| 类型转换 | 上游列类型识别错了(数值被当文本)时纠正。 | |
| 特征工程 | WOE / IV 分箱 | 把连续变量切成箱、算出 WOE 编码与 IV 值,评分卡建模的标准环节。 |
| 特征重要性 | 给每个特征打分,用来筛掉没贡献的列。 | |
| 相关性 / 共线性过滤 | 按相关系数阈值成对删列,并可按方差膨胀因子(VIF)阈值迭代删共线列(阈值填 0 表示不做这一步)。 | |
| 算法 | 逻辑回归 / 梯度提升树 / 随机森林 / 一键训练 | 训练环节,逐项说明见下表。 |
| 评估 | 二分类评估 | 产出 AUC、KS 这类模型效果指标。 |
| 模型对比 | 把多个模型并排排序,主排序指标可选 AUC / KS / F1 / PSI。 | |
| 风控专有 | 评分卡刻度转换 | 把模型算出的概率按评分卡刻度换算成"分",要出分而不是出概率时接上它。 |
| 输出 | 导出模型文件 + 生成注册契约 | 训练流程的最后一步:导出标准化模型文件,并生成输入特征 / 输出标签的注册契约,写回模型内容。 |
重要提示: 不接输出算子,训练结果落不到模型上。 画布跑通只代表算法训完了,只有末尾的导出算子执行过,模型文件和输入 / 输出契约才会回写到"模型内容" Tab。训完记得回那个 Tab 确认输入特征表和输出标签表有行。
算法逐项说明 —— 一条流程里选一个;想比较就用"模型对比"算子把几个并排接上:
| 算法 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
| 逻辑回归 | 线性模型,可解释性最好,能直接翻成评分卡。可配正则化方式(L2 / L1 / 不做,默认 L2)和类别权重(不加权 / 按样本量自动加权,默认自动加权)。 | 信贷准入的默认选择——要向业务和监管解释"为什么拒",只有它讲得清。 |
| 梯度提升树(LightGBM) | 树的集成模型,表格数据上效果通常最好,但解释性弱于逻辑回归。可配类别权重(不加权 / 自动加权)。 | 追求效果、且不要求逐特征解释时。 |
| 梯度提升树(XGBoost) | 另一种梯度提升树实现。参数面与上一个并不相同:它没有类别权重这一项,处理样本不均衡靠正样本权重(填一个倍数,不均衡时可设为"负样本数 ÷ 正样本数",默认 1),另外多一个行采样比例(默认 1.0,即每棵树都用全部样本)。 | 与上一个并排比一比,挑效果稳的那个。 |
| 随机森林 | 袋装树。类别权重多一档"每棵子树各自重算权重"。 | 当基线模型用,或者拿它算特征重要性。 |
| 一键训练(AutoML) | 自动挑算法、自动调参。任务类型可选自动判断 / 分类 / 回归(默认自动判断);训练时长只有 5 分钟 / 30 分钟 / 2 小时三档(默认 5 分钟),填别的会报"训练时长档位非法";评价指标决定自动搜索按什么标准挑模型,必须和任务类型对上(见下方提示),默认 roc_auc;模式当前只有一个取值,选无可选。 | 还不确定该用哪个算法、想先跑个基线看看数据有没有信号时。 |
一键训练 · 评价指标 —— 自动搜索按这个指标挑最优模型,取值分两组,选错组会直接报错、训练跑不起来:
| 适用的任务类型 | 可选取值 | 怎么选 |
|---|---|---|
| 分类 | roc_auc(默认)/ accuracy / f1 / log_loss | 信贷这类正负样本悬殊的场景用 roc_auc;更在意"抓出的坏样本准不准"用 f1;accuracy 在坏样本占比很低时会虚高,别拿它当准绳。 |
| 回归 | rmse / mae / r2 | 预测金额、天数这类连续值时选这一组。 |
注意: 评价指标必须和任务类型属于同一组。任务类型判成分类却选了 rmse,或者反过来,算子会当场抛错并提示"评价指标 XXX 与任务类型 XXX 不匹配";任务类型留"自动判断"时,系统按目标字段的取值先判类型,再拿它去校验这一项。
关键算子的参数逐项说明 —— 这几个参数选错不会报错,但会让模型效果悄悄变差,值得逐项看清:
读数据表 · 取数方式
| 取值 | 是什么 / 什么时候用 |
|---|---|
| 从数据源取表 | 从运维配好的数据源白名单里选一个数据源、再选一张表。数据源、数据表、字段三个下拉是级联的,选了上一级才拉下一级。常规都用这个。 |
| 从工作区取 | 从建模工作区里取已经准备好的数据。 |
注意: 数据源候选是运维配的白名单,里面不含账号口令,建模人员看不到也改不了。取数只支持单表,不写 SQL——多表关联、口径加工请先在数据中台里做成一张宽表,再到这里读。
缺失值填充 · 数值列填充方式
| 取值 | 是什么 / 什么时候用 |
|---|---|
| 中位数(默认) | 取该列中位数补空。有长尾、有异常值时用它,不会被极端值带偏。 |
| 均值 | 取该列平均值补空。分布比较对称时可以用。 |
| 众数 | 取出现最多的值补空。数值列本身是离散取值(档位、等级、次数)时用它。 |
| 固定常量 | 补一个自己指定的值,例如用 −1 表示"没这个字段"。 |
注意: 这一项名字里的"数值列"是实指——它只作用于数值列。类别列(文本列)的空值由算子固定按众数补,不受这个下拉控制,也没有地方能改。所以想给类别列换一种补法是做不到的,真要控制,请在上游把类别列先处理掉。
标准化 · 方式
| 取值 | 是什么 / 什么时候用 |
|---|---|
| Z 分数(默认) | 减均值、除标准差。最通用的一档。 |
| 最小最大缩放 | 线性压到 0~1 之间。要求输出落在固定区间时用。 |
| 稳健缩放 | 用中位数和四分位距代替均值和标准差,抗异常值。 |
| 最大绝对值缩放 | 除以绝对值最大值。稀疏数据上用。 |
说明: 逻辑回归这类对量纲敏感的算法,前面必须接标准化;树模型对量纲不敏感,可以不接。
训练测试集拆分 · 拆分方式
| 取值 | 是什么 / 什么时候用 |
|---|---|
| 随机切(默认) | 打乱后按比例分。样本之间无时序、无分组关系时用。 |
| 按时间切 | 前一段当训练集、后一段当测试集。 |
| 按分组切 | 同一组的样本不会被拆到两边(例如同一个申请人的多笔申请)。 |
注意: 信贷这类有时间漂移的业务,拿随机切出来的测试集评估会高估模型效果——测试集里混进了和训练集同期的样本。这种场景请用"按时间切"。
采样 · 采样方式
| 取值 | 是什么 / 什么时候用 |
|---|---|
| 随机欠采样(默认) | 随机丢掉一部分多数类样本。样本总量足够大时优先用它。 |
| 随机过采样 | 复制少数类样本。样本总量很小、不舍得丢时用。 |
| 合成少数类样本 | 在少数类样本之间插值造新样本。 |
| 先合成再欠采 | 上面两种的组合。 |
注意: 两种"合成"采样要求特征全部是数值列,只要还留着类别列就直接报错。用它们之前,先把类别列做成 One-Hot 或 WOE 分箱。
其他常用参数
| 算子 · 参数 | 取值 | 是什么 / 什么时候用 |
|---|---|---|
| WOE / IV 分箱 · 分箱方法 | 等频(默认) | 每箱样本数接近。取值分布偏斜时用它,不会出现空箱。 |
| 等宽 | 每箱的取值区间等长。分布比较均匀时用。 | |
| 特征重要性 · 计算方式 | 随机森林(默认) | 用树模型的分裂增益打分,最贴近最终模型的用法。 |
| 梯度提升树 | 同上,换一种树模型来打分。 | |
| 互信息 | 衡量特征与标签的统计相关性,不依赖具体模型。 | |
| 方差 | 只看特征自身的离散程度,用来剔除几乎不变的列。 | |
| 类型转换 · 目标类型 | 小数 / 整数 / 文本 / 类别 | 把某一列强制转成指定类型;"类别"内部按文本处理。 |
验证: 画布跑完后回到模型内容 Tab,输入特征表与输出标签表已经自动填好行、且能点导出模型文件导出一份,说明训练结果确实落到了这个模型版本上;再去测试 Tab 跑几条用例能返回概率,就可以发布了。
测试模型
在详情页测试 Tab,填入用例数点自动生成测试组(系统按输入变量类型随机造值),或上传 CSV(首行列名映射输入变量),点测试批量执行,结果把输入与输出并排展开逐样本对比。
注意: 编辑态不能测试,须先保存。测试走的是选定版本,切了版本记得重新测。
4.5 规则集与评分卡:把概率翻译成结论
模型算出一个 0.745 的概率,业务方看不懂——他们要的是"90 分,通过"。把概率、负债率、逾期次数这些输入,按业务逻辑翻译成分数和结论,就是规则集干的事。
说明: 本产品里"模型"分两类:一类是上一节的机器学习模型:(算概率),另一类是评分卡 / 打分模型:(配置化的分数逻辑)。评分卡在本产品里不单设模块,直接用规则集承载——一条规则命中即赋 admission_score 分值并给出 decision 结论。规则与模型是串联关系(先跑模型算概率,再过规则判分),规则集消费模型输出的 approveProb,这正是"打分决策"的由来。
规则集用规则把模型概率等输入翻译成业务结论;命中即返回的优先级链,让业务逻辑显式、可读、可审计。
打开侧边导航栏,在决策引擎 → 规则集里找到规则集列表。这个页面解决的是"我的规则集都有哪些、从哪儿改"的问题:它是内容树里只看规则集的过滤视图,左侧选目录、右侧列规则集,行操作有打开 / 编辑 / 删除 / 接口。工具条上还有一个生成示例(需 content:ruleset:seed),点一下会在根目录下建一个"信贷风控示例"目录,灌进几套现成的示例规则集——第一次上手时拿它照着看最快;同名目录已存在会自动跳过,不会重复灌。
点打开进规则集详情页,一共 6 个 Tab:
| Tab | 干什么用 |
|---|---|
| 规则内容 | 写规则本体:加规则、加分支、加条件、加动作。核心工作面。 |
| 变量表 | 定义这套规则要用的输入 / 输出 / 中间变量。必须先建变量,规则里才选得到。 |
| 版本控制 | 新建版本、激活历史版本、删版本。用法见 4.10。 |
| 测试 | 建测试组批量跑当前版本。用法见 4.11。 |
| 基础信息 | 名称、备注这类实体属性。 |
| 发布历史 | 每次发布的记录与这一版的接口契约。见 4.10。 |
顶部工具条:编辑 / 保存 / 发布 / 导出。规则集是"先建变量、再写规则、最后发布"的顺序,下面按这个顺序走一遍。
第一步:建变量表
涉及该操作的功能权限:内容实体的新建 / 编辑;发布需 content:ruleset:publish,测试需 content:ruleset:test。
在变量表 Tab 定义规则要用到的输入、输出与中间变量。变量表是整套规则的字典:规则里能选到的变量,全部来自这里;对外接口的入参和返回值,也由这里的两个开关决定。
| 参数名称 | 描述 |
|---|---|
| 变量名 | 规则脚本里引用的名字,也是接口契约里的字段名。 |
| 类型 | 四选一,逐项说明见下表。类型决定值怎么被写进规则脚本、怎么被比较。 |
| 默认值 | 运行时该变量没有取到值时的兜底值。留空时按类型给零值(字符空串、整数 0、小数 0、布尔假)。 |
| 说明 | 口径解释,不参与执行。 |
| 输入开关 / 输出开关 | 决定这个变量在接口契约里的角色,四种组合逐项说明见下表。 |
变量类型逐项说明:
| 类型 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
| 字符 | 值被当文本处理,写进规则脚本时系统自动加单引号并转义;留空按空串处理。 | 结论、等级、渠道名这类文本口径,例如 decision = '拒绝'。 |
| 整数 | 值不加引号原样写进脚本,运行时按整数转换;留空按 0 处理。 | 逾期次数、申请笔数这类计数。 |
| 小数 | 运行时按高精度十进制转换,不是二进制浮点——所以不会出现 0.1 + 0.2 这种精度尾巴;留空按 0 处理。 | 负债率、通过概率、金额比率。 |
| 布尔 | 只认两个值:填 true 或 1 视为真,其余一律视为假。 | 黑名单命中、设备风险这类是非标记。但先读完下面这条提示。 |
重要提示: 布尔变量不要用"等于 / 不等于"去比。 规则引擎在比较时把脚本里的 TRUE / FALSE 当成普通文本处理,和真正的布尔值比一律不相等——后果是 if 某布尔变量 == TRUE 在该变量为真时也不会命中,而 if 某布尔变量 != TRUE 在任何取值下都会命中。这类错误不报错、只是结果不对,极难发现。两个可行的写法:1. 切到表达式模式,把布尔变量直接当条件用(if 某布尔变量 then …),不要写等号;2. 干脆把口径改成字符型,用 '是' / '否' 这样的取值。
输入 / 输出开关的四种组合:
| 组合 | 这个变量成了什么 / 运行时会发生什么 | 什么时候用 |
|---|---|---|
| 只开输入 | 进入接口的入参契约。运行时按调用方传进来的值做类型转换;没传就是没有,不会替它推断默认值。 | 消费方必须传进来的原始特征,如 age、debt_ratio、approveProb。 |
| 只开输出 | 进入接口的返回值契约。执行完从上下文取值放进返回体;若上下文里没有它,先用默认值兜底,默认值也为空时按类型给零值。 | 要还给消费方的结论,如 admission_score、decision。 |
| 两个都关 | 只在规则内部当临时量用,不出现在接口契约里。运行时同样会被预置默认值 / 零值。 | 算分过程中的中间累加值、临时标记。 |
| 两个都开 | 既是入参又是返回值:按传进来的值初始化,执行完(可能被规则改过)再回到返回体里。 | 想让消费方看到自己传进来的值在决策过程中被怎么改的。 |
注意: 这两个开关直接决定接口契约,是最常见的返工点。1. 忘开输入开关,消费方传了值也进不来——变量会被按默认值初始化,规则照跑,只是判断依据不对;2. 忘开输出开关,算出来的结论返回不出去,接口返回体里根本没有这个字段。建完变量先把这两列从头到尾核一遍,再去写规则。
第二步:写规则内容
在规则内容 Tab 添加规则。先记住这套结构,后面每一层都有自己的取值要选:
一个规则集 = 若干条规则(自上而下依次执行);一条规则 = 一个规则类型 + 若干个分支;一个分支 = 若干条件行(什么情况下命中)+ 若干动作行(命中了做什么)。
编写模式:结构化还是表达式
条件行和动作行各自都有一个模式开关,可以逐行分别切(分支这一层没有模式开关,不用找):
| 模式 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
| 结构化(默认) | 从下拉里选变量、选运算符、填值,系统负责拼脚本、加引号、按变量类型格式化。不用操心写法。 | 新用户一律先用这个,绝大多数规则用它就够。 |
| 表达式 | 直接手写一段规则脚本片段,系统原样拼进去(动作行选了"返回"而表达式没以 return 开头时,会自动补上 return )。 | 结构化表达不出来的逻辑:要用或(OR)、要判断在不在一组值里(IN)、要做模糊匹配(LIKE)、要用括号嵌套或函数嵌套时。 |
说明: 模式开关是按行生效的,切一行不影响别的行:某个分支的条件行改成表达式,同一条规则里的其他分支(包括后面的 ELSE IF / ELSE)照常编译、照常执行。所以一条规则里完全可以一部分条件行手写表达式、另一部分留结构化,不必为了用一次表达式就把规则拆开。
注意: 表达式里的字符串字面量必须用单引号(如 decision = '拒绝'),写成双引号会被当作变量名解析并报错。
规则类型:三选一
| 规则类型 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
| IF | 条件规则。按分支顺序编译成"如果…就…,否则如果…就…,否则…"。这是唯一会真正做条件判断的类型。 | 绝大多数场景。评分卡的每一条打分规则都是它。 |
| ASSIGN | 无条件赋值。系统只取第一个分支的动作,包成一个恒真条件执行——也就是"不管什么情况,都把这个变量设成这个值"。 | 初始化中间变量、给结论变量兜一个底值,放在规则链最前面。 |
| RETURN | 无条件返回。同样是恒真执行,执行到这条就中断整个规则集,后面的规则一律不再跑。 | 在规则链最后放一条兜底返回。 |
注意: 选了 ASSIGN 或 RETURN 之后,这条规则下的条件行不参与编译——界面上还能填,填了也没有任何作用,规则照样无条件执行。要带条件,规则类型必须选 IF。
分支类型:一条规则内部的多档判断
| 分支类型 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
| IF | 编译成"如果…就…"。条件留空时会被当成恒真,也就是无条件执行。 | 一条规则的第一个分支。 |
| ELSE IF | 编译成"否则如果…就…",接在上一个分支后面。可以有多个。 | 同一条规则里再加一档判断,例如分数分三段。 |
| ELSE | 编译成"否则…",不带条件。一条规则里只允许有一个。 | 该规则内部的兜底动作。 |
| ASSIGN 块 / RETURN 块 | 规则类型选了 ASSIGN 或 RETURN 时,系统自动生成的唯一分支,不带条件、也删不掉。 | 不用手工选,跟着规则类型走。 |
条件行:变量、运算符、值
一个分支里可以放多条条件行。多条条件行之间固定是"并且"(AND)——界面上没有切换"或"的地方。要表达"或",只能把这个分支切成表达式模式手写 OR。
结构化模式下的运算符逐项:
| 运算符 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
| 等于 | 见下方重要提示,当前不要用。 | —— |
| 不等于 | 判断变量不等于某个值。数值和字符都能正确判断;两边同时为空时判为"不成立"。 | 排除某个具体取值,如 渠道 != '线下'。 |
| 大于 | 按数值或字符自然序比较。 | 阈值判断,如逾期次数大于 3。 |
| 大于等于 | 同上,含边界。 | 评分卡里最常用的一档,如通过概率 ≥ 0.7。 |
| 小于 | 同上。 | 上限判断。 |
| 小于等于 | 同上,含边界。 | 含边界的上限判断,如负债率 ≤ 0.4。 |
重要提示: 结构化模式里的"等于"当前不生效,请改用表达式模式。 规则引擎认的相等写法是单等号,而结构化模式的"等于"生成的是双等号,引擎没有实现这一种;碰到它时,整个条件会退化成"看左边那个变量本身是不是真",于是 预警等级 等于 '红色' 在预警等级是 '绿色' 时照样命中。这条不报错、不告警,只是结果全错。正确写法:把这条条件行切成表达式模式,手写单等号,例如 warningLevel = '红色'。已经建好的规则集,请逐条检查有没有用到"等于",有就改掉并重新发布。
动作行:命中之后做什么
动作类型下拉里显示的是 ASSIGN 和 RETURN 两个英文取值(和规则类型下拉用的是同一套写法),含义如下:
| 动作类型 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
| ASSIGN(赋值) | 把一个值写进目标变量。一个分支里可以放多条赋值动作,会被打包成一组依次执行。 | 命中后给分数、结论这些输出变量赋值,如 admission_score = 90、decision = '通过'。 |
| RETURN(返回) | 中断整个规则集,后面的规则不再跑。一个分支里选了 RETURN 之后,其他动作会被顶掉,只保留这一个。 | "命中即返回"的优先级链——评分卡每条规则末尾都放一个。 |
动作类型选 RETURN 后,还要再选一个返回模式:
| 返回模式 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
| 无返回值 | 只中断执行,返回值为空;但此前赋过的输出变量照常出现在返回体里。 | 评分卡的常规写法——结论已经写在 admission_score / decision 上了,不需要再返回别的。 |
| 常量 | 中断并带回一个固定值,值按动作行上选的"值类型"格式化。 | 想让接口返回值字段带一个固定标记。 |
| 变量 | 中断并带回某个变量的当前值。变量名不能留空,留空发布时报"返回变量不能为空"。 | 想把某个中间量作为返回值单独带出来。 |
注意: 动作行右边那个值类型下拉(字符 / 整数 / 小数 / 布尔)只在"RETURN + 常量"这一种情况下真正生效。做 ASSIGN 赋值时它不起作用——系统看的是目标变量在变量表里声明的类型,不是这里选的。所以给一个"小数"变量赋值时,即便这里选了"字符",值也不会被加引号。另外数值类型的值不做合法性校验:填了非数字不会报错,而是被当成另一个变量名去解析,结果不对但不提示。填值时看准目标变量的类型。
以信贷评分卡 credit_admission_score_v1 为例,4 条规则按优先级从上到下、命中即 return:
- R01 高风险拒绝: 逾期次数 ≥ 3 或 负债率 ≥ 0.7 →
admission_score = 20,decision = '拒绝',return。 - R02 优质通过: 通过概率 ≥ 0.7 且 负债率 ≤ 0.4 →
admission_score = 90,decision = '通过',return。 - R03 人工复核: 通过概率 ≥ 0.5(落在中间地带)→
admission_score = 65,decision = '人工复核',return。 - R04 兜底拒绝: 通过概率 < 0.5(以上都不命中)→
admission_score = 40,decision = '拒绝',return。
说明: R01 的条件是"逾期次数 ≥ 3 或 负债率 ≥ 0.7",带一个"或"。结构化模式的多条条件行之间固定是"并且",所以 R01 这一条得把条件行切成表达式模式,写成 overdue_count >= 3 OR debt_ratio >= 0.7;切的只是这一行,这条规则要再挂 ELSE IF / ELSE 分支照样可以。R02~R04 都是单条件或双条件"并且",用结构化模式即可。
内置函数库
规则脚本可以调用 18 个内置函数,在规则内容里点函数说明能看到用法面板。逐个说明如下:
| 函数 | 作用 | 用法要点 |
|---|---|---|
SUM | 求和 | 忽略空值;全部为空时返回空。常用来把多个分项累加成总分。 |
MAX | 取最大值 | 忽略空值;全部为空时返回空。 |
MIN | 取最小值 | 忽略空值;全部为空时返回空。 |
ABS | 绝对值 | —— |
EXP | 自然指数(e 的多少次方) | 概率变换时用。 |
INT | 转成整数 | —— |
FLOOR | 向下取整 | —— |
ROUND | 四舍五入 | 第二个参数是舍入单位(不是小数位数),默认 1;传 0 会报错。要保留两位小数写 ROUND(x, 0.01)。 |
CATS | 拼接字符串 | 自动跳过空值。常用来拼"命中规则编码串"。 |
SUBSTR | 截取子串 | 起始位从 1 开始;起始位传 0 会报错。 |
SUBSTRN | 安全截取子串 | 与上一个的区别:遇到缺失值或越界不报错,返回空串。不确定长度时用它更稳。 |
TRANWRD | 替换子串 | —— |
COMPRESS | 压缩字符 | 默认删掉所有空格;也可以指定要删的字符集。 |
INDEX | 查子串位置 | 位置从 1 开始,找不到返回 0。判断"包含"可以用 INDEX(x, 'BL') > 0。 |
MISSING | 判断是否为空 | 为空返回真,否则返回假。用来判断上游到底给没给这个字段。 |
RAND | 按分布生成随机数 | 支持均匀、正态、伯努利、二项四种分布:正态要传均值和标准差,伯努利要传概率,二项要传次数和概率。 |
RANUNI | 生成 0 到 1 之间的随机数 | 可传一个整数种子。 |
CALL_MODEL | 在规则内部直接调用一个已发布的模型 | 见下方提示。 |
注意: 两个随机数函数会让同一笔请求两次跑出不同结果,不要放进正式打分逻辑,只在做抽样、灰度打标时用。
重要提示: CALL_MODEL 只接受一个参数——发布记录的标识,不是模型名。这个标识要去模型详情页的发布历史 Tab 里取。调用时平台把当前所有变量整体发给模型运行时,拿回来的输出会直接合并进当前变量上下文(也就是说模型的输出变量可以在后面的规则里直接引用),函数本身返回真;模型调用失败会中断整个规则集。另外界面上的函数说明面板没有收录这一条,查不到它的用法属于正常——用法就是这一段。规则流里的模型节点,编译出来也是这个函数调用。
表达式模式可用的运算符
切到表达式模式手写时,可用的运算符就这些,别的写法会在发布时报语法错:
| 运算符 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
= | 相等判断。两边同时为空时判为相等。 | 表达式里做相等判断一律用这个单等号。 |
!= / ^= | 不等判断,两种写法等价。两边同时为空时判为不成立。 | 排除某个取值。 |
== / <> | 不要用。 这两种写法语法上能过,但引擎没有对应的比较实现,条件会退化成"看左边那个变量是不是真",结果全错且不报错。 | —— |
> >= < <= | 大小比较,支持数值和字符自然序。 | 阈值判断。 |
IN / NOT IN | 判断在不在一组值里,写成 变量 IN ('A', 'B')。 | 枚举值白名单 / 黑名单,比写一串 OR 干净。 |
LIKE | 模糊匹配,用 % 通配:'%BL%' 表示"包含 BL"。 | 字符串包含判断。 |
NOT LIKE | 不可用,见下方提示。 | —— |
AND / OR | 逻辑与 / 或,带短路求值(左边已经定胜负就不算右边)。任一边取不到值时结果按"不成立"处理。 | 多条件组合。结构化模式只支持"并且",要用"或"必须来表达式模式。 |
NOT | 逻辑非,写在条件前面。 | 取反,如 NOT (v LIKE '%x%')。 |
+ - * / | 加减乘除。内部统一用高精度十进制,不会有浮点误差;任一边为空则结果为空。 | 在表达式里现算一个中间值。 |
% | 不要用。 取余符号在语法上认得,发布也不报错,但引擎没有实现这一步运算——写了 a % b 会原样返回左边那个数,和 == / <> 属于同一种静默退化。 | —— |
注意: NOT LIKE 在规则脚本里不成立,写了会直接抛语法错、发布失败。要表达"不包含",写成 NOT (变量 LIKE '%关键词%'),把 NOT 单独放在括号外面。
第三步:保存、发布、导出
点保存,再点发布填写模型发布名,规则集即成为可调用的打分模型。可点导出留存规则清单(表格文件)。
验证: 发布后进入测试 Tab,分别用"高逾期""优质""边缘"几种画像各跑一条:若逾期 4 次的样本命中 R01 返回 20 分 / 拒绝、优质样本命中 R02 返回 90 分 / 通过,说明优先级链与赋分逻辑串对了。
注意: 发布前请把这三条再核一遍:1. 表达式里的字符串字面量必须用单引号,双引号会被当作变量名解析并报错;2. 相等判断只能在表达式模式里用单等号 =——结构化模式的"等于"不生效(见"条件行"那一节的重要提示);3. 要用"或"(OR)、"在不在一组值里"(IN)、模糊匹配(LIKE)这类写法,得把对应的条件行切成表达式模式,结构化模式的运算符下拉里没有它们。
说明: 发布前会做语法 / 引用校验,不通过会当场报错并拒绝发布;发布成功即为 ACTIVE 生效版本。回到规则内容修正语法或引用问题后再重新发布即可。
4.6 规则流(决策流):把多段逻辑编排成一条链
单个规则集或单个模型往往不够。真实决策是"先算概率、再判规则、再分流"这样多段串联的。规则流就是把这条链画出来。
规则流(决策流)把"取数 → 跑模型 → 过规则 → 出结论"编排成一条可视化的有向流程,链式串接多个规则集、规则流、模型节点,是决策资产的编排形态。
打开侧边导航栏,在决策引擎 → 规则流里找到规则流列表。这个页面解决的是"我有哪些编排好的链路"的问题:内容树里只看规则流的过滤视图,左选目录、右列规则流,行操作有打开 / 编辑 / 删除 / 接口。工具条上同样有生成示例(需 content:ruleflow:seed),可以灌一批现成的示例规则流照着看;这个按钮支持重建,重复点会覆盖示例、不会越灌越多。
点打开进详情页,6 个 Tab:
| Tab | 干什么用 |
|---|---|
| 规则流内容 | 可视化编排画布,拖节点、连线、配分支。核心工作面。 |
| 变量表 | 这条流用到的全部变量,标输入 / 输出,并显示每个变量是哪个节点带上来的。 |
| 版本控制 | 新建版本、激活历史版本。用法见 4.10。 |
| 测试 | 测试组批量跑,另有"示例验证"。用法见 4.11。 |
| 基础信息 | 名称、备注这类实体属性。 |
| 发布历史 | 每次发布的记录与接口契约。见 4.10。 |
涉及该操作的功能权限:内容实体的新建 / 编辑;发布需 content:ruleflow:publish,测试需 content:ruleflow:test。
- 进入规则流详情页,点编辑进入编辑态。
- 从左侧内容树拖入节点,或在画布上右键选新增内容 / 新增分支添加节点。
- 用连线把节点按执行顺序串起来(START → 模型 → 规则 → END)。
- 点中某个内容节点,在右侧属性面板里为它选择具体的版本(未发布版本会带标记),必要时可替换内容。
- 点保存,再点发布。可导出流程图。
节点类型逐项说明
画布上一共六种节点。开始和结束是画布自带的,其余四种靠拖入或右键新增:
| 节点类型 | 是什么 / 放上去会发生什么 | 什么时候用 |
|---|---|---|
| 开始 | 流程的唯一入口,自带、不可删。它本身不产生任何执行逻辑,只用来确定"第一步走哪个节点"。缺了它发布时报"规则流缺少开始节点"。 | 固定存在,不用手工加。 |
| 结束 | 流程的出口,走到这里链路就结束了。 | 固定存在。每条分支路径都要接到一个结束节点,否则那条路会走到一个空返回上,输出只剩默认值。 |
| 规则集节点 | 把被引用的那一版规则集的规则内容整段展开进当前流程一起执行(不是远程调用)。不指定版本就用该规则集当前的生效版本;取不到可用版本时报"规则集不存在可用版本"。 | 要在流程里跑一段规则判断时。 |
| 子规则流节点 | 把被引用的整条规则流递归展开进来。系统带循环引用检测,互相引用会报"规则流存在循环引用"。 | 复用一段已经编排好的公共链路,例如"通用反欺诈前置校验"。 |
| 模型节点 | 编译成一次模型调用。运行时模型的输出会直接合并进流程变量,下游的规则集节点可以直接引用模型算出的概率。 | "先算概率、再判规则"的经典串联。 |
| 分支节点 | 按某个变量的取值把链路岔开。每加一条条件,节点上就长出一个出口端口。没配条件报"分支节点未配置条件";没选分支变量报"分支变量未配置"。 | 按分数段、按结论、按渠道分流。 |
注意: 1. 模型节点引用的那一版模型必须已经发布过,否则发布规则流时报"模型版本未发布: 模型名@版本号"——先去把模型发了再来编排;2. 除分支节点外,其余节点只允许有一个出口,不小心连了两条线,发布时报"节点存在多个出口";3. 链路不能成环,成环报"规则流存在闭环节点"。
分支节点的条件运算符
选中分支节点后,右侧属性面板里先选一个分支变量,再一条条加条件。可选的运算符随分支变量的类型变化:
下拉里的比较运算符是符号(= != > >= < <=),集合与文本类的才是中文词,别按中文去找符号那几档:
| 运算符 | 适用的变量类型 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|---|
= / !=(等于 / 不等于) | 整数、小数、字符、布尔 | 判断变量等于 / 不等于填的那个值,值会按变量类型自动格式化。 | 最常用。字符型和数值型上工作正常。 |
> / >= / < / <= | 整数、小数 | 数值比较。 | 按分数、概率、金额分档。 |
| 属于 / 不属于 | 整数、小数、字符 | 值填多个、用英文逗号分隔,判断在不在这组值里。值留空报"分支条件值不能为空"。 | 把若干个离散取值归到同一条路上,例如渠道 A、B、C 走同一条。 |
| 介于 / 不介于 | 整数、小数 | 值填两个、用逗号分隔,是闭区间(含两端)。不足两个值报"介于条件至少需要两个值"。 | 分数段分档,如 60,80。 |
| 包含 | 字符 | 判断字符串里含不含填的那段文字。 | 结论文本里含某个关键词就走这条路。 |
| 不包含 | 字符 | 不要用,见下方提示。 | —— |
重要提示: 分支条件里的"不包含"用不了,选了会导致规则流发布失败。 它编译出来的写法在规则脚本里不成立,一点发布就抛语法解析错误。两个替代做法:1. 改用包含,再把这个出口和默认出口对调(满足包含的走原来的"否"那条路);2. 把这段判断挪进规则集,用表达式模式写成 NOT (变量 LIKE '%关键词%')。
注意: 分支变量的类型选布尔时,运算符下拉里只剩 = 和 != 这两个,但它们对布尔判断不生效——引擎把真假值当文本比,= 真 永远不命中、!= 真 永远命中,且不报错。也就是说布尔分支怎么配都判不对。布尔口径请改成字符型,用 '是' / '否' 这类取值来分流。
默认分支
| 出口 | 是什么 / 会发生什么 | 什么时候用 |
|---|---|---|
| 默认分支 | 分支节点自带的一个出口,承接"不满足上面任何一条条件"的输入,编译成整条判断链最后的"否则"。 | 每个分支节点都应该把它接出去,保证任何输入都有出路。 |
注意: 默认分支不接的话,不满足任何条件的那批输入会走到一个空返回上直接结束,输出变量只剩默认值——链路看着跑通了,结果却是空的。
变量表与变量来源
规则流的变量表会把各节点带上来的变量汇总在一起,并在"来源"列标明每个变量是谁带来的:
| 来源 | 是什么 | 怎么用 |
|---|---|---|
| 来自规则集节点 | 这个变量是画布上某个规则集节点的变量表带上来的,标签显示那个规则集的名字。 | 只读信息,用来回答"这个变量是哪来的"。 |
| 来自子规则流节点 | 来自被展开进来的子规则流的变量表。 | 同上。 |
| 来自模型节点 | 来自模型的输入特征或输出标签的绑定变量。 | 同上——模型算出的概率就是靠它进入流程的。 |
| 自建 | 在变量表里手工加的,不属于任何节点。 | 需要一个纯粹的流程级中间量时自己加一个。 |
注意: 同名但类型不同的变量会被标成类型冲突,变量表下方出现一组红色标签列出冲突项。但这只是提示,不会拦住保存、也不会拦住发布——冲突真正发作是在执行的时候:类型对不上的分支条件会安静地算出错误结果。看到红色冲突标签就当场统一类型,别留到上线后。
验证: 编排完成后,到详情页测试 Tab,用自动生成或 CSV 测试组批量跑;规则流另有示例验证,一键跑内置样例并对比"期望值 / 实际值",可下载结果 JSON。若期望与实际一致,说明这条链路串对了。
注意: 1. 模型节点必须选已发布过的模型版本,未发布的版本在下拉里会带标记,选了它规则流一发布就报"模型版本未发布"——先去把模型发了再来编排;2. 变量类型冲突只是红字提示,不拦保存也不拦发布,得靠人自己统一类型(见上一小节);3. 改完任何节点都要重新发布这条流,否则线上跑的还是旧版;4. 规则流切换版本前要先保存当前编辑,编辑态下不能新建或切换版本。
4.7 打分流程(任务流):面向对外消费的实建形态
规则流适合在设计态把决策逻辑编排清楚。但当决策服务要对外给没有平台账号的第三方消费、且必须走网关治理时,实建上更常用任务流——用两个 HTTP 调用节点把"调模型"和"调规则集"链式串起来。
打分流程是用任务流实现的对外打分服务:START → ml(HTTP 调用模型)→ rule(HTTP 调用规则集)→ END,把特征算成 approveProb,再算成准入分与决策。 节点用任务配置绑定入参,用响应字段解析输出。
说明: 为什么对外用任务流而不是规则流?因为对外消费方无平台账号、要走网关治理。任务流的同步运行接口会把执行身份切成一个专用的打分服务账号、并校验网关共享密钥头,比规则流更适合承接对外调用。产品里的"决策流"(4.6)与这里的"打分流程"是两个不同的"流",切勿混用。
重要提示: 打分服务账号是最小权限身份,不是特权身份——它要读中台数仓的哪张表,就得像普通人一样被显式授权到那张表,读到明文还是掩码同样按第二章 2.5.2 的口径判定。搭新打分流时忘了给它授权,表现是流程跑到取数那一步失败,而不是模型算错。
涉及该操作的功能权限:任务与编排的新建 / 编辑 / 发布。
任务流没有单独的"工作流"菜单。打开侧边导航栏,在数据中台 → 数据开发下操作:任务本身在任务开发里建,把任务串成链路在任务编排里画。
- 进任务开发,建两个 HTTP 调用 任务:
ml指向模型执行端点、rule指向规则集执行端点。 - 进任务编排新建一条编排,按 START →
ml→rule→ END 把两个任务连成一条链路。 - 在节点的
nodeConfig.outputBindings里,把任务输出映射成流变量——这是链式串接的关键。 - START 用 inputBindings 声明流入参、END 用 outputBindings 声明流出参。
- 发布这条编排。
注意: 任务编排画布的候选任务列表当前把 HTTP 调用类型过滤掉了——画布上拖得出来的是数据加工类任务。所以这条打分链路的两个 HTTP 节点在画布上选不到,搭建时请联系实施人员按上面的口径配好再发布;链路配好之后的发布、运行、排障,和普通编排完全一样,后文照读即可。
在任务开发里新建任务时要选一个任务类型,一共五种。搭打分流程只用第一种,其余四种属于数据开发域,列在这里是为了在下拉里认得出:
| 任务类型 | 是什么 / 选了要配什么 | 什么时候用 |
|---|---|---|
| HTTP 调用 | 发一次 HTTP 调用。要配:目标路由、请求体绑定、请求头绑定(如鉴权头)、响应字段解析(声明输出编码 + 从返回体的哪个路径取值)。 | 搭打分流程就靠它——一个节点打模型执行端点、一个节点打规则集执行端点。 |
| SQL 任务 | 执行一段 SQL。 | 打分前先取一批特征落表。 |
| 指标提取 | 按指标定义抽取指标值。 | 把 4.3 建好的指标口径接进链路。 |
| 离线同步任务 | 跑一次离线数据同步。 | 数据开发域用,打分流程一般用不到。 |
| 子编排 | 复用另一条已经编排好的流程。 | 公共链路抽出来复用。 |
说明: 画布上还有开始、结束、分支三种节点,那是编排用的画布节点,不出现在任务类型下拉里,也不需要配任务参数。
HTTP 调用节点有两种请求体形态,别混:一种吃扁平请求体(直接 {"age":35,...}),一种吃 {"inputs":[{"name":"age","value":35}, ...]} 结构;两者的响应统一从 data.outputs 里按输出名取值(如 data.outputs[name=approveProb].value)。
流程发布后有两个运行端点,职能不同,别混:
| 运行方式 | 是什么 / 调了会发生什么 | 什么时候用 |
|---|---|---|
| 异步运行(run) | 提交后立刻返回一个实例标识(instanceId),实际执行在后台跑。拿这个标识去运行记录里,可以逐节点展开看输入输出。 | 自测和排障——搭完流程自己验一遍、看是哪个节点断的。 |
| 同步运行(run-api) | 同步等结果返回。返回体里除了结束节点声明的输出之外,还带 instanceId / success / status 等平台信封字段。这个入口会把执行身份切成专用的打分服务账号,并校验网关共享密钥头。 | 对外发布——数据网关的对外路由重写到的就是它。 |
注意: 对外路由如果没有注入网关鉴权头,同步运行端点会直接报凭证校验失败——这个密钥只有网关持有,消费方不需要也拿不到。
验证: 发布后用异步运行(run)跑一条自测,拿 instanceId 到运行记录里展开看每个节点的输入输出:确认 ml 节点产出了 approveProb、rule 节点吃到 approveProb 并给出 admission_score 与 decision,即链路串通。
重要提示: 链式串接靠节点的 nodeConfig.outputBindings,不是靠任务本身的请求体绑定——这是最容易改错的地方。若不设 outputBindings,上游 ml 节点的输出会被自动加前缀(如 mlApproveProb),下游 rule 节点按 approveProb 取值就取不到,报"任务输入缺少必填字段"。
4.8 发布成对外 API:让第三方一次调用拿决策
决策逻辑编排好、能跑了,下一步是让下游系统真正调得到它。这一步是"决策引擎负责算、数据网关负责放行"的交接点。
模型 / 规则集 / 规则流 / 决策流发布后,先生成平台内部执行端点;要给第三方消费,再到数据网关发一条对外路由,绑定应用与 apiKey,消费方一次 HTTP 调用即拿决策。
涉及该操作的功能权限:内容资源的发布权限 + 网关路由 / 应用的管理权限。
- 拿内部端点: 在内容详情页点发布,填模型发布名,得到形如
/model/model/<模型名>/execute的平台内部执行地址——它经平台网关可直接调用,地址里出现两段/model:前一段是网关路由前缀、后一段是运行时控制器基路径,不是笔误。 - 建对外路由: 进数据网关新建一条路由(如
/score/credit),关键字段见下,重写(rewrite)到流程的同步运行端点,并在请求头规则里注入网关鉴权头,最后把状态改为已发布。 - 建应用取密钥: 新建一个应用,拿到应用标识(X-APP-ID)与应用密钥(X-API-Key),并把这条路由显式绑定给该应用授权。
- 消费: 消费方带上
X-APP-ID+X-API-Key调网关地址即可。
| 参数名称 | 描述 |
|---|---|
| 路由类别 category | 对外接口填 api,且必须同时配置 apiConfig;缺 apiConfig 报"API路由必须配置API参数"。 |
| 重写(rewriteMode) | 把外部路径重写到内部同步运行端点(流程的 run-api)。 |
| 请求头规则(headerRules) | 注入网关鉴权头(如 X-Gateway-Auth: <网关共享密钥>),用于内部校验来源合法。 |
| 授权应用 | 路由必须显式绑定授权应用;未绑定一律拒绝(fail-closed),且跨应用不能互相调用。 |
| 消费头 | X-APP-ID + X-API-Key;缺 X-APP-ID 报"缺少应用标识"。 |
一次成功的对外调用示例:
curl -X POST 'https://<数据网关地址>/score/credit' \
-H 'X-APP-ID: <应用标识>' \
-H 'X-API-Key: <应用密钥>' \
-H 'Content-Type: application/json' \
-d '{"age":35,"monthly_income":25000,"debt_ratio":0.2,"overdue_count":0}'返回:
{"code":200,"msg":"操作成功","data":{"outputs":{"decision":"通过","admission_score":"90.0","approveProb":"0.744778"},"instanceId":"...","success":true,"status":"SUCCESS"}}说明: 返回体是平台统一信封,不是扁平结构。业务输出在 data.outputs 下(decision / admission_score / approveProb),外层 data 还带 instanceId / success / status 等平台字段;code / msg 为最外层调用状态。
消费方只传原始特征,平台内部先用模型算概率、再喂规则集出分,最后把结论返回。
验证: 用上面的 curl 发一次请求,能在 data.outputs 下拿到含 decision / admission_score / approveProb 的返回,三者均为字符串值、approveProb 是一个正常小数(非科学计数),即对外链路已放行、算分正确。
注意: 1. 对外路由不注入网关鉴权头,同步运行会报"网关调用凭证校验失败"(该密钥只有网关持有);2. category=api 必须配 apiConfig;3. 路由必须显式绑定授权应用,否则拒绝调用;4. decision / admission_score / approveProb 三个输出均以字符串返回,概率最多 6 位小数、无科学计数法;消费端如需数值请自行 parseFloat。
4.9 在线试调与自动接口文档:发布后怎么调,页面自解释
以前一个模型发布后,消费方要问建模同学"接口地址是啥、传什么参数、返回长什么样"。现在不用问了——列表页操作列有一个接口按钮,点开就是一份自解释的文档加一个能当场发请求的试调面板。这是本版的核心新功能。
模型 / 规则集 / 规则流列表的操作列里都有一个「接口」按钮,点开弹出"接口调用文档 + 在线试调"弹窗:自动生成接口地址、方法、入参表、出参表、curl 示例,并可直接填参发请求看返回。
涉及该操作的功能权限:内容实体的查看(content:entity:query)——这一项只管打开弹窗看文档;弹窗里点发送请求要另外持有 content:model:execute,缺它会被拒。
- 在模型 / 规则集 / 规则流列表里,某行点操作列接口按钮。
- 系统按该内容的 entityId 拉取最近一条发布记录,自动生成文档:接口地址(POST,形如
/model/model/<模型名>/execute——前/model是平台网关路由前缀、后/model是运行时控制器基路径)、模型名、请求头(Authorization Bearer)。 - 弹窗上半部是文档,下半部是试调:入参区按发布契约(inputSchema)自动生成请求体;没填的字段按类型自动填一个随机样例值,方便新用户直接试。
- 点发送请求,系统用当前登录态调平台内部执行端点,展示 JSON 返回;可点复制 curl 把调用命令拷走。
入参区里没填的字段,系统按该字段声明的类型自动补一个样例值,规则逐项如下:
| 字段类型 | 自动填成什么 | 说明 |
|---|---|---|
| 布尔 | 随机的真或假 | 只为让请求能发出去。 |
| 整数(含长整数) | 0 ~ 99 之间的随机整数 | 同上。 |
| 小数(含高精度小数、通用数值) | 0 ~ 100.0 之间、保留一位小数的随机值 | 概率类字段会被填成一个远超 1 的值,试调结果不代表真实打分。 |
| 日期、时间 | 一个固定的示例日期 | 同上。 |
| 其他(字符及未识别类型) | 字符串 test | 同上。 |
注意: 这些值是为了让请求发得出去才补的,不带任何业务含义。要验证阈值对不对、结论准不准,请把入参手工改成真实画像的值,或者干脆去详情页的测试 Tab 用测试组批量跑(见 4.11)。
验证: 点发送请求后弹窗下半部展示一段 JSON 返回,含该内容声明的输出字段(如 admission_score / decision),即说明发布契约、执行端点、登录态令牌三者贯通,该资产已可被消费。
注意: 只有查看权限的账号点得开弹窗、点不动发送请求。 文档、curl 示例、入参表都能看,但一按发送请求就会被挡下——发起调用要的是 content:model:execute,和查看不是同一项。给"应用开发者"这类只读账号配角色时,记得把这一项也带上,否则试调面板等于半瘫。
注意: 弹窗里的试调用的是平台内部端点 + 当前登录态令牌,仅供开发者自测;对外正式消费仍要走网关路由 + apiKey(见 4.8,弹窗内也有醒目提示说明)。未发布的内容点接口会显示"该内容尚未发布",请先完成发布。
说明: 内部执行端点有两种请求体形态,别混:/model/model/<名>/execute 只接受 {"inputs":[{"name":...,"value":...}]} 数组,直接 POST 扁平体会报"缺少模型输入变量";/model/model/<名>/execute/simple 才吃扁平 Map。§4.8 给出的扁平示例入参仅适用于对外网关路由(经任务流转换后再落到内部端点),不能直接打内部 /execute。
4.10 版本控制与发布历史:让线上跑的是确定的一版
决策规则会不断迭代——今天把逾期阈值从 3 改成 2,明天调整概率门槛。若不做版本管理,谁也说不清此刻线上跑的到底是哪一版、出了问题怎么回滚。
每个决策内容实体都有版本管理:同一时刻只有一个生效版本,其余都是归档的历史版本;可新建版本、激活(把某个历史版本切回生效)、删除;发布与测试都基于当前选定的版本。 模型、规则集、规则流共用同一套版本面板。
先理清一件事:生效版本同时就是草稿。 详情页里点"保存"写的就是当前生效版本,系统不会另外生成一条草稿记录——也就是说,改了还没定版的内容,是直接压在生效版本上的。想留一个改之前的快照,做法是先点"新建版本"。
涉及该操作的功能权限:内容实体的编辑,以及对应内容的版本权限(content:ruleset:version / content:ruleflow:version / content:model:version,激活对应 activate)。
- 进详情页版本控制 Tab。
- 填主版本.副版本 + 说明,点新建版本。系统会新建一条版本记录、把当前生效版本的内容整份复制进去,然后把新版本切成生效、把原来那版置为归档。所以新建版本的效果是"给现状打个快照并继续往下改",不是"清空重来"。
- 列表里对某个历史版本点激活,可以把它切回生效(原来的生效版本同时被归档),这就是回滚;点删除移除不再需要的版本。
| 参数名称 | 描述 |
|---|---|
| 主版本 / 副版本 | 版本号,形如 1.0、1.1、2.0。同一个实体内不能重复。 |
| 版本说明 | 这一版改了什么,回滚时全靠它辨认。建议写清楚,别留空。 |
| 状态 | 见下方逐项说明。 |
版本状态逐项说明:
| 状态 | 是什么 / 能做什么 | 什么时候出现 |
|---|---|---|
| 生效 | 当前正在被编辑、被发布、被测试的那一版,同时就是草稿。一个实体同一时刻只有一个。 | 日常编辑改的就是它。 |
| 归档 | 历史版本,保留的是被归档那一刻的内容快照。可以点"激活"把它切回生效。 | 新建版本时,原来的生效版本被自动置成归档。 |
说明: 系统在版本状态上还预留了一个"草稿"档,但没有任何操作会把版本置成它,界面上也见不到——编辑中的内容就压在生效版本上,不存在独立的草稿版本行。看到版本列表里只有"生效"和"归档"两种,属于正常。
验证: 新建版本后,版本列表多出一行历史版本;对它点激活,该行标记为生效版本,再去发布 / 测试时默认用的就是这一版,即版本切换生效。
发布历史与执行契约
发布历史 Tab 记录每一次发布:发布名称、版本、执行地址、发布时间,以及该版本的输入 / 输出 schema(点弹窗查看变量名 / 类型 / 默认值 / 输入标记 / 输出标记)。这份记录正是「接口」文档和策略实验室挂模型版本的数据来源。
| 参数名称 | 描述 |
|---|---|
| 发布记录列 | 发布名称(modelName)/ 版本(主.副)/ 执行地址(executeUrl)/ 发布时间 / 模型输入输出。 |
| schema 项 | name(变量名)/ varType(类型)/ defaultValue(默认值)/ inputFlag(输入标记)/ outputFlag(输出标记)。 |
三类内容点"发布"时,平台在背后做的事不一样,但落下来的记录结构是同一套:
| 发布的是 | 平台在背后做了什么 |
|---|---|
| 规则集 | 把规则内容编译成一段规则脚本,交给规则引擎做编译缓存;发布记录里存的是编译产物。 |
| 规则流 | 把整条流(含展开进来的规则集、子规则流、模型调用)编译成一整段规则脚本,同样交给规则引擎。 |
| 模型 | 把模型文件登记成一份运行时快照,由服务端在进程内加载执行,不产生规则脚本。 |
说明: 上面这一列是发布时按内容类型自动判定的,界面上没有让人选的地方,也不需要配。
说明: 发布记录里的 executeUrl 存的是运行时服务内基路径 /model/<模型名>/execute;「接口」弹窗据此在前面补上平台网关前缀 /model,拼成消费方可直接调用的 /model/model/<模型名>/execute。模型 / 规则集 / 规则流三类共用同一套发布记录结构,所以「接口」弹窗对三类通用;执行地址与输入 / 输出 schema 让下游(网关、任务流 HTTP 调用、实验室、接口试调)都能自动对齐参数。
注意: 1. 编辑态不能新建或切换版本,须先保存;2. 生效中的版本不可删除,会提示"生效版本不可删除"——要删它先激活另一个版本;3. 规则流切版本前要先保存;4. 同一实体内版本号不能重复;5. 机器学习模型新建版本时,模型文件、输入输出契约、建模训练画布会自动一并复制到新版本,不需要手工搬。
4.11 测试能力:发布前批量验证
一条规则改完,不能只凭一个例子就上线——要覆盖优质、高逾期、高负债、边缘等多种画像,才敢发布。
模型 / 规则集 / 规则流详情页都有「测试」Tab:把多条用例组成"测试组"批量跑,结果按输入 / 输出字段展开逐样本对比,并给每个组标一个状态。
涉及该操作的功能权限:content:model:test(模型)/ content:ruleset:test(规则集)/ content:ruleflow:test(规则流)。
- 进详情页测试 Tab,两种方式建测试组:
- 填用例数点生成测试组:系统按输入变量类型随机造值。
- 点上传 CSV:首行列名映射到输入变量,按变量类型(整数 / 小数 / 布尔 / 字符)解析每列。
- 点测试批量执行。
- 点查看展开对比表:输入列、输出列、返回标识、返回值、耗时、错误信息逐样本罗列。
测试组表格的列:序号 / 测试组 / 来源 / 用例数 / 状态 / 最近测试。其中"来源"和"状态"两列的取值逐项如下。
来源 —— 决定这组用例是怎么来的,也决定它能验证什么:
| 来源 | 是什么 / 怎么产生 | 什么时候用 |
|---|---|---|
| 自动生成 | 填一个用例数,系统按每个输入变量的类型随机造值,组名形如"自动生成-N条"。 | 想快速验证链路通不通:接口能不能调通、变量有没有断。随机值不带业务含义,不能拿它验证阈值对不对。 |
| CSV 上传 | 上传一个 CSV,首行当列名映射到输入变量,按变量类型(整数 / 小数 / 布尔 / 字符)逐列解析每行值,组名形如"CSV导入-文件名"。文件至少要有表头加一行数据,否则报"CSV 至少需要表头和一行数据"。 | 要覆盖优质 / 高逾期 / 高负债 / 边缘这些真实画像时——发布前该跑的是这一种。 |
状态 —— 这一列是系统按最近一次执行结果算出来的,不用手工维护:
| 状态 | 含义 | 该做什么 |
|---|---|---|
| 空 | 这个组里还没有用例。 | 补用例,或者删掉这个空组。 |
| 待测试 | 有用例,但还没跑过。 | 点"测试"跑一遍。 |
| 存在失败 | 跑过,且至少有一条用例报错。 | 展开看错误信息,定位是哪条规则或哪个特征的问题。 |
| 成功 | 全部用例都跑通了。 | 可以进入发布环节——但"跑通"只代表没报错,返回值对不对还得人看。 |
验证: 若某样本返回值与预期不符,展开该行看输入与输出,即可定位是哪条规则或哪个特征出了问题,修正后重测;直到全部样本状态为"成功"、返回值也符合预期,才具备发布条件。
注意: 1. 编辑态不能测试,先保存;2. 测试跑的是当前选定的版本,切了版本要重测;3. 测试接口要求的是可写级别的权限(和发布同级)——只有查看权限的账号点测试会被拒,这不是故障;4. 规则流除测试组外还有示例验证,跑内置样例并对比"期望值 / 实际值",可下载结果 JSON,适合做回归校验。
4.12 策略实验室:A/B 对比选型
策略同学想验证"把评分卡换成机器学习模型,通过的人群会怎么变",但绝不能拿线上决策做实验。策略实验室提供一个与生产解耦的隔离环境,专门用来比对不同策略。
4.12.1 沙盒空间:A/B 的前置隔离环境
沙盒是面向策略运营的自助 A/B 环境。创建沙盒等于快照克隆当前整棵内容库,沙盒内可任意改 / 发布 / 测试,不碰生产,并支持到期自动销毁。
打开侧边导航栏,在决策引擎 → 策略实验室里找到沙盒列表。这个页面解决的是"上哪儿找一个能随便改的环境"的问题:每一行是一个沙盒,行操作有进入 / 删除,还支持批量删除。涉及该操作的功能权限:lab:sandbox:query(查看)/ lab:sandbox:create(创建)/ lab:sandbox:remove(删除)。
- 点创建沙盒,填名称、说明、自动销毁时间。
- 点沙盒名进入沙盒空间(地址带 sandboxKey),在里面建实验。
| 参数名称 | 描述 |
|---|---|
| 名称 / 说明 | 沙盒标识与用途,给自己和同事看的。 |
| 自动销毁时间 | 决定这个沙盒什么时候被自动回收,逐项说明见下表。默认选中的是 7 天。 |
| 唯一标识(sandboxKey) | 沙盒的程序标识,由系统生成;进入空间、查沙盒里的模型树都靠它。 |
自动销毁时间逐项说明:
| 取值 | 是什么 / 选了会发生什么 | 什么时候用 |
|---|---|---|
| 24 小时 | 从创建时刻起算 24 小时后到期。 | 只想验一个当天就有结论的小问题。 |
| 3 天 | 同上,3 天。 | 一次短周期比对。 |
| 7 天(默认) | 同上,7 天。 | 常规实验周期,拿不准就用这一档。 |
| 30 天 | 同上,30 天。 | 跨月的长周期选型。 |
| 自定义 | 自己挑一个具体时刻。不填会提示"请选择自定义销毁时间";填的时刻必须晚于当前时间,否则报"自动销毁时间必须大于当前时间"。 | 实验周期不规则、要卡在某个评审日之前时。 |
| 永久 | 不设到期时间。到期回收任务因此永远扫不到它,沙盒常驻占用资源,只能人工删。 | 长期保留的基准环境。不建议默认选它。 |
沙盒状态逐项说明 —— 列表"状态"列的四种取值:
| 状态 | 是什么 / 什么时候出现 | 该做什么 |
|---|---|---|
| 创建中 | 沙盒记录已经建好,正在把整棵内容树克隆一份出来。 | 等一会儿刷新。 |
| 运行中 | 克隆成功,内容树已就位。 | 正常可用,点进去建实验。 |
| 创建失败 | 克隆过程出错,记录留下但沙盒不可用。 | 删掉重建一个。 |
| 已到期 | 后台每分钟扫一次,把到期的沙盒先通知引擎侧删掉克隆出来的整棵内容树,再置成这个状态。 | 到期自动发生,不用手工操作。 |
重要提示: "已到期"是真删,不是打个标记。 到期那一刻,沙盒里克隆出来的整棵内容树连同你在里面改过的东西一起被清掉,没有回收站可捞。实验结论、对比 CSV 这类要留档的东西,请在到期前导出到沙盒外面。手工删除沙盒的效果与到期一致,同样会通知引擎侧清掉整棵克隆树。
验证: 创建后沙盒列表新增一行,状态由"创建中"变为运行中、到期时间按预设显示;点沙盒名能进入独立空间(地址带 sandboxKey),空间内已有一份克隆自生产的内容树,即沙盒就绪。
注意: 1. 沙盒里的模型、规则集是克隆出来的新实体,不是生产那一份,取的时候必须用沙盒自己的模型树;2. 挂实验前,沙盒里得先有已发布的规则集 + 已发布的机器学习模型,否则没得挂;3. 若策略实验室菜单打不开或接口报服务不可用,通常是实验室服务未启动,联系管理员确认。
4.12.2 A/B 实验:同一批数据,两种策略并排比
在沙盒内建实验做 A/B:多个实验组各挂不同模型版本(如 A 组挂规则集、B 组挂机器学习模型),用同一批数据集真跑,逐样本并排对比各组输出,导出 CSV。系统不自动判胜负,由人工看对比。
这里有两层页面,先分清:
- 沙盒空间(点沙盒名进来):这个页面解决的是"这个沙盒里有哪些实验"的问题,它就是一张实验列表。实验只能建在沙盒里,外面建不了。行操作有进入 / 删除,支持批量删除。
- 实验详情(点实验名进来):这个页面解决的是"同一批数据在几套策略上分别跑成什么样"的问题。实验组、数据集、执行、结果对比都在这一页。
涉及该操作的功能权限:lab:experiment:create / remove(实验)、lab:experiment:group:create / remove(实验组)、lab:dataset:create / remove(数据集)、lab:experiment:run(执行)。
- 在沙盒空间点创建实验,填实验名称、说明、负责人,建好后点进实验详情。
- 点新建实验组,填组名和说明(就这两项)。一个实验里建两组以上才有对比意义,例如 A 组代表现行策略、B 组代表候选策略。
- 组内点添加模型,从沙盒的模型树里选一个规则集 / 规则流 / 模型,并选版本,然后点保存变更落库。
- 点创建数据集,选数据类型后贴 JSON 或上传文件,给两组喂同一批样本。
- 点执行实验并选一个数据集,系统整批真跑(规则组走规则引擎、模型组走服务端模型运行时)。
- 点查看结果看横向对比矩阵,点导出对比 CSV 拿走结果。
实验组里能挂哪几类内容:
| 类型 | 是什么 / 运行时怎么跑 | 什么时候用 |
|---|---|---|
| 规则集 | 该组用一套规则集打分,运行时走规则引擎。 | A 组挂现行评分卡。 |
| 规则流 | 该组用一条编排好的规则流打分。 | 要比的是整条链路而不是单个组件时。 |
| 模型 | 该组用机器学习模型打分,运行时走服务端模型运行时。 | B 组挂候选的统计学习模型。 |
注意: 沙盒里的内容是克隆出来的新实体,不是生产里的那一份,所以必须从沙盒的模型树里选,别去找生产那棵树。挂模型时内容和版本两项都是必填,缺了会落库报错;版本没发布过的会带"未发布"标记,挂了跑不出结果。
重要提示: 实验组卡片上的"流量"不是分流开关。 新建实验组的表单里根本没有这一项,所以卡片上永远显示"流量:-%";就算通过接口塞进去一个值,执行时也不会按它切流量——系统的做法是把数据集里的每一条样本发给每一个组的每一个模型,全量并排跑。因此策略实验室不是"按流量分流的线上 A/B",它的准确定位是:同一批数据在多组策略上全量并排跑、逐样本比分歧。真要做线上分流,得靠对外发布之后在业务侧做。
数据集类型逐项说明 —— 创建数据集时先选一个数据类型:
| 类型 | 是什么 / 选了要填什么 | 什么时候用 |
|---|---|---|
| 测试用例(JSON) | 直接在文本框里贴 JSON:一个对象算一条样本,一个数组则每个元素算一条。系统会解析、规范化,顺带从样本里推出字段定义并记下条数。还可以点生成示例,按实验内模型的输入契约自动造一段出来改。 | 样本不多、想手工控制每个取值时最省事,推荐默认用它。 |
| CSV 文件 | 上传 .csv,可配分隔符、编码、首行是否为列名三个选项。没上传文件会提示"请先上传数据集文件"。 | 从数仓导出的批量样本。 |
| Excel 文件 | 上传 .xlsx,可配首行是否为列名,解析逻辑与 CSV 一致。 | 业务同学直接给过来的 Excel。 |
| 自定义 | 走的是和"测试用例(JSON)"完全相同的解析路径——也是贴文本、按 JSON 解析,只是换了个名字。 | 与 JSON 没有实际差别,统一用"测试用例(JSON)"就行。 |
注意: 数据集是实验私有的,别的实验的数据集在这里选不到,硬传会报"数据集不存在或不属于当前实验";指标模块里的数据集是另一回事,更不能拿来用。数据集的字段必须覆盖实验内全部模型的输入变量,缺一个字段就会让整次运行失败。
运行状态逐项说明 —— 点了执行实验之后,运行记录上的状态:
| 状态 | 是什么 | 该做什么 |
|---|---|---|
| 运行中 | 记录刚落库,正在整批调各组的模型。整批是同步跑完的,接口没返回就说明还在跑。 | 等它跑完。 |
| 已完成 | 所有样本都跑完,逐样本结果已写入结果表,实验的最后运行时间和耗时同时回写。 | 去看结果矩阵。 |
| 失败 | 过程中出错。错误信息是当场以"运行实验失败:…"的提示弹出来的,这一次不会在运行记录列表里留下行——整次运行连同那条记录一起被撤销了,别去运行记录里找它。常见原因:数据集里没有有效样本、数据集字段没覆盖某个模型的输入变量、某个模型版本没发布。 | 照弹出的错误信息定位,多半是上面三条之一;信息一闪而过的话,重跑一次把它记下来。 |
结果表里每一行(每条样本)还有自己的状态:
| 明细行状态 | 是什么 |
|---|---|
| 成功 | 该样本在所有组的模型上都执行成功。 |
| 失败 | 任一组失败就记失败,并带上第一条错误信息。 |
说明: 实验和实验组本身不带运行状态——它们创建出来就是"草稿",之后一直是,不会变成"运行中"或"已完成"。要看跑成什么样,看运行记录,别在实验列表上找一个永远不变的状态;但要注意运行记录里只留得下跑成功的那些,失败的那次不落库,得靠当场的报错提示定位。另外,执行实验的弹窗里可能还留着一句"实验运行目前返回示例数据"的旧提示,那句话已经过时——实验是通过模型服务真跑的。
结果表: 样本标识 + 各组模型的输出列并排 + 错误信息;每行可以展开看这条样本的原始输入和各组的原始输出。
验证: 结果矩阵里,同一个申请人在 A 组和 B 组给出的分数 / 结论并排显示,分歧样本一眼可见——实验室的价值正是暴露分歧样本,辅助策略选型。
注意: 1. 挂组模型时内容与版本都必填,缺了会落库报错;2. 数据集实验私有,字段须覆盖实验内全部模型的输入变量;3. 整批为单次调用,超时上限约 10 秒,数据量别一次给太大;4. 系统不自动判胜负、不做指标聚合、数据集也没有真实标签列,胜负由人工判读——它给的是"分歧在哪",不是"谁赢了"。
4.13 端到端实战:搭一条信贷准入评分链
前面把每个零件讲清楚了,这一节把它们焊成一条真实业务线,跑通就等于"从 0 通了第一个决策服务"。
背景: 某消费信贷业务需要一个对外的"准入评分"服务——下游受理系统把一笔申请的原始特征传进来,平台返回准入分与通过 / 拒绝结论。要产出的具体对象:数据集 1 个、指标若干、机器学习模型 credit_lr 1 个、评分卡规则集 credit_admission_score_v1 1 个、打分流程 credit_scoring_flow 1 条、对外路由 /score/credit 1 条。
准备: 一张信贷申请人特征宽表 dws_credit_applicant_feature_df(含 age、monthly_income、debt_ratio、overdue_count 等字段);账号具备本章 4.1 所列权限;一份离线训练好的标准化模型文件 credit_lr(逻辑回归)。
操作步骤(严格按作业顺序):
建指标 / 特征(涉及权限:数据集与指标的新建 / 查看)。在数据中台 → 指标引擎 → 数据集新建数据集,用"数据源数据集"建法绑定
dws_credit_applicant_feature_df并发布;再建统计 / 衍生 / 复合指标——月收入、负债率、历史逾期次数(统计,按applicant_id出单人值)、偿债能力比(衍生,月收入 ×(1 − 负债率)÷ 申请金额)、组合逾期率(复合,SQL 出总体率),逐一发布。训模型(涉及权限:内容新建 / 编辑,
content:model:test,发布content:model:publish)。在离线环境训好逻辑回归、导出标准化模型文件credit_lr;在模型里新建、上传解析,把输出标签labelName手补为运行时合成的通过概率名(如probability(1)),绑定变量指向approveProb;测试无误后发布模型 credit_lr。建评分卡规则集(涉及权限:
content:ruleset:publish)。在规则集里建变量表(输入age/monthly_income/debt_ratio/overdue_count/approveProb,输出admission_score/decision),写 4 条命中即 return 的规则,发布 credit_admission_score_v1。其中 R01 带"或"条件,那一条的条件行要切表达式模式写(见 4.5"编写模式");R02~R04 用结构化模式,阈值一律用大于等于 / 小于等于这类比较,不要用"等于"。编排打分流程(涉及权限:任务与编排的新建 / 编辑 / 发布)。在数据中台 → 数据开发里建任务流——两个 HTTP 调用任务建在任务开发、链路画在任务编排:START →
ml(HTTP 调用模型)→rule(HTTP 调用规则集)→ END,用节点outputBindings把approveProb链式传给下游,发布 credit_scoring_flow。发布成 API。在数据网关建
/score/credit路由(类别 api + apiConfig,重写到流程同步运行端点,请求头注入网关鉴权头),建应用取 apiKey 并把路由授权给它。消费验证。下游带
X-APP-ID+X-API-Key调/score/credit,只传原始特征。用 4 个画像各调一次,期望结果如下:
| 画像 | 通过概率 | 准入分 | 决策 | 命中规则 |
|---|---|---|---|---|
| 优质(收入高、负债低、零逾期) | 0.745 | 90 | 通过 | R02 |
| 高逾期(逾期 4 次) | 0.008 | 20 | 拒绝 | R01 |
| 高负债(负债率 0.75) | 0.208 | 20 | 拒绝 | R01 |
| 边缘 | 0.288 | 40 | 拒绝 | R04 |
验证闭环: 四个画像的返回与预期逐一吻合,说明"特征 → 概率 → 准入分 → 决策"这条链从头到尾通了。任何模型或规则发布后,都可在列表接口按钮里看自动文档并在线试调,再验一遍。
- (可选)A/B 选型。在策略实验室创建沙盒克隆内容,建实验:A 组挂规则集、B 组挂机器学习模型,喂同一批数据真跑,逐样本对比、导出 CSV,辅助判断两种策略在同一人群上的分歧。
说明: decision / admission_score / approveProb 三个输出均以字符串返回,概率最多 6 位小数、无科学计数法;消费端如需数值请自行 parseFloat。若下游拿到形如 5.1e-23 的科学计数,说明取到了未经统一格式化的原始值,检查是否走的是正规发布端点。
注意: 上述例子的字段、阈值、样例概率与命中结果仅适用于本节举例,不代表任何行业规范或国家标准。实际搭建时,请以本机构风控政策与官方专业标准规范文档为准。