跳到主要内容

AI Agent 的 CAP 定理:为何你的 Agent 在本该优雅降级时却彻底崩溃

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的 AI Agent 运行得一切正常,直到某一刻它彻底不行了。某个工具宕机——也许是搜索 API 触发了限流,也许是数据库响应迟缓,也许是代码执行沙箱超时——整个 Agent 随之崩溃。不是部分答案,不是降级响应,而是彻底失败。要么一片空白,要么满是幻觉。

这不是一个 Bug,而是一个设计选择——而且几乎没有人是刻意做出这个选择的。我们今天所构建的 Agent 架构隐式地选择了"彻底失败",原因只有一个:没有人设计过部分可用路径。如果你有分布式系统的经验,这个模式应该让你感到似曾相识。这正是 CAP 定理,以一副新的面孔出现了。

你不知道自己正在做的那个权衡三角

在分布式数据库领域,CAP 定理指出:一致性 (Consistency)、可用性 (Availability) 和分区容忍性 (Partition Tolerance) 三者最多只能同时满足其二。当网络分区发生时——而它总会发生——你必须在两者之间做出选择:要么提供可能陈旧的数据(选择可用性),要么拒绝服务直到分区恢复(选择一致性)。

AI Agent 面临类似的约束。当 Agent 因为 API 中断、限流、超时或网络抖动而无法访问某个工具时,它面临着同样的根本问题:是用现有信息作出响应(可能不完整或不够准确),还是拒绝响应?

大多数 Agent 框架对这个问题的回答方式,是干脆不回答它。它们将每一次工具调用都视为硬依赖。搜索工具失败了,整条调用链就失败。代码解释器超时了,Agent 就返回错误。这种架构在没有人写下任何需求文档的情况下,就隐式地选择了一致性而非可用性。

如果工具故障是偶发的,这倒没什么问题。但事实并非如此。在生产级 Agent 系统中,工具故障时刻都在发生——流量峰值时的限流、Serverless 函数的冷启动延迟、间歇性 DNS 故障、第三方 API 的维护窗口。2024 年 12 月的 OpenAI 大规模宕机事件引发了广泛关注,但更小、更隐蔽的工具故障每小时都在每一个生产 Agent 部署中发生着。

没有人为之设计的三种故障模式

Agent 故障并非非黑即白。在"完美运行"和"彻底崩溃"之间存在一个连续的谱系,但大多数架构只处理两端的极端情况。理解这片中间地带,需要识别三种截然不同的故障模式。

优雅降级 (Graceful degradation) 是指某个非关键工具不可用时,Agent 以降低后的能力继续运行。一个通常会同时进行网络搜索、数据库查询和计算的 Agent,在只有两个工具可用时依然能给出有用的答案。关键词在于"非关键"——但大多数 Agent 设计从未对哪些工具是关键的、哪些是可选的进行过明确分类。

部分故障 (Partial failure) 是指工具返回了不完整或降级的结果。搜索 API 只返回了三条结果而不是十条。数据库查询在返回一半数据后超时。Agent 收到了某些东西,但少于预期。这是生产环境中最常见的故障模式,也是 Agent 框架中处理最少的一种。

静默失败 (Silent failure) 是最危险的模式。工具调用看似成功,但返回的是陈旧数据、来自其他查询的缓存响应,或者一个看起来完整实则被截断的结果。Agent 自信地基于这些被污染的输入继续推进,生成看起来合理实则系统性错误的输出。没有错误信息,没有任何标志。故障只会在 Agent 输出被付诸行动之后,才在下游暴露出来。

为何大多数 Agent 架构选择"彻底失败"

根本原因在于工具调用架构。在典型的 Agent 循环——观察、思考、行动、观察——中,每次工具调用都是同步的、全有或全无的操作。LLM 生成工具调用,框架执行它,结果回流到下一个推理步骤。如果执行失败,框架有三个选项:重试、报错或产生幻觉。大多数框架先选第一个,再选第二个。

这种设计与早期将网络视为可靠的分布式系统如出一辙。正如分布式计算的谬误告诉我们:网络并不可靠,延迟不为零,带宽也非无限——Agent 的构建者们正在重新学到:工具可用性无法保证,工具延迟不可预测,工具结果并不总是完整的。

在多 Agent 系统中,这个问题会成倍放大。当 Agent A 依赖 Agent B 的输出,而 Agent B 又依赖工具 C 的 API 响应时,单个工具故障会在整条流水线中层层级联。每个下游 Agent 都将残缺或丢失的输入视为可信的事实。文档第二页的一个解析错误会污染后续所有的分析步骤。一个被误解的目标会被完美无误地执行成一个完全错误的东西。

来自分布式系统的熔断器 (circuit breaker) 模式在这里可以直接套用:当故障超过某个阈值(例如,10 次请求中失败率达到 50%)后,停止尝试调用故障工具并绕过它。但绕过它需要有地方可以绕到——而这需要提前设计好部分可用路径。

设计部分可用路径

修复方案并不复杂。它需要三个大多数团队从未明确做出的架构决策。

