跳到主要内容

智能体系统就是分布式系统:在遭遇惨痛教训前应用微服务经验

· 阅读需 16 分钟
Tian Pan
Software Engineer

多智能体 AI 系统在生产环境中的失败率令人汗颜。一项分析了七个流行框架、超过 1,600 条执行追踪的地标性研究发现,失败率在 41% 到 87% 之间。卡内基梅隆大学的研究人员指出,在多步基准测试中,领先的智能体系统的任务完成率仅为 30–35%。Gartner 预测,到 2027 年底,40% 的智能体 AI 项目将被取消。

这就是令人不安的事实:这些并不是 AI 问题。它们是工程师在 2010 年至 2018 年间已经解决的分布式系统问题,这些解决方案详尽地记录在博客文章、会议演讲以及 Martin Kleppmann 的《数据密集型应用系统设计》(Designing Data-Intensive Applications)中。今天能够交付可靠智能体系统的团队并没有施展什么魔法——他们应用的是熔断器(circuit breakers)、舱壁隔离(bulkheads)、事件溯源(event sourcing)和幂等键(idempotency keys)。那些失败的团队则将智能体视为一种全新的范式,而实际上,它们只是旧模式的新部署目标。

失败分类似曾相识

MAST 论文对多智能体失败的分类分为三类:系统设计问题(约 42%)、智能体间失配(37%)以及任务验证失败(21%)。剥离掉针对 LLM 的特定表述,你得到的是:糟糕的架构、协调故障和缺失的可观测性。2015 年的分布式系统文献将这些称为强耦合、级联故障和静默数据损坏。

最具破坏性的失败模式是级联幻觉传播(cascading hallucination propagation)。一个智能体产生了一个自信但错误的输出,并将其存储在共享状态中,下游智能体则将该存储值视为经过验证的事实。这正是静默数据损坏在共享可变数据库的微服务中传播的方式——第一个服务写入垃圾数据并返回 200 OK 状态,随后的每个服务都忠实地读取它。

第二种最常见的模式是协调延迟崩溃(coordination latency collapse)。在两个智能体同步协调的情况下,你会看到大约 200 毫秒的开销。如果有八个智能体处于同步链条中,开销将增长到四秒以上。如果你曾见过将单体架构拆分为一打通过同步 HTTP 调用通信的微服务,你就见过这种情况。解决方法是一样的:将协调异步化,并围绕事件传播而非请求/响应链进行设计。

第三种模式——级联超时(cascading timeouts)——对于任何运营过服务网格(service mesh)的人来说都不需要解释。一个缓慢的依赖项阻塞了所有调用者。调用者积压。积压向上传播。所有东西一起垮掉。智能体只是为这些组件取了带有 LLM 风格的名字而已。

熔断器:缺失的可信赖性原语

熔断器模式(circuit breaker pattern)在 2012 年左右通过 Netflix 的 Hystrix 库在微服务中普及。它封装了出站调用,并在三种状态之间转换:闭合(closed,调用正常通过)、断开(open,立即拒绝调用而不尝试)和半开(half-open,测试有限的调用以查看依赖项是否已恢复)。其目的是防止失败的依赖项消耗资源并增加延迟,同时提供快速失败路径,允许调用者优雅降级。

对于智能体系统,每一次 LLM 调用、每一次工具调用以及每一次智能体间的通信都是一次可能失败的服务调用。在正常条件下,由于速率限制、超时或服务器错误,LLM API 的失败率在 1%–5% 之间。如果没有熔断器,一个遭遇下游故障的智能体编排器将排队更多请求,耗尽速率限制,为失败的 Token 处理付费,并可能无限期停滞。

其实现方式与微服务版本完全相同。你在滑动窗口中跟踪错误率。当错误率超过阈值(例如过去 60 秒内超过 50%)时,你会断开电路并立即拒绝调用,并返回回退(fallback)——通常是缓存的响应、空操作(no-op)或下游智能体知道如何处理的结构化错误。在冷却期后,你允许有限的流量通过以测试恢复情况。这种模式消除了由于一个智能体的 LLM 调用降级,导致所有 12 个下游智能体都在排队等待永远不会到达的响应的情况。

舱壁隔离:资源 isolation 之间智能体类

舱壁模式(bulkhead pattern)的名字来源于船体中的水密隔舱,这些隔舱可以防止一个舱室的破损导致整艘船沉没。在微服务中,这意味着为不同的服务依赖分配独立的线程池、连接池和资源配额,这样一个池的枯竭就不会导致其他池也陷入饥饿。

在多智能体系统中,等效的失败是“吵闹邻居”(noisy-neighbor)问题:一个具有高并发、重度工具使用或昂贵模型调用的智能体类垄断了共享资源。一个进行大量网页搜索的后台研究智能体可能会耗尽与延迟敏感的面向用户智能体共享的速率限制。一个批处理智能体可能会填满共享内存缓冲区,并导致交互式智能体出现 OOM。

