AI Agent 错误处理与恢复:构建高可靠性生产系统
生产环境中的 AI Agent 时刻面临错误。工具调用会失败,LLM 会返回意外格式,API 会触发限流,网络连接会中断。如果没有稳健的错误处理机制,这些失败会级联扩散,导致工作流中断和用户体验糟糕。本指南涵盖 AI Agent 系统在 production 中的实用错误处理与恢复策略。
为什么错误处理对 AI Agent 至关重要
与输入可预测的传统软件不同,AI Agent 运行在概率性环境中。相同的 prompt 在不同调用中可能产生不同输出。工具可能暂时不可用。LLM 响应可能格式不规范或不完整。这些不确定性要求错误处理策略超越简单的 try-catch 模式。
考虑一个处理退款的客服 Agent。如果支付 API 返回错误,naive 的实现可能会静默失败或无限重试。高可靠性的系统会识别失败,通过备选路径尝试恢复,并向用户呈现有意义的状态。这两种方式的区别决定了你的 Agent 是感觉可靠还是脆弱。
未处理错误的代价
| 错误类型 | 业务影响 | 恢复复杂度 |
|---|---|---|
| 临时 API 故障 | 延迟 1-2 秒 | 低 — 带退避的重试 |
| LLM 格式不匹配 | 无效的工具调用 | 中 — 解析并重试 |
| 工具持续宕机 | 工作流停滞 | 高 — 需要备选路径 |
| 超出限流限制 | 突发流量节流 | 中 — 队列与延迟 |
| 安全/拒绝错误 | 硬性失败 | 低 — 快速失败并告警 |
理解这些分类有助于你设计合适的处理策略,而不是对所有失败应用无差别重试。
核心错误处理模式
带抖动的指数退避
当工具临时失败时,立即重试浪费资源并可能加剧限流。指数退避将重试尝试分布在逐渐增加的时间间隔内,而抖动(jitter)添加随机性以防止多个 Agent 同时重试时产生的「雷群」(thundering herd)问题。
从 100-500 毫秒的基础延迟开始。每次失败后延迟翻倍,最高不超过 30 秒。在当前延迟值范围内添加 0 到当前延迟之间的随机抖动。大多数 production 系统将总重试次数限制在 3-5 次,超出后升级处理。
熔断器模式
当工具或 API 频繁失败时,持续重试浪费时间与资源。熔断器监控失败率,在超过阈值后打开电路,立即快速失败而非尝试恢复。
熔断器由三种状态定义:
- 闭合(Closed):正常运行,请求正常通过
- 打开(Open):失败过多,请求立即失败,不尝试调用工具
- 半开(Half-Open):超时后,允许发送测试请求以探测服务是否恢复
根据 SLA 设置失败阈值。10 次请求中 50% 失败率可能表明工具退化值得调查。半开状态让你无需人工干预即可检测恢复。
备选链
单点依赖等于单点故障。备选链为关键操作维护替代实现或数据源。当主路径失败时,Agent 按优先级尝试备选方案。
示例:一个天气查询 Agent 可能先尝试 OpenWeatherMap,主路径限流时回退到 WeatherAPI,两者都失败时使用缓存结果。每个备选方案带有不同保证——缓存命中是陈旧的但即时,而次要提供商可能有不同的数据覆盖范围。
LLM 特定错误处理
响应验证
LLM 输出是概率性的。即使使用结构化输出 prompt,解析器也必须优雅处理意外格式。在处理之前,应针对预期 schema 验证响应。当验证失败时,记录实际输出并决定是否使用更严格的 prompt 重试或升级给人工处理。
三个验证层级防护常见失败:
- 结构验证:检查必需字段是否存在且匹配预期类型
- 语义验证:验证值在领域内有意义(例如,温度应该是数字而非字符串)
- 业务规则验证:确认输出满足约束(例如,退款金额不能超过原始购买金额)
畸形 JSON 恢复
当 LLM 返回截断或畸形 JSON 时,在完全拒绝之前尝试恢复。常见的恢复技术包括关闭未闭合的括号、转义未转义的引号,以及从周围文本中提取部分结构。某些 Agent 使用专门的二次 LLM 调用来修复畸形输出,以延迟换取可靠性。
内容策略失败
LLM 内容过滤器可能拒绝其他方面有效的 prompt。不要完全失败,而是分析拒绝模式以调整 prompt 措辞。建立已知拒绝触发器和替代措辞的字典。将拒绝日志与其他错误分开,以便识别系统性 prompt 问题而非随机过滤。
工具集成韧性
超时配置
每个外部工具都需要合适的超时时间。简单查询使用短超时(5 秒)。复杂操作如图像生成或文档处理使用较长超时(30-60 秒)。基于历史延迟百分位数(而非平均值)配置每个工具的超时,以应对尾部延迟。
权限与认证错误
认证失败与临时错误不同。当工具报告无效凭证或过期 token 时,不要重试——重试会得出相同失败结果。相反,立即向用户或系统管理员呈现认证错误。在可能的情况下,为 OAuth 集成实现 token 刷新流程。
恢复策略
语义重试 vs. 盲重试
盲重试期望不同结果而重复相同的失败操作。语义重试根据错误上下文修改方法。当工具返回验证错误时,用相同输入重试浪费时间。当工具返回超时,用调整后的参数(更长超时、更小 payload)重试成功率更高。
在决定重试之前对错误分类。临时错误(超时、连接被拒绝、5xx 响应)值得重试。永久错误(400 错误请求、401 未授权、403 禁止)需要备选处理。
检查点与恢复
长时间运行的 Agent 工作流受益于检查点。在每个步骤完成后保存进度,这样失败从上次成功点而非从头开始重启。这对多步骤流程(如文档生成管道或跨越数十次工具调用的数据聚合工作流)特别有价值。
优雅降级
当完整功能不可用时,提供部分价值而非完全失败。无法获取实时数据的 Agent 可以服务带有新鲜度时间戳的缓存结果。无法生成自定义内容的 Agent 可以回退到带清晰限制的模板化响应。
监控与告警
错误分类法
系统性地对错误分类以实现有效监控。按类型(临时、永久、验证、安全)、按工具和按严重程度跟踪错误率。显示错误率趋势的仪表板有助于区分流量增加(绝对错误增多但比率稳定)和真正退化(错误率上升)。
平均恢复时间(MTTR)
测量错误持续多久才能恢复。恢复时间包括检测延迟、决策时间和执行时间。自动重试减少检测和决策时间。熔断器和备选链通过提供即时备选方案减少执行时间。
故障模式文档
维护已知故障模式及其处理的活文档。当出现新错误模式时,将其添加到分类法中并附带响应程序。新团队成员和自动 on-call 系统从对熟悉错误类型的统一响应中受益。
实施清单
| 组件 | 建议 | 优先级 |
|---|---|---|
| 重试 | 带抖动的指数退避,最多 3-5 次 | 必需 |
| 熔断器 | 每工具的打开/半开阈值 | 外部工具必需 |
| 超时 | 基于 P99 延迟按工具配置 | 必需 |
| 验证 | LLM 输出的 schema + 语义检查 | 必需 |
| 备选 | 替代工具或缓存数据 | 关键路径高优先级 |
| 检查点 | 每个逻辑步骤后保存状态 | 长工作流高优先级 |
| 错误日志 | 带错误分类的结构化日志 | 必需 |
| 告警 | 错误率和恢复时间的阈值 | 高优先级 |
FAQ
重试多少次算太多?
超过 5 次重试很少能成功,通常表明是永久失败。每次重试消耗 token、时间,并可能加剧限流。如果重试耗尽,转向备选或错误处理而非继续重试。
我应该重试 400 Bad Request 错误吗?
不。400 错误表明请求本身无效,而非服务临时不可用。重试相同的 400 请求浪费资源。相反,验证你的输入并修复请求或升级错误。
我如何区分临时故障与永久故障?
临时错误通常返回 5xx 状态码、超时消息或连接被拒绝响应。永久错误返回 4xx 状态码、验证消息或认证失败。结合错误消息内容和状态码进行分类。
当所有备选都失败时会发生什么?
当所有恢复路径都耗尽时,优雅失败。向用户返回清晰错误消息,说明失败内容以及可用选项。记录完整错误链以便调试。考虑实现死信队列来追踪永久失败的待操作供后续审查。
如何在没有真实故障的情况下测试错误处理?
使用混沌工程原则:在测试环境中注入故障,通过阻塞网络请求、返回错误响应或模拟超时而实现。在受控条件下测试你的重试逻辑、熔断器和备选链。大多数测试框架支持 HTTP 拦截器模式来模拟失败场景。
错误处理会引入安全风险吗?
会。过于冗长的错误消息可能泄露内部实现细节。无限流的重试逻辑可能导致拒绝服务攻击。在暴露错误消息之前始终对其进行清理,对重试实施限流,切勿在错误追踪中记录敏感数据。
AI Agent 应如何处理部分成功?
当多步骤工作流完成部分步骤但在其他步骤失败时,保存已完成步骤的进度并从失败点恢复而非重新开始。这需要检查点和幂等操作,即重新执行已完成步骤产生相同结果。
结论
构建高可靠性 AI Agent 需要分层错误处理:对临时故障的即时重试、防止级联失败的熔断器、关键操作的备选链,以及完整功能不可用时的优雅降级。持续监控错误模式并根据 production 经验优化处理策略。在生产环境中感觉可靠的 Agent 有一个共同特征:它们 visibly 地失败、自动恢复,并从失败中学习以改进未来性能。
更多关于构建 production-ready AI Agent 的指南,请访问 SmaugBrain 并探索我们在 Agent 部署、安全和优化方面的资源。