跳到主要内容

AI Agent 的 SRE:凌晨 3 点到底什么会出故障

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个市场调研流水线连续运行了 11 天。四个 LangChain Agent —— 一个分析器(Analyzer)和一个验证器(Verifier)—— 来回传递请求,在原始任务上毫无进展,并在被人发现之前累积了 47,000 美元的 API 费用。系统从未返回错误,也没有触发报警。直到损失造成几天后,计费仪表板才发现了这一异常。

这绝非个案。它是典型的 AI Agent 事故。如果你现在正在生产环境中运行 Agent,你现有的 SRE 运维手册(runbooks)几乎肯定没有涵盖这种情况。

传统的运维实践是基于一个核心假设构建的:故障会产生信号。服务崩溃、超时触发、错误率飙升。你编写报警来捕获这些信号,编写运维手册来解释它们的含义,并编写演练手册(playbooks)来告诉值班人员如何应对。系统之所以运行良好,是因为有缺陷的代码往往会“自我宣告”。

AI Agent 打破了这个假设。它的故障模式不是崩溃,而是系统在运行正确的同时在做错误的事情。LLM 响应了,工具调用执行了,循环在继续。从基础设施的角度看,一切都很健康。从业务的角度看,你正在烧钱且一事无成。这两者之间的差距就是 Agent 事故存在的地方。

传统监控遗漏的故障模式

Agent 的故障可分为四类,每一类对于标准的错误率监控来说都是不可见的。

无限工具循环(Infinite tool loops) 是最昂贵的。一个被分配了目标但没有完成标准的 Agent 将无限期地发出工具调用。造成最大损害的变体是“软循环”:Agent 不是重复调用完全相同的工具(去重机制可以捕获这种情况),而是重新措辞相同的查询、在搜索中增加一个词或稍微改变参数,但在实现目标方面没有实际进展。每一次迭代都会消耗 Token。上下文窗口不断扩大。随着窗口填满,每次调用的成本也随之增加。团队通常是通过账单数据而不是监控发现这些问题的。

长时工作流中的上下文溢出(Context overflow in long-running workflows) 发生在多步骤任务累积了工具输出、先前的推理和对话历史,直到填满上下文窗口时。与内存分配失败不同,这不会导致进程崩溃 —— Agent 只是开始丢失早期步骤的记忆,产生越来越不连贯的推理,同时继续执行。一个有记录的材料科学工作流在达到这种状态之前消耗了 2,000 万个 Token;通过内存指针(用简短标识符替换完整数据)重新实现它后,Token 使用量减少了 99% 以上。

幻觉 API 调用(Hallucinated API calls) 发生在 Agent 构建了一个语法有效但在实际 API Schema 中不存在参数的请求时。导致成本失控的特定故障模式是:Agent 无法区分“API 拒绝了我的请求”和“任务不可能完成”,因此它会带着不断增长的上下文窗口,数百次地重试同一个格式错误的调用。据报道,一起事故因为对同一个失败调用的 847 次重试而损失了 2,000 美元。

Schema 漂移和凭证失效(Schema drift and credential rot) 是最常见的隐蔽生产故障。当工具的 API Schema 发生变化 —— 参数名称被重命名、增加了必填字段、更新了身份验证流程 —— Agent 仍会根据其缓存的 Schema 理解继续运行。调用会因 Agent 无法正确解读的验证错误而失败,导致行为混乱,而不是清晰的错误升级。证书过期也是这种模式的一个变体,通常在持续数月的静默续期失败后才被发现。

复合数学是残酷的。一个单步准确率为 85% 的 Agent,在包含 10 个步骤的工作流中,其端到端成功率大约只有 20%。这个数字还是建立在故障能产生清晰信号的假设之上的。当故障产生的是隐蔽循环时,有效的成功率看起来可能还行,但成本和时间却在螺旋式上升。

你的 SRE 体系没有衡量什么