修复方法很简单。为每个智能体类分配独立的资源池。在编排器层级强制执行 LLM API 调用、内存分配和并发工具执行的配额——而不是在每个智能体看不到其他智能体在做什么的智能体层级执行。基础设施级别的隔离(例如按工作负载层级划分独立的 Azure OpenAI 部署)可以防止软限制导致无关智能体出现硬故障。

这并不是什么稀奇的模式。这和你不在生产环境的 OLTP 数据库上运行分析查询、不在延迟敏感的 API 和批量导入服务之间共享连接池、以及不让后台任务与实时请求竞争 CPU 是同一个道理。

事件溯源与松耦合

分布式单体反模式(distributed monolith antipattern)扼杀了许多早期的微服务迁移。团队在 API 边界分解了服务,但仍通过共享的可变数据库保持耦合。每个服务都可以读写每张表。一个服务的模式(schema)更改会破坏其他五个服务。所谓的“微服务”只是增加了网络延迟的单体。

多智能体系统正在高速复制这一反模式。团队构建了专门用于研究、草拟、审查和执行的智能体,但所有协调工作都通过直接的同步调用和共享的可变状态进行。智能体 A 调用智能体 B,B 再调用智能体 C。当 B 慢时,A 就在等待。当 C 失败时,一切都会崩溃。当共享状态的模式发生变化时,缓存了假设的智能体就会无声无息地崩溃。

适用于微服务的修复方案在这里同样奏效:智能体通过事件而不是直接调用进行通信。每个智能体订阅与其角色相关的事件,并在完成工作时发布事件。编排器通过事件路由而不是显式的调用图进行协调。这意味着智能体可以按自己的节奏运行,故障在事件边界被隔离,添加或删除智能体类型不需要更新调用链。

除了去耦,事件溯源还带来了第二个好处:你获得了一份关于每个决策和状态转换的完整、不可变的记录。当你的自主智能体在生产环境中做出意想不到的行为时(它一定会发生的),你可以回放事件日志,以了解导致该结果的确切输入和输出序列。没有这个,在生产环境中调试涌现的智能体行为就像是在考古。有了它,你就拥有了一台时光机。

幂等性不是可选的

在运行分布式系统时,你学到的第一件事就是:至少一次交付(at-least-once delivery)是实际的默认设置。网络会分区。服务会在请求中途重启。超时会导致调用者重试实际上已经完成的操作。任何不具备幂等性的操作最终都会执行两次并产生错误的结果。

LLM 智能体面临着这一问题更严重的版本。不仅网络问题会导致重试,智能体编排器本身也可能在恢复过程中决定重试失败的步骤。OpenAI 在其 Codex 生产智能体中使用的 Temporal 持久化执行模型使这一点变得具体:当工作流崩溃并恢复时,它会从持久化的检查点进行重放。任何非幂等副作用——写入数据库、发送电子邮件、调用外部 API——都会再次执行。

解决方案与分布式系统中的相同:为操作分配幂等键(idempotency keys)。幂等键是逻辑操作的唯一标识符,允许接收服务检测并去重重复的请求。当智能体决定发送电子邮件时,该决策会获得一个 UUID。如果操作失败并使用相同的 UUID 重试,电子邮件服务会识别出重复项并返回成功,而不会再次发送。

这并不是智能体特有的智慧。这是 Stripe API 自 2013 年以来一直在做的事情,是 Kafka 消费者从一开始就通过消费者组偏移量在做的事情,也是每个支付处理器为了避免向客户重复收费而做的事情。唯一的新鲜事是将它应用于你的智能体执行的操作。

带抖动的指数退避(Exponential backoff with jitter)是补充性的原语。当需要重试时,你不希望所有重试的调用者同时冲击正在恢复的服务——这就是重试风暴如何搞垮几乎快要恢复的系统。AWS 的研究证明,与固定间隔重试相比,带抖动的指数退避可减少 60–80% 的重试风暴。其模式是:在第 1 次重试前等待 1 秒,第 2 次重试前等待 2 秒,第 3 次重试前等待 4 秒,并加入随机抖动因子以分散负载。限制总尝试次数。配合熔断器(circuit breakers)使用这些机制,以便在依赖项明显退化时完全停止重试。

可观测性债务在累积

在拥有生产环境智能体部署的组织中,94% 的组织已经实施了可观测性工具。62% 的组织拥有详细的追踪。这些数字听起来很合理,直到你意识到接受调查的组织中只有 5.2% 实际上在生产环境中部署了智能体——其余仍处于可观测性压力较低的试点和原型阶段。

多智能体系统在某一特定方面使得可观测性比微服务更难:推理链是不透明的。对于微服务,你可以追踪请求经过服务 A、B 和 C 的路径,并读取每一跳的日志。对于智能体,每个智能体内部的“处理”是一个产生 Token 的 LLM 推理,而关于下一步做什么的决策就嵌入在该 Token 流中。标准的请求追踪会告诉你一个智能体花费了 3.2 秒并返回了一个字符串;它不会告诉你为什么智能体决定调用文件删除工具。

