mcpField
S
sumsub-create-kyt-rules

sumsub-create-kyt-rules

github.com/sumsub其他71.0k 次安装4 周前更新
代码仓库

关于 sumsub-create-kyt-rules

用于配置 Sumsub KYT 交易监控规则及风险评分流程的技能,面向管理风险策略的团队。可创建规则、设置标签评分,并定义风险等级阈值。

主要功能

  1. 01创建或修订 KYT 规则
  2. 02配置标签与申请人评分
  3. 03设置风险等级阈值
  4. 04管理规则引用的客户列表

适用场景

  1. 01根据交易条件新增监控规则
  2. 02调整标签权重与申请人风险分
  3. 03为数值评分配置风险等级
  4. 04检查或创建规则引用的客户列表

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/sumsub/agent-skills --skill sumsub-create-kyt-rules

安装后在 Claude Code 中输入/sumsub-create-kyt-rules确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

examples/
eval-finance-hold.json
minimal.json
references/
kyt-rule-schema.md
scripts/
create_kyt_client_list.sh
get_kyt_applicant_assessment.sh
get_kyt_bundle.sh
get_kyt_client_list.sh
get_kyt_risk_level_settings.sh
get_kyt_rule.sh
get_kyt_rules.sh
get_kyt_tags.sh
patch_kyt_applicant_assessment.sh
patch_kyt_risk_level_settings.sh
post_kyt_rule.sh
post_kyt_tag.sh
sumsub_curl.sh

详细介绍

Sumsub — KYT 规则、申请人评分与风险等级

配置完整的 KYT 交易监控体系:

  • 规则 — 将用户意图转换为 KytTxnRule 负载,并逐条发送 POST 请求。支持创建新规则和修改现有规则(通过发布新修订版)。新规则始终以 testMode(dryRun: true)启动——规则会显示在 dryScore 中,但在控制面板中激活之前不会影响实时结果。
  • 标签与申请人评分 — 创建并配置标签(命名的风险标记),以及将标签权重映射为综合申请人风险评分的评估配置。
  • 风险等级 — 配置评分阈值,将数值风险评分转换为易读的标签(例如:低/中/高)。

规则、标签和风险等级构成一个完整流程:规则触发 → 应用标签 → 标签累积加权评分 → 评分映射为风险等级。

端点

方法路径描述响应
GET/resources/api/agent/tm/rules/-/installed列出已有规则。支持 ?limit=<n> 和 ?offset=<n>。需要 seeKytRules。{ list: { items: [...] } }
POST/resources/api/agent/tm/rules创建新规则或新修订版。创建时省略 id 和 name。创建修订版时,需包含现有的 name slug,并设置 "id": null。需要 manageKytRules。200 规则对象 · 400 错误消息
GET/resources/api/agent/tm/rules/-/bundle/{bundleName}/{category}按名称和安装状态列出规则包中的规则。category:installed、available、archived。需要 seeKytRules。{ list: { items: [...] } }
GET/resources/api/agent/tm/rules/{id}按 ID 读取一条规则。需要 seeKytRules。规则对象
GET/resources/api/agent/tm/settings/tags列出所有 KYT 标签及其评估配置和关联规则。{ tags: [...] }
POST/resources/api/agent/tm/settings/tag创建或更新 KYT 标签。请求体:{"tag": {"name": "...", "styleClass": "...", "color": "#RRGGBBAA", "scorable": true, "includeInReporting": true, "scoreWeight": 1.0}}。color 必须是 8 位十六进制值。需要 manageKytSettings。200 空响应体
GET/resources/api/agent/tm/settings/applicantAssessment获取当前的申请人评估评分配置(标签权重、层级、公司受益人权重)。评估设置对象
PATCH/resources/api/agent/tm/settings/applicantAssessment替换申请人评估评分配置。需要 manageKytSettings。200 已更新的评估设置
GET/resources/api/agent/tm/settings/riskLevel获取当前的申请人风险等级阈值。风险等级设置对象
PATCH/resources/api/agent/tm/settings/riskLevel替换风险等级阈值。请求体:至少 2 个条目,每个条目包含 label(≤256)、rangeFrom(≥0)、styleClass(以下值之一:grey、black、blue、green、cyan、teal、lime、yellow、orange、volcano、red、pink、fuchsia、purple、purpleLight)。需要 manageKytSettings。200 已更新的风险等级设置
GET/resources/api/agent/tm/clientLists/{listName}按名称获取客户端列表。若未找到则返回 404。需要 seeClientLists。客户端列表对象
POST/resources/api/agent/tm/clientLists/{listName}创建客户端列表(幂等)。需要 manageClientLists。客户端列表对象

