无向量库、无Cypher:这家反欺诈Agent如何靠图记忆破案

LedgerLens 反欺诈 Agent 用单一 FalkorDB 图数据库承载所有记忆与审计,通过固定工具和证据声明实现可解释调查。
LedgerLens 是一个反欺诈 AI Agent,其核心创新在于摒弃向量数据库和手写 Cypher,将所有数据、记忆、SOP 和审计轨迹统一存入 FalkorDB 图数据库。Agent 只能使用 26 个预定义工具,每个答案必须声明五种证据形态之一(如 with_path、from_memory),确保可解释性。一个关键 Bug 修复让 Agent 学会持久化“正确拒绝”的决定,避免重复调查无辜警报。实测显示,拒绝警报仅需 11 次工具调用,端掉团伙需 37-62 次,记忆检索延迟亚毫秒级。图算法(WCC、pageRank 等)作为工具集成,用于团伙检测和资金流分析。
无向量库、无Cypher:这家反欺诈Agent如何靠图记忆破案
当大多数AI Agent还在用向量数据库+RAG搭建记忆时,LedgerLens反欺诈Agent走了一条截然不同的路:没有向量存储,没有手写Cypher查询,所有记忆、数据、SOP和审计轨迹都塞进同一个FalkorDB图数据库里。上线三天,它已经能识别出“这不是新团伙,而是旧案复发”——全靠一次全文检索,在毫秒间完成跨会话回忆。

