AirShelf 后端生成管线 · 全景结构图

// 商品 → 脚本 → 基础资产 → 故事板 → 视频 → 导出  ·  2026-06-19 实测代码录制

看清楚每一步:触发(哪个端点)→ 读了哪些数据提示词怎么拼哪步是 AI / 哪步是纯代码参考图怎么引落到哪。 橙色=真在调 AI 模型,灰色=纯程序在跑,绿色=数据落点。

AI 调用 —— LLM / 图像 / 视频模型真在生效
纯代码 —— 规范化 / 校验 / 拼提示词 / 调度 / 落库
数据落点 —— DB 表 / project.metadata
1
脚本 Agent
POST /script-agent-stream/ · SSE 流式
模式 auto / theme / revise(可精准改1镜)
选文本模型 load_ecommerce_skill 拼系统提示词 拼商品+卖点上下文 预扣额度 ① 1 次 text LLM 流式调用 抽JSON+规范化兜底 落库
AI 节点 ① · 唯一一次 AI 调用
能力  text(纯文本,无图无视频)
底座  火山直连 VolcanoArk · 或中转站 OpenAICompatible(看模型 provider)
模型  请求指定 或 最早创建的 active 文本模型
系统提示词  SKILL.md + 5 篇 references + 运行时输出协议
AI 一次性产出(同一次调用里)
entities[] 角色/场景/商品,每个带: id · type · name · visual_prompt(给图模型的生图词) · ref_index segments[] 每 15 秒一镜: index · role(钩子/痛点/卖点/CTA) · narration(口播) · visual(画面) · product_exposure · entity_refs(本镜引用哪些实体)
关键澄清:角色/场景/商品 = AI 生成脚本时「一次性吐出」的,不是后面用程序/正则单独提取。 skill 里把 entities 写进同一份输出契约,要求 AI 为每个实体自动写一份 visual_prompt(小白不用打字)。后端只做规范化兜底,不再二次调 AI。
纯代码步骤(无 AI)
normalize_draft 抽 JSON+对抗字段名漂移 · _merge_single_segment 精准改1镜只换该镜 · _map_entities_to_project_metadata 把 entities 拆进 metadata · 计费 reserve→charge
数据落点
ScriptVersion content=完整JSON · metadata={entities 全量}   ScriptSegment(每镜) narration · visual_prompt · role · entity_refs · dialogue   project.metadata cast · cast_prompts{名:visual_prompt} · scenes · scene_prompts · script_entities(全量)
project.metadata.cast_prompts / scene_prompts / script_entities  ——传给下游——→
2
基础资产(人物 / 场景 / 商品图)
POST /generate-base-asset/ · 202秒回
真出图在后台 worker
前端读 metadata.cast_prompts[名] 当 prompt + label=实体名 POST 按 kind 拼最终 prompt ② 图像模型出 1 张图 落 Asset + 归组 + 自动采用 ③ 人物再出三视图
提示词拼装(按 kind 三选一)
# 商品(有主图)→ image_edit 锁包装 参考图1是「商品名」真实主图,严格参照包装/配色/Logo 生成三视图:正面/侧面/背面,纯白底,16:9 + {前端prompt} # 人物 → 文生图,固定模板包裹 电商真人模特,氛围正面全身照,{visual_prompt}, 自然妆容,柔和影棚光,单人,纯色背景 # 场景 → 原样透传 {visual_prompt}(不加模板)
AI 节点 ②③
底座  默认图像模型 = tokenssr:gpt-image-2(中转站 OpenAICompatible)
商品  image_edit images=[商品主图] · 锁一致性
人物/场景  image_generation 纯文生图
三视图  image_edit 据立绘/主图 → 1 张 16:9 横图(4 视角并排)
label = 实体名:生成时 group.metadata.label = 前端传的实体 tag。下游故事板就靠它把参考图对回实体。
数据落点 + 推进
BaseAssetGroup kind · metadata.label=实体名 · candidate_assets · adopted_asset  ·  三种 kind(人+场景+商品)都有采用资产 → 推进到故事板阶段
segment.entity_refs + 已采用 BaseAssetGroup(按 label)  ——→ 选参考图
3
故事板(分镜图)
POST /generate-storyboard + /poll-storyboard
HTTP秒回 + 后台线程出图(非 celery)· 最多 4 并发
取本镜 15s 脚本(visual/narration/露出) _storyboard_reference_images 选参考图 拼 @图N + 导演指令 + 分镜脚本 ④ image_edit 多图合成 落 StoryboardFrame
提示词拼装(refs 版 · 实际走这个)
【设定】@图1是小美(角色),@图2是耳机(商品), @图3是地铁(场景)。 根据以下脚本生成导演故事板,用于指导 seedance 视频生成。 {项目级 cast/scene/色调摘要} 【分镜脚本】(本段约 15 秒) 画面:{segment.visual_prompt} 口播:{segment.narration} 商品露出:{segment.product_exposure} 请严格保持各参考图同一张脸/同一商品外观配色; 9:16 竖屏,一镜一图。
参考图怎么选 · _storyboard_reference_images
来源  本镜 entity_refs → script_entities 查实体 → 找已采用的 BaseAssetGroup
匹配  先精确(kind + label==实体名)→ 匹不到放宽到"同类任一组"
商品兜底  无商品组 → 直接用商品真实主图(已修)
上限/顺序  最多 4 张 · 角色→商品→场景(与 @图N 对齐)
AI 节点 ④
image_edit tokenssr:gpt-image-2(中转站)· multipart 上传 N 张参考图合成 · 1024×1536
无参考图时降级走纯文生图 build_storyboard_frame_prompt(没有 @图N、没有"锁脸锁商品"那句)→ 一致性会丢。所以参考图配齐很关键。
同一套参考图引擎 + 末位多追加 1 张「故事板帧」 ——→
4
视频(Seedance 片段)
POST /submit-video-segment + /poll-video-segment
同步提交 + celery 轮询(+前端兜底)· 5–10 分钟/段
取同一镜脚本 _video_reference_images(=故事板那套+追加故事板帧) 拼 @图N + @故事板图 + 脚本 + 规格 ⑤ Seedance 出视频(带音) 落 VideoSegmentVersion
提示词拼装 · build_video_segment_prompt
【设定】@图1是小美(角色),@图2是地铁(场景), @图3是耳机(商品)。 【分镜】根据@图4分镜图生成「商品名」短视频。 【脚本】{画面/口播/露出} + {用户额外提示} 15s · 9:16 竖屏电商带货,镜头稳定,商品露出清晰, 节奏有转化感。
AI 节点 ⑤
底座  火山直连 VolcanoArk(create_video_task)
能力  video / Seedance · 9:16 · 720p
参考图  角色→场景→商品 + 末位故事板帧,作 reference_image 传入
音频  generate_audio=True(直接出音效+人物声,不是哑片)
降级  带参考图被拒 → 退纯文生视频(文本含旁白/画面)
AI 调用总清单(整条管线一共在哪几处真调了模型)
#阶段能力底座 / 模型输入纯代码 or AI
脚本text(LLM 流式)火山/中转站 · 文本模型skill 系统词 + 商品上下文AI 脚本+实体一次产出
基础资产·商品image_edit中转站 gpt-image-2商品主图 + 模板词AI
基础资产·人物/场景image_generation中转站 gpt-image-2实体 visual_promptAI
基础资产·三视图image_edit中转站 gpt-image-2立绘/主图AI
故事板分镜图image_edit 多图合成中转站 gpt-image-2N 张参考图 + 分镜脚本AI
视频片段video(Seedance)火山直连 VolcanoArk参考图+故事板帧+脚本AI

