超时并不等于上游没有处理请求。客户端可能已经发出请求,上游也已经扣费,只是响应没有及时回来。如果网关收到超时就重新发送,最终可能得到两次模型调用、两次账单,甚至把“创建订单”“发邮件”这样的工具动作执行两遍。
幂等键不是随便生成的 request_id
一个可用的幂等键必须代表“同一次业务意图”,而不是每次网络重试都重新生成。网关可以要求客户端传入业务键,也可以根据租户、会话、动作编号和请求版本生成。键需要绑定模型、工具参数和关键请求选项,避免同一个键被错误复用于完全不同的任务。
服务端要保存幂等键的状态:处理中、已完成、已失败但可重试、结果未知。遇到相同键时,不能简单返回“重复请求”,而应根据状态返回原结果、告知仍在处理,或要求人工确认。保存时间也要和客户端可能的重试窗口匹配,太短会留下重复执行的空档,太长则会阻塞合法的新任务。
把请求重试和工具重试分开
纯文本生成通常可以在明确失败后重试,但工具调用要看副作用。查询、读取和校验类工具可以通过相同幂等键安全重放;写入、删除、付款和发送类工具必须由工具服务自己提供幂等约束,不能把责任全部推给 AI 网关。
一个实用做法是把模型响应中的工具调用先放入“待执行”状态。工具执行器检查动作键、租户和权限后再提交;提交结果写回后,重复请求只返回原执行结果。对“响应已丢失”的情况,网关还需要提供状态查询接口,让客户端先查结果,再决定是否重试。
测评时故意制造不确定性
测试不能只模拟明确的 500。还要制造这些情况:上游已经接收但网关读不到响应、响应在工具调用后断开、客户端在超时后立刻重试、队列重复投递、数据库写入成功但回包失败。每种场景都要对照调用次数、上游账单、工具执行记录和客户端最终状态。
在统一入口上做多供应商测试时,可以让 top-api.cc 负责鉴权、路由和调用记录,再把幂等键贯穿网关、队列和业务服务。这样能区分“同一个业务请求切换了上游”与“同一个请求被重复提交”这两类问题。
最小实现清单
- 幂等键由业务意图生成,重试不改变;
- 记录处理中、完成、失败和结果未知四种状态;
- 对工具副作用使用工具侧幂等键;
- 保存原始响应摘要和账单关联 ID;
- 设置明确的幂等键过期时间;
- 给客户端提供查询未知结果的接口;
- 日志中隔离租户、密钥和敏感参数。
幂等设计的目标不是让所有请求都可以无限重试,而是让系统在“不知道上游到底做没做”的时候仍然能收敛到一个可解释状态。只要业务动作可能产生费用或副作用,就应把幂等当成网关的基本能力,而不是出了重复扣费再补数据库脚本。
参考资料:HTTP 方法幂等语义、主流支付 API 的 Idempotency-Key 设计,以及 Portkey Gateway 的重试配置说明。实际字段以目标供应商 API 为准。
如果需要先统一不同上游的鉴权、路由和账单关联,再逐步补齐幂等策略,可在 top-api.cc 上用低风险查询和测试模型验证完整链路。
Leave a Reply