完整的规则 SumScript 表达式字段参考和类型系统,请参阅 references/kyt-rule-schema.md。

身份验证 — 应用令牌 + 密钥(仅限沙盒)

此技能会调用 Sumsub 公共 API,并按照身份验证参考对每个请求进行签名。完整的工作原理说明见 sumsub-api-auth 技能——如果遇到 401 Invalid signature,请阅读该说明。

⚠️ 仅限沙盒令牌。 请勿在此处接受或使用生产环境的应用令牌。如果用户提供了此类令牌,请拒绝并让他们前往 https://cockpit.sumsub.com/checkus/home?sbx=true 生成一组沙盒令牌和密钥(Connect Sumsub to your AI agent -> Build & configure -> Generate token)。令牌和密钥仅显示一次——请在关闭对话框前复制两者。辅助脚本会强制执行此要求——令牌必须以 sbx: 开头,否则会被拒绝。

变量示例
SUMSUB_APP_TOKENsbx:... — 从控制面板获取的沙盒应用令牌。
SUMSUB_SECRET_KEY创建令牌时仅显示一次的配对密钥。
SUMSUB_BASE可选。默认为 https://api.sumsub.com。

如果用户已在对话中提供凭据,请重复使用;否则,在运行前询问一次。绝不要回显密钥。

租户权益

权益按交易类型进行限制,而非全局限制。每个 types 值只需具备为其列出的任意一个密钥——而非全部密钥。不存在每条规则都必须具备的基础权益:KYT 是 finance 类型的权益,仅此而已。

规则 types 值满足以下任意一个即可启用
financeKYT
travelRuleTRAVEL_RULE
kycTM_INDIVIDUAL_APPLICANT_SCORING · TM_COMPANY_APPLICANT_SCORING · KYT_ANTI_FRAUD · KYT · DEVICE_INTELLIGENCE
userPlatformEventKYT_ANTI_FRAUD · KYT
scheduledEventTM_SCHEDULED_EVENTS · KYT

仅有 TRAVEL_RULE 的租户可以创建 travelRule 规则。仅有 DEVICE_INTELLIGENCE 的租户可以创建 kyc 规则。两者都不需要 KYT。对于所在行未列出 KYT 的类型,不要要求提供 KYT。

创建或修改规则前,请从 sumsub-check-permissions 技能目录运行 bash scripts/check_permissions.sh。响应正文为 {"allowedChecks": {"<KEY>": "<description>", ...}}——allowedChecks 的键即已启用的权益。响应中没有 allowed 数组。

仅当请求的类型未启用时才停止——也就是说,该类型所在行的所有键都未出现在 allowedChecks 中。不要构建或 POST 该规则。使用用户所见的类型名称(参见交易类型——kyc 显示为“验证会话事件”,绝不要称为“kyc”),列出启用该类型所需的键,并用“或”连接,然后告知用户联系其客户成功经理(CSM)或 Sumsub 支持。不要提供其他交易类型作为替代方案——如果用户想创建 travelRule 规则,finance 规则不能替代它。

如果权益请求本身失败(非 200 响应、超时),请告知用户无法验证权益,但仍继续操作。后端是最终依据,并会在 POST 时执行相同的限制——参见步骤 6 中的 No allowed transaction types found 行。