新兴的标准是 OpenTelemetry 的 GenAI 语义约定(GenAI Semantic Conventions),截至 v1.37 版本,它已成为官方规范的一部分。其模式与服务的分布式追踪相同——追踪 ID(trace ID)在整个智能体工作流中传播,每个智能体发出 Span,Span 包含模型名称、提示 Token、补全 Token 和调用的工具等语义属性。不同之处在于,LLM Span 还会捕捉推理轨迹:思维链(chain-of-thought)输出、工具选择理由以及传递给下游智能体的结构化输出。

这些数据回答了生产环境中最重要的问题:不是“智能体失败了吗”(你的熔断器已经知道了),而是“它为什么要做它所做的事情”。

框架之问

不同的智能体框架内化了不同程度的分布式系统规范。LangGraph 的显式状态模式(state schemas)和由 reducer 驱动的状态管理映射了事件溯源(event sourcing)原则,并防止了共享可变状态这一反模式。Temporal 的持久执行(durable execution)在基础设施层面处理了幂等性、重试和检查点(checkpointing),这也是为什么 OpenAI 为 Codex 选择了它——你可以直接获得可靠性模式,而无需为每个 agent 单独实现。

AutoGen 自从在 2025 年末与 Semantic Kernel 合并进入微软统一的 Agent Framework 后,带来了企业级的可观测性集成和结构化错误处理。CrewAI 基于角色的层级结构非常适合原型设计,但对于需要在不同 agent 类型之间进行细粒度故障隔离的团队来说,灵活性较低。

常见的错误是根据 demo 任务中的基准性能来选择框架,然后在生产环境中才发现其可靠性模型的缺失。更重要的问题是:当 agent 超时、当工具调用返回垃圾数据、或者当 LLM API 返回 429 错误时,这个框架会做什么?一个让可靠性模式显式化且可配置的框架,在生产环境中的价值远高于一个在评估集上得分更高的框架。

DDIA 讲透了,但 Agent 教程跳过的点

《数据密集型应用系统设计》(Designing Data-Intensive Applications,简称 DDIA)用了大约 400 页的篇幅来讨论多个进程共享状态时出现的问题:复制延迟、脑裂场景、脏读、顺序保证、共识协议。这些内容之所以对 agent 系统至关重要,是因为 LLM agent 本质上是共享状态的有状态进程——它们只是使用英语消息和工具调用,而不是 SQL 事务和 gRPC 端点。

最直接相关的概念包括:

线性一致性(Linearizability)意味着如果 agent A 写入了一个值,随后 agent B 读取它,B 应该看到 A 的写入。这听起来理所当然,但大多数 agent 的共享内存实现(内存对象、松散协调的缓存)在并发写入下无法保证这一点。结果就是 agent 在不知情的情况下根据过时或矛盾的状态进行推理。

因果一致性(Causal consistency)虽然较弱但通常已经足够:如果 agent A 的输出导致 agent B 采取了行动,那么任何看到 B 行动的 agent 也应该看到 A 的输出。这防止了 agent 在观察到“果”时却看不到“因”——这种一致性违规会让调试多智能体交互变得极其混乱。

共识协议——Raft、Paxos 及其变体——是 Temporal 和类似的持久执行系统在内部使用的,用以保证工作流状态在 agent 进一步执行之前已被持久化提交。理解这些协议的存在及其提供的功能,就能解释为什么 Temporal 的恢复保证比你自己用数据库写入实现的检查点(checkpointing)更强大。

你并不需要读完所有 600 页。关于共识和事务的章节是可以直接应用的。重点并不是你需要为你的 agent 实现 Raft——你不需要。重点是如果你理解了为什么 Raft 存在以及它解决了什么问题,你就不会再尝试通过缺乏相同保证的临时状态同步来解决这些问题。

模式是旧的,部署目标是新的

行动手册早已存在。用于故障隔离的断路器(Circuit breakers)和隔舱(bulkheads)。用于避免分布式单体反模式的事件溯源和松耦合。用于保证“至少一次交付”的幂等键和持久执行。用于在不透明处理步骤中实现可观测性的分布式链路追踪。

在构建 agent 之前就应用了这些模式的团队,正将多智能体可靠性鸿沟视为一个已解决的问题。而那些正在生产环境中摸索这些模式的团队,正在以失败的部署、损坏的输出以及各种事故为代价进行学习——自主智能体删库、执行未经授权的购买、产生具有法律风险的幻觉——这些事故最终会出现在事故复盘报告和监管备案中。

讽刺的是,分布式系统领域花了十年时间记录这些模式,正是因为通过被动反应来学习它们的代价太高了。2015 年的微服务社区正是从这种经历中产出了 Hystrix、隔舱模式、边车网格、结构化日志,并最终发起了可观测性运动。那些文档至今依然准确。部署目标变了,但问题没有变。

References:Let's stay in touch and Follow me for more thoughts and updates