跳到主要内容

并行智能体系统中的隐性数据损坏问题

· 阅读需 14 分钟
Tian Pan
Software Engineer

当一个多智能体系统开始出现奇怪的行为——给出不一致的答案、丢失任务追踪、做出与早期推理相矛盾的决策——本能反应是责怪模型。调整提示词,换一个更强的模型,添加更多上下文。

真正的原因往往更平凡,也更危险:并发写入导致的共享状态损坏。两个智能体读取同一块内存,都计算出更新,其中一个默默地覆盖了另一个。结果状态在技术上是有效的——没有异常抛出,没有模式违规——但在语义上是错误的。之后读取它的每一个智能体都在对错误信息进行正确的推理。

这种故障模式在单个操作层面是不可见的,在测试环境中难以复现,仅通过查看输出几乎无法与模型错误区分开来。O'Reilly 2025年关于多智能体内存工程的研究发现,36.9%的多智能体系统故障源于智能体间的不对齐——智能体在对共享信息的不一致视图上运行。这不是一个理论上的顾虑。

为什么这看起来像模型故障

共享内存损坏的阴险之处在于它在起源地的几步之后才显现出来。一个协调器派生出五个并行研究智能体。智能体A和B都读取共享任务队列(计数:3),都处理任务,都将结果写回。智能体B的写入最后落地,默默地覆盖了智能体A的写入。任务计数仍然显示为3,但智能体A的工作消失了。

现在,合成智能体D读取"3个任务完成",并接收来自4个智能体(而非5个)的输出。它对接收到的数据进行完美推理——但那些数据是错误的。最终合成看起来像幻觉或推理错误。如果你再次以串行方式运行相同的工作流,它运行良好。这个bug只在并发负载下出现,这意味着它完全逃过了大多数开发环境测试。

时间窗口使这个问题更加严重。在运行20到50个并发智能体的生产系统中,在测试环境中需要微秒级精度才能复现的竞态条件会例行发生。你无法按需触发它们。你只能提前对它们进行检测。

三种故障模式

并行智能体系统中的共享内存竞争以三种不同的模式表现出来:

丢失更新。 智能体A读取balance = 100,智能体B读取balance = 100,智能体A写入95,智能体B写入150。最终状态:150。智能体A的工作消失了。这是经典的读-改-写竞态条件。用数据库术语来说,这是导致丢失更新的不可重复读。

脏读。 智能体A执行多步骤状态变更——任务开始"处理",数据转换,状态更新为"完成"。智能体C在变更中途读取,看到部分更新的状态:任务处于"处理"状态,但下游计数尚未更新。智能体C对这种部分状态进行推理并做出决策,一旦智能体A的变更完成,这些决策就会变得不一致。

级联污染。 单个竞态条件造成的损坏状态向下游扩散,因为其他智能体将其纳入自己的推理。Galileo AI的模拟发现,单个损坏的状态值在引入后四小时内毒化了87%的下游决策。这种毒性之所以传播,是因为每个后续智能体都将损坏的数据视为基本事实。

所有三种故障模式都共享同一个特征:单个操作看起来有效;只有当你检查跨时间的多个操作之间的关系时,不一致性才会出现。

将数据库隔离级别应用于智能体内存

分布式系统领域对这些确切问题有数十年的艰难获得的解决方案。数据库隔离级别——未提交读、已提交读、可重复读、可序列化——不是特定于数据库的概念。它们描述了任何共享状态系统都可以实现或近似实现的一致性保证。

未提交读意味着智能体可以读取并发智能体正在修改过程中的状态。对于偶尔的陈旧读取可以接受的超低延迟系统很有用。对于部分状态在语义上无效的任何情况都很危险。

已提交读意味着智能体只看到已提交的更改。防止脏读,但允许这样一种情况:在单个智能体执行过程中,如果另一个智能体在两次读取之间提交,同一次读取可能返回不同的结果。这是大多数多智能体框架中的默认一致性模型——比大多数工程师假设的要弱。

可重复读保证在单个智能体的逻辑事务中,同一次读取始终返回相同的值。智能体在其推理持续期间获得共享状态的一致快照。对该快照的并发更新被推迟到智能体完成之后。这适用于对共享数据进行多步骤决策的智能体。

可序列化是最强的保证:行为与智能体按某种顺序依次执行相同。并发执行在实现层面发生,但可观察到的结果与某种串行顺序匹配。这适用于只能发生一次的操作——认领任务、更新共享计数器、分配资源。

关键洞察是不同的内存区域需要同时具有不同的隔离级别。每个智能体应恰好认领一个项的共享任务队列需要可序列化的一致性。多个智能体只追加结果的共享发现库只需要已提交读。私有智能体草稿本根本不需要协调。将所有共享内存视为单一一致性域既过度设计(将所有内容锁定为可序列化会扼杀吞吐量),也欠缺设计(在所有地方应用最弱级别会在关键资源上创建竞态条件)。

为什么最后写入者胜利是错误的

最简单的冲突解决策略——当两个智能体写入冲突的值时,保留最近时间戳的那个——对于分布式系统,进而对于分布式智能体协调,从根本上是错误的。

时钟偏差是问题所在。即使使用NTP同步,机器时钟也会漂移数百毫秒。服务器1上的智能体A(时钟快100毫秒)在"系统时间10:00:05.000"写入。服务器2上的智能体B在"系统时间10:00:04.950"写入。智能体A胜出,因为它的时间戳更晚——即使智能体B根据实际现实时间先写入。最后写入者胜利不会选择最近的写入;它选择来自时钟最超前的机器的写入。

现代框架已经认识到这一点。LangGraph明确地用确定性归约函数替换了最后写入者胜利:"在并行分支收敛时,编排器根据预定义的状态转换规则确定性地合并片段,确保一致且可重现的状态演化。"合并两个并发写入的结果由合并函数定义,而不是由哪个写入先到达。

实际有效的冲突解决策略

加载中…
Let's stay in touch and Follow me for more thoughts and updates