本文档包含两个PRD示例,展示两种产品设计思路的本质差异
| 对比维度 | 堆砌式设计 ❌ | 体系化设计 ✅ |
|---|---|---|
| 概念清晰度 | 维度/层级/级别概念模糊,可相互替代 | 每个概念有明确定义和边界,MECE原则 |
| 场景扩展 | 每个场景独立开发,重复造轮子 | 新场景通过配置组合现有能力 |
| 数据模型 | 一张大宽表承载所有数据 | 按概念分层建模,RiskEvent/RiskSnapshot分离 |
| 问题-方案分离 | 场景与实现深度绑定 | 问题域与方案域独立演化 |
| 指标管理 | 每个场景重复定义"近7天交易" | 指标中心统一定义,多场景复用 |
| 规则复用 | 规则与场景绑定,无法复用 | 规则是独立概念,可被多个策略流引用 |
| 可维护性 | 场景越多越混乱,无法收敛 | 场景越多能力沉淀越多,形成复利效应 |
公司跨境支付业务发展迅速,需要建设风控系统来防范交易风险。
支持多种风控场景,满足业务风控需求。
系统需要支持以下场景的风控:
规则要素:
| 字段名 | 类型 | 说明 |
|---|---|---|
| rule_id | 字符串 | 规则ID |
| rule_name | 字符串 | 规则名称 |
| level | 枚举 | 规则级别:高风险/中风险/低风险 |
| dimension | 枚举 | 维度:用户维度/交易维度/商户维度/设备维度/渠道维度 |
| layer | 枚举 | 层级:事前/事中/事后 |
| condition | JSON | 规则条件 |
| action | 枚举 | 处置动作:拦截/放行/人工审核/打标签 |
| inherit_from | 字符串 | 继承自(父规则ID) |
| scene | 字符串 | 适用场景 |
| priority | 数字 | 优先级 |
| 字段名 | 类型 | 说明 |
|---|---|---|
| source_id | 字符串 | 数据源ID |
| source_name | 字符串 | 数据源名称 |
| source_type | 枚举 | 类型:内部/外部/API/文件/数据库 |
| config | JSON | 配置信息 |
| scene | 字符串 | 适用场景 |
| 字段名 | 类型 | 说明 |
|---|---|---|
| index_id | 字符串 | 指标ID |
| index_name | 字符串 | 指标名称 |
| calc_type | 枚举 | 计算方式:实时/离线/混合 |
| formula | 字符串 | 计算公式 |
| scene | 字符串 | 适用场景 |
| dimension | 枚举 | 所属维度 |
| 字段名 | 类型 | 说明 |
|---|---|---|
| endpoint_id | 字符串 | 接入点ID |
| endpoint_name | 字符串 | 接入点名称 |
| business_type | 枚举 | 业务类型:支付/收款/转账/提现 |
| scene | 字符串 | 场景标识 |
| rules | 数组 | 适用的规则列表 |
| data_source | 字符串 | 使用的数据源 |
CREATE TABLE risk_event (
event_id VARCHAR(64) PRIMARY KEY,
event_type VARCHAR(32),
event_time TIMESTAMP,
scene_code VARCHAR(32),
business_type VARCHAR(32),
business_code VARCHAR(64),
merchant_id VARCHAR(64),
merchant_name VARCHAR(128),
merchant_level INT,
user_id VARCHAR(64),
user_name VARCHAR(64),
user_register_time TIMESTAMP,
user_level INT,
trade_id VARCHAR(64),
trade_amount DECIMAL(18,2),
trade_currency VARCHAR(8),
trade_country VARCHAR(16),
pay_method VARCHAR(32),
device_id VARCHAR(64),
device_type VARCHAR(32),
ip_address VARCHAR(32),
ip_country VARCHAR(16),
risk_level VARCHAR(16),
risk_tag VARCHAR(256),
hit_rules VARCHAR(512),
decision VARCHAR(16),
action VARCHAR(32),
-- 预留50个扩展字段
ext_field_1 VARCHAR(256),
ext_field_2 VARCHAR(256),
...
ext_field_50 VARCHAR(256),
create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
设计说明:所有数据统一存储,方便查询,避免多表关联。
CREATE TABLE risk_rule (
rule_id VARCHAR(64) PRIMARY KEY,
rule_name VARCHAR(128),
rule_desc VARCHAR(512),
level VARCHAR(16),
dimension VARCHAR(32),
layer VARCHAR(16),
scene_code VARCHAR(32),
condition_json TEXT,
action VARCHAR(32),
inherit_rule_id VARCHAR(64),
priority INT,
status TINYINT DEFAULT 1,
create_time TIMESTAMP
);
规则可以继承其他规则的条件,减少重复配置。
本文档描述跨境支付风控引擎的产品设计,遵循**领域驱动设计(DDD)**原则,将问题域(业务问题)与方案域(技术实现)分离,通过清晰的概念模型支撑多场景业务。
┌─────────────────────────────────────────────────────────────────┐
│ 问题域(Problem Space) │
├─────────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ 风险事件 │ │ 风险处置 │ │ 风险快照 │ │
│ │ RiskEvent │ │ RiskResponse │ │ RiskSnapshot │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────────────────┐
│ 方案域(Solution Space) │
├─────────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ 规则 │ │ 指标 │ │ 数据源 │ │
│ │ Rule │ │ Indicator │ │ DataSource │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────────┐ │
│ │ 接入点 │ │ 策略流 │ │ 决策结果 │ │
│ │ AccessPoint │ │ DecisionFlow │ │ DecisionResult │ │
│ └──────────────┘ └──────────────┘ └──────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
核心原则:
定义:风控系统需要分析判断的一个业务活动实例。
解决的问题:统一描述"发生了什么事",不依赖于具体业务类型。
| 属性 | 类型 | 说明 |
|---|---|---|
| eventId | 字符串 | 事件唯一标识 |
| eventType | 枚举 | 事件类型:PAYMENT/TRANSFER/WITHDRAWAL/REGISTER |
| eventTime | 时间戳 | 事件发生时间 |
| eventData | Map | 事件原始数据(业务数据) |
| initiator | Participant | 事件发起方(用户/商户) |
| counterpart | Participant | 事件对手方(如有) |
关键设计:
定义:风险事件发生时,风控视角下该事件的完整状态快照。
解决的问题:为规则判断提供所需的全部上下文信息,确保判断时可复现。
| 属性 | 类型 | 说明 |
|---|---|---|
| snapshotId | 字符串 | 快照唯一标识 |
| eventId | 字符串 | 关联的事件ID |
| snapshotTime | 时间戳 | 快照生成时间 |
| indicators | Map | 计算后的指标值(指标ID → 值) |
| tags | List | 已打上的标签(如:新用户、高风险国家) |
| context | Map | 上下文信息(如:关联的历史事件) |
关键设计:
定义:针对风险判定结果采取的业务行动。
解决的问题:统一描述"发现了风险后怎么办",实现处置策略的标准化。
| 类型 | 业务含义 | 适用场景 |
|---|---|---|
| ACCEPT | 接受,放行通过 | 无风险或风险可接受 |
| REJECT | 拒绝,拦截阻断 | 确认存在风险 |
| REVIEW | 转人工审核 | 需要人工判断 |
| CHALLENGE | 增加验证挑战(如OTP) | 疑似风险需进一步确认 |
| DELAY | 延迟处理 | 暂时挂起等待更多信息 |
定义:向风控引擎提供原始数据的来源。
解决的问题:抽象数据获取方式,使规则不关心数据从哪来。
| 类型 | 说明 | 示例 |
|---|---|---|
| INTERNAL_DB | 内部数据库 | 用户中心、交易记录 |
| EXTERNAL_API | 外部API | 征信查询、黑名单服务 |
| MESSAGE_QUEUE | 消息队列 | 实时交易流、行为日志 |
| CACHE | 缓存 | Redis中的用户画像 |
定义:基于数据源计算得出的、可用于风险判断的量化值。
解决的问题:将原始数据转化为可直接用于决策的风控特征。
| 类型 | 定义 | 示例 |
|---|---|---|
| ATOMIC | 原子指标,直接从数据源获取 | 用户ID、交易金额 |
| DERIVED | 派生指标,基于原子指标计算 | 交易金额分级(高/中/低) |
| AGGREGATE | 聚合指标,基于时间窗口统计 | 近7天交易笔数 |
关键设计:
定义:基于指标值进行逻辑判断,输出风险判定结果的逻辑单元。
解决的问题:将风控专家的经验转化为可执行、可管理的判断逻辑。
| 类型 | 说明 | 适用场景 |
|---|---|---|
| CONDITION | 条件规则,IF-THEN逻辑 | 简单阈值判断 |
| SCORECARD | 评分卡,多维度加权评分 | 信用评估 |
| MODEL | 机器学习模型 | 复杂模式识别 |
| AGGREGATION | 聚合规则,组合其他规则 | 策略组合 |
规则条件语法示例:
condition:
operator: AND
conditions:
- indicator: txn_amount_7d_sum
operator: GT
value: 10000
- indicator: user_register_days
operator: LT
value: 30
output:
decision: REVIEW
riskScore: 70
tags: ["新用户大额", "高频交易"]
定义:由多个规则按特定逻辑编排而成的决策流程。
解决的问题:支持复杂的策略编排,实现规则的组合、分流、并行等。
策略流节点类型:
| 节点类型 | 说明 |
|---|---|
| START | 起始节点 |
| RULE | 规则执行节点 |
| CONDITION | 条件分支节点 |
| AGGREGATE | 规则聚合节点(取最大/最小/平均) |
| DECISION | 决策输出节点 |
| END | 结束节点 |
策略流示例:
[START] → [白名单检查] → {通过?} → [YES] → [规则集A] → [AGGREGATE] → [DECISION] → [END]
↓
[NO] → [直接拒绝] → [END]
定义:业务系统接入风控引擎的入口配置。
解决的问题:管理不同业务场景使用风控能力的入口,实现场景与策略的解耦。
关键设计:
┌────────────────────────────────────────────────────────────────────┐
│ 业务系统 │
└─────────────────────┬──────────────────────────────────────────────┘
│ 发送事件数据
↓
┌────────────────────────────────────────────────────────────────────┐
│ 接入点(AccessPoint) │
│ ├─ 接收事件数据 → 转换为 RiskEvent │
│ ├─ 调用快照服务 → 生成 RiskSnapshot │
│ └─ 调用决策服务 → 执行 DecisionFlow │
└─────────────────────┬──────────────────────────────────────────────┘
│
┌─────────────┼─────────────┐
↓ ↓ ↓
┌──────────────┐ ┌──────────┐ ┌──────────────┐
│ 数据源管理 │ │ 指标计算 │ │ 策略执行 │
│DataSource │ │Indicator │ │ DecisionFlow │
└──────────────┘ └──────────┘ └──────────────┘
│
↓
┌────────────────────────────────────────────────────────────────────┐
│ 决策结果(DecisionResult) │
│ ├─ 决策类型:ACCEPT/REJECT/REVIEW/CHALLENGE/DELAY │
│ ├─ 风险评分:0-100 │
│ ├─ 命中规则列表 │
│ └─ 风险标签列表 │
└─────────────────────┬──────────────────────────────────────────────┘
│
↓
┌────────────────────────────────────────────────────────────────────┐
│ 风险处置(RiskResponse) │
│ └─ 映射为业务动作,执行处置 │
└────────────────────────────────────────────────────────────────────┘
业务系统 ──发送事件──→ 接入点 ──1.创建事件──→ 风险事件(RiskEvent)
│
└─2.生成快照──→ 快照服务
│ │
│ ├─查询数据源(DataSource)
│ ├─计算指标(Indicator)
│ └─组装快照(RiskSnapshot)
│
└─3.执行策略──→ 策略引擎
│
├─加载策略流(DecisionFlow)
├─执行规则(Rule)
└─聚合决策
│
└─4.返回结果──→ 决策结果(DecisionResult)
│
├─转换为风险处置(RiskResponse)
└─执行处置动作
1. 定义数据源(DataSource)
└─ 配置数据从哪来、什么格式
2. 定义指标(Indicator)
└─ 基于数据源定义可计算的指标
3. 定义规则(Rule)
└─ 使用指标构建判断逻辑
4. 编排策略流(DecisionFlow)
└─ 将规则组合成决策流程
5. 配置接入点(AccessPoint)
└─ 绑定事件类型与策略流
| 对比维度 | 堆砌式设计 ❌ | 体系化设计 ✅ |
|---|---|---|
| 概念清晰度 | 维度/层级/级别概念模糊,可相互替代 | 每个概念有明确定义和边界,MECE原则 |
| 场景扩展 | 每个场景独立开发,重复造轮子 | 新场景通过配置组合现有能力 |
| 数据模型 | 一张大宽表承载所有数据 | 按概念分层建模,RiskEvent/RiskSnapshot分离 |
| 问题-方案分离 | 场景与实现深度绑定 | 问题域(RiskEvent/RiskResponse)与方案域(Rule/Indicator)独立演化 |
| 指标管理 | 每个场景重复定义"近7天交易" | 指标中心统一定义,多场景复用 |
| 规则复用 | 规则与场景绑定,无法复用 | 规则是独立概念,可被多个策略流引用 |
| 处置标准化 | 每个场景自定义处置方式 | RiskResponse统一抽象,5种标准处置类型 |
| 可维护性 | 场景越多越混乱,无法收敛 | 场景越多能力沉淀越多,形成复利效应 |
功能堆砌是"做加法":每来一个需求就做一个功能,最后变成一团乱麻。
体系化设计是"做乘法":把能力抽象成模块,新业务是现有能力的组合配置。
对风控业务来说,体系化设计的核心价值是:让风控能力成为可复用的基础设施,而不是每次从0开始的工程项目。