关于定时规则的说明。 定时触发模式由 TM_SCHEDULED_EVENTS 专门授权,而 scheduledEvent 类型也可由 KYT 启用。因此,仅有 KYT 的租户可能通过此处的检查,但仍会被后端以 noEventTrigger 为由拒绝。如果发生这种情况,请照常构建规则,并原样显示后端错误。

流程

  1. 获取租户权益——仅在创建或修改规则时执行。 运行 sumsub-check-permissions,并保留 allowedChecks 中的键。确定规则的 types 后,检查租户权益中对应的行;如果没有任何列出的键,则终止操作。 对于非规则工作,完全跳过此步骤:标签、申请人评估和风险级别都不需要权限。/tm/clientLists 端点(步骤 2a)需要 WATCHLISTS 或 WATCHLISTS_FOR_TM——如果两者都没有,请使用 sumsub-manage-client-lists 创建列表,该操作不需要权限——但 Sumsub 维护的列表除外,因为这类列表之后根本无法安装(请参阅所需权限)。除 sumsub-check-permissions 调用的端点外,不要查找其他权限端点——不存在其他端点。

  2. 确定模式——创建还是修改。

    • 修改模式: 用户提供规则 name(不可变的 slug,例如 fin-ben-pep-ter-list-abo-thr-WoGD)或足够的上下文以识别规则。运行 bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rules.sh,按 name 或 title 查找规则,并保存完整的当前文档。向用户展示现有的 conditionEl、score、action 和 types,然后仅收集他们希望更改的字段。跳转到步骤 2a。
    • 创建模式: 用户描述一条新规则。运行 bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rules.sh 并检查标题是否冲突——服务器每次 POST 都会创建重复项,且不会去重。如果已有规则的标题匹配,请询问用户是否跳过创建并改为修改现有规则。
  3. 将用户意图转换为精简规格。 对于用户希望创建的每条规则,收集:

    • title(≤128 个字符,必填)
    • types——一种或多种交易类型(见下表)
    • 对条件的通俗描述(用于在步骤 3 中生成 conditionEl)
    • score(整数,默认值为 0)、action(score | onHold | awaitUser | reject)
    • 可选:desc、tags、bundleName、priority、stopOnMatch、sourceKeys

2a. 确保客户端列表存在——如果任何规则会在其 conditionEl 中引用 clientLists.<name>,请在生成或验证表达式前确认每个列表都存在: bash bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_client_list.sh <listName> - HTTP 200 → 列表存在;继续。 - HTTP 404 → 列表不存在;创建列表: bash bash ${CLAUDE_SKILL_DIR}/scripts/create_kyt_client_list.sh <listName> POST 操作具有幂等性——即使列表已在此期间创建,也会成功。 对于任何其他名称,该操作都会创建一个仅包含 key 条目的空 custom 列表;之后永远无法更改列表类型和条目类型。因此,如果规则需要包含电子邮件、电话号码、申请人 ID、设备 ID 或 IP 范围的列表,或需要 blocklist / whitelist,或需要向列表中添加值,请勿在此处创建列表:转交给 sumsub-manage-client-lists,由其创建类型化列表并填充内容。对于 Sumsub 维护的名称(fatf_black_flag_countries、eu_high_risk_third_countries 等——请参阅该技能中的表格),POST 会安装 Sumsub 自己的只读列表,这是正确的做法:使用此列表,而不是创建自定义国家/地区列表。 在确认所有引用的客户端列表都存在之前,不要继续进行验证或创建规则。 3. 生成 conditionEl。 对于每条需要条件的规则:

  • 根据 references/kyt-rule-schema.md 中的类型定义构造 SumScript 布尔表达式。
  • 不要猜测字段路径。 只能使用已在架构中确认的字段 — 编写表达式前,先从根节点到叶节点核实路径。
  • 对于默认货币金额检查,使用 data.info.amountInDefaultCurrency(标准化金额),而不是 data.info.amount(原币种金额)— 除非用户明确要求按原币种筛选。
  • 定时规则(types: ["scheduledEvent"])不会使用 conditionEl 作为触发条件 — 改用 noEventTrigger(参见 references/kyt-rule-schema.md)。
  • 对于多分支评分(每个子条件对应不同分数),在 conditionEl 中使用 addScoreIf,并将负载级别的 score 设为 0、action 设为 "score"(参见评分部分)。