大多数可观测性堆栈跟踪可用性、延迟和错误率。这些指标是必要的,但对于 Agent 来说是不够的。一个看起来健康的系统可能同时在:

  • 单个会话中消耗了 10 倍于预期的 Token 预算
  • 在用户的实际目标上毫无进展
  • 运行一个已经活跃了 6 小时的工具循环
  • 针对一个已经弃用了三个月的 Schema 进行执行

可观测性缺口是结构性的。Token 成本是一个异步指标 —— 当每日支出阈值的预算报警触发时,额外的 API 循环早已完成。目标进展是一个语义指标 —— 它不会出现在 HTTP 状态码或数据库写入计数中。工具参数相似度是一个需要大多数团队尚未构建的插桩(instrumentation)工具来捕获的单次调用行为指标。

业界正趋向于将 OpenTelemetry 作为 Agent 追踪的标准框架。推动采用的关键洞察在于区分 基础设施可观测性(服务是否在运行?)和 行为可观测性(Agent 是否在做正确的事情?)。你两者都需要。

行为可观测性需要:

  • 单步 Token 消耗量:针对每个会话的预算进行跟踪,而不是每日汇总
  • 工具调用历史:通过参数去重来检测软循环
  • 实现目标的步数计数:当在 N 步内没有可衡量的状态变化时触发停机切换
  • 上下文窗口利用率:以百分比形式跟踪,在达到 70% 容量时报警
  • 停机原因代码:区分超时、最大步数(max_steps)、成本上限、错误与正常完成

一个三层追踪架构 —— 用于完整用户交互的 Trace 级别、用于单个 LLM 调用和工具调用的 Span 级别、用于结构化元数据的 Attribute 级别 —— 能让你具备调试 Agent 事故的粒度,而无需在事后从日志中重建行为。

成本熔断器:为什么警报不等于强制执行

那起 47,000 美元的事件之所以具有启发意义,正是因为团队并没有疏忽大意。他们设置了计费警报,且警报按设计正常运行。问题在于,预算警报报告的是已经发生的事情;它们并不能阻止下一次 API 调用的发生。

对 Agent 进行有效的成本控制需要在 API 调用层面进行同步强制执行。在每次 LLM 请求或工具调用之前,执行层都会检查该会话的剩余预算。如果预算已耗尽,则不会执行调用。这与基于累计支出的警报架构有着本质的不同。

实际实现位于代理 (Proxy) 或中间件层,独立于 Agent 框架代码。将强制执行逻辑排除在 Agent 提示词 (Prompt) 之外并非可选项——提示词中表达的任何成本限制都是一种“软约束”,模型可能会对其进行推理、在极端情况下绕过它,或者在对抗性输入下直接忽略它。强制执行必须存在于模型看到请求之前运行的代码中。

按 Agent 类型划分的合理默认预算结构:

  • 研究型 Agent(无边界探索任务):每会话 5 美元
  • 运营型 Agent(特定任务执行):每会话 0.50 美元
  • 对话型 Agent(面向用户的对话):每轮 0.10 美元

这些是起点,而非通用值。重要的属性是它们是每会话的硬上限,而不是每日累计额度。一个失控的 Agent 如果在晚上 11 点触发了每会话上限,只会让你损失该会话的预算,而不是十一天的 API 费用。

分层防御增加了韧性:任务级上限嵌套在会话级预算中,会话级预算嵌套在按 Agent 类型划分的集群上限中。集群上限是防止单个配置错误的 Agent 部署影响整个系统的熔断器。

编写真正涵盖 Agent 事件的运行手册 (Runbooks)

传统的运行手册结构可以很好地映射到基础设施故障:症状、诊断命令、修复步骤、升级路径。Agent 事件需要相同的结构,但内容不同。

Agent 事件的症状检测:

  • 成本警报触发,但相应的错误率没有增加 → 调查活跃会话是否存在死循环
  • 会话持续时间超过该 Agent 类型的 P99 值 → 在追踪 (Traces) 中检查步骤数和参数相似度
  • 特定端点的工具错误率激增 → 检查是否相对于当前 API 规范发生了 Schema 漂移
  • 用户目标完成率下降,而技术成功率保持不变 → 语义退化

