K5.3.2 Task 5.3

"数据库错误"——编排器重试了 5 次。数据库早就永久下线了。

通用错误消息——“失败”、“不可用”、“发生错误”——剥离了所有恢复信息。编排器分不清超时(重试)、永久故障(切换来源)还是认证过期(刷新凭证)。它盲目重试一切,包括永远不会成功的错误。

通用错误的代价

3 个月内 1,000 次子代理故障使用通用错误消息:

  • 350 个永久错误被重试了 3 次 = 1,050 次浪费的 API 调用
  • 480 次故障有部分结果被丢弃后重新获取
  • 总浪费:$2,100 API 成本 + 15 小时的客户解决延迟

切换到结构化错误后:浪费的调用减少 94%,89% 的故障保留了部分数据。

通用错误导致什么

问题影响
盲目重试永久故障浪费算力,永远不会成功
丢弃部分结果重做已完成的工作
不切换备选来源永久故障永远恢复不了
无法区分三种返回”failed”的故障类型所有故障用同样的通用重试

有了结构化错误:编排器只重试瞬态故障(65%),对永久故障切换来源(35%),保留了 48% 的部分结果。

修复:用结构化字段替换通用字符串

"search failed" 替换为:

{
  "failure_type": "auth_error",
  "partial_results": [],
  "alternatives_suggested": ["refresh credentials"],
  "retry_recommended": false
}

编排器按 failure_type 路由:timeout → 重试,auth → 刷新,permanent → 切换来源,unknown → 人工审查。

处理未知故障类型

在 failure_type 枚举中包含一个 "unknown" 类别。即使是未知故障也可能有部分结果,子代理可以指示重试是否可能有帮助。原始错误消息伴随 unknown 类型提供诊断上下文——而不是退回到通用错误反模式。

监控 + 恢复:不是取舍

基础设施团队想要简单状态用于仪表板。编排层想要详细上下文用于恢复。两个需求通过一个响应就能同时满足:一个顶层 status 字段用于监控,加上详细字段用于恢复。不需要妥协。


一句话总结: 通用错误每季度导致 $2,100 的浪费重试和 15 小时延迟——用结构化的 failure_type、partial_results 和 alternatives 替换它们,把浪费减少 94%。