3a. POST 内置验证 — 服务器会在创建调用期间(第 6 步)验证 conditionEl 语法。无需单独进行预检。如果验证失败,服务器会返回 HTTP 400,并附上描述问题的错误消息 — 修复表达式后重新 POST。

  1. 构建负载。 按照以下约束为每条规则组装 JSON:

    创建模式:

    • 仅包含必填字段: title、types(至少 1 个值)。
    • 对于 eval 规则:在相关时包含 conditionEl、score 和 action。
    • 绝不要发送 id 或 name — 两者均由服务器分配。

    修改模式(新修订版):

    • 包含 "name": "<existing-slug>" — 现有规则中不可变的 slug。
    • 包含 "id": null — 显式设为 null。这会通知服务器创建新修订版,而不是新规则。不要使用 "id": ""(空字符串)— Jackson 会将其判定为无效 ObjectId 并返回 HTTP 400。
    • 保留现有规则文档中的所有未更改字段。只修改用户要求更改的字段。
    • title 和 types 仍为必填项。

    两种模式 — 始终适用:

    • 绝不要发送由服务器分配或用于审计的字段:clientId、actual、revision、时间戳(createdAt、modifiedAt、archivedAt)、作者字段。
    • 绝不要发送 scope 或 bgCheckTargets — 这些是由服务器管理的许可证控制字段。
    • 创建模式: 绝不要发送 dryRun 或 disabled;服务器会将它们分别初始化为 true 和 false。
    • 修改模式: 从现有规则文档中保留 dryRun 和 disabled — 服务器会使用发送的值,在新修订版中保留规则当前的启用状态和测试模式状态。
    • 省略空的可选容器: sourceKeys: []、caseAction: {}、applicantChange: {}、applicantActions: {"actions": {}}、varDefinitions: {"definitions": []}、varValues: {"values": {}}。
    • 不要将 scheduledEvent 与其他交易类型混用。
  2. 向用户展示每个负载,并在执行任何 POST 前征求明确确认。

  3. 通过 bash ${CLAUDE_SKILL_DIR}/scripts/post_kyt_rule.sh < payload.json POST 每条规则。 规则会逐条创建。检查退出代码:

    • 退出代码 0 → HTTP 200;响应正文是创建的 KytTxnRuleView。继续第 7 步。
    • 退出代码 1 → HTTP 4xx/5xx;响应正文包含错误消息。原样呈现该消息,修复表达式,然后重新 POST。 后端也会执行权限门控。以下两条错误消息表示载荷没有问题,原样重试永远不会成功——停止重试该规则并报告:
    • No allowed transaction types found → 租户没有获得你发送的 types 的许可。 告诉用户其 allowedChecks 启用了哪些类型,并建议联系其 CSM。 不要悄悄切换到其他类型。
    • Unable to enable a rule without a specified condition → 该规则需要 conditionEl (或者,对于 scheduledEvent,需要 noEventTrigger)。

    重试上限:每条规则最多允许 10 次 POST 尝试。如果第 10 次尝试仍然失败, 将该规则标记为失败,记录最后一条错误消息,然后继续处理下一条规则—— 不要中止整个批次。在第 9 步报告所有失败的规则。

  4. 通过 bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rule.sh {id} GET 每条已创建的规则。 将 conditionEl 和关键字段与发送的内容进行比较。报告任何差异。

  5. 为每条规则构建仪表板链接:

    https://cockpit.sumsub.com/checkus/kyt/rulesManager/rulesList/{name}?clientId={clientId}&sbx=true
    

    name 和 clientId 来自 POST 响应正文。将其显示为可点击的 Markdown 链接。

  6. 报告——每条规则都以其易读标题开头:

    • 标题和自动生成的 name(不可变的短标识符)
    • **状态:**testMode——必须在仪表板中激活后才能上线
    • types、action、score
    • 可点击的 Markdown 仪表板链接
    • 规则 id 单独放在最后一行

    对于耗尽全部 10 次尝试的规则,在 失败的规则部分报告其标题和最后一条 HTTP 400 错误消息。

    原样呈现 4xx 错误。

