use-case
统一异步任务:提交、轮询与结果生命周期
直接答案对适合后台执行的 POST 请求,可在原路径前加 /async 提交并用 /get-async?id=... 查询;流式、模型列表、Files 和 Realtime 不能这样包装。
更新 · 审核信息
小白:提交与轮询
通用异步包装保留原 POST 路径,只在前面加 /async。下面把视频创建放入后台;请用模型广场实际支持的模型和路径。
submit=$(curl -sS "$BASE_URL/async/v1/videos" -H "Authorization: Bearer $API_KEY" -H "Content-Type: application/json" -d '{"model":"<MODEL_ID>","prompt":"雨后城市的短镜头"}')
task_id=$(printf '%s' "$submit" | jq -r .id)
curl -sS "$BASE_URL/get-async?id=$task_id" -H "Authorization: Bearer $API_KEY"
提交成功通常返回 202、任务 id 与 queued 状态。查询必须使用创建任务的用户和令牌权限,不能把任务 ID 当作公开下载地址。
状态机与终态
把 queued、not_start、submitted、in_progress 视为非终态;failure 和 completed 为终态,expired 表示结果已清理。轮询采用带抖动的退避,例如 1、2、4、8 秒后稳定到上限,并设置总截止时间。不要每秒无限轮询;前端刷新也不应创建新的生成任务。
结果信封
JSON 上游结果会放在 result 字段;二进制结果以 Base64 返回,并带 encoding: "base64"、原始 content_type 和 status_code。客户端要先检查外层 status,再验证内层状态码与对象结构。完成后立即把需要长期保存的媒体流式复制到自己的对象存储。
不支持的包装
通用异步拒绝 GET、SSE、stream:true、模型列表、/v1/files、/v1/realtime 和 Gemini 流式生成。原生视频、Kling、Suno 等任务协议可能拥有自己的创建与查询路径,不应与通用任务 ID 混用。
幂等、失败与计费
网络在提交响应返回前断开时,任务可能已经创建。客户端应保存业务请求指纹并先查已有任务,避免盲目重发。队列满、参数错误和鉴权错误不可无限重试;临时 429/5xx 才适合有限退避。预扣、最终结算和退款可能跨越任务生命周期,需在终态后用任务 ID、Request-ID 与消费日志核对。
专家运维
监控队列深度、排队时长、执行时长、成功率、失败原因、结果大小、过期率和存储剩余空间。结果写入必须有大小上限并采用流式 I/O,避免整份媒体驻留内存。清理策略应保护运行中任务,低磁盘时拒绝新任务而不是删除仍需交付的结果。
适用场景
- 长耗时媒体与批处理请求
- 避免客户端连接超时并可靠取得结果
API 协议
/async/*/get-async/v1/videos/v1/video/generations
FAQ
哪些请求能加 /async?
仅 JSON、multipart 或表单 POST,且不能是流式、模型列表、Files、Realtime 或 Gemini streamGenerateContent。目标原路径本身仍须受模型与渠道支持。
轮询到 HTTP 200 就完成了吗?
不是。读取 status;queued、submitted、in_progress 仍需等待,completed、failure、expired 才是需要处理的结果状态。
结果为什么会变成 expired?
异步结果不是永久文件。清理、保存期限或存储异常都可能使结果不可再取,应在完成后及时复制到业务存储。
关联指南
官方来源
- OpenAI API Reference Official
- Gemini API Errors Official
- Claude API Errors Official
兔子API