其余全是纯代码:选模型、拼提示词、选参考图、规范化兜底、归组、落库、轮询调度、计费预扣结算。 「提取角色/场景」不是单独的程序步骤——它跟脚本一起由 AI ① 产出;后面所有图/视频用的"角色/场景/商品提示词"都源自 ① 那次,中途纯代码搬运、不再二次问 AI。

你 demo 撞到的断点 · 落在链路哪一步
① 商品参考图丢失  阶段3/4 选参考图
商品天生有真实主图,但旧逻辑非要"商品基础资产组"才认,没生成就丢掉商品参考。实测某项目每镜要 3 张只给 2 张。
✓ 已修:无商品组时直接用商品主图兜底(实测 2/3 → 3/3)
② 实体没全生成基础资产  阶段2
脚本 ① 提取了角色+场景+商品,但第二步常只生成一部分(漏场景/漏第二角色)→ 没生成的实体在阶段3/4 自然没参考图。实测某项目每镜要 4 张只给 1 张。
待修:第二步明确标出"还差哪几个实体没基础资产"(前端 UX 提示)
③ 资产标签 ≠ 脚本实体名  阶段2→3 接线
阶段3 按 label==实体名 精确匹配参考图。若生成的资产被标成别的名(如脚本"通勤女主"、资产"通勤打工人"),精确匹配失败、退到"同类随便挑一个",多角色就挑错人。
待定:从实体卡生成时强制 label=实体名 + 清理"·三视图"这类占位组的误匹配