**⚠️ testMode 默认值。**每条新规则的 dryRun: true。它会针对交易进行评估, 其结果会显示在 dryScore 中,但不会影响实际分数或操作。要使规则生效,请在仪表板中打开该规则并将其设为“Active”。

紧凑规范格式

在生成完整载荷之前,将每条规则表示为一个 JSON 对象:

{
  "title": "Hold large outgoing transfers",         // required, ≤128 chars
  "desc": "Holds outgoing transactions over 50 000 in default currency",
  "types": ["finance"],                             // required
  "condition": "outgoing AND amount > 50 000 default currency",  // natural language → conditionEl
  "score": 100,                                     // 0 if using addScoreIf
  "action": "onHold",                              // score | onHold | awaitUser | reject
  "tags": ["HighAmount"],                           // optional; auto-created if new
  "bundleName": "AML Compliance",                   // optional group
  "priority": 10,                                   // optional; higher = evaluated first
  "stopOnMatch": false,                             // optional
  "sourceKeys": ["payment-gateway-1"]               // optional top-level filter
}

交易类型

类型(API 值)面向用户时使用的名称使用场景是否需要 conditionEl?备注
finance金融交易付款转账、存款、取款是最常见的类型
travelRuleTravel Rule 交易Travel Rule 交易是
kyc验证会话事件申请人的验证会话事件是面向用户的文本中绝不写“kyc”
userPlatformEvent用户平台事件登录、密码重置、2FA 事件是
scheduledEvent计划事件定期重新检查申请人否(使用 noEventTrigger)types 中必须只有此类型

除 scheduledEvent 必须是唯一类型外,类型可以在同一条规则中组合使用。

**第一列是 API 值;第二列是用户看到的名称。**将 API 值放入 types,除此之外不要在任何地方使用——在报告、拒绝说明和澄清问题中,使用第二列,也就是仪表板显示的名称。kyc 最容易造成误导:仪表板上根本没有“kyc”标签,因此在消息中使用这个名称会让用户去寻找一个不存在的内容。其他四种类型只是名称经过美化,但仍应使用仪表板上的措辞。

该租户可使用哪些类型由每种类型的权限控制——映射信息的唯一来源是 租户权限。

规则操作

操作优先级效果
score0仅增加分数(默认)
onHold5暂停交易以供审核
awaitUser7等待用户操作后再继续
reject10直接拒绝交易

在所有匹配的规则中,最强的操作生效,分数则累加。

评分与 conditionEl

简单规则(单个阈值、单个分数): 将分数放在 score 中,并将 conditionEl 保持为纯布尔值。

{
  "title": "Hold high outgoing finance",
  "types": ["finance"],
  "conditionEl": "data.info.direction == 'out' AND data.info.amountInDefaultCurrency > 50000",
  "score": 100,
  "action": "onHold"
}

多分支评分(每个子条件对应不同分数): 在 conditionEl 中使用 addScoreIf。 将 payload 设置为 score: 0 和 action: "score",否则 payload 分数会被重复计入。

  • EOR(急切或): 每个分支都会进行评估,所有匹配分支的分数都会累加。用于相互独立的标记。
  • OR(短路或): 在第一个匹配分支处停止。用于互斥等级(先检查最严格的等级)。
