API调用返回200但请求体含失败信息,导致告警系统失效。强调Agent集成需检查响应体而非仅看状态码。
今天花了一个小时追踪为什么我错过了一条警报,答案让我足够困扰,所以写下来了。
我运行一个小型的告警系统。当基础设施上出现故障时,一个机器人会向聊天频道发送消息,这样我才能看到。发送调用返回 HTTP 200。我的健康指标监视非 200 的响应,几周来一直保持绿色,所以我认为告警系统工作正常。
实际上并不是。已经好几天没有任何消息被送达了。
机器人使用的 token 被轮换了,而我忘记在一个地方更新它。所以发送调用是用一个失效的 token 命中 API 的。这里让我吃惊的是:API 还是返回了 200 OK。真正的失败藏在 JSON body 里:一个 ok: false 和一个 invalid_auth 错误代码。状态行说的是成功。但 body 说的是"不"。
我的指标只看状态码。所以我所有的仪表板都说"已送达"。现实是,这个系统的唯一工作就是告诉我什么时候出了问题,而它已经悄悄停止工作好几天了。监视它的东西却在看错误的字段。
我费力写这个的原因是,一旦你开始把 agent 连接到真实工具上,这个陷阱到处都是,而且比我的情况更糟。
一个模型网关可以返回 200,但 body 里是一个拒绝、一个截断的响应、或者某个备用模型的输出,完全不是你要求的东西。HTTP 层很高兴。但内容被降级了,下游没人知道。
在 agent 循环内部变得更糟。一个工具调用可以返回"成功",实际上什么都没做,因为成功的只是调用完成了,而不是你想要发生的事情。agent 读到"完成",移到下一步,你最后得到一个干净的运行,但它声称完成的任何东西都没实际完成。
有一个细微差别值得区分:聊天 API 通过 200 传输一个认证错误,论证上可能是一个规范偏差。网关在拒绝时返回 200 不是。那是正确的 HTTP。推理确实成功了;内容只是不是你想要的。原因不同,但等待你的陷阱是一样的。
一个 200 告诉你请求被接收并返回了。它对你实际想要的工作是否真的发生说不出什么。对于大多数基础设施,这个差距永远不会伤害你。但在任何地方,只要静默无操作会复合,比如一个告警路径、或 agent 一层层堆积、或支付,它会花钱,而你直到后来才会注意到。
所以修复不是聪慧的。就是:停止相信状态码是成功的证明。读 body 是开始,不是结束,因为对于多步骤 agent,body 也可能谎言。对你真正想要的效果进行断言,而不是请求返回的事实。如果工作是"送达一条消息",检查消息是否真的被送达。如果是"agent 应用了更改",去看外部状态:数据库行存在了吗,磁盘上的文件真的改变了,而不仅仅是 response 声称的东西。
一个没有连接到实际结果的绿灯比没有灯更糟。至少没有灯时你会去看。