diff --git a/core/backend/apps/ai/services.py b/core/backend/apps/ai/services.py index c6c4abf..1027d0d 100644 --- a/core/backend/apps/ai/services.py +++ b/core/backend/apps/ai/services.py @@ -774,6 +774,8 @@ def _storyboard_reference_images(project, segment) -> list[dict]: groups = list(project.base_asset_groups.filter(adopted_asset__isnull=False).select_related("adopted_asset")) out: list[dict] = [] used: set = set() + # 商品天生有真实主图,不必先生成"商品基础资产":匹配不到商品组时直接拿主图当参考(原先这里会丢掉商品参考图) + product_cover = _product_cover_url(project.product) for rid in (segment.entity_refs or []): ent = entities.get(rid) if not ent: @@ -789,6 +791,8 @@ def _storyboard_reference_images(project, segment) -> list[dict]: url = _asset_preview_url(match.adopted_asset) if url: out.append({"url": url, "label": name or _ENTITY_TYPE_CN.get(ent.get("type"), "参考"), "type": ent.get("type")}) + elif ent.get("type") == "product" and product_cover and product_cover not in {r["url"] for r in out}: + out.append({"url": product_cover, "label": name or "商品", "type": "product"}) if len(out) >= 4: break if not out: @@ -797,6 +801,8 @@ def _storyboard_reference_images(project, segment) -> list[dict]: url = _asset_preview_url(pg.adopted_asset) if url: out.append({"url": url, "label": "商品", "type": "product"}) + elif product_cover: + out.append({"url": product_cover, "label": "商品", "type": "product"}) # 规范 @图N 顺序:角色 → 商品 → 场景(与下游 image_edit 传图顺序一致,标注不错位) _ord = {"character": 0, "product": 1, "scene": 2} out.sort(key=lambda r: _ord.get(r.get("type"), 9)) diff --git a/docs/todo/管线参考图链路诊断-2026-06-19.md b/docs/todo/管线参考图链路诊断-2026-06-19.md new file mode 100644 index 0000000..cf6d326 --- /dev/null +++ b/docs/todo/管线参考图链路诊断-2026-06-19.md @@ -0,0 +1,33 @@ +# 管线"参考图/参数传递链"诊断报告 + +> 用户 demo 撞到:第2步角色提示词没提取、第3步分镜图参考图没引用、第4步视频参考图没引用。 +> 本报告:整体扫了脚本 agent → 资产 → 故事板 → 视频 的代码,并**用真实项目数据实测**了参考图解析结果。 + +## 一句话结论 +**脚本 agent 没问题**(实体+提示词都正确提取了);断的是**"实体 → 基础资产 → 参考图"的接线**。链路本身是通的(资产配齐的项目 3/3 全中),问题是上游基础资产**没配齐 / 标签对不上 / 商品没走主图兜底**。 + +## 实测证据(`_storyboard_reference_images` 真实输出) +| 项目 | 已采用基础资产组 | 某镜要的参考 | 实际给到 | 丢了什么 | +|---|---|---|---|---| +| c77ac814(齐全) | 角色×3+商品+场景×2 | c1角色/s1场景/p1商品 | **3/3 全中** ✅ | 链路本身是对的 | +| 37197c57 | 角色×2+场景(**无商品组**) | c1/s1/p1 | **2/3** | **商品参考图丢**(p1) | +| 008d9a9b | **只 1 个角色组** | c1/c2/s1/p1 | **1/4** | 第二角色c2、场景s1、商品p1 全丢 | + +> 注:008d9a9b 脚本实体名 `通勤女主`,但生成的资产标签是 `通勤打工人` —— **名字对不上**,精确匹配失败、退到"随便挑同类",多角色时会挑错。 + +## 根因(都在"接线",不在脚本 agent) +1. **商品参考图必丢** —— `_storyboard_reference_images`(services.py:761)非要一个"商品基础资产组"才认;但商品本来就有真实主图,**应直接拿商品主图当参考**,不该要求先生成商品基础资产。→ **修:无商品组时兜底用 `product.cover/主图`**。后端,低风险,价值最高。 +2. **实体没全生成基础资产** —— 脚本提取了 角色/场景/商品,第二步常只生成一部分(漏场景/漏商品/漏第二角色)→ 没生成的就没参考图。→ **修:第二步明确标出"哪些实体还缺基础资产"**,别让用户漏。前端 UX。 +3. **标签↔实体名对不上** —— 从实体卡生成基础资产时,组的 `metadata.label` 没严格 = 实体 `name`(出现 `通勤打工人` vs `通勤女主`、`·三视图` 被当成 person、商品组 label=None)。→ **修:从实体 seed 生成/采用时,label = 实体名,严格对齐**;并清理 `·三视图` 这类错 kind 的脏组。 + +## Bug 1(第2步角色提示词) +实测 `cast_prompts` / `script_entities[].visual_prompt` **都有值**(24–45 字),提示词其实提取到了。第二步看着"没提取"= 同一个**名字接线问题**(卡片按 label 取 cast_prompts,label↔name 对不上就取空),与根因 #3 同源。 + +## 为什么第2/3/4步全错 +第3步分镜、第4步视频**用的是同一个 `_storyboard_reference_images`**(services.py:877 故事板 / :1059 视频)。上游第2步资产没配齐 + 标签错,下游 3/4 步全跟着错 —— 一处根因,三处表现。 + +## 建议修复顺序(都不碰脚本 agent) +- **P0 #1 商品主图兜底**(后端 `_storyboard_reference_images`)—— 纯接线,最稳,立竿见影 +- **P0 #3 标签对齐 + 清脏组**(生成/采用基础资产时 label=实体名) +- **P1 #2 第二步缺失实体提示**(前端 UX) +- 修完重跑 demo,逐镜核参考图齐不齐(可复用本报告的实测脚本)