一次创建请求可能已经到达供应商;客户端没收到响应,不等于任务没有产生。
摘要|AI 视频生成是长任务:创建接口可能先返回任务句柄,真正结果要在之后查询。最危险的处理不是超时本身,而是把不确定状态直接解释成失败并再次创建。本文从 Microi吾码当前源码和 13 项可复现测试出发,解释稳定 RequestId、租户与用户隔离、任务句柄、状态白名单和恢复流程怎样共同守住有限生成额度。
✦① 超时只证明你没有及时收到答案
一次视频创建通常跨过客户端、吾码后端、模型中转与供应商队列。任何一段网络都可能在任务已经落地后断开。如果客户端把“没有收到 200”直接翻译成“没有创建”,下一次点击就可能消耗第二份额度。
所以第一条工程原则是:超时属于未知状态,不是失败终态。未知状态需要回读,只有拿到明确的不存在、失败或参数冲突证据,才允许决定下一步。
错误直觉|网络错误发生在响应路径上;供应商任务是否已经创建,发生在业务路径上。两条路径不能被一个异常对象合并。
提交创建请求 ├─ 收到任务句柄 → 保存句柄 → 查询状态 └─ 响应超时 → 复用 RequestId 回读,禁止新建✦② 创建与查询必须是两条不同的动作
恢复链路的核心不是多试几次,而是把创建和查询分开。
创建动作会产生费用、占用每日配额并生成供应商任务;查询动作只读取已经存在的状态。它们不能共用一个“重试”按钮,也不能由同一个循环在异常后自动切换。
正确流程是把 RequestId 和任务句柄写入记录。页面刷新、Codex 重启或网络恢复后,先用旧记录查询;任务仍在 Preparing、Queueing 或 Processing,就继续等待,而不是再建一条。
- 创建前确定一个业务槽位,例如当天第 1 条视频第 2 幕。
- 同一槽位始终复用同一个 RequestId 和完全相同的参数。
- 创建返回后立即保存任务句柄;不确定响应则按旧键回读。
- 只有旧任务明确失败且策略允许,才生成新的业务槽位。
✦③ RequestId 不是随机追踪号
当前参数模型明确把 RequestId 定义为调用方稳定幂等键。同一个用户、租户和 RequestId 只能对应同一份生成参数。它的作用不是方便日志搜索,而是让系统识别“这仍然是同一次业务意图”。
如果每次重试都生成新 UUID,后端只能看见三次不同请求;即使每一条链路都实现了幂等,也无法知道它们其实来自同一个按钮。稳定来自业务命名,不来自随机性。
RequestId = 日期 + 内容槽位 + 场景序号 示例:article:20260816:tide-eye:scene-02 重试:复用原值 新场景:创建新值参数约束|RequestId 必须为 8—120 位,只使用字母、数字、点、下划线、冒号和短横线;稳定比看起来随机更重要。
✦④ 为什么还要绑定租户和用户
同一个文字键在不同租户或不同用户下,不应互相抢占任务。
源码中的幂等键不是简单拼接 RequestId。它还包含标准化后的 OsClient、用户摘要和 RequestId 摘要。这样既能让同一用户的同一请求收敛,也不会让不同租户碰巧使用相同文字键时互相覆盖。
任务句柄与文件句柄同样绑定用途、租户和用户,并验证签名。一个 task 句柄不能伪装成 file 句柄,另一个用户也不能拿它读取当前用户的结果。幂等与授权在同一条恢复链路上各做一件事。
源码事实|幂等键由租户段、用户 SHA-256 摘要和 RequestId SHA-256 摘要构成;句柄还会拒绝用途错配与篡改。
✦⑤ 6 秒 1080P 是安全默认值,不是宣传口号
当前 Microi吾码参数默认模型是 MiniMax-Hailuo-2.3,默认时长 6 秒、默认分辨率 1080P。源码允许 6 秒或 10 秒,但明确拒绝10 秒 + 1080P这一组合,要求改成 768P 或 6 秒。
这种约束应在请求进入供应商前完成。若把不支持的组合交给远端再等待错误,不仅反馈慢,还会把参数问题和网络问题混在一起。前置验证让失败更便宜、更清楚。
- 默认:MiniMax-Hailuo-2.3、6 秒、1080P。
- Fast 模型必须提供首帧,不能把文生视频参数直接套用。
- 首尾帧、模型和分辨率组合均需先走本地归一化。
✦⑥ 状态白名单比猜供应商文案可靠
当前状态归一化只接受 Preparing、Queueing、Processing、Success 和 Fail。供应商突然返回 completed、done 或其他新字符串时,系统不会擅自把它当成功,而是归为Unknown。
Unknown 不是坏体验,而是防止错误解释。它要求调用方保留原始响应、检查协议变化并升级适配,而不是把一个没见过的词当成可以下载和发布的成片。
状态原则|只对协议中已知的终态做不可逆动作;未知值先进入诊断,不自动创建新任务,也不自动发布。
✦⑦ 13 项测试到底证明了什么
本地 .NET 10 测试:13 执行、13 通过、0 失败;结果与源码 SHA-256 已归档。
本轮只运行 MiniMaxVideoSupportTests,结果为13 / 13 通过。覆盖安全默认值、Fast 模型首帧要求、HTTPS 首帧、时长与分辨率组合、尾帧限制、句柄绑定与篡改、幂等键隔离、状态白名单。
证据文件保存了命令、退出码、TRX、源码路径、行号和 SHA-256。它证明当前代码里的门禁按测试预期工作,不证明线上供应商永远可用,也不把本地测试包装成生产成功率。
- 可复现事实:13 项测试通过,退出码为 0。
- 源码事实:租户、用户、RequestId 共同限定幂等范围。
- 未被证明:所有网络故障都能自动恢复,或供应商从不变更协议。
✦⑧ 一套不会浪费额度的恢复清单
- 保存原始 RequestId、参数摘要、任务句柄与最后一次已知状态。
- 遇到超时先查询旧任务;无法确认时标记 Unknown,并保留诊断。
- 禁止在 Unknown 状态下换一个 RequestId 盲目再建任务。
- Success 后下载并校验媒体;Fail 后记录原始错误,再决定新槽位。
- 每次公开发布同样只提交一次,回读任务终态后再汇总平台结果。
这套流程看起来比“失败就重试三次”慢一点,却把最昂贵的动作从网络重试里拿了出来。AI 视频额度有限时,先恢复事实,再恢复流程,才是真正可靠的自动化。
结论|RequestId 守住的不是一串日志,而是同一次业务意图的唯一性。超时之后先查旧任务,才能避免把未知状态变成重复付费。