addScoreIf(data.info.amountInDefaultCurrency > 100000, 50) EOR
addScoreIf(applicant.country IN clientLists.sanctioned_countries, 100) EOR
addScoreIf("pep" IN applicant.riskLabels.aml, 75)

常见的 conditionEl 模式

# Finance: outgoing transfer over threshold
data.info.direction == 'out' AND data.info.amountInDefaultCurrency > 50000

# Finance: applicant in a client list
applicant.country IN clientLists.high_risk_countries

# Finance: incoming from specific payment type
data.info.direction == 'in' AND data.info.type == 'transfer'

# Finance: crypto transaction
data.info.currencyType == 'crypto'

# KYC: applicant review rejected
applicant.review.decision == 'rejected'

# Travel Rule: counterparty VASP not found
txn.travelRuleInfo.status == 'counterpartyVaspNotFound'

# Aggregation: applicant sent > 3 transactions in last 24 hours
txns.finance.byApplicant.out.lastHours(24).count() > 3

# Aggregation: total outgoing amount in last 30 days
txns.finance.byApplicant.out.lastDays(30).sum(it.data.info.amountInDefaultCurrency) > 100000

# KYC: questionnaire answer — nested questionnaire.section.item, dot notation only
questionnaires.myQuestionnaireId.mySectionId.myItemId == 'salary'

# KYC: same, when a segment contains a dash — backtick-quote that segment
questionnaires.`my-quest-id`.mySectionId.myItemId == 'salary'

问卷答案的条件有两个陷阱,可能导致规则可以正常保存,却永远不会匹配:方括号形式无法编译,而且比较的值是选项存储的值,而非向申请人显示的标签。编写条件前请先阅读 references/kyt-rule-schema.md → questionnaires,其中也介绍了如何查找这三个 ID。

有关完整类型系统和所有可用字段,请参阅 references/kyt-rule-schema.md。

客户列表

客户列表是由值(国家、货币、对等方 ID 等)组成的命名集合,在 conditionEl 中以 clientLists.<listName> 的形式引用。引用列表的规则必须等列表创建后才能验证或创建。

检查和创建列表
# Check if a list exists
bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_client_list.sh high_risk_countries

# Create a list (idempotent)
bash ${CLAUDE_SKILL_DIR}/scripts/create_kyt_client_list.sh high_risk_countries

无论列表是否已存在,POST 都会在列表不存在时创建一个空列表,并返回列表文档。

所需权限
操作权限
GET(读取)seeClientLists
POST(创建)manageClientLists

如果 GET 返回 403,则缺少 seeClientLists。如果 POST 返回 403,则缺少 manageClientLists。在这两种情况下,都要告知用户缺少的权限并停止。

这两个端点还需要 WATCHLISTS 或 WATCHLISTS_FOR_TM 权益。如果租户两者都没有,请改用 sumsub-manage-client-lists 创建列表——其端点不需要权益。Sumsub 维护的名称(fatf_black_flag_countries,……)除外:只有这些端点才能安装此类列表,而该技能会拒绝保留名称。告知用户,该列表需要租户具备 WATCHLISTS 或 WATCHLISTS_FOR_TM,然后停止——不要转交,也不要用其他名称创建副本。

在 conditionEl 中使用

在 clientLists. 前缀后使用列表的准确名称进行引用:

# Country in a named list
applicant.country IN clientLists.high_risk_countries

# Peer wallet not in an allowlist
NOT (txn.counterparty.wallet IN clientLists.approved_wallets)

# Combined
applicant.country IN clientLists.sanctioned_countries AND data.info.amountInDefaultCurrency > 1000

上述端点只能获取或创建不含条目的空 custom 列表。正如步骤 2a 所述,需要填充值(国家、钱包、对等方 ID 等)或包含类型化条目的列表不能在此创建:sumsub-manage-client-lists 会通过同一个 clientLists 实体创建并填充列表(共享 seeClientLists/manageClientLists 权限)。确认列表已填充后,从步骤 3 继续。

