12 KiB
12 KiB
附表 · 风控规则表(冻结版)
版本:v1.1(冻结部分 v1.0 原文不动 · 2026-09-07 追加 RISK-006/007/008 并入;变更已经独立 AI 评审→修订→复审通过,履行 PR 审批流程)
定位:团队共识文档。任何 Agent 涉及以下规则时,必须在此表查找,不得自行发明。
编号体系:SUIT-*适当性 /RISK-*事件规则引擎 /AML-*名单 /AI-*AI 行为边界 /TRADE-*交易时间 /DESENS-*脱敏 /MOCK-*模拟数据
与 PRD 的关系:本表是 PRD《风控监测Agent》FR-2/FR-3/FR-5/§7/§4A 引用的规则唯一权威来源。
变更:冻结后变更需 PR 审批并更新版本号。
1. 适当性管理规则(SUIT · 硬编码,不可绕过)
| 规则编号 | 规则内容 | 代码实现位置 | 违规后果 |
|---|---|---|---|
| SUIT-001 | 客户风险等级 C1 只能购买 R1 产品 |
app/service/suitability.py |
适当性违规 -10 |
| SUIT-002 | 客户风险等级 C2 只能购买 R1/R2 产品 |
app/service/suitability.py |
适当性违规 -10 |
| SUIT-003 | 客户风险等级 C3 只能购买 R1/R2/R3 产品 |
app/service/suitability.py |
适当性违规 -10 |
| SUIT-004 | 客户风险等级 C4 可购买 R1-R4 产品 |
app/service/suitability.py |
适当性违规 -10 |
| SUIT-005 | 客户风险等级 C5 可购买 R1-R5 产品 |
app/service/suitability.py |
适当性违规 -10 |
| SUIT-006 | 年龄 ≥ 70 岁的客户,适当性判定时按最高 C3 封顶(测评得 C4/C5 仍按 C3 校验);age IS NULL 跳过本条并在 reasons 标注"年龄缺失,建议人工复核" |
app/service/suitability.py |
适当性违规 -10 |
| SUIT-007 | Agent 生成产品推荐前必须调用 suitability_check();不匹配时禁止生成推荐语,必须输出拒绝话术(含原因 + 引导联系持证投顾)。推荐输出须附免责声明并标注"需经持证投顾审核",禁止具体操作指令(见 AI-006) |
客户财富 / 代理人助手 Agent | 适当性违规 -10 |
| SUIT-008 | 客户风险等级有效期为 365 天(.env: RISK_ASSESSMENT_VALID_DAYS 可配),超期后等级矩阵照常计算,但阻断新产品购买并提示重新测评 |
app/service/suitability.py |
功能缺失 -10 |
适当性匹配矩阵(代码直接用)
R1 R2 R3 R4 R5
C1 ✓ ✗ ✗ ✗ ✗
C2 ✓ ✓ ✗ ✗ ✗
C3 ✓ ✓ ✓ ✗ ✗
C4 ✓ ✓ ✓ ✓ ✗
C5 ✓ ✓ ✓ ✓ ✓
判定语义(对齐 PRD FR-2):
is_matched= 纯矩阵结果(含 SUIT-006 封顶后判定);blocked= 最终是否阻断(= NOT is_matched 或 SUIT-008 过期)。
2. 事件规则引擎(RISK · 风控监测 Agent)
| 规则编号 | 规则内容 | 触发阈值 | 系统动作 | 代码实现位置 |
|---|---|---|---|---|
| RISK-001 | 单笔大额预警 | 单笔 ≥ 500,000 元 | 预警单(pending_review)+ Redis 推送,不自动拦截 | app/service/risk/ |
| RISK-002 | 单日累计大额预警 | 同一客户当日申赎合计 ≥ 500,000 元(口径:core_trade) |
同上 | 同上 |
| RISK-003 | 频繁交易预警 | 同一客户同一产品当日申赎合计 ≥ 3 笔 | 同上(当日同客户同类型聚合出单) | 同上 |
| RISK-004 | 接近阈值试探预警 | 5 分钟内 ≥ 3 笔且每笔 ≥ 400,000 元 | 预警单(pattern) | 同上 |
| RISK-005 | 先小后大模式预警 | 当日首次大额前已存在 ≥ 3 笔 ≤ 10,000 元(不要求连续) | 预警单(pattern),文案标注模式 | 同上 |
| RISK-006 | 高风险资产配置集中度预警(v1.1) | 客户持仓中 R4+R5 市值占比 ≥ RISK_CONCENTRATION_THRESHOLD(默认 80%;市值口径 = core_holding.market_value 直接汇总) |
预警单(落库 alert_type='pattern' + payload.alert_subtype='concentration',并入事件类聚合)+ L3 watch + Redis 推送 |
app/service/risk/rules.py |
| RISK-007 | 预警单处置时效监控与自动升级(v1.1) | pending_review 超 RISK_ESCALATION_L1_HOURS/L2_HOURS(默认 4h/24h,AML 缩短为 1h/4h,settings 注入) |
升级推送(notify_role 追加 risk_manager/compliance)+ payload 写升级标记 + audit 留痕;不改 status |
app/service/risk/escalation_service.py + scripts/cron/escalation_scan.py |
| RISK-008 | 代理人异常行为链识别(v1.1) | 24h 内同一代理人诱导调仓 ≥3 次;或 72h 内越权试探(AUTH_403_SCOPE)≥5 次;或 24h 内非名下客户查询被拒 ≥10 次(阈值/窗口 settings 注入) |
代理人维度独立预警单(落库 alert_type='pattern' + payload.alert_subtype='agent_behavior')+ Redis 推送(risk_officer/risk_manager) |
app/service/risk/agent_behavior_service.py + scripts/cron/agent_behavior_scan.py |
⚠️ RISK-007 状态机与升级补充约束(v1.1 追加,对照真实 DDL)
risk_alert.statusENUM 冻结五值不含escalated(DDL 已核实)→ 本期不使用任何新状态值- 升级信息全部由
payload承载:escalation_level(1/2)+escalated_at;LEVEL_1 与 LEVEL_2 同机制,均先持久化 payload 标记再推送(LEVEL_1 持久化是幂等依据);该标记仅定时任务可写,人工处置 API 不感知不覆盖 - 升级幂等:仅当"本次计算级别 > payload 已记录级别"才执行动作,同级别不重复推送
- 每张单独立计时独立升级;同客户多张单同周期同级升级合并推送降噪
- 人工处置照常走
pending_review → 三态(FR-4 冻结不变);handler_result枚举外值 → 422 - 定时任务审计留痕显式
new_trace()生成 trace_id 并贯通 payload 与推送消息 escalated状态列入二期改表挂账
⚠️ RISK-008 出单维度与数据源补充约束(v1.1 追加)
- 不按客户维度聚合,按
payload.actor_id(代理人)+ 自然日去重(risk_alert无actor_id列,代理人标识由 payload 承载;customer_id冻结 NOT NULL → 填行为链主要涉及客户,payload 声明其语义为"涉及客户") - 同代理人同日命中多个子条件(A/B/C)→ 只一张 pending 单,
triggered_rules追加子条件标识 risk_score = 75(静态映射,R-05 评分模型接入后替换)- 数据源统一为
audit_log:条件 B =event_type='authz' AND code='AUTH_403_SCOPE';条件 C =event_type='authz' AND code IN ('AUTH_403_NOT_OWNER','AUTH_403_NOT_ASSIGNED')∪ 对话线 blocked 归属类拒绝(record_authz_denial双写);条件 A =event_type='trade_request'按发起人 actor 归属且排除本人交易(演示期 risk_demo 扮演代理人,见演示 SOP);input_guard_log不作为数据源(网关路径不写且无 code 字段) - 行为链明细展示范围:仅
risk_officer/risk_manager(上级角色,staff_type='risk_officer' + roles=["risk_manager"],不改表);其他角色 fail-closed;对话线入口维持"仅 risk_officer",经理统一走 HTTP 台账只读
⚠️ 风控 Agent 行为边界(硬约束)
- ❌ 禁止自动冻结账户
- ❌ 禁止自动拦截已发生交易(唯一例外:SUIT 不匹配时阻断交易请求进入流程)
- ❌ 禁止自动调整客户正式风险等级(C1~C5)
- ❌ 禁止自动上报监管
- ✅ 只能:监测 → 预警 → 通知 → 记录(处置由风控专员人工完成)
3. 反洗钱名单规则(AML)
| 规则编号 | 规则内容 | 说明 |
|---|---|---|
| AML-001 | 名单命中 → 生成 alert_type='aml' 最高级预警(risk_score=95)+ 紧急通知(notify_role=["risk_officer","compliance"])+ 标记 L3 monitor_tier='high' |
不自动冻结账户;处置由风控专员/合规官人工完成 |
| AML-002 | 匹配算法一期仅 display_name 归一化 + 相似度 ≥ match_threshold(默认 0.85);证件/银行卡匹配待 Core 提供证件数据后启用 |
名单镜像表 risk_aml_list |
4. 数据脱敏规则(DESENS)
| 规则编号 | 字段类型 | 脱敏规则 | 示例 | 代码实现位置 |
|---|---|---|---|---|
| DESENS-001 | 身份证号 | 保留前 3 位 + 后 4 位,中间 **** |
110****1234 |
app/utils/desensitize.py |
| DESENS-002 | 手机号 | 保留前 3 位 + 后 4 位,中间 **** |
138****1234 |
同上 |
| DESENS-003 | 姓名 | 保留姓氏,其余 ** |
张** |
同上 |
| DESENS-004 | 银行卡号 | 保留后 4 位,其余 **** |
****1234 |
同上 |
| DESENS-005 | 资产金额 | 前端展示保留整数位,隐藏小数 | ¥1,234,***.** |
前端组件 |
脱敏原则
- 数据库层:存储原始数据(
customer_id为系统内部代理键,不脱敏,保证审计索引有效) - API 层:返回脱敏后数据(默认)
- 前端层:二次确认脱敏(防后端遗漏)
- LLM 上下文:传入 LLM 的客户数据必须已脱敏(预警 payload、通知、对话输出)
- 审计
input_summary:脱敏后落库(按上表规则)
5. AI 行为边界规则(AI)
| 规则编号 | 规则内容 | 违规后果 |
|---|---|---|
| AI-001 | AI 不得代替客户执行申购、赎回、转账等交易操作 | 安全事故 -10 |
| AI-002 | 所有投资分析类输出必须附带标准免责声明 | 功能缺失 -5 |
| AI-003 | 产品推荐、投资方案必须标注「需经持证投顾审核」 | 功能缺失 -5 |
| AI-004 | AI 不得生成具体收益承诺(如「保证年化 8%」) | 安全事故 -10 |
| AI-005 | AI 不得询问客户密码、验证码、CVV 等敏感信息 | 安全事故 -10 |
| AI-006 | AI 不得输出具体操作指令("现在买入 X 万元""我帮您下单""帮你调仓"类表述一律拦截);推荐仅限产品与理由 | 安全事故 -10 |
标准免责声明(强制追加)
本内容仅为投资分析参考,不构成任何直接投资建议,不构成对任何产品的收益承诺,
据此操作风险自负,请谨慎对待。最终投资方案需经持证投资顾问审核确认。
预警系统级声明(区别于客户免责声明)
本预警由系统自动生成,最终判定需经风控专员人工审核。
6. 交易时间规则(TRADE · 本期风控不涉及,供后续模块沿用)
| 规则编号 | 规则内容 | 代码实现位置 |
|---|---|---|
| TRADE-001 | 交易日为周一至周五(不含法定节假日) | app/utils/trade_calendar.py(后续模块) |
| TRADE-002 | 交易日 15:00 前提交的申购/赎回,按 T 日净值处理 | 交易模块 |
| TRADE-003 | 交易日 15:00 后提交的申购/赎回,按 T+1 日净值处理 | 交易模块 |
| TRADE-004 | 基金申购确认份额一般为 T+1,查询持仓为 T+2 | 交易模块 |
| TRADE-005 | 非交易日提交的申请,顺延至下一个交易日处理 | 交易模块 |
模拟交易网关一期不校验交易时间窗口(演示可随时发起),真实交易系统接入后由其自行遵守。
7. Mock 数据一致性规则(MOCK)
| 规则编号 | 规则内容 | 校验脚本 |
|---|---|---|
| MOCK-001 | 客户年龄范围:18-80 岁 | validate_customer_age() |
| MOCK-002 | 身份证号格式:18 位,校验位正确 | validate_id_card() |
| MOCK-003 | 手机号:11 位,以 1 开头 | validate_phone() |
| MOCK-004 | 开户时间 < 首次交易时间 | validate_timeline() |
| MOCK-005 | 风险测评时间 < 首次购买时间 | validate_timeline() |
| MOCK-006 | 单笔交易金额 ≤ 账户总资产 × 120% | validate_trade_amount() |
| MOCK-007 | 客户风险等级与年龄匹配(≥70岁最高C3) | validate_risk_age_match() |
| MOCK-008 | 交易记录的产品风险等级 ≤ 客户风险等级 | validate_trade_suitability() |
| MOCK-009 | 产品收益率范围:货币 1.5%-3%,债券 3%-6%,混合 5%-15%,股票 -20%~30% | validate_product_return() |
本表 v1.0 冻结(2026-09-06),v1.1 追加 RISK-006/007/008(2026-09-07 经独立评审→修订→复审通过后并入);任何规则变更需经团队评审并更新版本号。原本地《02-业务规则表》停止维护,以本表为准。