关于 sumsub-create-aml-resolution-rules
为 Sumsub 配置 AML Resolution Rule Chain 的技能,可根据简要规格创建并更新草稿规则,也可按明确要求尝试发布。规则按顺序处理筛查命中,并能设置审核结果或标签。
主要功能
- 01读取草稿、已发布版本和规则模板
- 02创建、更新、排序或删除草稿规则
- 03检查规则提示并按条件发布
- 04以标签衔接申请人工作流
适用场景
- 01根据筛查策略编写 AML 自动审核规则
- 02用标签将筛查结果交给后续工作流路由
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ sumsub/ agent-skills --skill sumsub-create-aml-resolution-rules安装后在 Claude Code 中输入/sumsub-create-aml-resolution-rules确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
examples/auto-clear-dob-mismatch.jsonminimal.jsonreuse-previous-review.jsonreferences/aml-resolution-rules-schema.mdaml-rules-context-fields.mdaml-rules-enumerations.mdaml-rules-expressions.mdscripts/aml_rules_api.pybuild_aml_rule.py详细介绍
Sumsub — 创建 AML 处理规则
根据精简规范构建 AML 处理规则,通过 Agent API 将其写入租户的 草稿 AML 规则链,并可选择发布草稿使其生效。该规则链(也称为 AML 处理规则链)会自动审核收到的 AML 筛查命中项:系统会按顺序将每条规则应用于每个尚未审核的命中项;如果匹配,则设置该命中项的审核结果(匹配状态/风险等级/是否列入白名单/备注),和/或为案例添加标签。
所有网络请求步骤都通过同一个签名客户端执行:${CLAUDE_SKILL_DIR}/scripts/aml_rules_api.py(draft、published、archive、library、upsert、reorder、delete、publish);规则载荷由 ${CLAUDE_SKILL_DIR}/scripts/build_aml_rule.py 组装。
端点
所有端点都位于 /resources/api/agent/amlResolutionRules 下。每个租户只有 一条规则链,版本依次为 draft → published → archived。(每一行都对应 aml_rules_api.py 的一个子命令 — 请勿手动调用这些路径。)
| 方法 | 路径 | 子命令 | 使用时机 |
|---|---|---|---|
GET | /draft | draft | 读取可编辑版本。根据已发布版本(或空内容)自动创建草稿 — 已启用的租户不会返回 404。包含 notices[]。 |
GET | /published | published | 读取生效版本(尚未发布任何内容时返回 404)。 |
GET | /archive | archive [marker] | 修订历史,使用 marker 分页。速率限制为每分钟 5 次 — 请勿轮询。 |
GET | /library | library | 按类别分组的现成规则模板。 |
POST | /draft/rules | upsert | 写入一条规则:省略 id 以创建规则(追加到规则链末尾);提供现有 id 以替换该规则。响应为重新计算 notices[] 后的完整草稿。 |
PUT | /draft/rules/order | reorder | 调整顺序:请求体 {"ruleIds": [...]} 必须恰好列出每个规则 ID 一次。 |
DELETE | /draft/rules/{id} | delete <id> | 根据 ID 从草稿中移除一条规则。幂等 — 即使要删除的 ID 不在草稿中,操作仍会成功。请参阅下文的授权政策。 |
POST | /draft/publish | publish | 发布生效。存在任何 error 级别的通知时,将拒绝发布。之前的已发布版本会自动归档。 |
通过 API 发布仅适用于集成阶段。 集成被视为已启用后,API 可能会 拒绝发布(返回
4xx);此时必须由人工在 Sumsub 网页界面中审核并发布规则链。此阶段应将发布被拒视为预期行为,而非需要绕过的错误 — 请报告此情况,并引导用户前往网页界面。
除常规要求外,Token 还必须满足以下要求:这些是 Agent 端点,因此 App Token 必须是 AI 专用(在控制面板界面的 AI Token 页面创建),并具有 manageAmlCases + manageClientSettings 权限。配置错误时的表现:
403 "This endpoint is not allowed for this type of token"→ 使用的是常规 App Token,而非 AI Token。请让用户创建 AI Token。- 所有端点均返回
404 "API is not available"→ 此租户未启用 AML Resolution Rules API。立即停止 — 告知用户联系其 CSM 或 Sumsub 支持;不要重试其他端点。
⚠️ 发布会影响 LIVE 生产环境
AML Resolution Rule Chain 由生产环境和沙盒共享——只有 AML 案例 / 申请人彼此隔离,规则链本身并未隔离。发布会更改自动审核真实生产环境 AML 筛查命中项的规则链(清除误报、确认真阳性、加入白名单)——沙盒 sbx: 令牌并不能让此操作变得安全。发布之前的所有操作都安全:读取草稿、插入或更新规则、重新排序以及删除规则都只会修改草稿,草稿发布前不会审核任何内容。
因此,只有在用户明确要求时才发布,并且要知道发布可能会被后端拒绝:规则链激活后——即已经处理了过多申请人 / 集成已完成——API 会拒绝发布(返回 4xx)。这是预期行为,不要尝试绕过:请说明这一情况,并告知用户从 Sumsub 网页界面发布(参见端点说明)。
身份验证 — App Token + 密钥(仅限沙盒)
此技能会调用 Sumsub 公共 API,并根据
身份验证参考文档为每个请求签名。
完整的工作原理说明位于 sumsub-api-auth
技能中——如果遇到 401 Invalid signature,请阅读该文档。
⚠️ 仅限沙盒令牌。 此处不要接受或使用生产环境 App Token——这些规则会自动审核真实 AML 命中项。如果用户提供生产环境令牌,请拒绝并要求他们在 https://cockpit.sumsub.com/checkus/home?sbx=true 生成一组沙盒凭据(Connect Sumsub to your AI agent -> Build & configure -> Generate token——该页面会生成这些端点所需的 AI 令牌,见上文)。令牌和密钥只会显示一次——关闭对话框前请复制两者。
aml_rules_api.py会强制执行此要求——不以sbx:开头的令牌都会被拒绝。
| 变量 | 示例 |
|---|---|
SUMSUB_APP_TOKEN | sbx:... — 从仪表板获取的沙盒 AI App Token。 |
SUMSUB_SECRET_KEY | 创建令牌时显示一次的配对密钥。 |
SUMSUB_BASE | 可选。默认值为 https://api.sumsub.com。 |
如果用户已在对话中提供凭据,请直接使用;否则,在运行前询问一次。切勿复述密钥。
规则链的执行方式(设计规则时请牢记)
- 规则按从上到下的顺序运行——顺序很重要。
- 每条规则都会针对所有尚未审核的命中项进行评估。已获得
matchStatus(来自审核操作或前序规则)的命中项会被后续规则跳过。 - 效果会在运行过程中体现:前序规则添加的标签,以及重新计算后的
screening.answer/screening.tags/screening.matchStatuses,都会被后续规则看到——这使规则链式执行成为可能(规则 A 添加match_tin标签,规则 B 对screening.tags containsAny ["match_tin"]作出响应)。 - 请将具体且具有决定性的规则(ID 匹配、沿用先前审核结果)放在宽泛的清理规则之前——如果将宽泛的
false_positive规则放在最前面,它会抢先处理命中项,使其下方更精确的规则无法处理。
前提:AML 筛查必须确实正在运行
此规则链仅针对 AML 筛查产生的命中采取行动。如果筛查未运行,这些规则就不起作用——它们不会评估任何内容。两个相互独立的门槛决定筛查是否会在某个申请人级别运行:
- 租户权限
WATCHLISTS— 全有或全无,适用于整个租户。请调用sumsub-check-permissions技能进行验证。存在WATCHLISTS→ AML 筛查可用,并且默认在每个级别开启。不存在WATCHLISTS→ AML 筛查在整个租户范围内关闭;任何申请人级别的设置都无法将其开启,而且此规则链将永远不会看到命中。 - 按级别选择退出
disableWatchlists— 仅当通过门槛 1 后才相关。除非某个级别设置顶层disableWatchlists: true(客户端可借此排除不应进行筛查的级别),否则筛查会在该级别运行。这属于sumsub-create-level技能的职责,而非本技能的职责。
WATCHLISTS 权限 | 级别 disableWatchlists | 筛查会在该级别运行吗? | 规则链会处理其命中吗? |
|---|---|---|---|
| 不存在 | (任意) | 不会 — 整个租户范围内关闭 | 不会 |
| 存在 | 不存在 / false | 会(默认) | 会 |
| 存在 | true | 不会 — 该级别已选择退出 | 不会 |
每个租户只有一条规则链,它会处理筛查运行的所有级别产生的命中——它不限定于某个级别。因此,在构建规则前(步骤 0)请确认门槛 1。如果缺少 WATCHLISTS,此处编写的任何内容都会一直处于休眠状态,直到启用该权限。
标签连接到申请人工作流
规则标签是通用申请人标签——适用于整个租户,并非仅用于 AML。它们不仅会在 AML 运行中串联:还会作为 checks.personWatchlist.tags(个人)和 checks.companyWatchlist.tags(公司)出现在申请人工作流的条件中。因此,标签是规则链与工作流之间的交接点:规则链标记出复杂情况,工作流据此进行路由。例如:
- AML 规则 — 条件为“命中包含
pep风险标签,且申请人未满 30 岁”,标签操作为["youngPep"]。 - 工作流边 — 一个
condition用于测试checks.personWatchlist.tags是否包含youngPep→ 指向人工审核节点。
两个技能编写的都是相同的 Condition AST(见下文),因此两部分的结构相似。如果用户的目标包含筛查后的路由或操作,请在此处设置标签,并指引他们使用 sumsub-create-workflow 完成路由部分。
流程
- 确认已为租户启用 AML 筛查(参见 前置条件)。调用
sumsub-check-permissions技能,并确认WATCHLISTS属于租户允许的权益项。如果不存在,则表示整个租户范围内都未启用 AML 筛查,因此这条规则链永远不会触发:请明确告知用户(该权益项需由其 CSM / Sumsub 支持人员启用),并在继续之前取得明确确认——不要悄悄创建一条毫无作用的规则链。如果存在,则继续。 - 读取草稿:
${CLAUDE_SKILL_DIR}/scripts/aml_rules_api.py draft。这也用于检查服务是否可用——如果出现404 "API is not available"或403,请停止并报告(参见上文的端点说明)。检查现有规则:如果已有规则与用户的意图相同,请提出按id更新,而不是追加重复规则——upsert 不会按名称去重。记录变更前已存在的规则 ID——之后需要依据这些记录遵守删除授权政策。 - 先检查库:
${CLAUDE_SKILL_DIR}/scripts/aml_rules_api.py library。如果现成模板符合用户意图,请从其rule定义开始——移除id,再进行调整。检查模板的vendors列表,确认其中包含租户使用的 AML 供应商。 - 编写规则规范(如下)。直接将
condition编写为真实的 Condition AST——不存在表达式迷你语言(参见 编写条件)。通过input.entityType条件将规则限定为一种实体类型(默认为个人——参见 编写条件)。根据 references/aml-rules-context-fields.md 验证每个exp路径,并根据 references/aml-rules-enumerations.md 验证所有基于枚举的字段的允许值——未知路径会产生阻止发布的unknownField错误通知。 - 组装规则负载,使用
${CLAUDE_SKILL_DIR}/scripts/build_aml_rule.py——通过标准输入传入精简规范,标准输出返回完整规则 JSON。该构建器只是一个轻量组装工具:它会原样传递conditionAST、组装审核 / 标签操作、验证运算符 /matchStatus枚举 /emptyAction防护,并会在此处(任何网络调用之前)对拼写错误或格式错误的 AST 报错。 - 向用户展示解析后的负载,并在首次 upsert 前取得明确确认。如果规则的
tags操作会引入尚不存在的标签,请明确说明:upsert 会创建一个租户范围内的申请人标签(可在仪表板筛选器、工作流等各处看到)——请确认该名称值得保留(清晰、简洁、可复用),或改用现有标签。 - 通过
${CLAUDE_SKILL_DIR}/scripts/build_aml_rule.py < spec.json | ${CLAUDE_SKILL_DIR}/scripts/aml_rules_api.py upsert执行 upsert → 响应为包含重新计算的notices[]的完整草稿。创建多条规则时,每条规则都重复步骤 3–6。记录服务器为每条新建规则分配的 ID——这样才能确认规则归你创建(步骤 9)。 - 检查
notices。error通知(例如invalidTag、unknownField、unknownFunction)会阻止发布——请修正规则,并使用其id重新执行 upsert。warning/info仅供参考;请告知用户。参见 references/aml-resolution-rules-schema.md 中的通知键表。 - **排列规则链顺序。**新规则会添加到末尾。如果需要更改评估顺序,请传入完整排列:
echo '{"ruleIds": [...]}' | ${CLAUDE_SKILL_DIR}/scripts/aml_rules_api.py reorder。 - 仅按下方的授权政策删除规则。
${CLAUDE_SKILL_DIR}/scripts/aml_rules_api.py delete <ruleId>。 - 仅在用户明确要求时发布(参见“发布会影响 LIVE 生产环境”提示):
${CLAUDE_SKILL_DIR}/scripts/aml_rules_api.py publish。发布后,规则链会针对生产环境和沙盒环境中的真实 AML 命中生效——切勿在用户未提出要求时发布;在此之前,草稿不会生效。规则链激活后,后端可能会拒绝发布(已处理的申请人过多 / 集成已完成)——此时会返回4xx。这是预期行为:请报告该情况,并指引用户通过 Sumsub 网页界面发布(参见端点说明)。 - 报告(先列规则名称,绝不要只列 ID):
- 按评估顺序列出规则链(名称)、草稿
revision和通知摘要。 - 草稿(可编辑)视图:https://cockpit.sumsub.com/checkus/sdkIntegrations/globalSettings/amlScreening?revision=draft&tab=amlRules&sbx=true
- 已发布(生效)视图,发布后:https://cockpit.sumsub.com/checkus/sdkIntegrations/globalSettings/amlScreening?revision=published&tab=amlRules&sbx=true
- 两个链接都以可点击的 Markdown 链接形式呈现;
sbx=true指向沙盒工作区。 - 以独立一行
Rule id (for future updates / reorder): <id>结尾——在输出中,只有此处可以出现原始 ID。 - 失败时:逐字呈现 Sumsub 的
description/errorName。
- 按评估顺序列出规则链(名称)、草稿
删除规则 — 同意政策
delete 子命令会永久从草稿中移除一条规则(该规则会随修订版本归档,但会从可编辑规则链中消失)。请遵循以下限制:
- 本次会话中由你创建的规则 — 如果规则有误、用户要求替换,或你正在迭代自己的工作,可以直接删除。(通常按
id原地更新更好,因为这样可以保留规则的位置;只有在规则确实应该被移除时才选择删除。) - 任何非你创建的规则 — 无论是预先存在的规则、来自更早会话的规则,还是由人类编写的规则,只有在用户明确同意删除该特定规则后,才能删除。请说出规则名称(即其
name),并在删除前确认。绝不能以“清理”或“重建”规则链为由,顺带删除他人的规则。 - 如果不确定规则是否由你创建,请视为非你创建并询问。
删除操作具有幂等性,并会返回重新计算过 notices[] 的完整草稿——之后请重新检查这些通知(移除一条规则可能会改变剩余规则仍能支持哪些标签/字段)。
规则规范格式(JSON,通过 stdin 输入)
{
"name": "Auto-clear hits with incompatible date of birth", // required
"description": "Optional free-form description",
"id": "existing-rule-id", // only when updating an existing rule
// condition — the real Sumsub Condition AST, authored directly (see below).
"condition": {
"or": [
{ "and": [
{ "op": "ne", "args": [ { "exp": "input.entityType" }, { "lit": "\"company\"" } ] }, // individual-only — scope every rule (see Authoring conditions)
{ "op": "eq", "args": [ { "exp": "screening.vendor" }, { "lit": "\"complyAdvantageCSOM\"" } ] },
{ "op": "eq", "args": [ { "exp": "match.dobs.hasData" }, { "lit": "true" } ] },
{ "op": "call", "args": [ { "exp": "dobsIncompatible" }, { "exp": "match.dobs" }, { "exp": "input.dob" }, { "lit": "\"weakContainment\"" } ] }
] }
]
},
// Review action — what to set on matched hits (every field optional):
"review": {
"matchStatus": "false_positive", // unknown | potential_match | false_positive | true_positive
"riskLevel": "LOW", // vendor-specific — omit when unsure
"whitelisted": true, // accept the risk: allows approval despite the hit
"note": "Cleared automatically: DoB mismatch"
// OR the whole-review form (replaces all per-field keys):
// "expression": "match.previousReview" // carry over the previous screening's decision
},
// Tags added to the AML case when the rule matches. These are common applicant
// tags (tenant-wide, usable everywhere — not AML-only). A tag that doesn't exist
// yet is created automatically on upsert: prefer reusing an existing tag, and
// name new ones clearly and concisely (e.g. "youngPep", not "rule3_tag"):
"tags": ["auto_cleared_dob"]
}
规则必须包含 review 和/或 tags——两者都没有会产生 emptyAction 错误通知。Review 字段可接受标量(构建器会将其编码为 JSON {lit}),也可接受显式的 {"exp": "..."}/{"lit": "..."},用于计算值或直接提供值。
编写条件
规则的 condition 是直接编写的真实 Sumsub Condition AST——其形状和规则与工作流边条件相同,因此两项技能保持一致。不存在表达式迷你语言(旧的 condition: "screening.vendor = …" 字符串和 conditionRaw 键已移除;构建器会拒绝这两种写法,并在此处提供指引)。
⚠️ 请为每条规则指定实体类型范围。 个人和公司匹配会公开不同的字段,读取方式也不同,因此为其中一类构建的规则可能会在另一类上误触发。每条规则都必须包含一个
input.entityType条件——根据规则意图推断目标类型(个人姓名/出生日期/PEP 信号 → 个人;公司名称/KYB 信号 → 公司);不确定时,默认使用个人:
- 个人(通常情况):
{ "op": "ne", "args": [ {"exp": "input.entityType"}, {"lit": "\"company\""} ] }— entityType ≠ company。- 公司/组织:
{ "op": "eq", "args": [ {"exp": "input.entityType"}, {"lit": "\"company\""} ] }。只有在规则有意不区分实体类型时(较少见——例如“将来自国家 X 的所有
sanctions命中列入白名单”),才省略此条件。大多数库模板已包含此条件——改编模板时请保留。
{
"or": [ // OR of AND-groups; first matching branch wins
{ "and": [
{ "op": "eq", "args": [ {"exp": "screening.vendor"}, {"lit": "\"complyAdvantageCSOM\""} ] },
{ "op": "in", "args": [ {"exp": "input.country"}, {"lit": "[\"BRA\", \"ARG\"]"} ] }
] }
]
}
{exp: "<path>"}— 表达式路径,原样填写(参见 references/aml-rules-context-fields.md)。它是比较的左侧;在字段间检查中,也可以作为右侧({exp: "match.analysis.parentName"})。{lit: "<json>"}— 字面值,必须预先编码为 JSON 字符串(即 API 存储的形式):"\"complyAdvantageCSOM\""、"2"、"true"、"[\"pep\", \"sanctions\"]"。未编码的字面值({lit: "BRA"})会被 API 拒绝,因此必须进行编码。op是以下比较运算符之一(eq ne lt lte gt gte in notIn contains notContains containsAny notContainsAny containsAll containsOnly startsWith endsWith match empty notEmpty eqIgnoreCase …;完整列表见 references/aml-resolution-rules-schema.md)。构建器会根据已知集合验证每个op。- 列表字段的集合成员检查(
match.riskLabels、screening.tags、match.complyAdvantage.matchTypes):contains/containsAny= 包含指定值;containsAll= 包含所有指定值;containsOnly= 只包含所列值。若要匹配“仅标签 X”(例如,仅命中不利媒体),请使用containsOnly ["X"]— 切勿使用notContainsAny [其他标签],因为它会造成漏判:这种写法会默认你已列出整个封闭词汇表(风险标签集合恰好只有六个 — 参见 references/aml-rules-enumerations.md)。 call用于调用内置函数 — 这是 AML 条件支持、而工作流不支持的运算符。第一个参数是函数名,写作{exp: "namesIncompatible"};其余参数为函数的参数:{op: "call", args: [{exp: "dobsIncompatible"}, {exp: "match.dobs"}, {exp: "input.dob"}, {lit: "\"strict\""}]}。函数及其签名见 references/aml-resolution-rules-schema.md。- 否定通过
not*运算符(notIn、notContains、notContainsAny、ne、notEmpty、…)表示 — 不要设置negate标志;顶层的condition.negate会被拒绝(UI 不支持),与工作流技能一致。 - 日期:任何
Date字段(input.dob、match.previousReview.modifiedAt、match.sources.latestEndDate)都提供.ageInDays/.ageInYears/.year等属性 — 例如:{op: "lt", args: [{exp: "match.previousReview.modifiedAt.ageInYears"}, {lit: "2"}]}。
完整的 Condition/And/Criterion AST、字面值编码规则、运算符列表和内置函数签名见 references/aml-resolution-rules-schema.md;有效的 exp 路径见 references/aml-rules-context-fields.md,枚举字段值见 references/aml-rules-enumerations.md(两者均由 references/aml-rules-expressions.md 编入索引)。
示例
examples/minimal.json— 仅标签规则(对风险标签使用containsOnly)。examples/auto-clear-dob-mismatch.json—call函数 + 供应商匹配类型;最常见的自动清除结构。examples/reuse-previous-review.json— 整体审查的expression形式,用于沿用先前决定,并带有日期年龄条件。这也是少见的与实体无关的规则(沿用先前决定的方式对个人和公司相同)— 唯一不需要input.entityType筛选条件的情况。
另请参阅
- references/aml-resolution-rules-schema.md — 包含速率限制的端点、每个字段和枚举、条件 AST 结构、运算符列表、内置函数签名、通知消息键和执行模型。
- references/aml-rules-expressions.md — 表达式引用索引和前言(根变量、
applicant/Date结构、枚举注意事项)。指向下面的两个数据文件;这三个文件都是查询数据库,无需从头到尾阅读。 - references/aml-rules-context-fields.md — 每个合法
exp路径及其类型(## Types/## Index/## Functions)。 - references/aml-rules-enumerations.md — 封闭枚举字段的允许值(风险标签、匹配状态、PEP 机构类型、匹配类型,等等)。
sumsub-create-workflow— 在工作流边条件中编写相同的 Condition AST;其表达式参考涵盖applicant/applicantIdDoc的结构。