第一,按关键程度对工具进行分类。 并非所有工具生来平等。编程 Agent 的代码执行工具是关键的——没有它,Agent 无法验证自己的输出。但同一个 Agent 的网络搜索工具可能是可选的——它能改善答案,但并非基本功能所必需。这种分类应该在 Agent 的配置中明确体现,而不是隐含在错误处理逻辑里。

第二,定义降级响应契约。 当工具失败时,Agent 需要关于发生了什么的结构化信息——而不仅仅是一个错误码。降级响应应该包含:缺失了哪些数据、为何缺失,以及 Agent 应该为其剩余信息分配什么样的置信度。FAILURE.md 规范提出了一种有用的格式:{"status": "degraded", "missing_tools": [...], "reason": "timeout"}。当 LLM 收到这个信号时,它可以在响应中明确承认这一缺口,而不是假装缺口不存在。

第三,构建降级层级。 生产级 Agent 系统使用一套分层降级策略:

  • 主级 (Primary):正常条件下直接执行工具。
  • 次级 (Secondary):基于语义相似度匹配的缓存响应。一个调优良好、使用基于嵌入检索的缓存可以处理 60-70% 的重复查询。
  • 第三级 (Tertiary):针对常见、易于理解场景的基于规则的逻辑。重置密码不需要 LLM。
  • 第四级 (Quaternary):带用户确认的延迟处理。将请求加入队列,告知用户稍后会得到答复,并在工具恢复后处理它。

这几种方法之间的差异,就是"有用的 80% 答案"与"毫无价值的 0% 答案"之间的差异。

自主性-可靠性-监督三角

CAP 类比不止于工具可用性。Agent 架构师面临一个更广泛的权衡三角:自主性 (Autonomy)、可靠性 (Reliability) 和监督 (Oversight)。你可以优化其中两个,但第三个会随之受损。

自主性加可靠性 带来快速的无人值守流水线,能够处理歧义并适应意外状态。代价是监督——当这些系统出故障时,你没有审计追踪,没有干预点,也无法解释发生了什么。这对低风险自动化任务是可行的,但对任何涉及金钱、健康或法律后果的事情都是危险的。

自主性加监督 带来大胆行动、配备人工终止开关的实验性 Agent。代价是可靠性——输出是非确定性的,部署到生产是一场赌博。大多数演示版 Agent 都活在这个象限,这就是为什么它们在展示中看起来令人印象深刻,而在生产中令人不寒而栗。

可靠性加监督 以牺牲完全自主性换取可预测性。设有人工审批关卡的门控工作流。受限的工具访问权限。确定性的评估步骤。这是医疗、金融、法律等高风险领域今天应该采用的运作模式。它不如完全自主的 Agent 令人兴奋,但它是唯一能同时避免灾难性失败和不可审计结果的组合。

正确的选择取决于你在构建什么,但错误的选择是根本不做选择。

生产韧性的实战模式

如果你今天正在生产环境中运行 Agent,以下是最重要的几种模式。

带抖动的指数退避 (Exponential backoff with jitter) 是不可妥协的。 没有抖动时,来自多个 Agent 实例的同步重试会制造重试风暴,使故障更加严重。初始延迟一秒、最大延迟 32 秒、抖动系数 0.5x 到 1.5x 的配置,可以防止协调一致的重试雪崩。

请求批处理降低限流暴露。 按意图分类对工具请求进行排队和批处理——当积累到 10 个请求或 500 毫秒时触发,以先到者为准。这在高流量时期可以将 API 调用减少 70%。

对工具端点的健康检查能在用户发现问题之前捕获故障。 每 30 秒对每个外部工具进行一次心跳检测,结合熔断器逻辑(60 秒内三次失败触发熔断器),可以提供早期预警和自动路由切换。

在关键间隔重新注入核心指令。 Agent 在长任务序列中会随着早期上下文的消退而失去连贯性。定期重申 Agent 的约束和目标,可以防止规格漂移——即对指令的逐渐重新解读,导致 Agent 用统计上合理的内容而非实际要求的内容来填补模糊的空白。

那个令人不舒服的真相

关于 AI Agent 可靠性,有一个令人不舒服的真相:这是一个早已被解决的问题——几十年前由面临同样根本性约束的分布式系统工程师解决的。网络分区、部分故障、拜占庭故障、最终一致性——这些概念与工具宕机、降级响应、幻觉补全和陈旧缓存答案是直接对应的。

Agent 社区正在从头重新学习这些教训,是因为这些系统在表面上看起来不同。一个 LLM 调用工具,看起来与一个数据库节点向从节点复制数据毫无相似之处。但故障模式是一样的。权衡取舍是一样的。解决方案——熔断器 (circuit breakers)、分层降级 (fallback tiers)、明确的一致性模型 (explicit consistency models)、分区感知路由 (partition-aware routing)——也是一样的。

下次你的 Agent 因为一个工具宕机而彻底崩溃时,不要去修那个工具。去修架构。明确地决定:当 Agent 无法做到一切时,它应该做什么。生产级 Agent 与演示版 Agent 的区别,不在于模型或提示词,而在于是否有人设计了部分可用路径。

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