先给结论:异步多模态接口和同步文本接口只差四处
把多模态API接入视频生成,核心就是接受一个事实:你不能像调文本接口那样,一次请求等到底。异步视频接口与同步文本接口的差异,可以压缩成四处:响应语义从“完整结果”变成“任务ID”、状态需要客户端主动轮询、终态分类更复杂(排队、运行、完成、失败、过期)、产物是临时URL必须及时落盘。这套形态正在成为行业默认范式——2026年8月25日,OpenRouter 上线了统一的 Video Generation API,把不同视频模型的提交、查询与下载逻辑收敛成同一套异步规范。
为什么视频生成不能沿用一次请求等到底
单次视频生成通常耗时数十秒到数分钟,如果沿用同步 Chat Completions 那种“请求挂起直到返回”的模型,长连接极易撞上网关超时(比如 Vercel/Lambda 的 30-60 秒限制)和网络中断。因此主流平台(OpenRouter、SiliconFlow、Fal.ai)都选择了解耦链路:提交任务立刻返回 200/202,客户端通过轮询或 Webhook 获取结果。异步任务型API和同步接口有什么区别?简单说,同步接口把等待的成本压在调用方连接上,异步接口把等待的成本转移到服务端队列和客户端轮询逻辑里,换来的是更高的可靠性和可扩展性。
第一步:提交任务——参数、业务流水号与任务ID的落库时机
提交阶段的关键工程决策有两个:一是先落库再提交,还是先提交再落库。推荐先用业务流水号(比如 UUID)在本地任务表占位,状态设为 CREATED,再调提交接口;拿到任务ID后立刻更新到本地记录。这样即使提交后网络中断,你也能根据流水号识别哪些任务可能已经提交但没拿到ID,方便查漏。任务ID(有时叫 requestId)和轮询地址必须持久化,写入任务表对应字段。
需要明确的是,跨平台目前并没有统一标准的幂等标头(比如强制 Idempotency-Key)。OpenRouter 等平台虽然统一了接口形态,但各厂商的去重实现各异。所以去重要靠应用层任务表状态机自己保证,而不是指望平台帮你过滤重复提交。同步链路的鉴权方式可以沿用,但异步任务的防重必须另做。
第二步:轮询——状态机怎么写,间隔与指数退避怎么定
轮询的核心是状态机。异步任务状态通常包括:排队中(IN_QUEUE / queued)、运行中(IN_PROGRESS / in_progress)、完成(COMPLETED / completed)以及异常终态(FAILED / failed / expired / cancelled)。客户端拿到任务ID后,周期性地查询状态端点。
轮询间隔到底设多少秒,取决于你的任务耗时分布——比起固定间隔,指数退避更能兼顾首屏响应与限流风险。没有官方基准,必须按自己的任务预期耗时实测。一般原则是:间隔随任务预期耗时递增,比如初始 1 秒,最长 30 秒,每次轮询后间隔翻倍,直到上限。这能有效避免高频请求触发网关的 429 Too Many Requests 限流。下面是一个极简轮询骨架(Python 风格伪代码):
import time
def poll_task(task_id, max_wait=600, initial_interval=1, max_interval=30):
interval = initial_interval
waited = 0
while waited < max_wait:
status = query_status(task_id)
if status in ('COMPLETED', 'FAILED', 'EXPIRED', 'CANCELLED'):
return status
time.sleep(interval)
waited += interval
interval = min(interval * 2, max_interval)
return 'TIMEOUT'如果平台支持 Webhook,优先用 Webhook 减少无效轮询,但轮询作为兜底仍应保留。

第三步:终态处理——产物立刻转存,失败要先分类再决定重试
当状态变为 COMPLETED,你会拿到一个临时产物 URL。这里有个容易被坑的点:有平台的临时产物链接寿命只有分钟级(如 SiliconFlow 曾被观察到约 10 分钟),具体数值以各平台当前文档为准,接入前务必自测。业务系统绝对不能假定第三方 URL 永久可读。正确做法是在终态回调里立刻流式下载,转存到自己的私有对象存储,并更新任务记录里的产物地址。
如果状态是 FAILED 或其他异常终态,不要急着重试。先分类:参数错误(4xx)、内容拦截、上游超时、队列异常。只有非确定性失败(比如上游 5xx、网络抖动)才允许重试,且必须新建任务记录,用新的业务流水号,避免重复计费。如果是内容拦截,重试也没用,需要调整提示词。参数类错误可参考 Claude API 400 排查 定位。
关于多模态API调用失败要不要重试,经验法则是:只重试可能因为运气不好而失败的任务,而不是那些因为请求本身有问题的。客户端要能区分这两类。
第四步:超时与配额——任务级超时上限、并发任务数与队列积压兜底
你必须在客户端设置防御性上限,而不是依赖平台。第一,任务级最大等待时长:比如 10 分钟,超过就标记为 TIMEOUT,进入死信处理(人工介入或后续补偿)。第二,并发在途任务数:同时轮询的任务数不能无限增长,否则可能压垮你自己的服务。第三,积压降级:当队列积压超过阈值,可以拒绝新任务或走异步批处理。
这里有个事实边界:平台侧在极端排队情况下的全局兜底阈值没有统一公开基准,目前也没有可查的公开官方基准。OpenRouter 的指南也没有给出具体秒数。所以这些上限必须写在自己的代码里,作为工程防线。如果你用同步链路时已经积累了过 429 退避的处理经验,这部分可以完全复用。
统一协议收敛后,选型变量还剩哪些
当多厂商模型被抽象成同一套提交-轮询-下载循环后,接入方的代码成本大幅下降,选型变量就转移到了这些指标上:
| 指标 | 说明 | 是否需自测 |
|---|---|---|
| 队列等待时间 | 提交到开始执行的时间 | 是 |
| 产物链接寿命 | 从完成到链接失效的时间 | 是 |
| 失败可解释性 | 错误码是否清晰、能否定位 | 是 |
| 配额与状态透明度 | 是否清楚展示排队/运行状态 | 是 |
这四项都不是宣传承诺,而是接入前必须在灰度环境里自己复测的指标。