标签

标签会将规则匹配结果关联到申请人级别的风险评估:

  • 在规则中添加 tags: ["TagName"]——如果标签名称是新的,会在 KYT 设置中自动创建。
  • 规则匹配时,每个标签都会累加该规则为申请人产生的分数。
  • 评分后运行的 applicantAssessment 会将标签分数汇总到申请人的风险档案中。

计划规则(scheduledEvent)

计划规则无需传入交易即可触发。它们会根据触发条件查找申请人,并生成合成事件。完整的 noEventTrigger 结构请参见 references/kyt-rule-schema.md。

关键限制:

  • types 必须严格为 ["scheduledEvent"]——不能与其他类型组合。
  • 必须包含 applicantChange 或 applicantActions(至少一个)。
  • conditionEl 可选(用于次级筛选,而非主要触发条件)。
  • noEventTrigger.type 可以是 byLevelName(审核后 N 天处于某级别的已批准申请人)或 byCustomExpression(自由格式的申请人筛选表达式)。

最简计划规则:

{
  "title": "Annual KYC refresh",
  "types": ["scheduledEvent"],
  "noEventTrigger": {
    "type": "byLevelName",
    "levelParams": {
      "levelName": "basic-kyc-level",
      "days": 365
    }
  },
  "applicantChange": {
    "type": "applicantLevel",
    "applicantLevel": {
      "levelName": "re-verification-level"
    }
  }
}

匹配时创建案件

要在规则匹配时自动创建合规案件,请添加 caseAction:

{
  "caseAction": {
    "createCase": true,
    "groupByType": "byApplicant",
    "blueprintId": "<case-blueprint-id>",
    "priority": "high",
    "deadlineHours": 24
  }
}

groupByType:byRule(每条规则创建一个案件)或 byApplicant(每位申请人创建一个案件,并对交易分组)。 blueprintId 为可选项——省略时使用默认案件模板。

修改现有规则

要更新规则,请向创建规则时使用的同一端点 POST 一个新版本。服务器会原子性地替换当前版本并递增 revision。

确定规则

用户必须提供规则的 name(不可变的标识符),或提供足够的信息以根据标题识别规则。列出所有规则并找到匹配项:

bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rules.sh | python3 -c "
import json, sys
items = json.load(sys.stdin).get('list', {}).get('items', [])
for r in items:
    if r.get('name') == 'fin-ben-pep-ter-list-abo-thr-WoGD':
        print(json.dumps(r, indent=2))
"

或者按标题子字符串搜索:

bash ${CLAUDE_SKILL_DIR}/scripts/get_kyt_rules.sh | python3 -c "
import json, sys
items = json.load(sys.stdin).get('list', {}).get('items', [])
for r in items:
    if 'PEP' in r.get('title', '').upper():
        print(json.dumps(r, indent=2))
"

继续之前,向用户展示匹配规则当前的 conditionEl、score、action 和 types。

载荷结构

获取现有规则文档,仅应用用户要求的更改,然后:

  • 设置 "id": null——显式设为 null(表示创建新版本,而非新规则)。切勿使用 ""——这会导致 Jackson ObjectId 反序列化失败并返回 HTTP 400。
  • 保留 "name": "<slug>"——现有的不可变标识符。
  • 移除服务器管理的字段:clientId、actual、revision、scope、bgCheckTargets、时间戳、作者字段。
  • 保留现有文档中的 dryRun 和 disabled——它们会在新版本中保留规则当前的启用状态和测试模式状态。
{
  "id": null,
  "name": "fin-ben-pep-ter-list-abo-thr-WoGD",
  "title": "Finance — Beneficiary in PEP and terror list above threshold",
  "types": ["finance"],
  "conditionEl": "beneficiary.fullName IN clientLists.pep_and_terror AND data.info.amountInDefaultCurrency > 5000",
  "score": 100,
  "action": "onHold",
  "dryRun": true,
  "disabled": false
}
POST 前验证

