PRJ-01 LIVE
shatangAI 电商 AI 视频生成平台
multi-vendor ai video orchestration platform
从 0 到 1 的全栈 AI 视频生成平台,已上线生产环境
- AI Agent
- 音视频
- TypeScript
- 前端
6+
接入的视频生成供应商
10+
覆盖的生成方式
// 01
问题背景
电商短视频素材的生产有三个绕不开的痛点:一是供应商能力碎片化——每家的接口协议、参数语义、异步回调方式都不一样,业务代码里到处是 if-else;二是视频生成是典型的长耗时任务,动辄几分钟,进程一重启任务就丢了,用户只看到转圈;三是按积分计费时,一次网络抖动就可能导致重复扣费,而这类问题往往在财务对账时才被发现。
这个平台要解决的就是这三件事:把多源能力收敛成一套统一的生成语义,把长耗时任务的可靠性做进架构而不是靠重试碰运气,把计费做成可审计的。
// 02
系统架构
前端层
用户侧与管理后台分离,两套独立部署的 React 应用
调度层
统一的任务编排:状态机 + 队列 + 崩溃恢复
供应商适配层
把 6+ 家异构视频 API 收敛成一套内部协议
业务能力层
面向电商场景的生成方式编排与积分体系
基础设施层
多环境配置与一键部署
// 03
关键技术决策
每一条都包含「为什么这样选」与「代价是什么」——这是我理解这个项目的方式。
为什么用 BullMQ 统一调度,而不是各家供应商直调
最直接的写法是在 Controller 里直接 await 供应商接口。但视频生成耗时几分钟到十几分钟,同步请求必然超时;即使改成回调,6+ 家供应商的回调格式、重试语义、幂等键各不相同,业务层会被彻底污染。于是把所有供应商收敛到同一套内部协议后面,统一入 BullMQ 队列,由 Worker 消费。代价是引入 Redis 依赖与一层额外封装,收益是新增一家供应商只需要写一个适配器,且限流、重试、超时全部集中在一处可观测。
为什么设计完整状态机 + 积分冻结日志
任务状态如果只有「成功/失败」两态,就无法表达「已扣费但生成中」这个中间态——而这恰恰是最容易出问题的地方。所以设计成 pending → processing → done/failed 的显式状态机,并把扣减积分拆成「冻结」与「结算」两步,冻结时写入一条带唯一键的日志。这样即使同一个任务被重复消费,唯一键也会让第二次扣减失败,从根上消除重复扣费。代价是多了一次写库和一个需要定期对账的状态。
为什么要在启动时扫描异常任务重新入队
进程崩溃、容器重启、部署滚动更新,都会让正在 processing 的任务变成孤儿——队列里没有它,数据库里它又永远停在中间态。方案是启动时主动扫描所有 processing 状态的任务并重新入队。关键是这一步必须幂等:重新入队的任务要能从已有产出继续,而不是从头再来一次、再扣一次费。因此引用计数与产出记录都要先于任务执行落库。这是个典型的「用启动阶段的确定性,换取运行阶段的不确定性被兜住」。
为什么 TypeScript 全栈统一类型,管理后台却拆成独立项目
前后端共用类型定义,让供应商返回结构的任何变化在编译期就暴露,而不是等到线上 JSON 解析失败。但管理后台的数据可视化(Recharts)与用户端的产品逻辑几乎不共享任何视图代码,塞进同一个应用只会让两边的构建体积和依赖树互相拖累。所以拆成两个独立 React 项目、共享类型包——类型统一,部署独立。
// 04
我的职责与产出
RESPONSIBILITIES
- 从 0 到 1 负责平台全栈研发,包含用户端、管理后台与后端服务。
- 设计并实现多源 AI 视频生成的服务商适配层与统一任务调度。
- 设计任务状态机、崩溃恢复与积分冻结/结算的幂等机制。
- 实现多段视频一致性合并、分镜合并与首尾帧桥接等生成编排能力。
- 搭建多环境配置体系(本地磁盘 / 阿里云 OSS)与 Docker Compose 部署。
- 接入微信登录与微信支付,打通完整的用户与计费链路。
OUTCOMES
- 产品已上线生产环境并可对外访问(shatang.top)。
- 聚合 6+ 家视频生成供应商,覆盖商品展示、翻拍改编等 10+ 种生成方式。
- 通过状态机 + 崩溃恢复 + 积分冻结日志,消除长耗时任务的丢失与重复扣费两类生产事故。
- 前后端 TypeScript 类型统一,管理后台独立部署,可独立迭代。
// 05
踩坑与复盘
这个项目让我最深的体会是:AI 应用真正的难点从来不在调用模型。模型调用只是几行代码,难的是模型之外的那一整套工程——任务会失败、进程会崩、回调会重复、用户会为每一次失败付费。一开始我把重心放在「支持更多供应商」上,后来才发现真正决定产品能不能上线的是任务可靠性与计费正确性。如果重做一次,我会第一天就把状态机和幂等键设计出来,而不是等到第一次遇到重复扣费才补。
// 06
技术栈
- React 19
- Express 5
- BullMQ
- MySQL
- TypeScript
- DashScope
- 阿里云 OSS