死循环的诊断:

提取该会话的 Span 追踪。寻找参数相似度高于阈值的重复(工具,参数)对。检查步骤之间的状态是否发生了变化——如果 Agent 对世界的理解在连续五个步骤中都没有更新,那么它就处于“软循环”中。整个会话的单步成本可视化将显示出上下文窗口膨胀所特有的上升趋势。

修复:

对失控会话的即时操作是通过执行层进行终止——会话停止命令应与服务重启命令一起放在运行手册中。终止后,任务进入死信队列供人工审查。在弄清楚循环形成的原因之前,不要自动重试。

升级阈值:

与根据错误率或用户影响进行升级的基础设施事件不同,Agent 事件的升级依据是:达到预算上限(立即升级)、步骤数超过该 Agent 类型 P99 的 3 倍(15 分钟内调查)、工具错误率超过 5% 且属于 Schema 相关错误(一小时内调查漂移情况)。对于任何不可逆的 Agent 操作——文件删除、外部 API 写入、支付操作——无论 Agent 的置信度如何,人工回环 (Human-in-the-loop) 闸门都应该是强制性的。

你的 Agent 基础设施层

大多数 Agent 的可靠性问题并不是模型问题。它们是基础设施问题,之所以看起来像模型问题,是因为基础设施层尚未建立。

防止上述失败模式的组件包括:

持久化执行框架(如 Temporal 或 LangGraph 的持久化层)支持检查点 (Checkpointing)——在步骤之间保存执行状态,以便中断的 Agent 可以从上一个已知的良好状态恢复,而不是从头开始。对于任何长于单个 LLM 调用的 Agent 工作流来说,这都是基本要求。

启动时的工具 Schema 验证——而不是在调用时验证——可以在导致事件之前捕获漂移。在初始化时,执行层应根据实时 API 规范验证每个工具的 Schema。Schema 不匹配应阻止 Agent 启动,而不是在执行过程中表现为隐晦的错误。

幂等工具设计支持安全重试。如果使用相同的参数两次调用同一个工具产生相同的结果且没有副作用,你就可以在失败时重试而无风险。这需要刻意的 API 设计,但它是使熔断器和自动恢复成为可能且不会创建重复状态的基石。

分阶段上下文压缩可以防止长运行工作流超出上下文限制。有效的实现不是在每个请求中加载整个对话历史,而是使用内存指针、检查点摘要以及按优先级排序的剔除策略,在保持上下文在预算范围内的同时,保留 Agent 实际需要的信息。

从“AI 功能”向“AI 基础设施”的转变是目前大多数团队所处的阶段。90% 的 Agent 项目在 30 天内失败,失败模式不是模型——而是缺乏让模型变得可靠的周边工程。预算强制执行、行为可观测性、检查点和 Schema 验证并不是高级话题。它们是在生产环境中运行 Agent 的基本门槛。

值班初始清单

在你的下一个 Agent 部署上线之前,请验证是否具备以下特性:

  • 在执行层(而非提示词或告警中)强制执行的单会话预算上限
  • 包含工具参数捕获和步数追踪的 Span 级链路追踪
  • 软死循环检测:在连续 N 步没有状态变化后停止
  • 上下文窗口利用率在 70% 和 90% 容量时的告警
  • 针对因熔断而终止的会话,提供死信队列和人工审核流程
  • Agent 启动时针对实时 API 规范进行 Schema 验证
  • 无论模型置信度如何,不可逆操作都必须经过人工审批
  • 文档化的停止原因分类,以便值班人员能够区分超时、死循环与成本上限

那场损失 47,000 美元的死循环跑了 11 天,正是因为上述机制都不存在。这份清单上的每一项都是在真实组织的生产环境中发生过的具体故障模式。构建它们并非过早优化——而是负责任运营的底线。

在凌晨 3 点,你需要的是一份能告诉你该看什么、该做什么的操作手册(Runbook)。而实现这一目标的工作,现在就得开始。

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