AI 接口 504 后先查什么:X-Client-Request-Id、退避上限与幂等键
线上 AI 功能最容易出事故的时刻,往往不是模型返回 400,而是客户端等了 30 秒后只收到一个超时。此时服务器可能还在生成,业务却不知道这次请求到底有没有落地。安全做法不是立刻再发一遍,而是给每次业务操作固定请求标识,区分“可以重试”和“必须人工确认”,再用结果键把重复响应收敛掉。
- OpenAI 可用
X-Client-Request-Id记录客户端请求标识,服务端响应还应保存x-request-id便于排查。 - Gemini 官方建议只对超时、网络异常、408、429 和 5xx 等瞬态问题做有限次数的指数退避,并加入抖动。
- 重试前先查本地任务表;没有确定结果时用业务幂等键去重,不能把“重复提交”当成成功。
超时不是失败:先把一次调用拆成三种结果
我在一个“根据用户上传内容生成摘要”的接口上遇到过这个问题:网关 30 秒断开连接,后台日志却显示模型调用在第 34 秒返回成功。前端如果把超时直接当失败,再次点击就会产生两份摘要,甚至重复扣费。
因此,调用记录至少要有 accepted、succeeded、failed 三类最终状态;客户端超时只能写成 unknown。unknown 的意思是“结果尚未确认”,不是“可以马上重做”。
触发器、权限和请求标识要在入口固定
把重试逻辑散落在控制器、队列消费者和 SDK 里,最后很难知道到底重发了几次。更稳的入口是先创建一条业务任务,再让所有下游调用继承同一个 job_id。
job_id = "summary_20260824_01HZX..."
client_request_id = "job_id/attempt-1"
headers = {
"X-Client-Request-Id": client_request_id,
"Idempotency-Key": job_id,
}
X-Client-Request-Id 用来关联一次网络请求,Idempotency-Key 则是应用自己的业务去重键。两者不要混成一个字段:一次任务可能有多次 attempt,但同一个 job_id 仍然只能产生一个业务结果。
流水线按“记录—调用—核对—重试”推进
每个阶段都要有可观察的产物,否则失败后只能凭猜测补请求。
| 阶段 | 必须记录 | 下一步 |
|---|---|---|
| 创建任务 | job_id、输入摘要、业务状态 | 进入 queued |
| 发起调用 | attempt、client_request_id、开始时间 | 等待响应 |
| 收到响应 | HTTP 状态、x-request-id、模型结果 | 写入 succeeded 或 failed |
| 客户端超时 | 超时原因、attempt、最后已知状态 | 先查任务,再决定重试 |
OpenAI 的响应头包含服务端生成的 x-request-id,排查时要和自己的客户端标识一起保存。Gemini 的官方排障建议则明确把指数退避、随机抖动和最大重试次数放在调用方控制之下。
只对瞬态错误重试,退避时间不要写死
一个够用的策略是:第 1 次等待 1 秒,第 2 次等待 2 秒,第 3 次等待 4 秒,每次加一个 0 到 300 毫秒的随机抖动,并把总等待预算封顶。这样不会让一批同时超时的请求在同一秒再次撞向接口。
retryable = status in {408, 429, 500, 502, 503, 504} or network_timeout
delay = min(30, 2 ** attempt) + random.uniform(0, 0.3)
400 参数错误、401/403 鉴权问题、内容被拒绝以及明确的配额耗尽,不属于“多等一会儿就会好”的瞬态故障。对这些错误重试只会放大日志和成本。对于 504 这类没有响应体的情况,也不要假设服务端没有收到请求,应该先查 job_id 和请求标识。
门禁规则:重试前先查结果,成功后拒绝第二份
重试消费者取到 unknown 任务时,先按 job_id 查结果表,再按请求标识查调用日志。若上游已经成功,就把本地任务补成 succeeded;只有确认没有结果,且错误属于可重试集合,才允许发起下一次 attempt。
if task.result_exists:
return task.result
if task.attempts >= 3 or task.total_wait_ms >= 30000:
return mark_manual_review(task)
if task.last_error in RETRYABLE:
return enqueue_retry(task, next_attempt=task.attempts + 1)
return mark_failed(task)
写结果时再加一道数据库唯一约束,例如 UNIQUE(job_id)。应用层判断能减少重复工作,唯一约束负责挡住并发竞态;两道门都需要,不能只依赖其中一层。
失败处理要能回放,也要能停止
给每个任务保留输入摘要、模型名、attempt 列表和最后一次错误,运维才能回答“这次是否真正发到上游”。当同一任务连续三次超时,或者总等待超过 30 秒,进入 manual_review 比无限重试更安全。人工复核可以重新放行,但要沿用原来的 job_id,并生成新的 attempt 记录。
通知内容也别只写“AI 调用失败”。至少带上 job_id、最后的 HTTP 状态、重试次数、x-request-id(如果有)和用户是否已经看到结果。这样值班同学可以从一条通知跳到完整调用链。
相关问题
超时后立刻重试会不会丢结果?
不会因为“等待”本身丢结果,但可能制造重复任务。先把原任务标成 unknown,查询结果或日志,再决定是否重试。
客户端请求标识能代替幂等键吗?
不能完全代替。请求标识适合排查一次 HTTP 调用,幂等键要绑定业务动作,并由自己的任务表和唯一约束保证结果只落一次。
429 和 500 都应该无限重试吗?
都不应该。根据 Retry-After、指数退避和总预算有限重试;超过预算就停止并告警。
把一次重试变成可核对的结果
可靠的 AI 调用流程不是“失败就再试一次”,而是让每一步都能被还原:谁创建了任务、发了第几次请求、上游给了什么请求标识、结果是否已经落库、为什么停止。把这些证据写进任务表和日志后,超时只是一个待核对状态,重试才会成为可控的业务动作。


