制裁名单筛查看起来是个简单问题。
拿一个名字,和名单比对,分数超过阈值就送去人工审核。在动手搭建Verifex之前,我也是这么想的。实际完全不是一回事。
没人说破的真正痛点
合规审核员需要的不是"两个名字很像"这个结果。他们得搞清楚:匹配是怎么产生的?哪些证据支持?哪些证据削弱?六个月后审计时这个决定是否站得住脚?
一个孤零零的分数回答不了任何问题。引擎返回0.92,审核员还得从头猜:是姓氏对上了?别名?出生日期?国籍?还是来源名单的问题?没有拆解,每次审核都是从零开始的手动重建。
模糊匹配的盲区
字符串模糊匹配在干净数据上表现不错。John Smith对John Smith,ACME Ltd对ACME Limited,都没问题。但真实的制裁数据混乱得多。
名字顺序被打乱。不同来源的音译规则不一致。有的条目有别名,有的没有。出生日期缺失或残缺。国籍存储格式乱七八糟。常见名字制造噪音。有些名单把名字存成"姓氏, 名 父称"格式,而天真的解析器会把它们颠倒过来。
最后这个问题在早期版本里真的出过bug。解析器把PUTIN当成名字,因为它出现在逗号前面。匹配分数暴跌,但任何人类审核员一眼就能看出这是同一个人。单一的最终分数只能告诉你"哪里不对"。证据拆解才能告诉你"具体哪里"。
证据胶囊的设计
我围绕一个简单想法持续迭代:引擎不该只返回分数,而要给每个候选匹配生成结构化的证据对象。我称之为"证据胶囊"(Evidence Capsule)。
每个胶囊包含:查询名与候选名、来源名单信息、分词级别的名字比对、出生日期信号、国家与国籍信号、标识符信号、支持性证据列表、削弱性证据列表、原因代码,以及审计警告。
目标不是取代审核员,而是给他们结构化的解释,让他们不必每次都从零开始。
把评分重构为证据加权
模糊匹配输出的是相似度分数。我想要的是更接近证据加权推理的东西。内部模型采用对数几率结构:log_odds等于先验对数几率加上各项证据权重之和,后验概率则由sigmoid函数转换得到。
每个信号独立贡献。姓氏完全匹配会加分。出生日期完全匹配大幅加分。国家不匹配会拉低分数。仅基于常见名字的匹配会被惩罚。缺失的上下文被明确记录,而非直接忽略。但这不等于说输出是经过校准的概率,这个区别很重要。
为什么校准 matters
如果引擎输出0.90,这并不自动意味着90%的匹配是真正的命中。未经校准的模型在高置信度区间会系统性过度自信。审核员如果按字面理解这个数字,会产生错误的安全感。
校准需要代表数据。而制裁筛查的数据有个特殊问题:真正的正样本极其稀少。在大多数生产环境中,命中率低于0.1%。这意味着你几乎没有真正的匹配来训练校准曲线。
我目前的做法是分离两个概念:证据加权分数用于排序和阈值筛选;校准后的概率估计单独提供,并附带明确的置信区间和校准质量指标。审核员需要知道什么时候可以信任数字,什么时候该持保留态度。
从分数到叙事
证据胶囊的真正价值不在于技术细节,而在于它改变了审核员的工作模式。传统流程是看到分数、猜测原因、打开原始记录、手动比对、写下结论。新流程则是阅读证据摘要、验证关键信号、确认或质疑、最终决策。
审核时间从平均4分钟降到90秒。更重要的是,审核质量变得可审计。六个月后的复查可以看到当时的完整推理链条,而不是一个孤立的分数和一段手写备注。
还没解决的问题
这个架构也有明显局限。跨语言匹配仍然困难。阿拉伯语名字的罗马化变体可能多达十几种,证据胶囊会列出所有匹配,但审核员仍需判断哪些是合理的音译变体,哪些是无关噪音。
别名网络复杂化推理。当一个人有五个别名,每个别名又有多种变体时,证据胶囊的长度会爆炸。我正在实验分层摘要:先给总体匹配理由,再展开详细证据。
热门跟贴