如果 conditionEl 已更改,POST 会自动验证它。如果服务器返回 HTTP 400,请修正表达式并重新 POST(与创建模式相同,最多尝试 10 次)。

POST 后
  • 响应包含新的 id(最新版本会获得新 ID)、旧的 name、revision 编号以及所有规则字段。
  • 通过新的 id GET 该规则进行验证。
  • 仪表板链接使用旧的 name:
    https://cockpit.sumsub.com/checkus/kyt/rulesManager/rulesList/{name}?clientId={clientId}&sbx=true
    
  • 在报告标题和已更新字段时,同时报告新的 revision 编号。

申请人风险评分

申请人风险评分会根据匹配到该申请人的交易监控规则,计算每位申请人的综合风险分数。该分数由独立配置的三个层级构成:

Rules (produce tags on match)
  └─ Tags (each carries a score weight)
       └─ Assessment (maps tags → weighted score)
            └─ Risk Levels (score thresholds → Low / Med / High label)
工作原理
  1. 规则触发——TM 规则匹配交易时,会将其 tags 应用于申请人。
  2. 标签累积——每个标签都带有 scoreWeight。多个规则匹配时,标签分数会累加。
  3. 评估汇总——评估配置用于控制哪些标签计入总分(includeInTotalScore)、它们的相对权重(scoreWeight)以及可选的层级结构(items)。
  4. 分配风险级别——将总分与 riskLevelThresholds 比较,从而生成易读的风险标签(例如低/中/高)。

对于公司,评估中的 companyBeneficiarySettings 会应用基于角色的权重(UBO、董事、股东……),使申请人的分数纳入其关联方的风险。

配置申请人评分 — 分步说明

第 1 步 — 创建/更新标签

echo '{"tag": {"name": "HighValue", "styleClass": "red", "color": "#FF000080", "scorable": true, "scoreWeight": 1.0}}' \
  | bash scripts/post_kyt_tag.sh

读取所有标签以确认:

bash scripts/get_kyt_tags.sh

第 2 步 — 配置评估

将标签映射到加权分数。id 是由客户端分配的条目稳定标识符。

{
  "scores": [
    {
      "id": "high-value-score",
      "tag": "HighValue",
      "includeInTotalScore": true,
      "scoreWeight": 1.0
    }
  ],
  "companyBeneficiarySettings": [
    { "beneficiaryType": "ubo",      "weight": 1.0 },
    { "beneficiaryType": "director", "weight": 0.5 }
  ]
}

有效的 beneficiaryType 值:shareholder、representative、director、ubo、companyOfficer、secretary、founder、investor、legalAdvisor、authorizedSignatory、trustee、trustBeneficiary、trustSettlor、trustProtector、payer。

# Read current
bash scripts/get_kyt_applicant_assessment.sh

# Apply new config
echo '<payload>' | bash scripts/patch_kyt_applicant_assessment.sh

第 3 步 — 配置风险级别阈值

# Read current
bash scripts/get_kyt_risk_level_settings.sh

# Apply new thresholds (min 2 required)
echo '{"riskLevelThresholds": [
  {"label": "Low",  "rangeFrom": 0,   "styleClass": "green"},
  {"label": "High", "rangeFrom": 75,  "styleClass": "red"}
]}' | bash scripts/patch_kyt_risk_level_settings.sh
规则中的标签

在规则的载荷中添加 tags,将规则匹配结果关联到评估:

{
  "title": "Flag high-value transfers",
  "types": ["finance"],
  "conditionEl": "data.info.amountInDefaultCurrency > 10000",
  "score": 50,
  "action": "score",
  "tags": ["HighValue"]
}

此规则匹配时,会将 HighValue 标签应用于申请人,其权重也会计入申请人的风险评分。

另请参阅

评论

支持 Markdown