风控(Risk Control)是支付与交易系统里仅次于账务的”第二核心”。账务管”钱不能错”,风控管”钱不能走错地方、不能被坏人拿走、不能用于违法目的”。它不像撮合引擎那样有明确的算法答案,也不像清算那样有刚性的时间窗,但它和两者都纠缠在一起:撮合前要拦单、支付中要打分、清算后要复查。工程上它最难的不是”写几条规则”,而是在毫秒级延迟、全量流量、持续对抗的黑产环境下,把 规则、特征、画像、图、模型、决策 六件事编排成一套可回溯、可灰度、可回放的系统。
本篇面向已经搭过规则引擎、或在支付网关里写过
if amount > 10000
的读者。我们不写”什么是风控”,只谈怎么把风控做成一个引擎:它的分层、数据流、延迟预算、热更新、A/B
与冠军挑战者(Champion-Challenger)、以及一份可运行的 Go
最小实现。反欺诈模型细节、AML 报文、信用评分卡,分别留给第
20、21、22 篇。
阅读本文大约需要 40 分钟。如果你只是想抄一份架构图贴到设计评审里,可以直接跳到第四节的 SVG;如果你正在选型规则引擎或特征平台,第三节与第五节更有用;如果你在做代码实现,第十节的 Go 示例与第十三节的坑点更值得细读。
与本系列前几篇的差异:第 9 篇《支付网关》讲的是网关这一层怎么接各种上游下游、怎么做路由与幂等;本篇讲的是挂在支付网关下游的风控决策——两者在同一条链路上,但关心的问题完全不同。第 16 篇《撮合引擎》里提到的 Pre-trade Risk,本篇第 9.5 节会把它和支付风控做横向对比。
一、为什么风控必须做成”引擎”
1.1 从 if-else 到引擎的临界点
最早期的风控往往就是支付网关里一串 if:金额
> 5 万拦、夜间 > 2 点拦、同卡 1 分钟内 > 5
次拦。这种写法在两类场景下会崩溃:
- 规则数量 O(1000):业务、合规、反欺诈、反洗钱、商户运营,每个团队都要加规则。规则之间存在覆盖、冲突、短路;再用 if-else 写就变成一座没人敢动的祖传代码。
- 规则需要热更新:一条新的电信诈骗手法下午 3 点被识别出来,必须在 4 点前上线,否则晚上 8 点的晚高峰会被打穿。走发布流程要 2 小时,显然来不及。
当规则数量、更新频率、变更风险任何一个越过阈值,就必须把”规则”从”代码”里剥离,变成数据——这就是规则引擎存在的意义。再往上,特征、模型、决策流也逐一从代码里剥离,共同组成风控引擎。
从”几个 if”到”一套引擎”,中间要经历的不只是技术升级,还有组织升级:风控不再属于某个业务工程师顺手写的代码,而是专门团队维护的基础设施;规则变更走审批,上线走灰度,回放走仿真。把这套流程跑通,比写引擎本身更难。
1.2 三道防线:Pre / Online / Post
行业里普遍把风控分成三层,对应交易生命周期的三个阶段:
| 层 | 位置 | 延迟预算 | 数据可见性 | 典型手段 |
|---|---|---|---|---|
| 前置(Pre-trade / Pre-payment) | 下单 / 发起支付前 | < 50 ms | 用户画像、账户状态、历史统计 | 限额、名单、KYC 状态校验 |
| 在线(Online / In-flight) | 交易处理中、授权阶段 | < 100 ms(支付)/ < 10 ms(交易所) | 全量实时特征、模型打分 | 规则 + 模型 + 决策编排 |
| 事后(Post-event) | T+0 分钟级 / T+1 批 | 秒~小时 | 落地的全量订单、外部情报 | 离线挖掘、案件调查、补处置 |
三层不是串行,而是互相回流:事后调查发现的欺诈样本,回灌成离线训练数据,训出新模型再上线到在线层;在线层累积的命中率回到前置层调整名单。
前置层的核心作用是”挡掉明显不该来的流量”,降低在线层的压力——它对延迟最敏感但规则最简单;在线层是真正的决策中心,在这里支付/交易会被通过、拒绝、挑战、转人工;事后层承担”兜底 + 学习”的职责,也是监管报送(STR、SAR)的主要数据来源。
1.3 延迟预算:100ms 是怎么花出去的
以卡支付为例,端到端预算通常是 300 ms(用户可感知上限),从用户点”确认付款”到返回结果:
用户→收银台 → 网关 → 风控 → 发卡行 → 卡组织 → 回落
20 ms 30 ms 100 ms 80 ms 40 ms 30 ms
留给风控的大约 100 ms。这 100 ms 又要拆成:
- 特征读取:30 ms(Redis / Pika / Aerospike,几十次 KV 查询)
- 规则匹配:20 ms(几十到几百条规则)
- 模型推理:30 ms(XGBoost / LightGBM,特征 ~200 维)
- 决策编排 + 审计落盘:20 ms
交易所的撮合前风控(Pre-trade Risk)预算更苛刻,通常要求 < 10 ms 甚至 < 1 ms(做市商场景),这是因为撮合引擎本身的单笔处理常在微秒级,风控如果加几毫秒,队列就积压了。这种场景下几乎不能有远程 KV,只能把限额做到内存里并通过 TCP 心跳同步。
不同金融场景的延迟预算大致如下:
| 场景 | 端到端预算 | 风控预算 | 关键约束 |
|---|---|---|---|
| 扫码支付(境内) | 300 ms | 100 ms | 用户感知、发卡行响应 |
| 卡支付(跨境) | 800 ms | 150 ms | 跨境 RTT、3DS 挑战 |
| 贷款审批 | 秒级 | 500 ms | KYC、外部征信查询 |
| 证券下单 | 毫秒级 | < 10 ms | 撮合引擎吞吐 |
| 做市 / HFT | 微秒级 | < 1 ms | 本地内存、无远程调用 |
| 提现 / 转账 | 秒级 | 200 ms | 可接受延时决策 |
理解自己的延迟预算,是风控架构的起点:它决定了能不能加模型、能不能跑图、能不能做多次 KV 查询。
二、功能分解:引擎的六个盒子
一套成熟的风控引擎,大致可以拆成六个互相协作的子系统。每个子系统都能独立成文章(本系列后续会展开),本节先把”分工”说清楚。
2.1 规则引擎(Rule Engine)
规则引擎吃两样东西:上下文(Context) 与 规则集(RuleSet),吐出命中列表与动作建议。规则的三要素是:
Rule = 条件(Condition) + 动作(Action) + 元数据(Metadata)
元数据包括规则 ID、版本、生效时间、负责人、灰度配置、优先级等。工程上要把元数据和表达式一起存成数据,不能硬编码。主流实现有两条路线:
- 开源引擎:Drools(Rete 算法,表达力最强但重)、Easy Rules(轻量、Java 注解)、RuleBook、NRules(.NET)。
- 表达式语言 + 自研:MVEL、Aviator(阿里开源,字节码,快)、SpEL(Spring)、CEL(Google,安全、跨语言)、Starlark。
中国互联网公司做大体量风控时,很少直接用 Drools——Rete 算法在规则多且频繁变化时内存占用高,且 Java 重;更常见的是”自研 DSL + Aviator / Groovy 表达式”,这样可以:1)控制 DSL 语法,2)做静态分析与灰度,3)把规则编译成字节码获得更好性能。
2.2 名单(List)
名单看起来是最简单的风控手段,但工程细节不少:
| 类型 | 作用 | 数据量典型值 | 存储 |
|---|---|---|---|
| 黑名单(Blacklist) | 直接拒 | 卡号 1000 万、设备 5000 万、IP 2000 万 | Redis + Bloom Filter |
| 白名单(Whitelist) | 直接放 | 商户、大客户、内部测试账号 | Redis + DB |
| 灰名单(Greylist) | 加强核验(OTP / 人工) | 几百万到几千万 | Redis + TTL |
| 时效名单 | 短期拦截(例如近 24 小时风险设备) | 动态 | Redis TTL |
名单的维度至少包括:卡号(BIN / PAN hash)、设备指纹、IP、手机号、商户号、收款账户、UA、邮箱 MD5、身份证 hash。大型机构会把名单按来源分层——公安部名单、央行反洗钱名单、卡组织反欺诈名单、银联天眼、自营黑样本——每一层的权重和处置动作都不一样。
2.3 画像(Profile / Feature Store)
画像是”主体的历史画像”,特征是”画像的投影”。在工程上这两者往往融合在同一个特征平台(Feature Platform)里。
主体维度:用户、设备、IP、商户、卡、账户、收款人、订单、会话——每一维都可以独立建库。画像字段通常分三类:
- 静态画像:注册时间、实名等级、KYC 等级、设备机型、OS 版本。
- 统计画像:近 1 分钟 / 5 分钟 / 1 小时 / 1 天 / 30 天 各种 count、sum、avg、max、distinct。
- 衍生画像:关系密度、夜间活跃度、消费偏好、品类分布。
2.4 图(Graph)
图风控用关系代替孤立主体。一笔支付涉及的主体可能只有 4 个(付款账户、收款账户、设备、商户),但把它放进全量关系图,可能一跳就关联到几千个节点——团伙的识别靠这个。典型场景:
- 一卡多设备 / 一设备多卡:团伙薅羊毛
- 同一 WiFi 下多账户:裂变作弊
- 收款方一跳可达多个已知欺诈账户:洗钱疑点
- 跨境转账链路最短路径 包含已知制裁主体
图库选型里,Neo4j 工程成熟但单机;字节开源的 Nebula Graph 是国内大规模图风控的主流(蚂蚁自研图数据库 GeaBase 不对外);TigerGraph 商业授权、性能强;JanusGraph 依赖 HBase/Cassandra 扩展性好但延迟高。在线风控里常用的不是 OLAP 多跳查询,而是预计算的子图特征(Node2Vec、GraphSAGE 嵌入、社区 ID)落到特征平台,真正多跳查询留给事后调查。
2.5 模型推理(ML Scoring)
常见模型分两类:
- 传统机器学习:逻辑回归(LR)、GBDT(XGBoost / LightGBM)、随机森林。可解释性好、推理快(百微秒级),大多数反欺诈二分类问题首选。
- 深度学习:DNN、序列模型(LSTM / Transformer,用户行为序列)、图神经网络(GraphSAGE / GAT,关系风控)。推理时间更长(几毫秒到几十毫秒),落地要 GPU 或向量化 CPU。
在线推理服务要求:QPS 数万、P99 < 30ms、模型热更新、A/B 流量分流、特征一致性(训练-推理同源)。主流实现有 TensorFlow Serving、TorchServe、NVIDIA Triton,国内大厂多自研(蚂蚁 CoGNN、字节 ByteNN、阿里 RTP)。
2.6 决策编排(Decision Orchestration)
六个盒子的最后一环:把名单、规则、模型、图的结果编排成一个最终决策。编排器的关键职责:
- 并行化:特征读取 / 规则匹配 / 模型推理并行跑,拼延迟。
- 短路:命中黑名单就不必跑模型。
- 降级:模型超时就回退到纯规则;特征平台挂了就走本地缓存。
- 处置动作:通过 / 拒绝 / 挑战(2FA/OTP)/ 延时放行 / 转人工。
- 审计:每次决策必须落一条完整可回放的 trace。
阿里内部叫”决策流”(Decision Flow),蚂蚁的 AlphaRisk 里叫”策略画布”,Stripe 的 Radar 暴露给商户的则是”Rule Editor + Risk Score”。核心都是一张有向无环图,节点是”原子能力”,边是”条件”。
三、规则引擎的工程实现
3.1 Drools 的长处与短处
Drools 用 Rete 算法实现高效的多规则匹配——规则之间共享条件节点,避免每条规则独立求值。优点:
- 表达力最强:支持前向推理、规则链、议程(agenda)、全局变量。
- 生态完整:KIE Workbench 有可视化编辑器。
缺点也同样突出:
- Rete 算法在”规则频繁变、规则生命周期短”的互联网风控场景下效率反而变差(节点维护成本高)。
- JVM 重、启动慢、调优曲线陡。
- 中文文档稀少,团队踩坑成本高。
经验:银行、保险核心风控系统用 Drools 的不少(规则变化慢,强调合规追溯);互联网支付/交易风控几乎没人直接用,更多的是自研。
3.2 表达式语言对比
自研 DSL 的核心是一门沙箱化的表达式语言。几种主流选型:
| 语言 | 出身 | 语法 | 执行方式 | 安全性 | 热更新 |
|---|---|---|---|---|---|
| MVEL | 开源 | Java-like | 字节码/解释 | 一般(可注入) | 好 |
| Aviator | 阿里开源 | Java-like 简化 | 编译字节码 | 好(沙箱) | 好 |
| SpEL | Spring | Spring EL | 解释/编译 | 差(反射) | 好 |
| CEL | 声明式、受限 | 解释 | 极好(图灵不完备) | 好 | |
| Starlark | Bazel 衍生 | Python 子集 | 解释 | 好 | 好 |
| Groovy | Apache | Groovy | 字节码 | 差 | 好但慢 |
CEL 的特点值得多说一句:它被设计成图灵不完备——没有无界循环、无递归,保证每个表达式在常数步内返回。这让它非常适合做规则引擎的条件语言:拒绝服务攻击从语言层面被阻断,而且可以做静态开销估计。Google 的 IAM、Kubernetes Admission Webhook、Envoy 的 RBAC 全在用它。
选型经验:如果你是 Java 栈且规则复杂,选 Aviator;如果你要多语言(Go/Java/Python 都调),选 CEL;如果你是金融机构要过审计,选 Drools(生态稳定、社区认可度高)。
3.3 自研 DSL 的结构
自研 DSL 常见的是”条件树 + 动作”的 JSON / YAML 结构:
rule:
id: R20260418-0007
version: 3
name: "夜间大额新设备支付"
priority: 80
gray:
percent: 10 # 灰度 10% 流量
condition:
and:
- "amount >= 50000"
- "hour(trade_time) between [0, 5]"
- "device.age_days < 3"
- "user.kyc_level < 2"
action:
type: challenge
method: sms_otp
ttl: 120
metadata:
owner: risk-fraud
effective: 2026-04-18T00:00:00+08:00
expire: 2026-05-18T00:00:00+08:00
tags: [night, new_device, kyc]把它编译时做三件事:
- 语法校验:未定义变量、类型不匹配、语法错——拒绝发布。
- 依赖分析:提取引用的所有特征,交给特征平台预取。
- 字节码生成:Aviator 编译后缓存;Go 栈下用 Govaluate 或自研 AST 解释执行。
3.4 热更新与版本控制
风控规则不像代码,不走”Git → CI → 发布”的慢路径,但安全红线一点不能降。工程上常见模式:
- 规则仓库:所有规则存在 MySQL + 配置中心(Nacos/Apollo/etcd),每条规则有 version、status(草稿/灰度/生效/下线)、审批流。
- 发布流程:规则编辑 → 语法检查 → 回放测试(用昨天的流量重放,看命中率和误杀率)→ 影子模式(Shadow:只打日志不执行动作)→ 灰度 1%/10%/50%/100% → 全量。
- 回滚:每个版本都保留,一键回退到上一版本;紧急情况下有”kill switch”开关关闭整个规则集。
- 审计:谁在什么时间改了什么规则、配套的回放报告、审批人签字——全部落库,以备监管检查。
蚂蚁内部的”规则工厂”、字节的”Rangers”都内置了上面这套流程。开源领域还没有特别成熟的对标,Feast 管不了规则,Drools Workbench 的审批流太重。
3.5 规则引擎的性能优化
当规则数量上到几千条,朴素遍历会成为瓶颈。几种常用优化:
- 索引化条件:把
user_id in [...]、merchant_type == 'xx'这类等值条件建倒排,查询时只对命中的规则做完整表达式求值。 - 预编译字节码:Aviator、Groovy 都支持把表达式编译成 JVM 字节码,比解释执行快 5–10 倍。Go 生态可以用代码生成或 LLVM 绑定。
- 条件短路:AND 节点左小右大排序,常 false 的条件优先求值;OR 节点反之。
- 按场景分片:不同业务线的规则集独立编译独立调度,避免一条规则影响全局 JIT。
- 特征批量获取:合并同一请求所有规则引用的特征 key,一次批量 MGET,减少 RTT。
经过这些优化,几千条规则的求值可以稳定在 10 ms 以内。
四、架构总图
下图是一套典型的实时风控引擎分层架构。最上是请求入口,最下是数据源,中间是六个盒子与决策编排。
图中的两条虚线框(决策结果、Champion-Challenger)是常被架构图忽略但实战上最关键的两块:前者把”引擎给不给过”落成具体的用户体验,后者决定了”新策略能不能安全上线”。
五、特征平台:风控的发动机
5.1 三类特征的分工
| 类型 | 窗口 | 延迟 | 典型实现 | 典型例子 |
|---|---|---|---|---|
| 实时特征 | 秒到分钟 | ms | Flink / Storm / RisingWave + Redis | “最近 1 分钟同设备下单数” |
| 近线特征 | 分钟 | 秒 | Kafka Streams / 小批 Spark | “最近 30 分钟同 IP 金额和” |
| 离线特征 | 小时到天 | 小时 | Hive / Spark / Iceberg | “过去 30 天夜间消费占比” |
实时特征必须”写入即可读”,因为同一笔请求前脚刚进,后脚就要根据统计拦它。Flink 的 KeyedState + RocksDB + 写 Redis 是最常见的 pipeline。近线可以忍几秒延迟,用于捕捉”几分钟内的群体异常”。离线跑全量样本,沉淀长期画像。
一致性陷阱:训练用离线特征、推理用实时特征,定义口径稍有偏差就会出现”训练-推理不一致”(train-serve skew)。解决办法是把特征定义集中注册(Feast 的 feature view、字节 ByteNN 的 feature catalog),同一份 SQL/DSL 两边分别编译成 Flink job 和 Spark job,保证语义一致。
5.2 实时特征的窗口与去重
滑动窗口(sliding window)在 Flink 里常见写法:
DataStream<Txn> txns = env.addSource(kafkaSource);
txns.keyBy(Txn::getDeviceId)
.window(SlidingProcessingTimeWindows.of(Time.minutes(1), Time.seconds(1)))
.aggregate(new CountAgg())
.addSink(new RedisSink("feat:device:{}:txn_cnt_1m"));关键工程点:
- 基数特征(distinct user / distinct card)用 HyperLogLog,不要用 Set,否则状态会爆。
- 乱序数据:允许迟到(allowedLateness),否则”用户重试”可能被算两次。
- 状态 TTL:设备不活跃 7 天以上自动清理,否则 RocksDB 越涨越大。
- 热点 Key:爆款商户的 key 会打爆单个 TaskManager,需要二次分桶(keyBy + 随机 salt + 合并)。
5.3 特征平台选型
- Feast:开源、语言无关,社区活跃;但需要自己搭 Redis、Kafka、离线 Spark。
- Tecton:商业化,SaaS 体验好,价格感人。
- 字节 ByteNN / 阿里 AOI / 蚂蚁自研:不对外,但思路都类似”统一特征定义 + 物化到在线存储 + 训练样本回灌”。
- 自研最小可行:Redis Cluster + Flink + 特征元数据表(MySQL)+ 一个 Go/Java 的查询 SDK,足以支撑中等规模。
5.4 特征命名与治理
特征越多,命名越重要。大厂普遍采用”维度_指标_窗口_聚合”四段式:
user_txn_amt_1m_sum # 用户 1 分钟内交易金额总和
device_login_cnt_1h_uniq # 设备 1 小时内登录次数(去重)
merchant_chargeback_30d_rate # 商户 30 天内拒付率
ip_user_cnt_24h_distinct # IP 24 小时内关联用户数(distinct)
每个特征都有元数据:定义 SQL、类型、默认值、来源上游作业、owner、使用方。没有注册到元数据系统的特征不能在规则里引用——这是防止”幽灵特征”的铁律。
特征下线同样重要。Flink 作业数会随特征数线性增加,资源成本失控。做法是:每月扫描特征使用情况,连续 60 天零引用的特征自动停掉对应 Flink 作业,释放资源。
六、画像与图风控
6.1 多维画像
画像不是一张大宽表,而是一组按主体维度切分的独立存储。设计要点:
- 主体 ID 标准化:同一个”用户”在 App / Web / 小程序可能有不同 ID,必须有统一映射表(ID Mapping)。
- 隐私合规:手机号、身份证、卡号必须 hash + 加盐,原文只在必要场景解密。
- 版本化:KYC 升级、手机号换绑都要有时间戳,回放时能还原”当时”的画像。
- 按热度分层:30 天内活跃用户全字段在 Redis;30 天以上转冷到 HBase / Cassandra;年级别进 Iceberg。
典型支付风控用到的画像维度组合:
(用户, 设备, IP, 卡, 商户, 收款方, 会话, 订单)
八个主体两两之间都能形成”关系特征”:用户-设备新鲜度、IP-卡地理距离、商户-卡历史交易数……这些关系特征构成了规则表达式里最常用的字段。
实际画像存储示例(用户维度):
CREATE TABLE profile_user (
user_id BIGINT PRIMARY KEY,
register_ts BIGINT,
kyc_level TINYINT, -- 0 未实名 1 L1 2 L2 3 L3
risk_tag VARCHAR(64), -- 标签集合
device_count_30d INT,
ip_count_30d INT,
txn_cnt_30d INT,
txn_amt_30d DECIMAL(20, 4),
night_ratio_30d DECIMAL(5, 4), -- 夜间交易占比
community_id BIGINT, -- 图社区 ID
embedding BLOB, -- 行为序列 128 维向量
updated_ts BIGINT,
version INT,
INDEX idx_community (community_id),
INDEX idx_updated (updated_ts)
);这张表并不会真的建在 MySQL 里——数据量过亿后它通常物化在 HBase/Cassandra 或自研 KV 里。建表语句的价值在于把字段口径定死,所有上游 Flink/Spark 作业按这个口径生成。
6.2 图风控的实战价值
图风控真正擅长的不是”多跳查询”,而是团伙识别与关联穿透。几个经典模式:
- 社区发现(Community Detection):Louvain 算法把”紧密联系的主体”划成一个社区,社区 ID 成为风控特征——某个社区最近命中率飙升,该社区的新交易要加重审查。
- 异常子图:一个新账户一小时内被 50 个设备访问,图上明显异常。
- 最短路径:收款方到已知诈骗账户的最短路径 ≤ 2,强烈怀疑资金通道。
- 图神经网络(GNN):把”主体 + 交易”当成节点和边,训练 GraphSAGE / GAT 做节点级分类,输出每个节点的风险分。
选型建议:
- 体量不大(亿级节点以下):Neo4j 单机够用,开发者体验最好。
- 中国大型互联网场景:Nebula Graph(字节主推)、TuGraph(蚂蚁开源,与 GeaBase 同源)、HugeGraph(百度,Apache 孵化)。
- 超大规模 + 强事务:TigerGraph(商业)、或自研(蚂蚁 GeaBase、腾讯 GraphX)。
在线层一般不跑多跳查询(延迟不可控),而是离线预计算子图特征(节点嵌入、社区 ID、1/2 跳邻居聚合值)落到特征平台,在线层只做 KV 查询。
6.3 图风控的建模案例
一个典型的洗钱团伙识别流程:
- 构图:节点 = 账户、设备、IP、收款方;边 = 转账、登录、绑卡,权重 = 近 30 天频次与金额。
- 降噪:过滤掉头部节点(支付宝官方账户、代扣通道账户),否则会把所有人连成一个巨型连通分量。
- 社区发现:跑 Louvain 或 LPA(Label Propagation),得到社区划分。
- 特征抽取:每个账户得到所属社区 ID、社区规模、社区内高风险账户占比、社区中心性。
- 上线:社区特征作为规则输入(“社区内欺诈账户占比 > 30% 则强挑战”)或模型特征(GBDT/GNN 输入维度)。
这一流程通常是”离线每日一跑 + 在线 KV 查询”模式,在线不做任何图遍历。唯一例外是实时关联分析场景(例如收款方刚刚被标黑,需要实时穿透到过去 1 小时内所有向它转账的账户),这时要么用 Flink CEP 做流式关联,要么用 TigerGraph / Nebula 的实时子图查询能力。
七、模型在反欺诈中的角色
模型细节留给第 20 篇,这里只讲模型在引擎里的位置。
7.1 选型的演进路径
一个典型的风控团队,模型演进大致经历四个阶段:
- 纯规则期:几十条硬编码规则,主要靠风控专家经验。
- LR + 规则期:逻辑回归做 baseline 模型,规则依旧是主力,模型分仅作为一条规则条件。
- GBDT 期:XGBoost/LightGBM,特征工程 + 集成树,模型开始挑大梁,规则降级为”红线”和”兜底”。
- 深度学习 + 图期:用户行为序列(Transformer)+ 关系图(GNN)+ 多模态(文本、图像)特征融合,模型成为主决策,规则只在极高风险与极低风险两端做硬性兜底。
国内一线机构大多处于阶段 4(支付宝 AlphaRisk、腾讯钱龙、京东 ZGuard),二线多在阶段 3,中小机构在阶段 2。
7.2 训练-推理一致性
模型在风控里真正难的不是建模,是线上线下一致性。三条铁律:
- 特征同源:同一份特征定义编译出训练(Spark)与推理(Redis/Flink)两条 pipeline,禁止手写两份。
- 时间穿越防护:训练样本生成时,特征快照必须是”当时”的值,不能是”现在”的值——否则模型在训练集表现极好,上线就崩。
- 样本偏差修正:被模型拒掉的交易永远不知道”如果放行会不会欺诈”,导致训练样本只看得到放行的部分。工程上要定期”开窗放行”一批可疑样本(Shadow Pass)来采集全量标签。
7.3 模型可解释性
金融风控的合规要求远高于推荐、广告。监管常要求能回答”这笔交易为什么被拒”:
- SHAP / LIME:给 GBDT、DNN 模型做特征贡献度拆解,是目前最常用的解释工具。
- 白盒模型兜底:极高风险决策(直接拒绝 + 报监管)必须由可解释规则或 LR 模型做出,DNN/GNN 只能作为辅助。
- Reason Code:每次决策输出 3–5 个”主要原因”字段,存入 trace;申诉时直接基于 reason code 给客服交代。
7.4 模型半衰期与再训
黑产不断进化,模型性能会不断衰减。工程上要盯住两个指标:
- KS 衰减:相比上线首日,近一周 KS 下滑超过 10% 就要预警。
- 冠军-挑战者 gap:Challenger 持续显著优于 Champion 超过 2 周,就该切换。
常见重训节奏:GBDT 每周或每月;DNN/GNN 2–4 周;关键高风险模型每日增量 + 每周全量。
八、决策编排与 Champion-Challenger
8.1 决策流(Decision Flow)
决策流是一张 DAG:节点是原子能力(一组规则、一个模型、一次查询),边是条件。调度器负责并行、短路、降级、落 trace。
flowchart LR
A[入口] --> B{黑名单?}
B -- 命中 --> Z[拒绝]
B -- 未命中 --> C[并行]
C --> D[规则组-限额]
C --> E[规则组-行为]
C --> F[GBDT 模型]
C --> G[GNN 图模型]
D & E & F & G --> H[融合决策]
H --> I{score}
I -- ">0.9" --> Z
I -- "0.6~0.9" --> J[OTP 挑战]
I -- "0.3~0.6" --> K[延时 + 观察]
I -- "<0.3" --> P[通过]
融合策略(Fusion)可以是加权和、OR 规则、或另一个 meta-model。出于可解释性,很多金融机构要求主决策必须是规则可读的——模型分作为一个输入,最终”YES/NO”由规则判定。
8.2 Champion-Challenger
新策略上线不能直接替换旧策略,因为风险巨大:万一误杀率暴涨,GMV 立刻掉。Champion-Challenger 模式:
- Champion:当前生效策略,承接 100% 流量的决策。
- Challenger:新策略并行跑,但结果只落日志不执行(Shadow Mode)。
- 过 1~2 周,离线对比:同样输入下,Challenger 对已知欺诈的召回率、误杀率。
- 指标达标后切 1% 实际流量,再逐步放大到 10%、50%、100%,完成替换。
工程上的关键点:Champion 和 Challenger 必须用同一份上下文(相同的特征快照),否则对比不可信。
8.3 A/B 实验
A/B 不只用于”选更好的模型”,也用于测策略(挑战 vs 拒绝)、测文案(OTP 提示怎么写用户更愿意通过)、测阈值(分数 0.8 还是 0.85 拦)。每个实验要:
- 随机分组(通常按 user_id hash)
- 定义唯一主指标(通常是 “有效成交率” 或 “欺诈金额 / GMV”)
- 控制放量节奏,防止流量倾斜
- 结束后强制复盘与沉淀
8.4 决策编排引擎的技术细节
在并行化调度之上,决策编排通常还要做几件事:
- 超时控制:每个节点独立超时(例如模型 30 ms、图查询 20 ms),任一节点超时不能拖累整体,超时走降级分支。
- 限流保护:某个节点(尤其是图查询、外部情报接口)流量骤增时启动限流,保护下游。
- 熔断降级:连续错误率超阈值自动熔断,走”纯规则 + 基础模型”兜底路径。
- 一致性快照:DAG 中并行节点读取的特征要来自同一时刻快照,否则规则看到 “amount > 1 万”、模型看到 “amount = 5 千” 会导致矛盾决策。
- 可观测性:每个节点的耗时、命中率、错误率实时上报,出故障能立即定位。
可以把这一层类比成”微服务编排 + 实时性要求极端化”。国内大厂的决策编排引擎大多参考开源工作流引擎(如 Conductor、Argo)但重新实现,以满足 P99 < 100 ms 的硬性要求。开源工具如 Temporal 的吞吐与延迟暂不能满足生产风控要求,可以作为异步批任务使用。
九、行业案例
9.1 蚂蚁集团 AlphaRisk
AlphaRisk 是支付宝的实时风控大脑,对外公开资料里强调几点:
- 图 + 深度学习融合:用图神经网络捕捉团伙欺诈,用序列模型分析用户行为。
- 毫秒级响应:全量支付请求 P99 < 100 ms。
- AI 对抗:用 GAN 生成新的欺诈样本训练防御模型。
- 自动化策略生成:减少人工规则书写,由 AI 自动挖掘规则并上线。
AlphaRisk 公开披露的四代演进可以粗略概括为:
- 第一代 规则驱动:以资深风控专家经验为核心。
- 第二代 数据驱动:引入 LR/GBDT 做决策辅助。
- 第三代 模型驱动:深度学习 + 图网络成为主力。
- 第四代 智能对抗:引入强化学习、GAN 做动态博弈,对新型欺诈模式做零样本泛化。
每一代的共性是”特征-模型-策略”三件套越来越自动化。
芝麻信用是 AlphaRisk 生态里的信用评分子系统,给出 350–950 的芝麻分,用于免押、贷款、信用卡初审。其特征覆盖身份、履约、行为、人脉、资产五个维度。详细机制留给第 22 篇。
9.2 Stripe Radar
Stripe Radar 是国外最成熟的支付反欺诈服务之一,特点:
- 跨商户数据:Stripe 处理的全球交易形成巨大样本池,一个在 A 商户欺诈过的卡,在 B 商户试图再次使用会立即被识别。
- 机器学习为主:Radar 的”风险分”(0–100)由深度学习模型给出;商户可以在此基础上叠加自定义规则。
- 可视化规则编辑器:商户能在 Dashboard 里直接写规则并灰度。
- 3D Secure 集成:高风险交易自动触发 3DS 挑战,降低失败率的同时合规 PSD2 SCA。
Radar 在面向商户暴露能力时做了一个值得借鉴的设计:风险分 + 规则 双层。风险分由 Stripe 负责维护与迭代,商户无权访问模型细节,但可以基于分数 + 其他字段写自己的规则。这套分层让 “Stripe 的专家经验” 与 “商户的业务经验” 解耦,也规避了大量跨商户合规难题。
9.3 PayPal 反欺诈
PayPal 是最早大规模使用机器学习做反欺诈的支付机构之一,1999 年就有 IGOR 系统。关键经验:
- 黑产对抗是持久战:PayPal 内部有专门的”模型半衰期”概念,一个反欺诈模型通常 3–6 个月就需要重训。
- 设备指纹 + 行为生物特征:鼠标轨迹、打字节奏、陀螺仪数据全部用于识别机器人和欺诈。
- 关系图:早期就用图结构分析关联账户,如今已迭代多代。
9.4 国内其他案例
- 美团风控(钱包 + 外卖):应对骑手套现、用户刷单,自研”天网”风控平台。
- 京东 ZGuard:白条、支付、提现一体化风控,偏零售场景。
- 腾讯钱龙:覆盖微信支付、财付通、理财通,图风控强。
- 陆金所、微众银行:贷款反欺诈为主,KS、AUC 指标公开披露。
9.5 交易所的 Pre-trade Risk
交易所的风控与支付风控有本质差异:延迟更苛刻(< 10 ms)、规则更简单(主要是限额、自成交防护、过于偏离市价的订单)、没有模型打分(时间根本不够)。CME、纳斯达克以及中国期货交易所的 Pre-trade Risk 都是纯规则、内存化、与撮合引擎同机部署的。
然而,交易所的风控承担了撮合引擎”最后一公里”的合规防护:
- Fat Finger(胖手指):单笔数量或金额异常大,强制拦截。
- 自成交防护:同一客户的买卖单不能自成交(可能是做市商洗单)。
- 持仓限额:单户单品种持仓不得超过市场份额阈值。
- 限价带:订单价格偏离基准价一定幅度即拒绝。
这些规则在第 15、16 篇讲撮合时已粗略提及,本篇不再展开。
十、Go 代码:一个最小可运行的规则引擎
下面的代码实现了:条件树解析、特征获取接口、规则匹配、决策编排。不到 200 行,但结构和生产系统同构——读懂它再看大厂代码会顺畅很多。
package riskengine
import (
"context"
"encoding/json"
"fmt"
"sync"
"time"
)
// FeatureFetcher 从特征平台/缓存里拿特征
type FeatureFetcher interface {
Get(ctx context.Context, keys []string) (map[string]any, error)
}
// Action 决策动作
type Action string
const (
ActionPass Action = "pass"
ActionReject Action = "reject"
ActionChallenge Action = "challenge"
ActionReview Action = "review"
)
// Rule 规则定义
type Rule struct {
ID string `json:"id"`
Version int `json:"version"`
Name string `json:"name"`
Priority int `json:"priority"`
GrayPct int `json:"gray_pct"` // 灰度百分比
Condition ConditionNode `json:"condition"`
Action Action `json:"action"`
Meta map[string]any `json:"meta"`
}
// ConditionNode 条件树节点
type ConditionNode struct {
Op string `json:"op"` // and / or / gt / gte / lt / lte / eq / in
Field string `json:"field"` // 叶子节点引用的特征
Value any `json:"value"` // 叶子节点比较值
Children []ConditionNode `json:"children"` // 组合节点
}
// Decision 决策输出
type Decision struct {
Action Action `json:"action"`
Hits []string `json:"hits"` // 命中规则 ID
Score float64 `json:"score"` // 模型分(若有)
TraceID string `json:"trace_id"`
Features map[string]any `json:"features"`
TookMS int64 `json:"took_ms"`
}
// Engine 规则引擎
type Engine struct {
mu sync.RWMutex
rules []Rule
feats FeatureFetcher
hash func(string) uint32 // 用于灰度分桶
}
func NewEngine(f FeatureFetcher, hash func(string) uint32) *Engine {
return &Engine{feats: f, hash: hash}
}
// UpdateRules 热更新:一次性替换全部规则
func (e *Engine) UpdateRules(rs []Rule) {
e.mu.Lock()
defer e.mu.Unlock()
e.rules = rs
}
// Evaluate 核心入口
func (e *Engine) Evaluate(ctx context.Context, traceID string, input map[string]any) (*Decision, error) {
start := time.Now()
// 1) 收集所有规则要用的特征字段
e.mu.RLock()
rules := e.rules
e.mu.RUnlock()
keys := collectFeatureKeys(rules)
// 2) 一次批量拉取特征(让平台侧合并 IO)
feats, err := e.feats.Get(ctx, keys)
if err != nil {
// 降级:特征拿不到时只用 input 里的原生字段
feats = map[string]any{}
}
for k, v := range input {
feats[k] = v
}
// 3) 按优先级从高到低评估
var hits []string
finalAction := ActionPass
for _, r := range rules {
// 灰度控制:hash(traceID+ruleID) 落入灰度区间才执行
if r.GrayPct > 0 && int(e.hash(traceID+r.ID)%100) >= r.GrayPct {
continue
}
ok, err := evalNode(r.Condition, feats)
if err != nil {
continue
}
if ok {
hits = append(hits, r.ID)
// 动作优先级:Reject > Review > Challenge > Pass
finalAction = mergeAction(finalAction, r.Action)
if finalAction == ActionReject {
break // 短路
}
}
}
return &Decision{
Action: finalAction,
Hits: hits,
TraceID: traceID,
Features: feats,
TookMS: time.Since(start).Milliseconds(),
}, nil
}
func mergeAction(cur, in Action) Action {
order := map[Action]int{
ActionPass: 0, ActionChallenge: 1, ActionReview: 2, ActionReject: 3,
}
if order[in] > order[cur] {
return in
}
return cur
}
func collectFeatureKeys(rs []Rule) []string {
seen := map[string]struct{}{}
var walk func(ConditionNode)
walk = func(n ConditionNode) {
if n.Field != "" {
seen[n.Field] = struct{}{}
}
for _, c := range n.Children {
walk(c)
}
}
for _, r := range rs {
walk(r.Condition)
}
out := make([]string, 0, len(seen))
for k := range seen {
out = append(out, k)
}
return out
}
func evalNode(n ConditionNode, feats map[string]any) (bool, error) {
switch n.Op {
case "and":
for _, c := range n.Children {
ok, err := evalNode(c, feats)
if err != nil || !ok {
return false, err
}
}
return true, nil
case "or":
for _, c := range n.Children {
ok, err := evalNode(c, feats)
if err == nil && ok {
return true, nil
}
}
return false, nil
case "gt", "gte", "lt", "lte", "eq":
lv, ok := toFloat(feats[n.Field])
rv, ok2 := toFloat(n.Value)
if !ok || !ok2 {
return false, fmt.Errorf("non-numeric compare on %s", n.Field)
}
switch n.Op {
case "gt": return lv > rv, nil
case "gte": return lv >= rv, nil
case "lt": return lv < rv, nil
case "lte": return lv <= rv, nil
case "eq": return lv == rv, nil
}
case "in":
arr, ok := n.Value.([]any)
if !ok { return false, nil }
for _, x := range arr {
if fmt.Sprintf("%v", x) == fmt.Sprintf("%v", feats[n.Field]) {
return true, nil
}
}
}
return false, nil
}
func toFloat(v any) (float64, bool) {
switch x := v.(type) {
case float64: return x, true
case float32: return float64(x), true
case int: return float64(x), true
case int64: return float64(x), true
case json.Number:
f, err := x.Float64()
return f, err == nil
}
return 0, false
}这段代码里有几处写生产代码时必须补齐的地方:
- 动作融合不只是最大值:真实场景下 Challenge 和 Review 会同时发生(挑战失败后转人工),需要返回一组动作序列。
- 规则评估并行化:独立规则间无依赖,可以起 goroutine 并发跑,但要注意特征一致性快照。
- trace 落盘:每次 Decision 要写到一个 trace 存储(Kafka → ClickHouse),供 24 小时后回放。
- 灰度分桶的稳定性:hash 必须可重复(同一 traceID 任何时候都落同一桶),推荐 xxhash 而不是 Go 默认 map hash。
- 规则的版本快照:decision 要记录使用的规则集版本,防止事后追查时规则已改。
十一、决策结果的产品化
决策结果不只是 “通过 / 拒绝” 两个枚举值——落到用户界面上,它决定了转化率、客诉率和风险损失的三角平衡。
11.1 五种典型处置动作
| 动作 | 含义 | 适用场景 | 用户感知 |
|---|---|---|---|
| 通过(Pass) | 正常放行 | 绝大多数低风险交易 | 无感 |
| 拒绝(Reject) | 终止交易 | 命中黑名单、极高分 | “交易失败,请联系客服” |
| 挑战(Challenge) | 追加验证 | 中高风险 | 短信 OTP / 指纹 / 3DS / 刷脸 |
| 延时(Delay) | 异步风控 | 高金额但非实时场景 | “处理中,稍后通知” |
| 人工审核(Review) | 转人工 | 极高风险且无法机器判断 | “交易受限,等待审核” |
工程要点:
- 挑战要支持多种因子降级:一开始要求指纹 + 短信,设备不支持指纹时降级为短信 + 图形验证码。
- 拒绝要区分可恢复与不可恢复。可恢复的(金额超限)可提示升级 KYC,不可恢复的(命中制裁名单)只返回通用错误码,避免泄露风控逻辑给黑产做探测。
- 延时动作要承诺最长窗口(如 10 分钟),超时自动降级为拒绝,避免用户体验黑洞。
- 转人工必须有兜底 SLA,比如 30 分钟未处理自动转二级队列。
11.2 话术与错误码治理
对外错误码不能暴露风控逻辑。例如命中”设备指纹欺诈团伙”,对用户提示”当前网络环境异常,请更换网络后重试”——这既不泄露信息又给了用户一条可操作路径。内部错误码则必须 1:1 对应规则 ID + 模型子分支,供 CSR(客服)反查。
大厂风控团队通常会沉淀一套”错误码词典”,每个错误码三列:内部原因、用户话术、客服话术。任何新规则上线前必须挂靠已有错误码或申请新码。
11.3 申诉与回滚闭环
被误拦的用户会走客服或 App 内申诉通道。申诉命中率高的规则会反向推高业务指标下滑——风控团队的 OKR 里必须同时写 “欺诈损失率” 与 “误拦申诉率” 两项。典型闭环:
- 用户申诉 → 人工审核 → 判定为误拦
- 误拦样本回灌到”白样本池”
- 每周离线复算,定位到具体规则 / 模型子分支
- 触发规则重评估或模型重训
11.4 决策的业务指标体系
评价一套风控引擎不能只看”拦了多少欺诈”,更要看综合业务影响。典型指标组:
| 指标 | 口径 | 目标方向 |
|---|---|---|
| 欺诈损失率 | 欺诈金额 / GMV | 越低越好 |
| 误拦率 | 误拦订单数 / 全部订单 | 越低越好 |
| 召回率 | 成功拦截的欺诈 / 全部欺诈 | 越高越好 |
| 精确率 | 成功拦截的欺诈 / 所有拦截 | 越高越好 |
| 挑战通过率 | OTP 通过数 / 挑战数 | 上升说明挑战偏严 |
| 转人工比例 | 转人工数 / 全部决策 | 控制在 0.1%–1% |
| 人工审核 TAT | 转人工到处理完成耗时 | 越低越好 |
| 申诉平反率 | 申诉成功数 / 申诉总数 | < 10% 合格 |
这些指标要日报 + 周报,异常波动要回溯到规则 / 模型版本。OKR 里最常见的两个顶层指标是 “欺诈损失率 < X bp” 和 “误拦申诉率 < Y%”,二者对立制衡。
十二、可回放与审计
金融场景的风控决策必须可回放——监管、内审、业务复盘三方都会要求”为什么 2026-04-20 14:35:22 这笔交易被拦了”。
12.1 决策 Trace 的最小字段集
trace_id, ts, user_id, order_id, biz_type,
ruleset_version, model_version, feature_snapshot_id,
hit_rules: [id, version, action],
model_score, model_subscores,
graph_features_used,
final_action, final_reason_code,
challenge_result, human_review_result,
downstream_latency_ms
其中 feature_snapshot_id 是关键:特征值在写 trace 时必须快照,不能只存 “key”。否则 24 小时后 Redis 里的特征已经变了,trace 无法重现当时决策。
12.2 回放与影子执行
回放系统的作用有三:
- 线上问题复盘:给定 trace_id,回放整条决策流,定位哪条规则误杀。
- 新规则预演:把昨天的全量流量回放一遍,统计新规则命中率、误杀率。
- 模型离线评估:把生产流量当做评测集,对比 Champion 与 Challenger。
回放要解决的核心是”时间还原”:特征必须是当时的快照而不是当前值。工程上两种方式:
- 特征快照法:每次决策时把用到的特征全部写入 trace。优点简单,缺点 trace 体积大(单条 10–50 KB)。
- 事件溯源法:不存快照,只存事件 id + 时间戳,回放时重算特征。优点体积小,缺点要维护一套”时间回溯特征引擎”,复杂度高。
大厂做法多是两者结合:核心特征走快照,边缘特征走事件溯源。
12.3 监管审计接口
境内支付与持牌机构需要按期向央行、银保监、外管报送数据。风控 trace 是报送的重要原料之一:
- 可疑交易报告(STR):大额 + 可疑行为组合触发,详细字段在第 21 篇展开。
- 拒付分析报告:每月汇总拒付率、欺诈损失、申诉回滚。
- 年度审计:外部审计师会抽样要求回放若干”被拒绝的高额交易”,验证规则命中逻辑可解释、可追溯。
因此 trace 存储必须满足:至少 5 年可访问(部分监管要求 10 年)、不可篡改(可用追加日志 + 哈希链,或直接上区块链存证)、可基于规则版本和模型版本精准回放。
十三、工程坑点
- 特征穿越:训练时用到”未来数据”(比如目标事件发生后才可见的字段),模型在测试集上近乎完美,上线后崩盘。写特征定义 DSL 时要强制”as-of-time”。
- 规则爆炸:几年不做治理,规则数能到 5000+,其中 40% 实际从未命中。要有规则下线机制:连续 30 天零命中自动转草稿,90 天自动归档。
- 灰度失效:灰度按 user_id hash,但一个黑产用户往往控制多个 user_id,落到不同桶,灰度统计被污染。要按”风险桶”二次分层。
- 模型过拟合黑样本:黑样本少且偏,模型容易记忆特定欺诈团伙的指纹而不是学习通用特征。用对抗训练和特征消融缓解。
- 冷启动:新用户没有历史画像,大部分特征为空,规则和模型都失效。对策是走”新用户专用策略”,偏保守 + 强挑战。
- 供应商失联:第三方设备指纹、IP 情报接口偶尔抖动,风控决策不能卡住。要定 SLA 并做 circuit-breaker 降级。
- 合规冲突:国内监管要求报送 STR,欧盟 GDPR 要求最小化数据留存,跨境业务时必须在产品和架构上做区域隔离。
- 人工审核瓶颈:人工通道是风控最后一道闸门,但人力不是无限。当转人工比例 > 1% 时,业务指标会受影响,要盯住这根红线。
- 规则-模型互相屏蔽:规则先拦掉的样本不会再被模型看到,长期导致模型在高风险段欠拟合。解决办法是固定留一小撮”开窗样本”让模型也能打分,实际动作仍由规则决定,模型只记录打分用于重训。
- 时钟漂移:分布式系统中各节点时钟不一致,基于 “近 1 分钟窗口” 的特征在边界上抖动。统一用 Kafka 时间戳或 NTP 同步的网关时钟作为 event time,不要用本地墙钟。
- 热点账户:个别商户或代付账户一天几千万笔流水,KeyedState 把整个 Flink 作业打爆。需要在维度上加 salt 做二次分桶,聚合时再合并。
- Redis 大 Key:黑名单、图嵌入常被一次性 SET 成巨大 HashMap,导致阻塞。拆分为多个分片 key 或改用 Aerospike / Pika 这类为大 value 优化的存储。
- 治理漂移:规则负责人离职后没人敢动他的规则,堆成”祖传规则”。每条规则必须有主副两个 owner,owner 离职自动触发 review。
十四、选型建议与落地清单
14.1 规模-选型矩阵
| 场景 | 规则引擎 | 特征平台 | 图 | 模型服务 |
|---|---|---|---|---|
| 日均单量 < 100 万 | Easy Rules / 自研 DSL | Redis + 直写 | Neo4j | 模型内嵌 Go/Java |
| 100 万 – 1 亿 | Aviator + 自研 | Feast + Redis | Nebula / TuGraph | Triton / 自研 gRPC |
| > 1 亿(大厂级) | 自研 DSL + 字节码 | 自研(字节 / 阿里 / 蚂蚁路线) | Nebula / 自研图库 | 自研(ByteNN / 类 AlphaRisk) |
| 银行 / 证券合规重 | Drools / 商业 BRMS | 厂商方案或自研 | TigerGraph / JanusGraph | 自研 + 白盒模型 |
14.2 落地清单(新建团队 6 个月 roadmap)
- M1-M2 基础版:搭网关 + 名单 + 硬编码规则,把 80% 高频欺诈挡住。
- M2-M3 规则引擎化:把硬编码规则搬到 DSL,加版本、灰度、审计。
- M3-M4 特征平台 v1:Flink 算几十个实时特征,落 Redis,规则开始引用。
- M4-M5 上 GBDT 模型:先影子再上线,Champion-Challenger。
- M5-M6 图 + 监管:离线图挖掘、社区 ID 特征上线;监管报送接口(STR/SAR 留到第 21 篇)。
十五、与后续文章的衔接
- 第 20 篇《反欺诈》将深入设备指纹、行为序列、黑产对抗的具体技术与模型。本篇只提到 “模型在引擎里的位置”,下一篇会讲模型本身怎么训、怎么对抗、怎么识别真人 vs 脚本。
- 第 21 篇《AML / KYC》讲合规风控:尽调、交易监测、STR/SAR 报送、FATF 40 条。本篇中的”事后层”与 STR 生成逻辑将在第 21 篇详细展开。
- 第 22 篇《信用风险》讲评分卡、违约预测、巴塞尔 III——和本篇的反欺诈风控共享引擎,但目标函数完全不同:本篇关心”这笔交易是不是欺诈”,第 22 篇关心”这个客户未来会不会违约”。
- 第 23 篇《对账》里会反过来用风控输出:拦截订单 vs 成交订单的资金对账,是风控效果验证的重要一环。
- 第 24 篇《金融级可靠性》会讨论风控引擎的异地多活、单元化部署——风控同样要求 RPO=0、RTO<30s。
如果把这几篇放在一起看,就能理解为什么大厂的”风险与合规中台”往往是几百到上千人的团队:规则、特征、模型、图、KYC、AML、信用、对账、监管报送——九件事互相耦合,任何一块薄弱都会被黑产或监管放大。
十六、参考资料
- 《Feast: Feature Store for Machine Learning》官方文档:https://docs.feast.dev/
- Google CEL 规范:https://github.com/google/cel-spec
- Aviator 表达式引擎:https://github.com/killme2008/aviatorscript
- Drools 官方文档:https://www.drools.org/
- Apache Flink 文档:https://flink.apache.org/
- Nebula Graph 文档:https://docs.nebula-graph.com.cn/
- Stripe Radar 文档:https://stripe.com/radar
- 蚂蚁集团 AlphaRisk 技术分享(InfoQ、ATEC 公开资料)
- 《支付清算行业风险防控白皮书》中国支付清算协会
- PayPal Engineering Blog:https://medium.com/paypal-tech
- 《Fraud Analytics Using Descriptive, Predictive, and Social Network Techniques》Bart Baesens 等,Wiley
- 《Real-Time Fraud Detection with Apache Flink》Confluent 技术博客
- Tecton 官方博客:https://www.tecton.ai/blog/
- RisingWave 流式数据库:https://www.risingwave.com/docs/
- 中国人民银行《金融机构反洗钱和反恐怖融资监督管理办法》
- 阿里云风控平台(数据风控 BSA)官方文档:https://help.aliyun.com/
- Banco Central do Brasil / ECB 风控与支付监管报告(用于跨境对比参考)
上一篇:《证券登记结算:中证登、DTCC、Euroclear、T+1、DvP》
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【金融科技工程】金融科技工程全景:从支付到交易所的系统分类与读图
金融科技(FinTech)不是普通后端加一张账户表。钱的原子性、监管的硬边界、一个小数点的代价,把这个领域推进到工程强度最高的那一档。本文是【金融科技工程】25 篇的总目录与阅读地图:先交代为什么它比一般业务系统更难,再给出对账体、支付体、交易体、风控合规体四维分类,把后续 24 篇挂到骨架上,最后给出一份绿地项目的落地顺序建议。
【金融科技工程】反欺诈:设备指纹、关系图谱、行为序列、黑产对抗
系统梳理反欺诈工程:欺诈类型、特征工程、模型演进(规则到 GNN)、类别不平衡、图风控、实时决策、对抗性与可解释性,附 Python + NetworkX + LightGBM 简化团伙识别与欺诈评分示例。
【金融科技工程】对账系统工程:账单、总账、资金对账、差错处理
从金融本质、分层架构到文件格式、匹配算法、差错处理与调账流程,系统讲解对账系统的工程落地,包含 Python/Go 示例、Mermaid 状态机与大型平台十亿级对账方案。
金融科技工程
面向中国工程团队的金融科技系列。从账务底盘、支付、清结算、交易所、风控合规到可靠性与灾备,中国与全球视角并举,讲清楚金融系统在工程落地中的真实挑战。