为什么反欺诈需要图记忆,而非向量检索
反欺诈问题很少是简单的查找。“哪些账户与这笔可疑交易有关?”本质上是在共享设备、地址、所有者和资金流之间的一次游走。文本检索依赖片段来猜测相关性,而图则沿着实际记录的关系前进。当Agent冻结一个账户时,它走过的路径就是交给合规部门的解释。
据作者介绍,整个上下文层就是图本身:数据、记忆、标准操作流程和审计跟踪。一个FalkorDB实例托管每个银行一个图,隔离通过图键实现——每个句柄都是select_graph("bank_<slug>"),slug对照严格模式验证,查询无法跨租户,因为根本没有办法命名另一个租户。
FalkorDB 与图数据库基础
FalkorDB 是一个开源的图数据库,底层基于 Redis 的稀疏矩阵引擎,支持属性图模型和 openCypher 查询语言。与传统关系型数据库不同,图数据库将实体建模为节点(Node)、关系建模为边(Edge),并允许节点和边携带属性。这使得多跳关系查询(如“账户 A 通过设备 D 关联到账户 B,B 又向 C 转账”)无需复杂的 JOIN 操作,而是沿着边直接游走,查询延迟通常与遍历深度而非数据总量相关。FalkorDB 的一大特色是内置了图算法库(如社区发现、中心性、路径查找),并支持多图隔离——每个图有独立的键空间,这为多租户场景提供了天然的隔离边界。在 AI Agent 场景中,图数据库不仅能存储结构化关系,还能承载非结构化记忆(如会话消息、发现记录),从而成为统一的上下文层。
三条规则让Agent保持诚实
规则一:模型永远不写Cypher
如果Agent自己写查询,它的答案就依赖于没人审查过的代码。所以它得到一个固定的26个工具菜单,每个工具内部的查询都由人类编写。CYPHER.md从实时工具注册表生成,产品依赖的每个查询都公开供审查。
ID在运行前验证:validate_entities会对照图校验参数,错误的ID返回unknown_entity而不是自信的猜测。读操作无法写入:每个读工具都通过GRAPH.RO_QUERY执行。写操作留下痕迹:freeze_account和escalate_case会创建一个Action节点,记录操作者、原因和时间戳,链接到案件。
Cypher 查询语言与 GRAPH.RO_QUERY
Cypher 是图数据库领域广泛采用的声明式查询语言,语法类似 SQL 但专为图模式匹配设计,例如 MATCH (a:Account)-[:TRANSFER]->(b:Account) RETURN a, b。然而,让 LLM 直接生成 Cypher 存在风险:模型可能产生语法错误、逻辑漏洞或越权查询(如跨租户读取)。LedgerLens 通过固定工具菜单彻底规避了这一问题——所有查询由人类预先编写并封装为工具函数。GRAPH.RO_QUERY 是 FalkorDB 提供的只读查询接口,它在服务端强制查询仅执行读操作,无法写入或修改图结构。这为读工具提供了硬性安全边界:即使工具内部逻辑有误,也无法意外篡改数据。写操作则通过专门的工具(如 freeze_account)执行,并强制记录 Action 节点,形成不可抵赖的审计链。
规则二:每个答案声明其证据类型
每个会话以JSON裁决结束,命名五种答案形态之一,工具层拒绝其他任何形式:
with_path:图持有关系,这里是跳数from_memory:过去的会话确立了这一点,时间在这里not_in_graph:实体存在,但没有以问题假设的方式连接unknown_entity:ID不在图中,所以没有执行查询action:一次经过审计的故意写入
not_in_graph阻止了“我找不到链接,所以应该没问题”的敷衍。在反欺诈工作中,缺失的关系本身就是发现。unknown_entity阻止虚构ID:图中没有ID就不执行查询。这些形态并不保证推理正确,但它们让每项声明都说明自己站在什么证据上,人类知道先检查什么。
规则三:必须不碰的账户
每个种子银行都包含一个高价值、合法、完全隔离的账户——新设备、新地址、没有团伙链接。这正是过度积极的Agent可能会为了显得有产出而冻结的对象。调查员应该检查它,什么也没发现,返回no_case。实时LLM测试断言它在每次运行中都保持不动。
那个让Agent学会“记住正确拒绝”的Bug
准备演示时,作者发现记忆设计有一个漏洞。Agent打开的每个案件都持久化为图记忆:发现、链接、时间戳。但当调查员正确拒绝对负控制项(一笔合法的12,400转账)采取行动时,这个决定没有留下任何图痕迹。图只记住了我们打开的案件,从未记住我们正确拒绝的案件。下一次会话会从头重新调查同一个无辜警报。
纪律不是记忆。一个必须每次都重新证明账户清白的Agent,早晚会出错一次。
修复方案(提交e93909f):清关结果现在持久化为Finding节点,链接到产生它的会话和相关的账户。这是agents.py中的38行代码加上一个27行的回归测试。一个全新的会话现在能以0.9的置信度回忆拒绝决定,附上发现ID和时间戳——就是上文展示的那个裁决。
算法只是更多工具
FalkorDB的图算法位于同一个菜单上:algo.WCC用于团伙组件,algo.pageRank和algo.betweenness用于组件内的枢纽和经纪人,algo.SPpaths用于最多三条最短资金路径(含各段金额),algo.maxFlow用于两个账户之间的漏斗容量。
这些算法需要直接的节点对节点边,但作者将每笔转账建模为Transaction节点,因为审计轨迹很重要。因此图保留了两种投影:TRANSFER按有序账户对聚合交易(金额求和,保留计数),每条有序对一条边也满足algo.maxFlow的简单邻接要求;LINKED_TO记录两个账户共享设备、地址或所有者。
团伙来自LINKED_TO加上内部资金密度,因为共享笔记本电脑的家庭也是一个连通组件。规模和内部流量将团伙与家庭区分开来。
一个v6的坑:算法API并不统一。大多数过程接受配置映射,但algo.pageRank仍然接受位置参数。作者对照运行中的服务器映射签名,而不是信任文档,可用的形式记录在CYPHER.md中。
图算法在反欺诈中的具体含义
- WCC(Weakly Connected Components,弱连通分量):将图中通过任意边相连的节点划分为同一分量,用于发现团伙——只要账户之间通过转账、共享设备等任意关系连通,就属于同一组件。但共享设备的家庭也会形成连通分量,因此需结合内部资金密度进一步区分。
- PageRank:衡量节点在全局网络中的重要性,常用于识别团伙中的核心账户(如资金归集点)。
- Betweenness(介数中心性):衡量节点作为“桥梁”的程度,用于发现连接不同子图的经纪人账户。
- SPpaths(最短路径):查找两个账户间资金流转的最短路径,支持返回路径上的金额分段,用于追踪资金流向。
- maxFlow(最大流):计算两个账户之间网络的最大资金吞吐容量,用于评估漏斗账户的洗钱规模。
这些算法均以过程(Procedure)形式暴露在 Cypher 中,如 CALL algo.pageRank(...)。LedgerLens 将它们作为工具菜单的一部分,由 Agent 按需调用,而非自动运行。
记忆就是更多的图
三种记忆都是节点和边。情节记忆:Session节点带有持久化的Message链(SAID_IN、NEXT),每个案件有自己的会话。语义记忆:Finding节点带有置信度和时间戳,链接到它们描述的实体,与案件标题和警报摘要一起全文索引,search_memory是开场场景和清关回忆的共同机制。程序记忆:Playbook和PlaybookStep节点持有每种警报行动前检索的SOP。结案可以调用learn_lesson,向playbook追加一个步骤,来源指向教会它的案件。之后每次调查都遵循它,每次变更都有纸面记录。
回忆之前的会话只是一个查询,没有第二个存储需要保持同步。
全文索引与 search_memory 机制
LedgerLens 的语义记忆依赖于 FalkorDB 的全文索引功能。Finding 节点及其关联的实体(案件标题、警报摘要)被纳入全文索引,search_memory 工具通过全文检索快速定位相关记忆。与向量检索不同,全文检索基于关键词匹配(支持词干化、停用词过滤等),不依赖嵌入模型,因此延迟极低(实测中位数 0.37 毫秒)。这种设计牺牲了语义泛化能力,但换来了确定性和可解释性——每个检索结果都能追溯到具体的关键词匹配。在反欺诈场景中,警报描述和案件标题通常包含高度结构化的术语(如账户 ID、金额、行为类型),关键词检索足以覆盖大部分回忆需求。对于需要语义理解的场景,Agent 仍可通过图遍历补充关联信息。
交接作为一条边
两个Agent用不同的权限运行同一个循环。 intake分析师进行分类、读取任何内容、打开案件,但不能冻结。案件调查员可以冻结、升级、结案,但只能在交接之后。open_case通过从分析师的会话到新的调查员会话写一条:HANDS_OFF边来触发它。协调变成了可以查询的东西,而不是消失的函数调用。
实测数据:拒绝只需11次工具调用,端掉团伙要37-62次
作者对实时栈并行运行了四次调查:
| 警报 | 裁决 | 工具调用 | 墙钟时间 |
|---|---|---|---|
| AUR-ALR-001 | no_case(拒绝) | 11 | 120.3s |
| NMB-ALR-001 | frozed_and_escalated | 37 | 221.4s |
| NMB-ALR-003 | frozed_and_escalated | 54 | 265.1s |
| AUR-ALR-003 | frozed_and_escalated | 62 | 408.6s |
墙钟时间包含LLM推理。所以拒绝大约需要11次工具调用,端掉团伙需要37到62次。
查询延迟(在实时FalkorDB上25次运行的中位数):search_memory全文检索仅0.37毫秒(p95 0.52毫秒),3跳资金路径遍历0.53毫秒,1跳关联链接0.58毫秒,algo.pageRank 1.94毫秒,algo.maxFlow 46.9毫秒,algo.WCC全图397.5毫秒(p95 498.2毫秒)。
记忆回忆是亚毫秒级查询,所以可以在循环的每一步运行而几乎零成本。模型是瓶颈,不是图。WCC最重,因为它标记整个关联投影,所以每次调查运行一次而不是每一步。
测试与下一步
44个pytest测试通过,包括3个实时LLM Agent测试和9个认证测试。每个银行在tests/fixtures/planted_<tenant>.json中有植入的基准真相,测试断言工具精确找到植入的内容而不多找。并发方面,测试套件运行24个并行读取加上并发的案件和发现写入,同时进行4路并行调查。零交叉干扰,没有使用应用级锁。MCP服务器通过stdio暴露相同的工具注册表,任何MCP客户端都可以驱动它。
下一步:时间边,因为复发需要时间而不仅仅是模式,以及将算法输出反馈到警报优先级排序中。
代码在GitHub上开源:github.com/Mihir-Rabari/ledgerlens。克隆它,启动FalkorDB,运行python seed.py --wipe,控制台会展示从分类到裁决的警报流程,每个结论背后的跳数都显示在屏幕上。
相关推荐

一人量产90集AI漫剧:10小时10块钱的完整制作流程
没有编剧经验也能做AI漫剧:10小时10块钱成本,红果平台单部收益4200元。本文拆解从AI生成剧本、分镜脚本到成片的六步完整流程,附万能提问公式和新手避坑指南。

豆包Agent自制报价测算器:接单报价告别凭感觉
B站UP主用豆包Agent零代码自制报价测算器,输入项目类型、数量、周期即可自动生成报价明细,支持加急与版权买断费率,一键复制发客户,手机端也能随时报价。

WorkBuddy实战教程:10个Agent项目从入门到简历级
WorkBuddy 实战教程解析:用中文交代任务的 AI 工作助手,配置环境比 Codex、Claude Code 更简单。10 个 Agent 实战项目覆盖文件整理、表格汇整、网页生成,新手三步上手,学完可写进简历。