AI Agent 的 SRE:凌晨 3 点到底什么会出故障
一个市场调研流水线连续运行了 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 部署影响整个系统的熔断器。
