请求超时,不等于服务器肯定没有处理
客户端超时只说明它没有在等待期限内拿到可用结果。请求可能还没到服务器,也可能已经开始处理而响应没传回来;只凭一个timeout,不能把本次业务标记为“未发生”,然后无条件重发。
官方错误文档也提醒,长时间非流式请求可能受网络空闲连接影响,并提供流式或批处理等方案。本文重点是应用如何记录未知结果,既不保证重试免费,也不声称API天然替你的业务做去重。
给任务与尝试分别编号
假设一个虚构任务要生成采购说明:任务ID表示用户这一次需求,尝试ID表示某一次API提交。一次任务可有多次明确记录的尝试,但不能因为浏览器刷新就创建多个互不相关的任务并重复提交。
提交前写入准备状态,发送时标为进行中。成功得到并验证结果后标为完成;明确失败则保留原因;超时且无法确认结果时标为未知。页面上的“再试一次”也应先查看当前任务状态,而非直接新发请求。
这些状态属于本站设计的应用层流程,不是Anthropic保证提供的上游幂等协议。能否找回某次结果,取决于所用接口、SDK和你已经保存的资料,不能凭一个本地编号自动查询所有历史响应。

一个最小状态机阻止盲目重发
将文末代码保存为uncertain-request-state.mjs,使用Node.js 22或更新的受支持版本运行node uncertain-request-state.mjs --demo,结果为unknown。它模拟准备→发送中→超时,不联网、不包含密钥,也不实际发送请求。
unknown不能直接再次submit;需要核对到明确结果,或经过业务允许的新尝试决定后进入approved_retry。完成状态也禁止再提交同一任务。这能演示边界,却不是完整任务队列。
真实服务还需持久化任务和尝试、事务或锁、并发领取控制与崩溃恢复。把这个纯函数复制到内存里,无法阻止多台服务器同时发请求,也不能在进程重启后自动保留状态。
决定再试前,看清代价与副作用
先查看是否已经取得request-id、部分输出、流结束事件或服务明确错误,并核对SDK是否还有自己的重试。没有响应就记录“未知”,不要捏造request-id或用另一次成功响应冒充本次结果。
生成文本与写入业务也要分开:拿到答案不应立刻重复发送邮件、扣款或发布文章。若后续有这些操作,需使用业务自己的去重记录与授权检查,不能依赖模型回复“已处理”。
如果确实批准新尝试,关联原任务,记录原因和新的尝试ID;再次失败也有次数和等待边界,不无限循环。费用、延迟和重复结果的处理应在业务设计中明确,不能宣传“重试总能恢复且不会重复”。
什么时候考虑改变调用方式
长输出经常触发空闲连接问题时,可评估官方流式方式;适合异步处理的批量任务可评估批处理及结果轮询。两者都需要各自的完成、失败和结果保存逻辑,不是设置一个开关就消除全部不确定性。
本地测试实际确认了未知和完成任务不能直接重复提交,以及显式新尝试和核实结果的状态转换;没有真实触发API超时、验证账单或模拟多机并发。因此本篇交付的是可测试的教学状态机与落地清单,不是已经验收的生产幂等系统。
参考资料与核验范围
资料核对日期:2026年10月18日。以下为官方原始资料;产品入口和可用范围仍以当前账户为准。
1. [官方资料1](https://platform.claude.com/docs/en/api/errors)