> ## Documentation Index
> Fetch the complete documentation index at: https://docs.didit.me/llms.txt
> Use this file to discover all available pages before exploring further.

# 事件规则：速率、比率、序列与关联

> Didit 提供基于事件数据的速率规则、比率规则、有序序列规则和跨主体关联规则，这些规则与交易规则使用同一个规则构建器编写。

[事件](https://docs.didit.me/zh/transaction-monitoring/events.md)由与交易相同的引擎进行评估。规则模型、条件词汇和操作集合都是同一套，规则只需声明其适用的记录类型。

## 适用于

`scope.record_types` 决定规则针对哪些记录触发。

| `record_types` | 触发于 |
| - | - |
| 省略或 `["transaction"]` | 仅交易 - **默认值** |
| `["event"]` | 仅事件 |
| `["transaction", "event"]` | 两者 |

> [!NOTE]
>
> 省略该字段时，规则仅针对交易。在事件功能推出之前编写的所有规则，其行为保持不变；规则也不会因为范围为空而开始匹配登录事件。

在控制台中，这一设置对应规则触发步骤上的 **适用于** 选择器。选择“事件”后会显示 **事件类别** 复选列表，用于进一步收窄规则范围；若全部不勾选，则对所有类别进行评估。

```json theme={null}
{
  "title": "Failed login burst",
  "scope": {
    "record_types": ["event"],
    "event_categories": ["security"]
  },
  "aggregation": [
    {
      "metric": "count",
      "operator": "gte",
      "value": 3,
      "window": "30m",
      "filters": {
        "subject_vendor_data": "__current__",
        "event.action_type": "login_failed"
      }
    }
  ],
  "actions": [
    { "type": "add_score", "value": 40 },
    { "type": "change_status", "value": "IN_REVIEW" }
  ]
}
```

`"__current__"` 表示“与正在评估的事件具有相同的值”。借助它，规则无需指定具体名称即可表达*按主体*、*按设备*或*按回合*的逻辑。

没有分组值的记录永远不会被归为一组。没有设备指纹的事件不会与其他同样没有设备指纹的事件被视为“同一设备”；未指定主体的事件也不会与其他匿名事件被视为“同一主体”。当被评估的事件缺少某个 `"__current__"` 字段的值时，无论使用何种运算符，该聚合都不会匹配。

## 事件字段

条件读取带命名空间的路径。你已经熟悉的交易词汇（`action_type`、`subject_vendor_data`、`subject_ip_country`、`custom_values.<key>`）同样可以在事件上解析。

| 分组 | 路径 |
| - | - |
| 事件 | `event.category`、`event.action_type`、`event.occurred_at`、`event.amount`、`event.currency`、`event.direction`、`event.session_id`、`event.session_sequence`、`event.score`、`event.status`、`event.ingest_source`、`event.retention_class`、`event.subject_vendor_data`、`event.business_vendor_data` |
| 设备与网络 | `event.device.fingerprint`、`event.device.persistent_device_id`、`event.device.bot_score`、`event.ip.address`、`event.ip.country`、`event.ip.asn_number`、`event.ip.asn_organization`、`event.ip.is_vpn_or_tor`、`event.ip.is_data_center`、`event.ip.proxy_type`、`event.ip.country_name`、`event.ip.city`、`event.ip.connection_type`、`event.ip.travel_distance_km`、`event.ip.travel_speed_kmh` |
| 游戏 | `event.gameplay.game_id`、`event.gameplay.table_id`、`event.gameplay.round_id`、`event.gameplay.hand_id`、`event.gameplay.match_id`、`event.gameplay.market_id`、`event.gameplay.side`、`event.gameplay.role`、`event.gameplay.counterparty_vendor_data`、`event.gameplay.net_result_amount`、`event.bonus.bonus_id`、`event.affiliate.affiliate_code` |
| 支付与争议 | `event.payment.reference_id`、`event.payment.payment_fingerprint`、`event.payment.instrument_reference_hash`、`event.payment.withdrawal_address_hash`、`event.dispute.dispute_id`、`event.dispute.chargeback_id` |
| 安全与负责任博彩 | `event.security.changed_field`、`event.responsible_gambling.identity_match_ref` |
| 机器人与辅助行为遥测 | `event.bot.timing_variance_ms`、`event.bot.actions_per_minute`、`event.bot.pointer_entropy`、`event.bot.reaction_time_ms_p50`、`event.bot.assistance_indicator` |
| 主体信号 | `subject.email.risk_score`、`subject.email.social_count`、`subject.email.is_disposable`、`subject.email.deliverability`、`subject.email.domain_reputation`、`subject.email.first_seen_days`、`subject.email.is_breached`、`subject.phone.risk_score`、`subject.phone.line_type`、`subject.phone.social_count`、`subject.phone.carrier`、`subject.phone.country`、`subject.phone.is_disposable` |
| 其他 | `event.payload.<key>`、`custom_values.<key>` |

主体信号缓存在受监控的用户上，而不是针对每个事件重新计算，因此规则可以在数据摄取时快速读取这些信号。

## 聚合

### 速率

你在交易上已经使用的聚合函数（`count`、`sum`、`avg`、`min`、`max`、`distinct_count`）可以在滚动 `window`（`30m`、`24h`、`7d`、`30d`）上应用。

### 比率

在同一窗口上使用两个聚合函数。投注与存款比、提现与存款比、奖金与存款比以及拒付率，均以此方式表示。

```json theme={null}
{
  "metric": "ratio",
  "window": "24h",
  "filters": { "subject_vendor_data": "__current__" },
  "numerator":   { "metric": "sum", "field": "event.amount", "filters": { "event.action_type": "bet_placed" } },
  "denominator": { "metric": "sum", "field": "event.amount", "filters": { "event.action_type": "deposit_completed" } },
  "operator": "lte",
  "value": 0.1
}
```

存款 1,000，投注 20，然后申请提现，比率为 0.02，这是典型的最低投注洗钱行为。

> [!NOTE]
>
> 没有分母的比率**永远不会匹配**。没有存款并不等于比率为零，而是没有证据；如果在这种情况下触发规则，就会把每一位全新用户都标记出来。

### 序列

窗口内的有序谓词。每个步骤可以按 `action_type`、`event_category` 或任意 `match` 过滤器进行匹配，并可要求在序列推进前出现 `min_count` 次。

```json theme={null}
{
  "metric": "sequence",
  "key": "ato_drain",
  "window": "24h",
  "steps": [
    { "event_category": "security", "action_type": "login_failed", "min_count": 3 },
    { "event_category": "security", "action_type": "mfa_changed" },
    { "event_category": "payment",  "action_type": "withdrawal_address_changed" },
    { "event_category": "payment",  "action_type": "withdrawal_requested" }
  ]
}
```

凭证填充攻击，随后是 MFA 接管，再到出款重定向，最后是资金耗尽。规则在完成整条链的事件上触发，匹配的证据会列出每个步骤的事件 ID。

序列状态按规则和主体分别保存，因此它会随事件到达而推进，而不是重新扫描时间线。超出窗口的进度会被丢弃，而不计入统计。

### 关联

跨主体关联：对与该事件共享同一分组的所有事件进行聚合。

```json theme={null}
{
  "metric": "correlation",
  "window": "7d",
  "pair": true,
  "group_by": ["subject_vendor_data", "event.gameplay.counterparty_vendor_data"],
  "filters": { "event.action_type": "p2p_settlement" },
  "correlate": {
    "metric": "sum",
    "field": "event.gameplay.net_result_amount",
    "filters": { "event.gameplay.role": "winner" }
  },
  "operator": "gte",
  "value": 500
}
```

`"pair": true` 会将两端作为无序集合进行匹配，因此 A→B 和 B→A 会落入同一分组。这正是让一条规则能够同时看到串通双方的原因。筹码倾销、反向下注和联盟自我推荐都属于这种模式。

关联规则务必设置用于收窄范围的 `filters`。没有它们，规则会考虑窗口内的每一个事件。

## 实时与异步规则

部分规则可以在接入请求内返回结果，部分则不能。

| 运行时机 | 规则类型 |
| - | - |
| **请求过程中** | 速率、比率以及时间窗口不超过 24 小时的有界序列 |
| **数分钟内，异步执行** | 关联规则，以及时间窗口超过 24 小时的序列 |

规则仍在等待执行的事件会返回 `"correlation_pending": true`。异步检查完成后，其状态和分数会就地更新。重复执行是幂等的，因此规则不会重复计分。

这样划分是有意为之：跨主体的团伙查询不应让登录请求等待。

## 操作

与交易规则使用相同的操作类型：`add_score`、`change_status`、`add_tags`、`add_note`、`add_to_list`、`open_case`。

事件规则有两点不同：

* 将 `change_status` 设为 `AWAITING_USER` 仅适用于交易，因为事件没有整改流程，实际会应用为 `IN_REVIEW`。
* `open_case` 将案件关联到**主体**，而不是某笔交易，并在案件上记录匹配的事件 ID。

## 证据

每次匹配都会保存其所见的全部内容：聚合时间窗口、计算值、预期值、抽样的事件 ID，以及每个匹配字段的**来源**。

| 来源 | 含义 |
| - | - |
| `server` | Didit 推导得出（IP、用户代理、来源）。权威数据。 |
| `sdk` | Didit SDK 从设备上报。 |
| `customer` | 由您的系统提供。 |

因此，分析人员在根据匹配结果采取行动前，可以区分由服务器记录的 IP 与客户端提供的提示信息。控制台会在事件抽屉面板中，于每个匹配字段旁显示其来源。

## 实际示例

> [accordion] 最低限度投注洗钱
>
> 存款、代币游戏、快速提现。条件为 `event.action_type eq withdrawal_requested`，并加上上文的投注与存款比率在 `24h` 内 `lte 0.1`。

> [accordion] 友好欺诈
>
> 每个主体在 `30d` 内 `count(chargeback_opened)` 与 `count(deposit_completed)` 的比率，`gte 0.5`。若要跨账户识别同一支付工具，请将分组依据从主体改为 `event.payment.payment_fingerprint`。

> [accordion] 账户接管资金转出
>
> 使用上文的 `ato_drain` 序列，并配合 `add_score 90` 与 `change_status DECLINED`。

> [accordion] 筹码转移
>
> 使用上文的成对关联规则。将 `value` 调整为对您的牌桌而言有实质意义的金额，并把 `event.gameplay.game_id` 加入 `group_by`，以便区分不同牌局。

> [accordion] 机器人游戏与实时辅助
>
> 条件包括 `event.action_type eq bot_signal_observed`、`event.bot.timing_variance_ms lte 10` 和 `event.device.bot_score gte 90`，并配合 `add_tags`。再结合按 IP 统计 `event.device.fingerprint` 的 `distinct_count`，以发现机器人农场，而不只是单个脚本。

> [accordion] 规避自我排除
>
> 条件为 `event.action_type eq self_exclusion_match` 与 `event.payload.re_registration_attempt eq true`，并通过 `open_case` 进行升级处理。

## 下一步

> [card] [事件接入](https://docs.didit.me/zh/transaction-monitoring/events.md)
>
> 信封格式、十个类别以及批量接口约定。

> [card] [规则 API](https://docs.didit.me/zh/transaction-monitoring/rules-api.md)
>
> 以编程方式创建、更新和回测规则。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.