实时风控决策引擎 — 系统设计文档
实时风控决策引擎 — 系统设计文档
项目编号:FIN-DESIGN-03
版本:v1.0
作者:MomoFinance
日期:2026-04-13
状态:设计完成
关联 ADR:ADR-001 规则引擎选型 / ADR-002 特征计算架构 / ADR-003 决策编排模式
一、需求分析
1.1 面试场景
面试官:"请设计一个实时风控决策引擎,要求毫秒级响应,支持规则+机器学习混合决策,日均亿级事件处理。"
这是金融系统设计面试中出现频率极高的题目。它考察候选人对高性能低延迟系统、规则引擎与 ML 融合、流式计算以及金融业务理解的综合能力。
1.2 需求澄清(10 个关键问题)
| # | 澄清问题 | 假设回答 | 对设计的影响 |
|---|---|---|---|
| 1 | 风控场景有哪些? | 交易/注册/登录/信贷 | 需要多场景策略编排,不同场景超时/降级策略不同 |
| 2 | 日均事件量?峰值? | 日均 10 亿,峰值 5 万 TPS | 需要水平扩展 + Kafka 削峰 |
| 3 | 延迟要求? | P99 < 50ms(同步决策) | 排除远程数据库查询;核心路径全内存计算 |
| 4 | 规则数量级? | 500-2000 条活跃规则 | 需要 Rete 算法优化匹配效率 |
| 5 | ML 模型数量? | 3-5 个在线模型 | 模型推理并行执行,需 GPU/ONNX 加速 |
| 6 | 规则更新频率? | 每天数次,紧急时分钟级 | 规则热更新 + 版本管理 + 灰度发布 |
| 7 | 是否需要人工审核? | 是,约 5% 事件进入人审 | 案件管理子系统 + SLA 管理 |
| 8 | 是否有合规要求? | AML/CTF 报送 + 决策可审计 | 全链路日志 + 可解释性 + 报送接口 |
| 9 | 多机房部署? | 双活 | 决策无状态 + 特征存储多机房同步 |
| 10 | 外部数据源? | 征信/设备指纹/IP 情报/行业共享名单 | 外部调用异步化 + 超时降级 |
1.3 功能需求
| 功能模块 | 核心能力 | 优先级 |
|---|---|---|
| 实时风控决策 | 同步接收事件,毫秒级返回 PASS/REVIEW/REJECT | P0 |
| 规则管理 | DSL 编写/编译/版本化/热更新/灰度 | P0 |
| 模型管理 | 模型注册/版本切换/A-B 测试/影子模式 | P0 |
| 特征计算 | 实时滑动窗口特征 + 离线画像特征 | P0 |
| 名单管理 | 黑/白/灰名单 CRUD + 布隆过滤器快检 | P0 |
| 案件管理 | 人审分配/SLA/审核工作台/反馈闭环 | P1 |
| 策略灰度 | 按比例/按维度灰度新规则和模型 | P1 |
| 监控告警 | 规则命中率/模型 AUC/延迟/资损率 | P1 |
1.4 非功能需求
| 指标 | 目标值 | 设计约束 |
|---|---|---|
| P99 延迟 | < 50ms | 核心路径零远程 I/O;预计算+内存缓存 |
| 可用性 | 99.99%(≈52 分钟/年) | 双活部署 + 降级策略 + 限流熔断 |
| 吞吐量 | 日均 10 亿事件,峰值 5 万 TPS | 无状态服务水平扩展 + Kafka 缓冲 |
| 规则热更新 | < 1 分钟生效 | 推拉结合 + 版本广播 + 本地缓存刷新 |
| 模型切换 | 零停机 | 双模型加载 + 流量灰度切换 |
| 数据一致性 | 特征最终一致(延迟 < 1s) | Flink 实时聚合 + Redis 原子写入 |
1.5 风控场景梳理
| 场景 | 事件触发点 | 核心特征 | 典型规则 | 超时策略 |
|---|---|---|---|---|
| 交易风控 | 支付下单 | 金额/频次/设备/收款方 | 单笔>5 万拒绝;5 分钟内>3 笔人审 | 超时放行(降低用户影响) |
| 注册风控 | 账户注册 | 设备指纹/IP/手机号段 | 同设备 24h>3 次注册拒绝 | 超时放行 |
| 登录风控 | 用户登录 | IP/设备/地理位置/时间 | 异地登录人审;暴力破解拒绝 | 超时放行+二次验证 |
| 信贷风控 | 贷款申请 | 征信/收入/负债/行为 | 多头借贷>5 家拒绝 | 超时拒绝(宁可拒绝不可放贷) |
关键洞察:不同场景的超时降级策略截然不同——交易/注册/登录超时放行(避免影响用户体验),信贷超时拒绝(控制资金风险)。这是面试中的高分答案点。
二、高层架构设计
2.1 C4 Context — 系统上下文
风控引擎作为中台能力,被多个业务系统调用,同时依赖多个外部数据源。
核心交互方:
| 系统 | 关系 | 交互方式 |
|---|---|---|
| 支付系统 | 调用方 | 同步 gRPC(交易风控) |
| 信贷系统 | 调用方 | 同步 gRPC(信贷风控) |
| 用户中心 | 调用方 | 同步 gRPC(注册/登录风控) |
| 征信机构 | 外部数据源 | 异步预拉取 + 缓存 |
| 设备指纹服务 | 外部数据源 | SDK 端侧采集 + 服务端验证 |
| IP 情报服务 | 外部数据源 | 异步批量更新本地库 |
| 案件管理系统 | 下游 | 异步 Kafka 推送人审事件 |
| 合规报送系统 | 下游 | 异步 Kafka 推送可疑交易 |
| 监控系统 | 下游 | Metrics + Alerting |
详细 C4 Context 图见 diagrams/c4-context.mmd。
2.2 C4 Container — 内部容器
风控引擎内部分为 9 个核心容器:
| 容器 | 职责 | 技术选型 | 说明 |
|---|---|---|---|
| Decision Gateway | 统一入口,协议适配,路由分发 | Go/gRPC | 无状态,水平扩展 |
| Rule Engine | 规则编译、匹配、执行 | 自研 Rete 引擎(Java) | 规则预编译到内存;见 ADR-001 |
| ML Serving | 模型推理服务 | TensorFlow Serving + ONNX Runtime | GPU/CPU 混合部署 |
| Feature Store | 实时/离线特征存储与服务 | Redis(热)+ HBase(冷) | 特征一致性保障 |
| Event Stream Processor | 实时特征计算 | Apache Flink | 滑动窗口聚合;见 ADR-002 |
| List Service | 名单管理与快速匹配 | Redis + Bloom Filter | 布隆预检 + 精确查询 |
| Case Management | 人审案件分配与管理 | Java/Spring Boot + PostgreSQL | SLA 驱动的工单系统 |
| Strategy Manager | 规则/模型灰度发布管理 | Java + ZooKeeper | 配置中心驱动灰度策略 |
| Monitoring Dashboard | 风控效果监控 | Grafana + Prometheus + ClickHouse | 实时指标 + 离线报表 |
详细 C4 Container 图见 diagrams/c4-container.mmd。
2.3 核心决策流程
事件接入 → 特征提取 → 名单匹配 → 规则执行 → 模型预测 → 决策编排 → 结果输出
↓
异步事后分析
决策编排采用 DAG 有向无环图模式(见 ADR-003),关键设计:
- 名单匹配优先级最高——命中黑名单直接拒绝,命中白名单直接放行,短路后续所有计算
- 规则执行和模型推理可并行执行,最后由决策编排器综合
- 整体超时控制:Gateway 层设置 50ms 超时,任何子环节超时触发降级
- 异步事后分析:决策结果异步写入 Kafka,供离线分析和模型训练
详细序列图见 diagrams/sequence.mmd。
三、数据模型设计
3.1 核心表结构
risk_event(风控事件表)
| 字段 | 类型 | 说明 |
|---|---|---|
| event_id | VARCHAR(64) PK | 事件唯一 ID(UUID/雪花) |
| event_type | ENUM | TRANSACTION / REGISTRATION / LOGIN / CREDIT |
| user_id | VARCHAR(64) | 用户 ID |
| device_fingerprint | VARCHAR(128) | 设备指纹 |
| ip_address | VARCHAR(45) | IP 地址(支持 IPv6) |
| amount | DECIMAL(18,2) | 交易金额(非交易场景为 NULL) |
| currency | VARCHAR(3) | 币种 |
| merchant_id | VARCHAR(64) | 商户 ID |
| channel | VARCHAR(32) | 渠道(APP/H5/API) |
| geo_location | VARCHAR(64) | 地理位置 |
| extra_data | JSONB | 扩展字段(场景特有数据) |
| created_at | TIMESTAMP | 事件时间 |
设计要点:extra_data 用 JSONB 存储场景差异化数据,避免表结构频繁变更。
risk_rule(规则表)
| 字段 | 类型 | 说明 |
|---|---|---|
| rule_id | VARCHAR(64) PK | 规则 ID |
| rule_name | VARCHAR(128) | 规则名称 |
| scene_type | ENUM | 适用场景 |
| dsl_expression | TEXT | DSL 表达式 |
| priority | INT | 优先级(数值越小优先级越高) |
| action | ENUM | PASS / REVIEW / REJECT |
| status | ENUM | DRAFT / TESTING / ACTIVE / DISABLED |
| version | INT | 版本号 |
| effective_time | TIMESTAMP | 生效时间 |
| expire_time | TIMESTAMP | 过期时间 |
| gray_ratio | DECIMAL(3,2) | 灰度比例(0-1) |
| created_by | VARCHAR(64) | 创建人 |
| created_at | TIMESTAMP | 创建时间 |
| updated_at | TIMESTAMP | 更新时间 |
risk_decision(决策结果表)
| 字段 | 类型 | 说明 |
|---|---|---|
| decision_id | VARCHAR(64) PK | 决策 ID |
| event_id | VARCHAR(64) FK | 关联事件 ID |
| decision_result | ENUM | PASS / REVIEW / REJECT |
| hit_rules | JSONB | 命中的规则列表 |
| model_scores | JSONB | 各模型得分 |
| final_score | DECIMAL(5,4) | 综合风险分 |
| decision_reason | TEXT | 决策原因(可解释性) |
| latency_ms | INT | 决策耗时(毫秒) |
| is_degraded | BOOLEAN | 是否降级决策 |
| created_at | TIMESTAMP | 决策时间 |
feature_config(特征配置表)
| 字段 | 类型 | 说明 |
|---|---|---|
| feature_name | VARCHAR(128) PK | 特征名(如 txn_count_5min) |
| feature_type | ENUM | REALTIME / OFFLINE / EXTERNAL |
| compute_type | VARCHAR(32) | COUNT / SUM / AVG / MAX / DISTINCT_COUNT |
| window_size | VARCHAR(32) | 时间窗口(5m / 1h / 24h / 7d) |
| entity_key | VARCHAR(64) | 聚合维度(user_id / device_id / ip) |
| data_source | VARCHAR(64) | 数据源(kafka_topic / hive_table) |
| status | ENUM | ACTIVE / DISABLED |
model_config(模型配置表)
| 字段 | 类型 | 说明 |
|---|---|---|
| model_id | VARCHAR(64) PK | 模型 ID |
| model_name | VARCHAR(128) | 模型名称 |
| version | VARCHAR(32) | 模型版本 |
| endpoint | VARCHAR(256) | 推理服务地址 |
| weight | DECIMAL(3,2) | 在决策中的权重 |
| status | ENUM | SHADOW / CANARY / ACTIVE / DEPRECATED |
| gray_ratio | DECIMAL(3,2) | 灰度比例 |
| timeout_ms | INT | 推理超时(毫秒) |
| fallback_score | DECIMAL(5,4) | 超时时的默认分数 |
| created_at | TIMESTAMP | 创建时间 |
list_entry(名单表)
| 字段 | 类型 | 说明 |
|---|---|---|
| list_id | VARCHAR(64) PK | 名单 ID |
| list_type | ENUM | BLACK / WHITE / GRAY |
| match_type | ENUM | USER_ID / DEVICE / IP / CARD / MERCHANT |
| match_value | VARCHAR(256) | 匹配值 |
| source | VARCHAR(64) | 来源(INTERNAL / EXTERNAL / INDUSTRY) |
| reason | TEXT | 加入原因 |
| effective_time | TIMESTAMP | 生效时间 |
| expire_time | TIMESTAMP | 过期时间 |
| created_at | TIMESTAMP | 创建时间 |
case_task(案件工单表)
| 字段 | 类型 | 说明 |
|---|---|---|
| case_id | VARCHAR(64) PK | 案件 ID |
| event_id | VARCHAR(64) FK | 关联事件 |
| case_type | ENUM | FRAUD_REVIEW / AML_SAR / APPEAL |
| status | ENUM | PENDING / IN_PROGRESS / CONFIRMED_FRAUD / FALSE_POSITIVE / ESCALATED |
| priority | ENUM | P0 / P1 / P2 |
| assigned_to | VARCHAR(64) | 分配审核员 |
| sla_deadline | TIMESTAMP | SLA 截止时间 |
| review_result | TEXT | 审核结论 |
| created_at | TIMESTAMP | 创建时间 |
| completed_at | TIMESTAMP | 完成时间 |
3.2 状态机设计
风控事件状态机
[接收] → PROCESSING → ┬→ PASSED(通过)
├→ REVIEWING(人审中)→ ┬→ APPROVED(审核通过)
│ └→ REJECTED(审核拒绝)
└→ REJECTED(直接拒绝)
案件工单状态机
[创建] → PENDING → IN_PROGRESS → ┬→ CONFIRMED_FRAUD(确认欺诈)→ [加黑名单+反馈模型]
├→ FALSE_POSITIVE(误杀放行)→ [加白名单+反馈模型]
└→ ESCALATED(升级)→ [高级审核员]
详细状态图见 diagrams/state-machine.mmd。
四、核心组件详细设计
4.1 决策编排引擎(Decision Orchestrator)
设计理念:将风控决策流程建模为 DAG(有向无环图),实现最大并行度。
DAG 执行拓扑
┌─→ [规则引擎] ──┐
[特征提取] → [名单匹配] ─┤ ├→ [决策合并] → [结果输出]
└─→ [模型推理] ──┘
核心机制
- 短路优化:名单匹配命中黑/白名单时直接短路,跳过规则和模型执行
- 并行执行:规则引擎和模型推理使用 Fork-Join 并行执行,取两者中较慢的耗时
- 优先级机制:名单 > 规则 > 模型(名单结果不可覆盖;规则 REJECT 优先于模型 PASS)
- 超时降级:
- 整体超时 50ms,分配给子环节:特征提取 10ms / 名单匹配 5ms / 规则+模型 25ms / 编排 10ms
- 规则超时 → 使用已完成规则的结果
- 模型超时 → 使用 fallback_score(默认中等风险)
- 全部超时 → 按场景降级(交易放行/信贷拒绝)
决策合并策略
最终决策 = f(名单结果, 规则结果集, 模型分数)
逻辑:
1. 黑名单命中 → REJECT(不可覆盖)
2. 白名单命中 → PASS(不可覆盖)
3. 任一规则命中 REJECT → REJECT
4. 任一规则命中 REVIEW 或 模型分数 > review_threshold → REVIEW
5. 所有规则 PASS 且 模型分数 < pass_threshold → PASS
4.2 规则引擎(Rule Engine)
DSL 语法设计
// 示例规则
RULE "大额境外交易"
SCENE: TRANSACTION
PRIORITY: 10
WHEN:
event.amount > 50000
AND event.geo_location NOT IN ("CN", "HK", "MO")
AND feature("txn_count_24h", event.user_id) < 3
THEN:
REJECT
REASON: "大额境外交易,用户近24小时交易次数少于3"
END
RULE "高频小额交易"
SCENE: TRANSACTION
PRIORITY: 20
WHEN:
feature("txn_count_5min", event.user_id) > 5
AND event.amount < 100
THEN:
REVIEW
REASON: "疑似盗刷:5分钟内多笔小额交易"
END
Rete 算法优化
选择自研 Rete 引擎而非 Drools(见 ADR-001),核心优化点:
- 规则预编译:DSL → AST → 编译后的 Rete 网络,缓存在 JVM 内存
- 增量匹配:只对变化的事实(Working Memory)做增量传播,避免全量重算
- Alpha 节点合并:相同条件的 Alpha 节点共享,减少重复计算
- 短路求值:AND 条件按选择性排序,高选择性条件前置
热更新机制
规则变更流程:
1. 策略分析师在管理后台编辑规则
2. 规则编译服务验证 DSL 语法 + 编译成 Rete 网络
3. 新版本写入配置中心(ZooKeeper)
4. ZooKeeper Watch 通知所有 Rule Engine 实例
5. 各实例异步拉取新版本,编译并替换本地 Rete 网络(双缓冲切换)
6. 替换完成后上报版本号,管理后台确认全量生效
时间线:编辑提交 → 30s 内全量生效(包含编译 + 分发 + 替换)
4.3 特征平台(Feature Store)
特征平台是风控引擎的「数据大脑」,直接决定规则和模型的表达能力。
实时特征(Flink 计算)
| 特征名 | 窗口 | 聚合 | 示例值 | 用途 |
|---|---|---|---|---|
| txn_count_5min | 5 分钟 | COUNT | 3 | 高频交易检测 |
| txn_amount_1h | 1 小时 | SUM | 15000.00 | 大额累计检测 |
| distinct_merchant_24h | 24 小时 | DISTINCT_COUNT | 12 | 分散消费检测 |
| max_single_txn_1h | 1 小时 | MAX | 8000.00 | 突增金额检测 |
| login_fail_10min | 10 分钟 | COUNT | 5 | 暴力破解检测 |
Flink 实现要点:
- 使用 滑动窗口(Sliding Window)而非滚动窗口,保证边界处特征平滑
- 窗口状态存储在 RocksDB StateBackend,支持大状态
- 计算结果原子写入 Redis(MULTI/EXEC),保证读一致性
- Checkpoint 间隔 10s,保证 Exactly-Once
离线特征(Spark T+1 计算)
| 特征名 | 更新频率 | 数据源 | 示例值 |
|---|---|---|---|
| user_risk_level | T+1 | 用户画像 | HIGH/MEDIUM/LOW |
| avg_monthly_txn | T+1 | 交易流水 | 45.2 |
| account_age_days | T+1 | 用户表 | 365 |
| device_bindcount | T+1 | 设备表 | 2 |
特征一致性保障
训练-推理偏斜(Training-Serving Skew)是 ML 风控的首要挑战:
解决方案:Feature Registry(特征注册中心)
1. 每个特征有唯一定义(名称/计算逻辑/数据源/窗口)
2. Flink 作业和 Spark 作业从同一 Registry 读取计算逻辑
3. 推理时和训练时使用同一套特征提取代码(Feature SDK)
4. 定期运行一致性校验作业:对比实时特征和离线重算结果
4.4 ML 模型 Serving
模型生命周期
训练完成 → 离线评估(AUC/KS) → 注册到 Model Registry
→ Shadow Mode(记录预测但不参与决策)
→ Canary(10% 流量灰度)
→ Active(全量上线)
→ Deprecated(老版本下线)
影子模式(Shadow Mode)
新模型上线最重要的安全网:
- 新模型部署后,先进入 Shadow 状态
- 每个风控事件同时发给新旧模型推理
- 新模型结果仅记录到日志,不参与实际决策
- 运营团队对比新旧模型的表现(准确率/召回率/误杀率)
- 确认新模型效果后,切换为 Canary → Active
模型监控
| 监控指标 | 告警阈值 | 监控频率 | 告警动作 |
|---|---|---|---|
| AUC | < 0.85 | 每小时 | P1 告警 |
| PSI(分布稳定性) | > 0.2 | 每天 | 触发重训 |
| 推理延迟 P99 | > 20ms | 实时 | 自动降级到规则 |
| 推理错误率 | > 1% | 实时 | 自动切换到备用模型 |
4.5 名单系统(List Service)
三级名单
| 名单类型 | 作用 | 数据量 | 匹配策略 |
|---|---|---|---|
| 黑名单 | 直接拒绝 | ~100 万条 | 精确匹配 |
| 白名单 | 直接放行 | ~10 万条 | 精确匹配 |
| 灰名单 | 加严审核 | ~50 万条 | 精确匹配 + 模糊匹配 |
匹配性能优化
查询路径(< 1ms):
1. Bloom Filter 预检(内存,0.1ms)
- 返回「一定不在」→ 跳过名单查询
- 返回「可能在」→ 进入第2步
2. Redis 精确查询(0.5ms)
- 使用 SET 数据结构,O(1) 查询
3. 命中后加载详细信息(名单来源/加入原因/过期时间)
名单来源管理
- 内部名单:案件审核确认欺诈 → 自动加入黑名单
- 外部名单:征信机构/央行反洗钱名单 → 定时批量导入
- 行业共享:联防联控名单 → API 实时同步
五、深度问题
5.1 性能优化
目标:P99 < 50ms,峰值 5 万 TPS
| 优化手段 | 收益 | 实现方式 |
|---|---|---|
| 规则预编译 | 规则匹配从 ms 级降到 us 级 | DSL → Rete 网络预编译到内存 |
| 特征预计算 | 消除实时计算开销 | Flink 持续聚合,结果写 Redis |
| 模型推理优化 | 推理延迟降低 50-70% | PyTorch → ONNX 格式;Batch 推理 |
| 内存计算 | 消除磁盘/网络 I/O | 规则/名单/热特征全部内存化 |
| 连接池预热 | 消除冷启动 | Redis/gRPC 连接池启动时预建立 |
| 短路优化 | 减少无效计算 | 名单命中即短路;规则按选择性排序 |
5.2 高可用设计
多机房部署
机房 A(主) 机房 B(备)
┌──────────────────┐ ┌──────────────────┐
│ Decision Gateway │◄─同步──►│ Decision Gateway │
│ Rule Engine │ │ Rule Engine │
│ ML Serving │ │ ML Serving │
│ Redis (Master) │──复制──►│ Redis (Replica) │
│ Flink Cluster │ │ Flink Cluster │
└──────────────────┘ └──────────────────┘
降级策略矩阵
| 故障场景 | 降级策略 | 风险评估 |
|---|---|---|
| 特征服务不可用 | 使用默认特征值 + 提高规则敏感度 | 中(可能误杀增加) |
| 模型服务不可用 | 纯规则决策 | 低(规则覆盖主要场景) |
| 规则引擎不可用 | 仅名单匹配 + 保守策略 | 高(大量人审) |
| Redis 不可用 | 本地缓存兜底(可能有延迟) | 中 |
| 全部不可用 | 按场景默认策略(交易放行/信贷拒绝) | 高 |
限流与熔断
- 接入层限流:Sentinel 限流,按调用方配额
- 模型熔断:Hystrix 熔断,连续 5 次超时自动熔断,30s 后半开探测
- 降级开关:运维可手动切换为纯规则模式
5.3 准确率 vs 召回率
风控核心矛盾:查全(召回率) vs 不误杀(准确率)。
多级阈值动态调整
模型输出分数范围 [0, 1]:
- score > 0.9 → REJECT(高置信拒绝)
- 0.7 < score ≤ 0.9 → REVIEW(中风险人审)
- score ≤ 0.7 → PASS(低风险放行)
阈值可按场景/时间/维度动态调整:
- 大促期间:适当提高 REJECT 阈值(减少误杀,保障交易体验)
- 盗刷高发期:适当降低 REJECT 阈值(宁可误杀,控制资损)
效果监控
| 指标 | 计算方式 | 目标值 | 监控频率 |
|---|---|---|---|
| 拦截率 | REJECT 数 / 总事件数 | 0.1% - 1% | 实时 |
| 误杀率 | 误杀数 / REJECT 数 | < 5% | 每日 |
| 资损率 | 未拦截欺诈金额 / 总交易金额 | < 0.01% | 每日 |
| 人审率 | REVIEW 数 / 总事件数 | < 5% | 实时 |
5.4 可解释性
金融监管要求风控决策必须可解释。
决策解释链
{
"event_id": "evt_20260413_001",
"decision": "REJECT",
"explanation": {
"list_check": { "result": "NOT_HIT" },
"rules_hit": [
{
"rule_id": "R001",
"rule_name": "大额境外交易",
"matched_conditions": [
"amount=80000 > 50000",
"geo_location=US NOT IN (CN,HK,MO)",
"txn_count_24h=1 < 3"
]
}
],
"model_scores": {
"fraud_model_v3": { "score": 0.92, "top_features": ["amount_zscore: 3.2", "new_merchant: true", "unusual_time: true"] }
},
"final_reason": "命中规则R001(大额境外交易) + 模型高风险评分0.92"
}
}
模型可解释性
- 使用 SHAP 值解释模型预测,输出 Top-5 影响特征
- 审核员可在案件工作台查看完整的决策解释链
- 合规审计可导出任意时间段的全量决策日志
5.5 对抗演化
欺诈手法持续进化,风控系统必须具备快速响应能力。
发现新欺诈模式 → 应急响应流程:
T+0小时:案件系统发现异常 pattern → 告警通知风控团队
T+1小时:分析师定义临时规则(DSL) → 热更新上线(<1分钟生效)
T+24小时:数据团队标注样本 → 启动模型增量训练
T+72小时:新模型完成训练 → 进入 Shadow Mode 观察
T+1周:模型效果验证 → Canary 灰度 → 全量上线
关键闭环:
案件审核结果 → 标注为 True Positive/False Positive → 反馈给特征工程+模型训练
5.6 合规要求
| 合规领域 | 要求 | 系统支持 |
|---|---|---|
| AML(反洗钱) | 大额交易报告/可疑交易报告 | 自动检测+报送接口 |
| CTF(反恐融资) | 制裁名单筛查 | 名单系统+实时匹配 |
| KYC | 客户身份识别 | 与用户中心联动 |
| 数据隐私 | GDPR/个人信息保护法 | 数据脱敏+日志保留策略 |
| 审计追溯 | 决策可审计/可追溯 | 全链路决策日志 + 7 年保留 |
六、架构决策摘要
| 决策点 | 选择 | 核心理由 | 详细 ADR |
|---|---|---|---|
| 规则引擎 | 自研 Rete 引擎 | 性能可控/无外部依赖/深度定制 | ADR-001 |
| 特征计算 | Flink 流批一体 | 统一计算引擎/特征一致性/低延迟 | ADR-002 |
| 决策编排 | DAG 模式 | 最大并行度/灵活扩展/短路优化 | ADR-003 |
| 模型推理 | ONNX Runtime | 跨框架/高性能/CPU 友好 | — |
| 名单匹配 | Bloom Filter + Redis | 预检快/精确查询 O(1) | — |
| 配置中心 | ZooKeeper | 强一致/Watch 推送/成熟稳定 | — |
| 消息队列 | Kafka | 高吞吐/持久化/生态成熟 | — |
| 监控 | Prometheus + Grafana | 生态丰富/开源/可定制 | — |
七、面试口述版
2 分钟版本
风控引擎的核心架构分三层:接入层接收各业务系统的风控请求,通过 gRPC 同步调用;决策层是核心,采用 DAG 编排模式,先做名单匹配快速短路,然后规则引擎和 ML 模型并行执行,最后合并决策;数据层包括 Flink 实时计算的滑动窗口特征和 Redis 存储的名单与特征。
要做到 P99 < 50ms,关键设计有三点:一是规则预编译到内存用 Rete 算法匹配,二是特征预计算存 Redis 避免实时聚合,三是模型用 ONNX 优化推理。高可用方面,多机房部署,超时降级策略按场景区分——交易超时放行保体验,信贷超时拒绝控风险。
5 分钟版本
在 2 分钟版本基础上追加:
规则引擎我选择自研而不是 Drools,原因是金融场景需要极致性能——Drools 的通用性带来了不必要的开销,自研 Rete 引擎可以针对我们的规则 DSL 做深度优化,预编译后单次匹配在微秒级。规则热更新通过 ZooKeeper Watch + 双缓冲切换实现,30 秒内全量生效。
特征平台采用流批一体架构,Flink 做实时滑动窗口聚合(如近 5 分钟交易次数),Spark 做 T+1 离线画像。解决训练-推理偏斜的关键是 Feature Registry——训练和推理共用同一套特征定义和提取代码。
ML 模型上线采用 Shadow → Canary → Active 的渐进式发布。Shadow 模式下新模型只记录不决策,是最重要的安全网。模型监控关注 AUC 和 PSI,PSI > 0.2 触发自动重训。
合规方面,全链路决策日志保留 7 年,支持 SHAP 可解释性,自动触发 AML 大额可疑交易报送。
15 分钟版本
在 5 分钟版本基础上,深入展开:
- 数据模型设计(各核心表的关键字段和设计考量)
- 状态机设计(风控事件和案件工单的完整状态流转)
- 降级策略矩阵(各故障场景的详细应对方案)
- 准确率 vs 召回率的动态平衡策略
- 对抗演化的闭环机制(案件反馈 → 规则更新 → 模型重训)
- 跨机房部署的特征同步方案
八、自评与反思
设计亮点
- DAG 决策编排:相比串行 Pipeline 减少了约 40% 的端到端延迟
- 名单短路:黑/白名单命中直接返回,避免无效的规则和模型计算
- Shadow Mode:模型上线的安全网机制,在金融场景中不可或缺
- 场景化降级:交易超时放行 vs 信贷超时拒绝,体现了对业务的深度理解
- 特征一致性:Feature Registry 解决训练-推理偏斜,是 ML 风控的核心挑战
设计取舍
- 自研 Rete vs Drools:选择了性能,牺牲了社区生态和学习曲线
- Redis 特征存储 vs 内嵌式:选择了水平扩展能力,牺牲了极致延迟(增加 ~1ms 网络开销)
- 同步决策 vs 异步决策:选择了同步阻塞式(业务需要实时结果),异步仅用于事后分析
进一步优化方向
- 联邦学习:多机构联合建模,解决数据孤岛问题
- 图神经网络:利用交易图谱识别团伙欺诈
- 自适应阈值:基于实时资损率自动调整决策阈值
- A/B 测试平台:支持更精细的策略实验
- 知识图谱:构建实体关系图谱,增强关联分析能力
面试常见追问
| 追问 | 回答要点 |
|---|---|
| 为什么不用 Drools? | 性能不可控、JVM 冷启动慢、定制化困难 |
| 特征延迟怎么保证? | Flink 滑动窗口 + Redis 原子写 + 本地缓存 |
| 模型和规则冲突怎么办? | 优先级机制:名单 > 规则 > 模型 |
| 误杀率怎么控制? | 多级阈值 + 人审兜底 + 案件反馈闭环 |
| 日均 10 亿怎么扛? | 无状态水平扩展 + Kafka 削峰 + 内存计算 |