多模态API怎么接异步视频任务?提交轮询4步

2026-08-29 54 0

先给结论:异步多模态接口和同步文本接口只差四处

把多模态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怎么写熟悉同步调用风格,再理解差异。

相关文章

OpenAI base_url 怎么改?三种写法与报错对照

评论(0)

暂无评论

发布评论