同一套代码怎么覆盖多种模态与多家模型
把同步链路的鉴权、超时、429 退避与请求ID 排障策略,可以自然复用到异步任务的提交与轮询封装上。NexAIX 提供 OpenAI Chat Completions 兼容接口(base_url https://api.nexaix.net/v1),支持流式输出与函数/工具调用;满载时返回标准 429 与重试建议,不静默切换模型,返回体 model 字段对应实际执行模型,便于把在途任务归因到具体模型。具体支持的模型与模态能力以 NexAIX 当前模型页与更新日志为准。
仍无标准答案的部分:队列超时与重试幂等要自己实测
目前跨厂商异步任务去重实现各异,没有强制统一的幂等标头与去重窗口;极端积压下的全局排队废弃阈值也没有公开基准。所以在接入前,建议做最小实测:
- 用同一个业务流水号重复提交两次,观察平台是否去重;
- 断网重连后,恢复轮询,看任务状态是否仍然可查;
- 长队列压测:提交超出平时并发量的任务,看排队表现和超时行为。
这些都只能靠你自己的环境去验证。
接入前必跑的多模态API回归清单
| 检查项 | 预期行为 | 备注 |
|---|---|---|
| 提交幂等 | 重复提交不产生重复任务 | 应用层实现 |
| 任务ID持久化 | 重启后仍能查询状态 | 落库必做 |
| 状态映射完整 | 所有状态码都有对应处理 | 含 expired/cancelled |
| 退避生效 | 轮询间隔递增,不触发429 | 观察日志 |
| 429与5xx分流 | 429走退避,5xx可重试 | 与同步链路策略一致 |
| 产物转存成功率 | 完成后的URL能及时下载 | 监测下载失败率 |
| 任务超时与死信 | 超时任务进入隔离区 | 人工介入 |
| 并发上限 | 在途任务数受控 | 防止压垮自身 |
| 可观测字段 | requestId、model、statusCode | 便于排障 |
跑完回归清单后,记得去 NexAIX 模型页与文档核对当前可用模型与限速配额。
常见问题
为什么视频生成任务一直pending不动?
pending通常意味着任务在排队队列中,但长时间不动可能卡住。先检查是否真的处于排队状态(IN_QUEUE),确认轮询逻辑没有因为退避间隔过大而漏查。如果超过你设定的最大等待时长仍无变化,可以提交工单或考虑取消重试。
轮询间隔设多少秒合适?
以下是工程经验值,非任何平台官方基准。一般建议从1秒开始,指数退避到30秒,但要根据你的任务平均耗时调整。如果平均值是60秒,那么前30秒可以低频轮询,后半段加快。最终参数以你自己任务耗时分布与限流日志实测结果为准。
多模态API调用失败要不要自动重试?
分情况:参数错误(4xx)或内容拦截不要重试,需要改请求;网络超时、5xx等非确定性失败可以重试,但必须限制次数(如3次),且每次重试都新建任务记录,用新流水号,避免重复计费。
视频生成API返回的链接会过期吗?
会。有平台的临时产物链接寿命只有分钟级(如 SiliconFlow 曾被观察到约 10 分钟),具体数值以各平台当前文档为准,接入前务必自测。无论平台怎么承诺,你都应在任务完成后立即流式下载并转存到自己的对象存储,不要把第三方URL存下来长期用。
同步链路的鉴权和重试策略能直接用于异步任务吗?
鉴权可以复用,但重试策略要改:同步链路重试是重新请求,异步链路是新建任务,幂等性完全不同。轮询和退避逻辑需要单独实现,不能直接套用。建议参考工具调用API怎么写熟悉同步调用风格,再理解差异。
NexAIX-官方博客
评论(0)