- 后端·可插拔 Provider 层:通用 OpenAICompatibleProvider(tokenssr 等中转站,base_url+api_key,零改代码换站)+ ModelProvider.api_key - 后端·脚本 agent:结构化 ScriptDraft 契约 + 加载电商 skill + 出稿/改稿一体对话 agent(3模式/多模型)+ 流式 SSE 端点(DRF SSE renderer) - 后端·图像:gpt-image-2 参考图出图 + 故事板 @图1@图2@图3 多锚点合成(锁脸锁商品);Seedance 打开 generate_audio - 后端·模特库:gpt-image-2 生成器(9:16氛围图→16:9白底三视图)+ seed_demo_models 管理命令 - DB·迁移:tokenssr 中转站 + 多模型 seed(豆包/GPT-5.5/Gemini + gpt-image-2);ScriptSegment 结构化字段 - 前端·脚本趴:接真 SSE(工具卡 + 思考流)+ 模型下拉 + 3模式 + 改稿;agentScriptStream - skills/ecommerce-video-script 电商脚本技能(运行时依赖) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
20 KiB
AirShelf · AI 生成 Agent 化落地方案
目标:把【脚本生成】升级为「多模型可选 + 出稿/改稿一体」的对话式 agent,并打通后续图片/故事板/视频 SOP。 用户定位:不懂视频制作的电商小白,点按钮就出"能吸睛、能转化"的带货短视频,提示词全替用户包好。 本文整合 2026-06-16 多轮讨论结论,作为开工 SSoT。
0. 一句话现状
5 阶段流水线(商品 → 脚本 → 图片 → 故事板 → 视频)页面已搭好,生成链路能跑,但:脚本是一次性散文+正则解析、无 agent、无多模型;图片"平台套图"是装饰;参考图生成断线;Seedance 音频被关。
1. 现状核查(已验证,带 file:line)
1.0 模型与中转站(最终方案,均已实测 200)
主力中转站 = tokenssr(https://king.tokenssr.com/v1,一把 key 通吃 90 模型,见 .env TOKENSSR_API_KEY)。
| 用途 | 模型 | 端点/调法 |
|---|---|---|
| 脚本·豆包 | doubao-seed-2.0-pro | 火山 ARK chat(本地直连) |
| 脚本·GPT | gpt-5.5 |
tokenssr chat/completions |
| 脚本·Gemini | gemini-3.1-pro-preview / gemini-3.5-flash |
tokenssr chat/completions |
| 纯文生图 | gpt-image-2 |
tokenssr images/generations |
| 参考图/编辑 ⭐ | gpt-image-2 |
tokenssr images/edits(multipart image[],1~多张参考图,返回 b64) |
| 视频 | seedance-2.0 | 火山 ARK(本地直连) |
- 多图参考(故事板 @图1@图2@图3)实测 200;
gemini-3-pro-image-preview(chat 多模态)留作图像备选/风格选择。 - YunQi 那家分组割裂、gpt-image-2 渠道残废 → 已弃用,仅留历史参考。
- token 用量正常返回,对齐"按实际 token 扣费"。
1.1 模型与 fallback
| 类型 | 实际模型 | Provider | Fallback |
|---|---|---|---|
| 脚本 text | Doubao-Seed-2.0-Pro | 火山 ARK(写死) | ❌ 无 |
| 图片 image | GPT-Image-2 / YunQi 网关(Seedream 被 disabled) | YunQi | ❌ 无 |
| 视频 video | Seedance-2.0 | 火山 ARK(写死) | ⚠️ 仅"丢参考图退纯文生视频" |
- 默认选模型 = 该能力下最早创建的 active 行 services.py:33-39
- 生图按 provider 分流(yunqi/火山) services.py:42-46
- YunqiProvider 继承火山,
chat_completion现成 → 文本接多模型很便宜 yunqi.py
1.2 脚本生成(无 agent)
- 系统提示词:4×15s、强制
镜头N/旁白/画面格式 services.py:53-77 - 正则抠字段 services.py:81
- 第二次 LLM 调用抽 人物/场景 JSON services.py:116
- 全是一次性调用,无循环/无工具/无自检
1.3 图片(平台套图是空壳)
- 三种模式提示词模板在前端 ai-tools.tsx:387
- 平台卡/模特卡选择
pickedIds只做高亮,不拼进 prompt、不发后端 ai-tools.tsx:1195 - 提交只发
{prompt, mode, count}api.ts:342;后端mode只决定任务类型/分类/命名,不加工 prompt services.py:1067
1.4 视频
- 视频提示词织入风格锚点+旁白+画面 services.py:621
- 已传参考图给 Seedance services.py:870-897
- 但
generate_audio写死 False volcano.py:129
2'. 开工就绪状态(2026-06-17 全部核实)
| 卡点 | 状态 |
|---|---|
| 电商 skill | ✅ 已写好 skills/ecommerce-video-script/(SKILL.md+5 references),输出契约与 §3 完全对齐(还多了 aspect_ratio + 四档时长) |
| 参考图出图 | ✅ tokenssr gpt-image-2 images/edits 实测(含多图) |
| 火山审核+绿/红标 | ✅ AirDrama 有整套现成:video-shuoshan/backend/utils/assets_client.py(建组/传素材/查审核)+ AssetGroup/Asset 模型(status: processing→active=绿标 / failed=红标)+ 轮询接口。照搬即可。策略:一团队一素材组(火山确认单组可放 500 万素材),后台 API 静默自动上传,前端不显示组、只显示绿/红标;红标提示"未通过审核,请改提示词重生" |
| 模特库 | ✅ 由 agent 用 gpt-image-2 预生成 2-3 个(先 9:16 正面氛围图 → 以其为参考出 16:9 白底三视图)。提示词见 §阶段4 |
| 前端结构 | ✅ routes 齐全,不用大动,主要接线+结构化渲染+聊天框+badge |
| 多模型 | ✅ 豆包/GPT/Gemini 实测可用 |
★ 架构原则:Provider 可插拔(不写死中转站)
除火山(ARK/Seedance,官方直连)外,其余全走中转站且随时可换 → 设计成:
- 一个通用
OpenAICompatibleProvider(base_url, api_key)覆盖所有中转站(tokenssr/yunqi/未来任意家),按ModelConfig.provider的base_url+api_key实例化。 - 换中转站 = 改 DB 里 Provider 的 base_url+api_key,零改代码;加新家 = 加一行(格式兼容则复用同一 provider 类)。
VolcanoArkProvider专管火山官方(文本/图/Seedance)。- 新增
ModelConfig.api_key;key 全部走 .env / DB,不写死代码。
2. ⚠️ 前置硬伤 / 必须先决策
GAP-1 参考图生成 —— ✅ 已解决(2026-06-17 实测,换中转站 tokenssr)
结论:换到中转站 tokenssr(base https://king.tokenssr.com/v1)后,gpt-image-2 直接支持参考图(含多图)。 之前 YunQi 是渠道残废,不是 gpt-image-2 本身不行。
- 一把 key 通吃 90 个模型(无 YunQi 那种分组割裂):gpt-image-1 / gpt-image-1.5 / gpt-image-2 / dall-e-3 + 全套 Gemini 文本&图像模型 + gpt-5-nano 等。
- gpt-image-2 传参考图,两条路实测 200:
- A·
images/edits(标准 OpenAI 格式,推荐):multipart,image[]传 1 张或多张参考图 +prompt+model=gpt-image-2+size;返回data[0].b64_json。多图参考(2张)实测 200 → 故事板@图1@图2@图3成立。 - B·
images/generations+image(base64):返回data[0].url(r2.sysrv.net/...png,直接是托管 URL)。
- A·
- 参考图来源:角色/场景/商品图在 TOS(URL)→ 取字节走 edits 的
image[],或 base64 走 generations;出图落 TOS。 - 需新增
TokenssrProvider:image_generate()(文生图)/image_edit(model,prompt,ref_bytes[],size)(参考图,multipart image[])。比之前 Gemini-chat 解析 markdown 的方案更干净(标准 OpenAI 格式、data[] 直接拿图)。 - 备选:同站的 Gemini 图像模型(
gemini-3-pro-image-preview)走 chat 多模态也可用,留作 fallback/风格选择。 - 这是图片/故事板/视频趴的前置依赖,现已具备。
GAP-2 Seedance 音频被关
- 你的设计:Seedance 直接出画面+音效+人声,不走 TTS。
- 现
generate_audio=False写死 volcano.py:129 → 需打开;音色一致性(audioReference,Seedance-2.0 支持 catalog.py:67)二期再接。
决策清单
- 图片参考图模型(已定·实测解决):用 tokenssr 的 gpt-image-2(
images/editsmultipartimage[],多图已验证);YunQi Gemini 图像模型留可选 fallback。 - 计费粒度(已定):按实际 token 消耗,每次调用扣一次费。含义:agent 自检循环每跑一轮都扣 → 循环要克制(≤2-3 轮),内部调用尽量精简,避免空转扣费。
- 平台套图(独立图片工具)(已定):暂不管,本方案聚焦视频项目流水线。
- 多 key 管理(基本解决):换 tokenssr 后,一把 key 通吃 90 模型,不再有 YunQi 分组割裂问题。后端仍加
ModelConfig.api_key字段(留作多 provider 共存:tokenssr / 火山本地)。
3. 数据契约:结构化脚本 ScriptDraft(全链路地基)
把脚本从"散文+正则"改成结构化输出(JSON/tool-calling),模型无关,一次喂饱全下游。
{
"hook": "前3秒主打钩子(一句话)",
"tone": "种草|测评|剧情|痛点",
"aspect_ratio": "9:16", // 不写死,可 16:9/1:1/4:5,透传下游
"total_duration": 60, "segment_count": 4, // 时长 15/30/60/90 四档,每15s一镜→1/2/4/6镜
"entities": [ // 角色/场景/商品,全脚本共享 → 保证4镜同一角色同一张脸/同一音色
{ "id": "c1", "type": "character|scene|product", "name": "女主",
"visual_prompt": "给图模型的生图提示词(AI自动生成,小白不打字)",
"ref_index": 1,
"voice_ref": "可选·角色音色参考(二期锁音色)" }
],
"segments": [
{ "index": 0, "duration": 15,
"role": "钩子|痛点|卖点|CTA", // 电商脚本的灵魂
"narration": "本镜要说出来的台词/旁白,≤55字(Seedance 15秒内直接发声,字数=可懂语速上限)",
"speaker": "可选·指向角色entity的id;null=画外旁白",
"visual": "画面描述",
"product_exposure": "商品露出方式(手持/特写/使用中)",
"entity_refs": ["c1"] }
]
}
它如何驱动全下游:
- 图片趴:直接读
entities[].visual_prompt预填出图卡(小白不打字) - 故事板趴:按
entity_refs+ref_index拼@图N - 视频趴:
narration(发声)+visual+@图N参考 → Seedance - 一致性:同一 entity 全程一份图/一份音色
从 AirDrama 保留:结构化思维、entity 层(一致性)、segment role。砍掉:三流、5 种 beat、est_sec、Section 嵌套、质量词三层 fork。
4. 分阶段落地
阶段 0 · 电商剧情 skill —— ✅ 已完成
- 产物在
skills/ecommerce-video-script/(SKILL.md + 5 references:methodology/hook-library/category-playbook/platform-tone/checklist)。 - 输出契约 = §3 ScriptDraft(并扩展了 aspect_ratio + 15/30/60/90 四档时长);3 模式路由、输出前自检、写作红线、渐进披露齐全。
- agent(阶段2)运行时加载它作为领域知识。无需再做。
阶段 1 · 结构化契约 + 多模型管子(后端 ~1d)
- 定
ScriptDraft类型(§3);脚本输出从正则改 tool-calling/JSON - 文本 provider 分流(照搬生图)或全走 YunQi 网关;
/api/ai/models/已能列模型,生成时透传model_config_id - DB:加 GPT-5.5 + Gemini-3.5-flash/3.1-pro(均 YunQi 已实测可用)文本模型设 active;按模型配各自 key(决策4)
- 验收:同一商品,豆包 / GPT-5.5 / Gemini 三家都产出合规
ScriptDraft,字段不崩 - 依赖:无 ‖ 可与阶段0并行
阶段 2 · 对话式脚本 agent(出稿+改稿一体)(后端 ~2-3d)
- 同一个 agent 跑在带状态会话上:第1轮=出稿(3模式 seed),第N轮=改稿(带上轮草稿)
- Session 状态:当前
ScriptDraft+ 消息历史 + 商品上下文 + 选定模型/调性 - 工具:
get_product / load_skill / validate / emit+edit_segment(index,instruction)/patch_draft(build_segment_rerun_promptservices.py:353 升级为工具) - 有界循环 ≤2-3 轮:读(草稿+用户话)→ 判(整篇重生/改某镜/答疑)→ 执行 → validate → emit
- 一个 endpoint:
(session_id, 可选消息, 当前草稿) → (新草稿, agent回话) - 计费:按实际 token、每次调用扣(决策2)→ 循环 ≤2-3 轮、内部调用精简,避免空转扣费
- 验收:点按钮 ~10-20s 出 4 镜结构化脚本;聊一句能精准改某镜;旁白≤55字、结构齐、entity 一致
- 依赖:阶段0 + 阶段1
阶段 3 · 前端脚本趴(前端 ~1.5d)
- 模型下拉(豆包/GPT/Gemini)
- 3 种出稿输入(全自动/一句话/自带脚本)
- 4 镜结构化渲染(钩子/痛点/卖点/CTA 标签 + 旁白/画面/商品露出)
- 聊天框(改稿)+ 每镜快捷按钮(重跑/改活泼/加钩子=预设改稿指令)
- 验收:设计师视角点按钮出稿、看得到分镜结构、能对话改 / 点按钮改单镜
- 依赖:阶段2
阶段 4 · 图片趴(后端+前端)
- 前置·新增
TokenssrProvider:image_generate()(文生图)/image_edit(model,prompt,ref_bytes[],size)(参考图,images/editsmultipartimage[]);新增ModelConfig.api_key - 三视图(商品创建即可生,视频项目内可补):prompt + 上传商品图(正/侧/背多参考)→ gpt-image-2
images/edits出三视图;无则用原图 - 实体出图:直接读脚本
entities[].visual_prompt预填卡,小白只点生成(不打字);不满意可改 prompt - 模特库(预生成 2-3 个电商模特,流程:① gpt-image-2 出 9:16 正面氛围图 → ② 以①为参考图出 16:9 白底三视图,提示词:
参考图1角色,生成角色三视图,从左往右依次为:胸像特写,全身正面,全身侧面,全身背面,白色背景)+ 自定义模特/场景(gpt-image-2 生) - 出图落 TOS,大图预览
- 火山审核(照搬 AirDrama
utils/assets_client.py+ AssetGroup/Asset 模型 + 轮询接口):一团队一素材组,后台静默自动上传(前端不显示组),轮询 status → active=绿盾标 / failed=红标(红标提示"未通过审核,请改提示词重生");env 复用 TOS_ACCESS_KEY/TOS_SECRET_KEY + ASSETS_API_ENABLED + PROJECT_NAME - 验收:小白零输入出齐角色/场景/商品图;三视图可参考原图;盾牌 icon 正确
- 依赖:阶段2(脚本 entities)
阶段 5 · 故事板趴(依赖阶段4)
- 拼装系统提示词 + 角色图/场景图/商品图(三视图优先)+ 本段 15s 脚本 → gpt-image-2
images/edits多图image[]出导演故事板(多图实测 200) - 提示词骨架:
制作导演故事板指导seedance / @图1角色 @图2场景 / 分镜脚本(15s) / 规则:景别·运镜·画面·角色动作·情绪·对白旁白·灯光 - 每帧场景/角色必须回溯脚本文字(靠
entity_refs) - 验收:每镜一张故事板,角色/场景跟回脚本,可指导视频
- 依赖:阶段4
阶段 6 · 视频趴(依赖阶段5)
- 分镜图+角色图+场景图+商品图+文字脚本 → Seedance(火山,参考图走 TOS URL,已在用)
- v1 固定模板:
【设定】@图1是X角色,@图2是X场景,@图3是X商品 【分镜】根据@图4分镜图生成X商品视频 【脚本】…(后续可做视频优化 skill) - 打开
generate_audio(GAP-2);二期接 audioReference 锁音色 - 火山审核盾牌 icon 同图片趴
- ⚠️ Seedance 出片慢:正常 5-10 分钟/段,凌晨可能 3-4 分钟。轮询超时要放长(≥15 分钟),测试时别误判失败;若实测耗时太长,视频趴只到"提交成功+轮询机制验证",标注成熟度交接。
- 验收:四镜成片、画面跟故事板、音画自带、审核 icon 正确
- 依赖:GAP-2 + 阶段5
5. 全链路数据流
商品(信息+图) ──┐
├─→ [脚本 agent] → ScriptDraft(hook/entities/segments)
前置条件(调性/平台)┘ │
├─ entities[].visual_prompt ─→ [图片趴] 角色/场景/商品图(三视图优先)
│ │
├─ entity_refs + 15s脚本 ──────────────→ [故事板趴] 导演分镜图
│ │
└─ narration + @图N + 分镜图 ──────────→ [视频趴] Seedance 成片(自带音)
│
全程:同一 entity = 同一张脸/同一音色 ;火山审核盾牌 icon
5'. 执行须知(compaction-safe resume 锚点 · 2026-06-17 夜)
压缩/换会话后,从这里 + 下面的 checklist 直接续干,不必重读全部代码。
凭证(都在 core/backend/.env):
TOKENSSR_API_KEY/TOKENSSR_BASE_URL(https://king.tokenssr.com/v1)= 主力中转站,一把 key 通吃 90 模型。FEISHU_APP_ID/FEISHU_APP_SECRET(机器人「小毛球」,文件上传权限已开)。- 火山:
VOLCANO_ARK_API_KEY、TOS_*、VOLC_TTS_*已就绪。
已验证可用模型(tokenssr,均 200): 文本 gpt-5.5/gemini-3.1-pro-preview/gemini-3.5-flash;图编辑 gpt-image-2(images/edits multipart image[],1~多张参考图,返回 b64)+ images/generations(文生图);Gemini 图像 gemini-3-pro-image-preview(chat 多模态,备选)。豆包/Seedance 走火山 ARK 本地。
关键代码事实(已读):
ai/models.py:ModelProvider(name/base_url/metadata,需加api_key字段+迁移)、ModelConfig(provider FK/name/capability/endpoint/status,默认选get_default_model=该能力最早 active)、AITask(idempotency_key 必填唯一、status 机、request/response_payload、estimated/actual_cost)。ai/services.py:create_ai_task→reserve_credit;charge_reserved_credit/release_credit(billing/services/ledger.py,幂等带行锁);get_image_provider按 provider.name 分流;build_*_prompt系列;generate_project_script(改结构化输出落ScriptVersion.metadata)。providers/:base.py(AIProvider Protocol)、volcano.py(VolcanoArkProvider:chat_completion/image_generation 带image参/create_video_task 有generate_audio=False需开)、yunqi.py。要新增OpenAICompatibleProvider(base_url,api_key)覆盖所有中转站 + tokenssr 的image_edit(images/edits multipart image[])。projects/models.py:ScriptVersion(content+metadata)、ScriptSegment(narration/visual_prompt/duration,需补 role/product_exposure/entity_refs/speaker 或塞 metadata)、BaseAssetGroup(kind: product/person/scene,adopted/candidate assets)、StoryboardVersion/Frame、VideoSegment/Version。assets/models.py:Asset(category: person/scene/product_image/…)+AssetFile(object_key/bucket/preview_url)。出图落 TOS 已有链路。- 前端 routes 齐全:
pipeline.tsx(五阶段主)、projects.tsx、ai-tools.tsx、api.ts、types.ts。不大改,只接线+结构化渲染+按钮+绿红标。
火山审核复用(照搬 AirDrama,有 4 个坑已处理): 源 video-shuoshan/backend/utils/assets_client.py(create_asset_group/create_asset/get_asset)+ AssetGroup/Asset 模型(status active=绿/failed=红/processing)+ 轮询。策略:一团队一素材组,后台静默上传 TOS URL,前端只显示绿/红标。
- 坑1·SDK:AirShelf
requirements.txt没volcengine(只有 boto3+requests)→ 加volcengine依赖装上(或用 requests 手写火山签名)。 - 坑2·密钥:AirDrama 用
settings.TOS_ACCESS_KEY/TOS_SECRET_KEY;AirShelf 改用独立 envASSETS_API_ACCESS_KEY/ASSETS_API_SECRET_KEY(已写入 .env,暂借 AirDrama 已邀测开通的 AK/SKAKLTNGJi…)。搬代码时把读 key 处改成读这俩。 - 坑3·配置:
.env已加ASSETS_API_ENABLED=true+ASSETS_API_PROJECT_NAME=int_dev_Airlabs(assets_client 里 PROJECT_NAME 常量改读这个 env)。 - 坑4·权限(用户已拍板):AirShelf 自有火山账号没开通人像素材库邀测 → 先用 AirDrama 的 AK/SK 跑通;交接 MD 必须标红:张业昌待办 = AirShelf 火山账号开通人像素材库后,把 .env 的
ASSETS_API_ACCESS_KEY/SECRET换成自己的(独立两行,不动 TOS_*)。
模特库提示词: ① gpt-image-2 出 9:16 正面氛围电商模特 → ② 以①为参考:参考图1角色,生成角色三视图,从左往右依次为:胸像特写,全身正面,全身侧面,全身背面,白色背景(16:9)。
收尾: 推 dev 分支;飞书小毛球发交接 MD 给 张业昌 13725102796 + 尹雨萱 15915987827(测试号 13811803069 已验证可发文件)+ 附言(署名 Claude + 用户),让他们明早接手。飞书流程:token→batch_get_id(mobile→open_id)→ 上传文件(/im/v1/files,file_type=stream)→ 发文件消息(msg_type=file)。
skill: skills/ecommerce-video-script/(SKILL.md+5 references),输出契约 = §3 ScriptDraft(+aspect_ratio + 15/30/60/90 四档),agent 运行时加载它。
6. 关键路径
- 阶段 0(skill)+ 阶段 1(契约/多模型)并行先启 = 整条线地基
- GAP-1 已解决(tokenssr gpt-image-2 参考图实测可用),图片/故事板/视频不再被阻塞
- 阶段 2 是把 skill+契约粘起来的执行器;阶段 3 让设计师能用
- 图片/故事板/视频(4/5/6)在脚本跑通后顺序推进
- 唯一待你拍板:决策4(多 key 管理方式) —— 不阻塞阶段 0/1,可边做边定