Fluxio
← 返回博客

流式人工智能接口重试实战:让同一次请求只扣费一次

token 经济账ZH

§1 第一步:明确“只扣一次”的业务边界

用户提交问题后页面超时,再点重试,不应该收到两笔账单。这里的目标不是保证网络只发送一次,而是让同一次业务操作最多产生一次有效扣款。幂等设计正是让重复调用不重复产生业务副作用的方法。([developer.mozilla.org](https://developer.mozilla.org/en-US/docs/Glossary/Idempotent?utm_source=openai))

先区分用户账单与上游成本。本教程建议由应用承担内部重试成本,不把每次尝试分别转嫁给用户。如果上游缺少幂等或结果查询能力,应用不能仅凭本地去重保证上游也只收费一次;此时应暂停不确定请求,而不是盲目重新生成。

§2 第二步:为一次生成保存稳定的幂等键

在首次提交前生成随机操作标识,保存到客户端和服务端。刷新页面、网络重连与自动重试必须沿用它;只有用户明确发起新的生成,才创建新标识。成熟支付接口也使用客户端生成的幂等键识别重复请求,并强调避免把敏感个人信息放进键中。([docs.stripe.com](https://docs.stripe.com/api/idempotent_requests))

建议以“账户标识加操作标识”建立唯一约束,同时保存请求参数摘要。同键同参数返回原任务,同键不同参数直接拒绝,避免修改提示词后误领旧结果。支付接口已有比较原始参数与重试参数的实践,可作为设计参考,但不能据此推断模型接口天然支持相同行为。([docs.stripe.com](https://docs.stripe.com/api/idempotent_requests))

§3 第三步:先登记任务,再调用上游

把任务设计为待执行、执行中、已完成、结果待核对和已失败五种状态。先在数据库中原子创建任务,再交给工作进程执行;重复提交只读取已有任务。建议采用以下处理顺序:

  • – 通过唯一约束抢占任务,避免两个并发请求同时启动生成。
  • – 执行中的任务返回现有任务标识,不再创建第二次调用。
  • – 已完成的任务返回已保存的结果,不再生成或扣款。
  • – 工作进程失联且上游结果不明时,进入待核对状态,不直接重新执行。

§4 第四步:把流式重连与重新生成分开

流式接口会在生成过程中逐步发送事件,因此连接中断不能直接等同于整次生成失败。([platform.openai.com](https://platform.openai.com/docs/api-reference/responses-streaming/error?lang=python&utm_source=openai)) 建议让后台任务独立于浏览器连接运行,把输出事件按递增序号持久化;客户端重连时提交最后接收的序号,由应用回放缺失内容。

这里恢复的是应用保存的事件流,不是假设任何上游都支持断点续传。即使客户端尚未收到首个片段,也应先查询任务状态。若后台没有结果、上游又无法核实,应显示“正在核对”,保留部分输出,而不是悄悄发起第二次付费生成。

§5 第五步:让有限重试服从幂等条件

只有确认重试不会重复执行,或确认原请求尚未执行时,才进行自动重试。对临时限流采用带随机抖动的指数退避,并设置次数上限和总时间预算;额度不足、计费配置等需要人工处理的问题不应循环重试。官方限流指南也明确区分临时限流与配额、计费错误。([developers.openai.com](https://developers.openai.com/api/docs/guides/rate-limits?utm_source=openai))

建议只让一个层级负责重试,并核查客户端开发包、应用服务和网关各自的配置。每次尝试使用独立追踪标识,但始终关联同一个业务操作标识,方便核对调用次数与最终账单。

§6 第六步:用唯一账本记录完成结算

建议先预留余额,再按已确认的用量结算,释放剩余预留。对“账户、操作、结算类型”设置唯一约束,并在同一数据库事务内完成账本写入与余额变更;重复完成事件只返回原结算记录。

如果还需要调用外部支付服务,应通过可靠事件投递连接两套系统,并为外部扣款复用稳定幂等键。支付接口支持相同键重放,但键的保留期限有限,因此本地账本不能依赖短期缓存承担永久防重责任。([docs.stripe.com](https://docs.stripe.com/api/idempotent_requests))

§7 第七步:接入 Fluxio 后验证扣费不变量

对于需要流式输出和按词元计费的产品,可以考虑 Fluxio 作为统一接入层;把任务去重、输出回放和用户账本放在自己的服务端,避免将接入便利误认为计费保障。上线前应单独确认其幂等、用量查询和中断请求的结算规则,不预设它提供这些能力。

测试时注入并发点击、输出中途断线、扣款成功但响应丢失,以及工作进程崩溃。逐一验证:同一操作最多一笔有效扣款,重复事件不改变余额,不确定用量不会触发第二次结算。把这些断言加入持续测试,才算完成这套重试逻辑。

欢迎注册 Fluxio。

创建 Fluxio 账号 →

顺流再读几篇