AI 接口 504 后要不要重发:请求标识、退避与幂等核对
- 上一篇
- AI 接口 504 后要不要重发:请求标识、退避与幂等核对
- 下一篇
- Cloudflare Gateway 怎么识别 MCP 流量:is_mcp 策略与 AI Security 报表实测
-
- 科技周边 · 人工智能 | 4小时前 | 向量检索 ·
- 向量检索与关键词检索怎样做混合召回
- 293浏览 收藏
-
- 科技周边 · 人工智能 | 6小时前 | 人工智能 ·
- 智能体评测不只看成功率:步骤、成本与恢复能力怎么量
- 290浏览 收藏
-
- 科技周边 · 人工智能 | 1天前 |
- 模型路由怎么做:按任务难度分配速度、成本与质量
- 147浏览 收藏
-
- 科技周边 · 人工智能 | 1天前 |
- 多模态模型读图前,图片缩放与裁切会影响什么
- 247浏览 收藏
-
- 科技周边 · 人工智能 | 1天前 | 人工智能 · 推理优化 ONNX Runtime 动态量化 nodes_to_exclude
- ONNX Runtime 动态量化怎么选择需要排除的节点
- 377浏览 收藏
-
- 科技周边 · 人工智能 | 1天前 | 人工智能 · 向量检索 · Sentence Transformers truncate_dim 嵌入维度 Matryoshka 向量存储
- Sentence Transformers 怎么截断嵌入维度减少存储
- 165浏览 收藏
-
- 科技周边 · 人工智能 | 1天前 |
- PEFT 多个 adapter 怎么按权重组合推理
- 454浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- PubMedQA
- 深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
- 378次使用
-
- H2O EvalGPT
- H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
- 448次使用
-
- LMArena
- LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
- 457次使用
-
- HELM
- 深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
- 400次使用
-
- MMBench
- MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
- 227次使用
-
- Go 批量 CSV 导入怎么控内存:流式读取、资源预算和失败行回传实战
- 2026-07-20 407浏览
-
- Go JSON 严格解码上线后请求变 400:DisallowUnknownFields 的兼容性故障复盘
- 2026-07-26 174浏览
-
- Go 流式响应怎么做:ResponseController.Flush、SSE 与断开回收的取舍
- 2026-07-26 463浏览
-
- Go 分页接口怎么设计:游标参数、错误码与兼容返回
- 2026-07-26 427浏览
-
- Go encoding.TextAppender 怎么减少临时字符串:追加接口、缓冲区复用与错误传播
- 2026-08-26 245浏览

