跟踪资金流向:使用 ES|QL 和跨集群搜索追踪洗钱网络

发布时间:2026/7/5 9:13:08
跟踪资金流向:使用 ES|QL 和跨集群搜索追踪洗钱网络 作者来自 Elastic Jon Williams支持 Mule 检测和洗钱网络追踪的数据模型、跨集群架构以及五个 ES|QL 查询这些都构建在大多数金融机构已经部署的基础设施之上。亲自动手体验 Elasticsearch深入了解我们在 Elasticsearch Labs 仓库中的示例 Notebooks开始免费的云试用或者立即在你的本地机器上试用 Elastic。五个ES|QL查询可以在整个账户组合中标记money mule资金中转账户从单个已报告案例向下游追踪洗钱网络并在无需移动任何数据的情况下将可疑支付与位于独立集群中的行为信号进行关联分析。本文介绍了我们基于Elasticsearch构建的欺诈调查平台背后的架构、数据模型以及 ES|QL 查询。同时还介绍了分层存储和logsdb索引模式如何将满足七年监管留存要求的存储成本最高降低 65%。这是三篇系列文章中的第二篇第一篇介绍了金融服务行业在金融犯罪调查中的调查缺口第三篇将介绍构建在该平台之上的 AI agents。欺诈调查平台是如何构建的我们在最近一次英国客户技术交流会上展示了这个平台。值得强调的一点是Elasticsearch、Agent Builder、ES|QL 和 Kibana 都是许多金融机构已经在运行的组件因此这里描述的调查能力可以基于现有基础设施进行组装而不是作为一套独立的新技术栈来采购。基于 Elasticsearch 的欺诈调查平台架构该平台采用分层架构在数据层、智能层和展示层之间实现清晰分离。图1Elastic 高级架构数据层两个集群一次搜索欺诈调查数据很少只存在于一个地方。交易记录、客户资料以及账户元数据通常位于由支付或核心银行团队管理的银行数据集群中。与此同时应用遥测数据移动应用会话日志、网上银行事件、设备指纹以及呼叫中心交互记录往往位于由工程或运维团队管理的可观测性集群中。跨集群搜索Cross-cluster search, CCS 允许每个团队继续拥有并管理自己的数据。同时调查人员可以在一次请求中跨两个集群进行查询无需迁移到单一集群也不需要单独的聚合层。银行集群保存交易数据可观测性集群保存行为信号。调查人员看到的是统一的结果集而两个团队都无需放弃对数据的控制权。跨集群搜索 不仅仅是一个技术上的便利。它解决了我们在第一部分中描述的组织内部障碍——不同团队拥有不同数据、对查询影响生产系统的担忧以及基于角色的访问控制这些控制本身是有充分理由的。CCS 在尊重这些限制的同时仍然允许跨域调查。智能层Agent Builder、skills 和 workflows智能层是 AI agents、ES|QL 查询、机器学习任务以及工作流自动化汇聚的地方。在 Elastic Agent Builder 中agents 会将请求路由到合适的 skill而每个 skill 会绑定其所需的 ES|QL 工具和 workflows例如 Investigation、Typology Narrative、Graph Network、COP/Vulnerability 以及 SAR Creation。第三部分将详细介绍 agent 和 skill 的架构。在本文中我们聚焦它们所依赖的数据与查询基础。展示层Kibana 与自定义应用该平台包含一个自定义调查界面用于与 agent 服务和 Elasticsearch API 通信。但同一份数据也可以在 Kibana 中用于临时的、分析师驱动的探索。这种双界面设计是有意为之结构化调查流程用于提升速度而 Kibana 用于回答工作流未设计覆盖的问题。Kibana 仪表板提供运营视图告警队列、案件数量趋势以及 mule 账户热力图而 Discover 和 Kibana 控制台中的 ES|QL 则让分析师能够自由运行探索性查询而无需等待他人构建新的仪表板。关于可用性说明本文中的数据模型和 ES|QL 查询可在任何 Elasticsearch 部署上运行但该架构中的两个能力有特定要求带 ES|QL 的跨集群搜索在 Elasticsearch 8.19 和 9.1 中通常可用需要两个集群都具备兼容订阅见 跨集群搜索 和 订阅。Elastic Agent Builder在 Elastic Cloud Serverless 上以及云托管和自管理部署的 Enterprise 等级中可用见 Agent Builder 正式发布。用于资金中转账户money mule检测的数据模型交易、账户与行为信号数据模型是一切的基础。欺诈调查是一个跨领域问题这意味着数据模型必须能够容纳不同的文档document类型同时仍然支持快速、灵活的查询。图2应用欺诈数据模型——FCA 沙盒银行业交易核心索引保存支付交易记录。每一条文档代表一次支付事件包含相关方、金额、时间以及元数据等字段。// Index: banking-transactions { transaction_id: a76fe1f9-c403-4855-bc61-22b0db37fc29, timestamp: 2025-01-20T23:47:12.341Z, account_id: 3f7932e3-9e69-4d69-aef5-41f281b3969b, amount_gbp: -15000, currency: GBP, is_credit: false, is_debit: true, channel: mobile_app, transaction_type: faster_payment, payment_code: XF, purpose_code: INVESTMENT, description: Investment deposit, counterparty_name: CryptoTrade Ltd, counterparty_account: 94738291, counterparty_sort_code: 20-45-67, merchant_category: 6211, geo_location: POINT (-0.1616 51.5296), graph.source_account: 47-83-82_10985194, graph.source_bank: Bank4, graph.dest_account: 20-45-67_94738291, graph.dest_bank: Bank2, graph.payment_flow: outbound, graph.amount_band: large, ... }有几个要点值得注意。purpose_code和merchant_category字段在可用时包含来自 ISO 20022 的增强信息使基于规则的系统可以与 AI agent 一起使用这些信号。负数金额表示借记同时通过is_credit和is_debit flags进行快速过滤。geo_location支持对交易模式进行空间分析。在具备 ISO 20022 增强数据的情况下付款用途代码、法人实体标识符Legal Entity Identifiers以及结构化汇款信息提供了额外信号。Elasticsearch 的无模式特性意味着我们可以将 ISO 8583 等传统格式与 ISO 20022 增强格式一起摄入到同一个索引中而不需要在前期定义严格的固定 schema。账户与人员客户数据通常托管在 CDPCustomer Data Platform中但为了简化架构我们将其放在同一个集群中。账户级数据存放在banking-accounts索引中而客户身份与画像数据存放在banking-people中。这种拆分是有意设计的调查人员在分析交易模式时无需访问个人身份信息同时 RBAC基于角色的访问控制可以限制只有授权角色才能访问 PII 数据。// Index: banking-accounts { account_id: 7179a225-19b5-4b24-9aae-b50ad43cb15c, account_number: 96435152, account_type: savings_account, account_status: active, person_id: 79393ff4-3a32-4bae-9021-4566e6b5008c, bank_name: Bank1, sort_code: 20-30-79, iban: GB62BANK20307996435152, balance_gbp: 39920.61, currency: GBP, opened_date: 2017-04-13T00:00:00.000Z, ... }person_id字段链接到banking-people索引该索引保存客户身份、地址、信用记录、就业信息以及弱势标记这些内容被单独存放在一个具有独立访问控制的索引中。一个简化示例如下// Index: banking-people { person_id: 4233d7fd-29aa-439d-8cc8-a07f1933128f, first_name: Rebecca, last_name: Brennan, date_of_birth: 1979-01-19T00:00:00.000Z, age: 47, address_line1: 244 Manor Terrace, city: Blackpool, postcode: FY1 6AN, location_geo: POINT (-3.050282 53.836826), credit_history.credit_score: 729, credit_history.vulnerability_flag: socially_isolated, credit_history.total_debt_gbp: 6548.49, accounts: [ { account_id: 528a..., account_number: 32540475, sort_code: 22-79-61, balance_gbp: 3242.93 }, { account_id: 692e..., account_number: 39261497, sort_code: 24-53-93, balance_gbp: 2175.45 } ], ... }应用遥测数据可观测性集群可观测性集群保存来自银行自身移动端与网上银行应用的会话级遥测数据。这不是浏览历史或外部网站数据而是来自机构自身服务的遥测信息支付服务提供商对这些数据拥有合法访问权限。// Index: app-telemetry (observability cluster, accessed via CCS) { session_id: sess-9f8e7d, customer_id: C847392, timestamp: 2025-01-20T21:32:00Z, app_platform: ios, event_type: screen_view, screen_name: payment_limits, session_duration_seconds: 8100, device_fingerprint: fp-abc123, ip_address: 82.132.xxx.xxx, geo_city: London, ... }会话遥测数据揭示了仅靠交易数据无法发现的行为模式客户在付款前在应用中停留的时间、他们访问的页面尤其是支付限额页面、设备指纹是否与其常用设备匹配以及登录位置是否与历史记录一致。呼叫中心日志客户服务交互会以结构化元数据方式被索引从而可以将服务电话与后续交易进行关联分析。// Index: call-centre-logs { call_id: CALL-29481, customer_id: C847392, timestamp: 2025-01-17T14:22:00Z, duration_seconds: 420, topic: payment_limit_increase, outcome: limit_raised, ... }如何使用 ES|QL 检测资金中转账户money muleES|QL 是 Elastic 的管道式查询语言专为跨大规模数据集的探索性分析而设计。在我们的平台中ES|QL 查询有两个作用一方面它们是 agent skills 可以以编程方式调用的工具另一方面分析师也可以在 Kibana 中直接使用它们进行临时探索。下面是驱动该平台的关键查询。mule 检测识别资金 “直进直出” 的账户这是平台中最重要的查询。它会检查每一个账户计算资金流入与流出的总量衡量资金停留的时间并标记那些资金快速 “流入即流出” 的账户。FROM banking-transactions | STATS incoming SUM(CASE(is_credit true, amount_gbp, 0)), outgoing SUM(CASE(is_debit true, ABS(amount_gbp), 0)), transaction_count COUNT(*), first_txn MIN(timestamp), last_txn MAX(timestamp) BY account_id | EVAL turnover_ratio TO_DOUBLE(outgoing) / GREATEST(TO_DOUBLE(incoming), 1.0), time_span_ms TO_LONG(last_txn) - TO_LONG(first_txn), days_active time_span_ms / 86400000.0, txn_frequency TO_DOUBLE(transaction_count) / GREATEST(days_active, 1.0) | WHERE incoming 5000 AND turnover_ratio 0.75 AND days_active 180 | SORT turnover_ratio DESC, incoming DESC | LIMIT 50示例输出account_id incoming outgoing txns turnover_ratio days_active 20-45-67_94738291 247,000 239,000 31 0.968 42.0 30-91-22_50271841 87,000 84,200 18 0.968 27.0 04-17-55_61398002 54,000 52,400 13 0.970 22.0 11-38-09_77450513 43,000 41,500 11 0.965 18.0 (top 4 of 50 results)turnover_ratio接近 1.0 表示几乎所有流入资金都立刻流出这是资金中转账户mule account的典型特征。days_active过滤条件用于聚焦新开账户而流入金额阈值用于过滤噪声数据。最终输出是按风险排序的可疑账户列表。对可疑账户建模谁在向其转账一旦某个账户被标记下一步就是分析其资金流入模式。该查询会识别所有向指定目标账户转账的账户并计算每个来源账户的总风险暴露。FROM banking-transactions | WHERE graph.dest_account 20-45-67_94738291 AND is_debit true | STATS total_sent SUM(ABS(amount_gbp)), tx_count COUNT(*), first_payment MIN(timestamp), last_payment MAX(timestamp) BY graph.source_account, graph.source_bank | SORT total_sent DESC示例输出graph.source_account graph.source_bank total_sent tx_count 20-30-79_88142251 Bank1 15,000 1 04-22-13_67391044 Bank3 14,200 1 11-90-56_20517783 Bank2 12,800 2 ... ... ... ... 23 source accounts · £247,000 total这会展示所有源账户的完整列表——潜在的受害者。当某个账户在六周内出现 23 个不同来源并且所有来源都向同一个目标账户发送大额资金时这种模式就非常清晰。向下游追踪网络mule 网络通常是分层结构的。为了追踪资金在主 mule 账户之后的去向我们将查询反转查看出账流动FROM banking-transactions | WHERE graph.source_account 20-45-67_94738291 AND graph.payment_flow outbound | STATS forwarded SUM(ABS(amount_gbp)), tx_count COUNT(*), first_forward MIN(timestamp), last_forward MAX(timestamp) BY graph.dest_account, graph.dest_bank | SORT forwarded DESC示例输出graph.dest_account graph.dest_bank forwarded tx_count 30-91-22_50271841 Bank4 112,400 8 04-17-55_61398002 Bank2 78,100 6 11-38-09_77450513 Bank5 48,500 4 3 downstream accounts · £239,000 forwardedagent 将这些查询串联起来先对主 mule 的下游账户进行画像然后对每一个账户重复运行同样的 mule 检测查询以判断它们是否也属于洗钱网络的一部分。这种递归模式能够将单一的举报案例扩展为完整的网络级调查。客户行为基线为了判断某一笔交易对特定客户是否异常我们会计算其历史行为基线并进行对比FROM banking-transactions | WHERE account_id 3f7932e3-9e69-4d69-aef5-41f281b3969b AND is_debit true | STATS avg_amount AVG(ABS(amount_gbp)), max_amount MAX(ABS(amount_gbp)), tx_count COUNT(*), first_txn MIN(timestamp), last_txn MAX(timestamp) | EVAL flagged_amount 15000, amount_ratio ROUND(flagged_amount / GREATEST(avg_amount, 1.0), 1), time_span_ms TO_LONG(last_txn) - TO_LONG(first_txn), days_active time_span_ms / 86400000.0amount_ratio为 12 表示该被标记交易金额是客户典型支付金额的 12 倍。agent 会结合该指标以及时间和渠道数据共同作为欺诈风险评估的输入。跨集群行为上下文跨集群搜索允许单个 ES|QL 查询从可观测性集群中拉取数据。下面的查询会获取在可疑交易发生前数小时内该客户的应用遥测数据FROM observability:app-telemetry | WHERE account_id 3f7932e3-9e69-4d69-aef5-41f281b3969b AND timestamp 2025-01-20T19:00:00Z AND timestamp 2025-01-21T00:00:00Z | STATS session_count COUNT_DISTINCT(session_id), total_duration SUM(session_duration_seconds), screens_viewed COUNT(*), limit_views SUM(CASE(screen_name payment_limits, 1, 0)) | EVAL hours_active ROUND(TO_DOUBLE(total_duration) / 3600.0, 1)示例输出session_count total_duration screens_viewed limit_views hours_active 4 7,320 38 7 2.0当这一分析显示某个平时习惯在午餐时间花 5 分钟处理银行事务的客户却在深夜花了 2 小时在应用内操作反复访问支付限额页面 7 次随后又进行了异常大额转账时整个图景就会变得清晰得多。这种行为上下文往往是“确定性欺诈判断”和“模糊可疑判断”之间的关键差异。使用 Elasticsearch 分层存储扩展欺诈数据留存规模欺诈调查平台只有在能够处理真实世界的数据规模以及满足监管留存要求时才具有实际价值。数据规模Elasticsearch 的分布式架构能够轻松应对这一点。同样的基础设施每天为企业客户处理数十亿级安全事件也完全能够支撑支付交易级别的数据量客户例如 BBVA。用分层存储满足监管留存英国金融监管通常要求保存 7 年的交易数据。这意味着极其庞大的数据量。Elastic 的分层存储架构使这种成本在经济上可行热层Hot tierNVMe SSD最近 7 到 30 天。用于活跃调查与实时告警支持亚秒级查询性能。温层Warm tierSSD30 天到 1 年。足够用于历史案件复盘与模式分析。冷层与冻结层Cold tier / Frozen tier对象存储1 到 7 年。用于合规与审计查询以及机器学习训练数据。Logsdb 带来的成本降低Logsdb 索引模式通过优化字段存储与索引方式可将交易数据的存储成本降低高达65%。对于需要长期保存海量数据的平台来说这种优化意味着从“可负担部署”到“成本不可承受部署”之间的关键差异。在 Elasticsearch 上构建欺诈调查平台的关键经验构建这个 Elasticsearch 欺诈调查平台过程中我们总结了一些值得分享的重要经验适用于任何正在构建类似系统的人。经验要点为什么重要如何实践从数据模型开始清晰的数据 schema 能让 AI agents 准确理解查询结果。所有下游查询、skill 和仪表盘都依赖它。提前定义明确的 mapping例如字段名、类型和关系。在不同索引间统一字段命名定义清晰的文档边界并规划跨集群查询模式。行为数据是关键差异点仅有交易数据往往是模糊的。一笔 15,000 英镑的支付可能是购房、购车或欺诈。行为上下文例如午夜两小时的应用使用、7 次访问支付限额页面、三天前的客服请求才能将模糊转化为确定性判断。在交易数据之外同时摄入应用会话遥测并在调查阶段通过跨集群搜索进行联合查询。跨集群搜索让架构可落地CCS 允许调查人员在遵守数据所有权边界的前提下跨银行与可观测性集群查询数据。如果没有它就需要数据迁移或单独的聚合层。将 CCS 视为结构性能力而不是优化项。它是该架构在真实机构中可部署的关键前提。下一步AI agents 与工作流自动化在数据模型与查询基础建立之后第 3 部分将介绍构建在该架构之上的 AI agents如何配置、使用哪些工具、workflow 自动化如何处理 SAR 报告生成与账户调查以及一个端到端的完整调查流程示例从告警到合规处置。最终目标是构建一个统一、可查询的调查层该层建立在许多机构已经在运行的基础设施之上。准备好探索用于欺诈调查的 Elastic 吗可以联系我们的金融服务团队讨论基于你数据的概念验证POC、现有欺诈技术栈的架构评估或关于 Elastic 如何融入你欺诈路线图的战略讨论。原文How to build a money mule detection platform on Elasticsearch - Elasticsearch Labs