Files
ai-toy-patent-workflow/HANDOFF_IMAGE_PIPELINE.md

47 KiB
Raw Blame History

生图链路重构交接文档

给后续 AI 开发者的实施清单。当前代码的整体骨架已搭好模板、Pack、Manifest、Seedance、GPT provider一致性机制是假的,需要按本文档重构。

路径:/Users/kangwan/Projects/code/20260518-ai-toy-patent-workflow/HANDOFF_IMAGE_PIPELINE.md


0. 一句话目标

让"上传图 + 风格 → 意向图 → 选中主方案 → 专利包 → 配件包 → 生产包 → 宣发包 → 视频"的整条链路里,每张图都基于上游锚图生成、每张图都能单独重做且不脱链。专利申请要求前后一致,配件六视图也必须自成体系。


1. 用户期望的目标流程

[上传图(单张/多张) + 选风格(风格库可视化)]
   ↓
批量生图4/8/12 张候选)
   ↓
九宫格快筛 → 选中主方案
   ↓
锁定 CharacterSpec角色基线+ 生成 L1 净化锚图
   ↓
按顺序生成(每步可单独重做,但参考链不能脱):
   ├─ 专利包(六视图 + 立体图 + 局部图)
   ├─ 配件包(先识别配件 → 每件孤立锚图 → 每件 6 视图 → 组合图)
   ├─ 生产包(尺寸/材料/拆件/包装)
   ├─ 宣发包(白底/场景/卖点/详情页)
   └─ Seedance 视频(用宣发白底图当锚)

核心约束

  1. 风格库要可视化(缩略图代表)+ 内容完整lighting/composition/material/negative
  2. 每张图都有明确的上游 anchor参考链不能跨级
  3. 单张重做必须沿用同一个 anchor
  4. 配件六视图必须基于配件孤立锚图,不是娃娃源图
  5. 视频参考宣发白底图,不是意向图

2. 现状的 6 个关键 Gap

Gap 1参考图根本没传给模型最严重

位置src/lib/providers.ts:62-65

const refHint = opts.refImages?.length
  ? `\n参考图 URL用于保持角色一致\n${opts.refImages.join('\n')}`
  : '';

问题:把参考图 URL 当文本拼在 prompt 末尾发给 /images/generations。这个端点根本不读图,模型只看到一串文本 URL等于没参考

真正的图生图必须走 /images/edits + multipart 上传图像字节,或者用 /responses + vision input 让 GPT 先描述再二次生图。

Gap 2风格库太薄、看不到样子

位置src/components/PromptPanel.tsx:5-12

只有 6 个文字按钮:毛绒玩偶 / 机甲风 / 可爱萌系 / 专利蓝图 / 赛博朋克 / 极简

问题

  • 没有代表缩略图(用户看不到"这个风格长什么样"
  • 没有完整的 style blocklighting、composition、color palette、material hint、negative prompt
  • 只是简单拼成 prompt + ", style: 机甲风"

Gap 3所有后续图都参考"最初那张意向图",逐级漂移

位置src/lib/packGenerator.ts:144

const prompt = renderPrompt(template.promptTemplate, characterSpec, opts.sourceImage.url);

问题:专利右视图、宣发场景图、配件六视图……全部参考同一张意向图。

正确做法 — 锚图链

L0 锚图 = 用户选中的意向图(可能还有背景、不够干净)
L1 锚图 = L0 净化后的白底正面图CharacterSpec 锁定时生成)
L2 锚图 = 各包的首图patent_front / acc_inventory / mkt_white_front
L3 节点 = pack 内其他图都参考自己包的 L2

现在所有 L2/L3 都跨过 L1 直接参考 L06-30 张图相互之间没有锚定,越生越漂

Gap 4配件链路是假的

位置src/lib/packGenerator.ts:36-37

if (prompt.includes('机甲')) accessories.unshift('机甲头盔');
if (prompt.includes('M logo')) accessories.unshift('胸前 M 标识');

问题

  • 配件清单是关键词硬匹配,换个 prompt 就识别不出
  • 配件六视图都把"主娃娃源图"当 ref配件本身轮廓、材质会被娃娃身体盖住

正确做法

  1. 锁定主方案后,调 GPT Vision 解析 L1 锚图 → 输出 [{name, isolatedDescription, bbox}]
  2. 为每个配件生成配件孤立锚图(白底、单件、无娃娃)
  3. 配件六视图基于自己的孤立锚图
  4. 最后单独生成"配件+娃娃组合图"

Gap 5单张重做会脱链

代码里只有 generateAssetPack(整包重做),没有单张重做接口

如果右视图不满意要单独重做,需要:

  • 知道这张图的锚图是谁(同包主视图)
  • 锚图必须存在且未变
  • 可选传 userRefinement 文本补充

需要新增 API POST /api/assets/[assetId]/regenerate,并在 ToyAsset 类型上加 anchorAssetId 字段。

Gap 6视频参考也不一致

位置src/app/page.tsx:161

imageUrl: image.url  // 还是那张原始意向图

问题:视频里的玩具和已定稿的电商图长得不一样。

正确做法:视频参考宣发白底主图(mkt_white_front),如果未生成就退到专利主图。


3. 实施方案(按依赖顺序)

阶段 1真图生图链路最高优先级1+2+3+5 是最小可用版本)

1.1 新增 generateGptImageEditproviders.ts

export async function generateGptImageEdit(opts: {
  prompt: string;
  anchorImage: Buffer | string;   // 真实图片字节或本地路径
  maskImage?: Buffer;             // 可选 mask局部重绘
  size?: '1024x1024' | '1024x1536' | '1536x1024';
}): Promise<GenImage>

实现要点:

  • https://api.openai.com/v1/images/edits
  • multipart/form-dataimage (Buffer)、promptmodel=gpt-image-1size
  • 必须传图字节而不是 URL
  • 返回 b64_json → 解码为 data URL

保留现有 generateGptImages 用于 L0 意向图阶段(无锚图,纯文本生图)。

1.2 数据模型扩展types.ts

export type ToyAsset = {
  // ...existing
  anchorAssetId?: string;       // 上游锚图 asset id
  anchorImageUrl?: string;       // 解析后的锚图实际 URL
  derivationLevel: 0 | 1 | 2 | 3;
};

export type CharacterSpec = {
  // ...existing
  cleanReferenceImageUrl?: string;  // L1 净化锚图(白底正面)
};

export type AssetTemplate = {
  // ...existing
  anchorTemplateId?: string;    // 显式指明上游锚图模板
};

1.3 模板加 anchorTemplateIdtemplates.ts

{ id: 'patent_front', anchorTemplateId: undefined, ... }       // 用 L1 锚图
{ id: 'patent_back', anchorTemplateId: 'patent_front', ... }   // 用包内主图
{ id: 'patent_left', anchorTemplateId: 'patent_front', ... }
// 配件同理
{ id: 'acc_inventory_sheet', anchorTemplateId: undefined, ... } // 用 L1 锚图
{ id: 'acc_front', anchorTemplateId: 'acc_inventory_sheet', ... }
{ id: 'acc_back', anchorTemplateId: 'acc_inventory_sheet', ... }

1.4 新增 API净化锚图

POST /api/character/cleanup

逻辑:

  • 输入:sessionId + imageId
  • generateGptImageEditprompt = "保持角色完全一致,把背景换成纯白色,产品居中,无任何文字水印,光线均匀"
  • 输出图 URL 写回 session.characterSpec.cleanReferenceImageUrl

1.5 改造 generateAssetPackpackGenerator.ts

async function resolveAnchorImage(template, packAssets, characterSpec) {
  if (!template.anchorTemplateId) {
    // 用 L1 净化锚图,没有则退到 L0
    return characterSpec.cleanReferenceImageUrl ?? characterSpec.sourceImageUrl;
  }
  const upstream = packAssets.find(a => a.templateId === template.anchorTemplateId);
  if (!upstream) throw new Error(`anchor ${template.anchorTemplateId} not generated yet`);
  return upstream.url;
}

按模板拓扑顺序生成(先无 anchor 的,再依次):

  1. 第一张 → 走 generateGptImageEdit(prompt, L1Buffer)
  2. 其它张 → 走 generateGptImageEdit(prompt, 同包首图 Buffer)

需要新增工具函数:从 URL/api/img/packs/xxx.png)读回 Buffer供 multipart 上传。

阶段 2单张重做

2.1 新增 API

POST /api/assets/[assetId]/regenerate
Body: { sessionId, userRefinement?: string }

逻辑:

  • 找到这个 asset 在哪个 pack
  • 解析它的 anchor按 template.anchorTemplateId
  • generateGptImageEditprompt 末尾追加 userRefinement
  • 替换原 asset保留 id 不变
  • 更新 session JSON

2.2 UI

PackPanel.tsx 里每个 AssetRow 加"重做"按钮和"refinement"输入框。

阶段 3风格库可视化

3.1 新增 src/lib/styles.ts

export type StylePreset = {
  id: string;
  label: string;
  thumbnailUrl: string;          // /styles/plush-classic.png
  promptBlock: string;            // 完整 style prompt 段
  negativePrompt: string;
  recommendedPalette: string[];
  recommendedMaterials: string[];
  goodFor: PackKind[];
};

至少 12-16 个预设,每个对应一张 256×256 缩略图放 public/styles/

建议初始风格列表:

  • 经典毛绒、长毛毛绒、超柔短绒、卡通圆胖
  • 机甲风、赛博朋克、未来科技
  • 可爱萌系、治愈系、Kuromi 暗黑可爱
  • 复古玩具、迪士尼风、皮克斯风
  • 黏土材质、绒线编织、3D 渲染、专利蓝图

3.2 改 PromptPanel

风格选择从 6 个按钮 → 4 列网格的图卡(缩略图 + 名称 + 适用包 tag

风格切换时:

  • promptBlock 合并到生图 prompt
  • negativePrompt 单独传给 providerGPT image edit 支持 negative
  • recommendedPalette/Materials 自动填到 CharacterSpec 默认值

阶段 4配件 Vision 识别

4.1 新增 src/lib/accessoryDetector.ts

export type DetectedAccessory = {
  id: string;
  name: string;
  isolatedDescription: string;
  recommendedColors: string[];
  approximateBBox?: { x: number; y: number; w: number; h: number };
};

export async function detectAccessories(anchorImageUrl: string): Promise<DetectedAccessory[]>

实现:

  • /responses 端点 + vision inputGPT-4.1-vision 或 gpt-5.5 多模态)
  • 把 L1 锚图作为图像输入
  • prompt = "识别图中玩具身上所有独立配件,输出 JSON 数组,每项包含 name、isolatedDescription、recommendedColors。不包括玩具主体本身。"
  • 严格 JSON 输出

4.2 配件包生成流程重构

1. 调 detectAccessories(L1_anchor) → [帽子, 背包, 标牌, ...]
2. 把每个 accessory 加入 session.characterSpec.accessoriesDetected[]
3. 为每个 accessory 生成 isolated_anchor白底、孤立、单件
   - 走 generateGptImageEdit(L1锚图, "只保留 ${name},其它部分擦除,白底,居中")
4. 每个 accessory 的 6 视图front/back/left/right/top/bottom/perspective
   都基于自己的 isolated_anchor
5. 最后生成 with_doll_assembly参考 L1锚图 + isolated_anchors 组合)

数据模型加:

export type AccessoryGroup = {
  id: string;
  name: string;
  isolatedAnchorUrl: string;
  views: ToyAsset[];  // 6+ 视图
};

export type AssetPack = {
  // ...existing
  accessoryGroups?: AccessoryGroup[];  // 仅 kind === 'accessories' 用
};

阶段 5视频参考一致性

5.1 改 handleGenerateVideopage.tsx

const mktFront = packs
  .find(p => p.kind === 'marketing')?.assets
  .find(a => a.templateId === 'mkt_white_front');
const patentFront = packs
  .find(p => p.kind === 'patent')?.assets
  .find(a => a.templateId === 'patent_front');
const videoAnchor =
  mktFront?.url ??
  patentFront?.url ??
  session.characterSpec?.cleanReferenceImageUrl ??
  image.url;

UI 上视频按钮旁边显示「参考:宣发白底图 / 专利主图 / 意向图」,用户清楚视频基于哪张。

如果宣发主图未生成,按钮可选「强制要求先生成宣发主图」或「使用专利主图」。

阶段 6UI 锚图链可视化

PackPanel 顶部"角色锁定 & 资产清单"卡片下方加一个可视化树:

L0 意向图 ──→ L1 白底锚图 ──┬──→ 专利主图 ──→ 专利右视图 / 左视图 / ...
                              ├──→ 配件锚图 ──→ 帽子 6 视图 / 背包 6 视图
                              ├──→ 宣发白底图 ──→ 视频任务
                              └──→ 生产主图 ──→ 尺寸图 / 拆件图

让用户一眼看到每张图沿用哪张作为基准,重做某个节点会影响下游哪些。

可以用简单的 flexbox 树或 SVG 连线。


4. 实施 Checklist

最小可用版本(先做这 4 项)

  • 1.1 新增 generateGptImageEditmultipart upload
  • 1.2 数据模型加 anchorAssetId / anchorImageUrl / derivationLevel / cleanReferenceImageUrl / anchorTemplateId
  • 1.3 模板加 anchorTemplateId
  • 1.5 generateAssetPack 按拓扑生成、用真图生图
  • 1.4 POST /api/character/cleanup 生成 L1 锚图

单张重做

  • 2.1 POST /api/assets/[assetId]/regenerate
  • 2.2 UI 加重做按钮 + refinement 输入框

风格库

  • 3.1 src/lib/styles.ts + 12-16 张 thumbnailspublic/styles/
  • 3.2 PromptPanel 改成图卡选择器

配件 Vision

  • 4.1 accessoryDetector.ts 用 GPT Vision
  • 4.2 配件包改成「识别 → 孤立锚图 → 6 视图 → 组合图」

视频和可视化

  • 5.1 视频参考切到宣发主图
  • 6.1 PackPanel 加锚图链可视化

5. 关键文件清单

用途 路径
GPT provider src/lib/providers.ts
视频 provider src/lib/videoProviders.ts
包生成主逻辑 src/lib/packGenerator.ts
模板定义 src/lib/templates.ts
类型定义 src/lib/types.ts
存储 src/lib/storage.ts
主页 src/app/page.tsx
输入面板 src/components/PromptPanel.tsx
九宫格 src/components/ResultGrid.tsx
资产面板 src/components/PackPanel.tsx
生图 API src/app/api/generate/route.ts
模板查询 API src/app/api/templates/route.ts
角色锁定 API src/app/api/character/lock/route.ts
单包生成 API src/app/api/packs/generate/route.ts
全包生成 API src/app/api/packs/generate-all/route.ts
视频生成 API src/app/api/video/generate/route.ts

6. 模型/环境变量约定

  • 文本 / 结构化 / VisionOPENAI_API_KEY + GPT_TEXT_MODEL(默认 gpt-5.5
  • 图像生成 / 编辑:OPENAI_API_KEY + GPT_IMAGE_MODEL(默认 gpt-image-2edits 端点可能要 gpt-image-1,按 OpenAI 实际支持调整)
  • 视频:SEEDANCE_API_KEY + SEEDANCE_MODEL(默认 seedance-1-0-pro

重要:本项目"文本 / 图片统一走 GPT 最高规格,视频固定 Seedance"是硬约束。不要引入其他供应商。


7. 验收标准

完成最小可用版本后,应该满足:

  1. 选中意向图 → 锁定 → 自动生成 L1 净化锚图
  2. 生成专利包,主视图基于 L1其它五视图基于专利主图实际传图不是文本 URL
  3. 重做任意一张图UI 显示它的 anchor 是谁,并能单独重做
  4. 风格切换有可视化预览
  5. 配件包能自动识别玩具上有几个配件,分别生成 6 视图
  6. Seedance 视频参考用的是宣发白底图

实测时拿一张复杂玩具图(带帽子、背包、标牌)跑全链路,所有图角色一致、配件清晰、视频与电商图一致。


8. 上传图入口的三种模式(二创 / 复刻 / 复刻+补全)

8.1 场景

用户的实际使用场景不止"从一句话开始",还有:

  • 已经有玩具/IP 图(手稿、成品照、参考海报、其他设计师的稿)
  • 只缺某些视角(手上有正面图,要补侧/背/俯视)
  • 想做风格化变体(已有原型,但要换成赛博朋克版/绒线编织版/迪士尼风)

当前 PromptPanel 是 prompt-first上传图只是被丢进 prompt 末尾当文本提示(见 Gap 1完全没真正参与生成。需要重新设计上传图的语义。

8.2 三种入口模式

Mode A · 二创Remix

用户:[上传图 1-4 张] + [选风格 + 描述变化方向]
系统:保留核心识别(轮廓/五官/品牌符号),按用户要求做风格/材质/配色变化
输出4-12 张候选变体
后续:选中 → Lock → 正常 Pack 流程

技术实现:

  • /images/edits multipart传第 1 张为主参考图
  • prompt 拼接:{风格 promptBlock} + {用户变化描述} + 强制 negative不改变身体比例、五官相对位置、品牌符号、配件轮廓
  • n=4/8/12 生成多张候选

Mode B · 复刻Replicate

用户:[上传图 1 张],标记为"主体图"
系统:跳过批量生图,直接以这张图作为 L0 锚图
       → 立刻做 L1 净化(白底、保真)
       → 调 Vision 识别配件、推断 CharacterSpec
       → 用户确认后进入 Pack
输出:完整专利/配件/生产/宣发包

适用场景:手上已有终稿原画,只需要把它"扩展"成完整素材包。

技术实现:

  • 上传图后跳过 /api/generate,直接构造一个 GenImage 写入 sessionstatus='selected'
  • 自动触发 /api/character/cleanup 生成 L1
  • 自动触发 /api/character/lockCharacterSpec 让 Vision 推断,用户可编辑)
  • 用户点"进入 Pack"才开始 pack 生成

Mode C · 复刻 + 补全Extend

用户:[上传图 1-4 张],每张标记为"主体 / 同角色另一视角 / 配件孤立图"
系统:先把"主体"作为 L0
       已有视角直接占用对应 slot如上传了"正面图" → 占用 patent_front
       缺失的 slot 才调 API 生成
输出:节省 80% 算力,前后一致性最强

适用场景:用户已经手工画了正面+背面,要补侧视图+俯视图+配件六视图。

技术实现:

  • 上传时弹出 tagging UI让用户选每张图的"槽位"
  • 后端在 generateAssetPack 前先合并预占的 slot
  • 已占 slot 跳过 API 调用,直接复用上传图

8.3 UI 入口设计

PromptPanel 改成 3 个 tab

┌─────────────────────────────────────────┐
│ [💡 想法]  [🎨 二创]  [📐 复刻]              │
├─────────────────────────────────────────┤
│ Mode A 二创 tab 内容:                    │
│   - 上传图1-4 张,第 1 张为主参考)        │
│   - 风格选择(图卡,引用 §3 风格库)          │
│   - 变化方向描述textarea                │
│   - 数量 4/8/12                          │
│   - [生成变体]                            │
└─────────────────────────────────────────┘

Mode B 和 Mode C 共享一个 tab差异在上传后的处理

  • 只传 1 张且不标记 → Mode B
  • 传多张并标注槽位 → Mode C

8.4 上传图的元数据(共用)

每张上传图都要附带:

export type UploadedImage = {
  id: string;
  url: string;                  // /api/img/uploads/xxx.png
  filename: string;
  uploadedAt: number;
  role: 'reference'              // 二创模式的灵感图
       | 'subject'               // 复刻模式的主体
       | 'view-front'            // 已有的视角,占用对应 slot
       | 'view-back'
       | 'view-left'
       | 'view-right'
       | 'view-top'
       | 'view-bottom'
       | 'accessory-isolated'    // 配件孤立图
       | 'accessory-named';      // 已命名的配件图
  accessoryName?: string;        // 仅 accessory-* 时有效
  needsCleanup: boolean;         // 是否需要先净化才能用
};

存储路径:data/uploads/

8.5 新增 API

POST /api/uploads
  Body: multipart, image file + role + accessoryName?
  Resp: UploadedImage

POST /api/projects/from-upload
  Body: { uploadedImages: UploadedImage[], mode: 'remix' | 'replicate' | 'extend',
          remixPrompt?: string, styleId?: string, count?: number }
  Resp:
    - mode=remix: { sessionId, images } (4-12 变体)
    - mode=replicate: { sessionId, characterSpec, l1AnchorUrl }
    - mode=extend: { sessionId, characterSpec, l1AnchorUrl, preFilledSlots }

POST /api/character/lock-from-upload
  Body: { sessionId, subjectImageId }
  Resp: 调 Vision 推断 CharacterSpec

8.6 Vision 推断 CharacterSpec

Mode B 和 C 没有原始 prompt需要 GPT Vision 看图推断。

src/lib/providers.ts 新增:

export async function inferCharacterSpecFromImage(opts: {
  imageUrl: string;
  userHint?: string;       // 用户可选输入"这是我的 IP, 名字叫小桔"
}): Promise<CharacterSpec>

实现:

  • /responses + vision input
  • prompt = "你是玩具产品经理,根据图片推断 CharacterSpec。严格 JSON包含 name/oneLiner/speciesShape/bodyRatio/faceFeatures/colorPalette/materials/accessories/signatureElements/patentFocus/negativePrompt 字段"
  • 如果 userHint 有值name 用它,否则让 GPT 生成

8.7 复刻模式的 L1 净化注意事项

复刻模式比"从 prompt 开始"对净化要求更高:不能改任何角色细节

/api/character/cleanup 在复刻模式下要使用更强的约束 prompt

保持原图完全一致,仅做以下修改:
1. 把背景换成纯白色
2. 去除任何水印、文字、价格标签、网页 UI 元素
3. 居中并适当裁剪到正方形构图

绝对不要修改:
- 角色五官、表情、姿态
- 主体配色、材质、纹理
- 配件位置、轮廓、细节
- 任何品牌符号(如胸前 logo

输出风格:商业产品图,柔和均匀打光,无阴影。

可以在 cleanup API 里加 preserveLevel: 'strict' | 'normal' 参数。

8.8 已有视角槽位的智能匹配Mode C

用户上传时标的 role: view-front 等,直接 1:1 占用专利包/配件包的对应模板:

上传 role 占用模板 ID
view-front patent_front + acc_front(如是配件)
view-back patent_back
view-left patent_left
view-right patent_right
view-top patent_top
view-bottom patent_bottom
accessory-isolated 该配件的 isolated_anchor

generateAssetPack 在生成前先检查 session.preFilledSlots已占用的 template 直接复用上传图,不调 API。

8.9 合规和版权提示

UI 上传图区域要醒目提示:

⚠️ 上传图必须为你拥有或有合法授权使用的素材。请勿上传迪士尼、三丽鸥、泡泡玛特等已注册 IP 的图像;生成结果用于专利申请时,需自行确认不与他人在先权利冲突。

后端可选做基础检测:

  • 调 GPT Vision 看图,若识别为已知品牌 IP"Hello Kitty"、"Mickey Mouse"、"Labubu")→ 阻止上传并给出明确警告
  • 这一步初版可不做,但要在 UI 留位

8.10 实施 Checklist 增量

在 §4 Checklist 之外,额外加:

  • 8.A 上传 API + 存储 data/uploads/
  • 8.B PromptPanel 改 3-tab想法 / 二创 / 复刻
  • 8.C Mode A二创multipart + /images/edits 批量变体
  • 8.D Mode B复刻跳过批量生图直接 lock + cleanup
  • 8.E inferCharacterSpecFromImage Vision 推断
  • 8.F Mode C上传图 role 标注 UI + preFilledSlots 合并
  • 8.G cleanup 加 preserveLevel 参数,复刻模式用 strict
  • 8.H 版权合规提示 UI

8.11 优先级建议

最实用顺序:

  1. Mode B 复刻(最常用:用户已有玩具图想做素材包)
  2. Mode A 二创(次常用:用户有概念图想做风格变体)
  3. Mode C 复刻+补全(高级:用户有部分视图想补齐)

如果只做一个,先做 Mode B —— 它对"前后一致"的帮助最直接,相当于直接拿用户图当 L0 锚图,跳过最容易漂移的"prompt → 意向图"阶段。


9. 实例:上传一张 lookbook 整图的工作流

9.1 场景描述

用户拿到一张已经完整的商品 lookbook 图(如 MUSE MATE 街头潮玩公仔的 14 区块大图),里面已经包含核心形象、包装、三视图、细节、场景、配件、社媒图、专利六视图、产品信息等。这是 Mode C 复刻+补全的极端情况——几乎所有 slot 都已经有素材,只需要补少量缺失视角和细节。

9.2 上传图的内容分类(以 MUSE MATE lookbook 为例)

01. 核心形象      → 单只主角图
02. 包装展示      → 礼盒 + 配件平铺
03. 三视图        → Front / Side / Back
04. 细节展示      → 头部 / 滑板 / 卫衣特写 ×4
05. 场景展示      → 涂鸦墙 / 唱片店 / 滑板公园 / 书桌 / 车载 / 包挂 ×6
06. 配件展示      → 帽子 / 耳机 / 滑板 / 喷漆 / 卫衣 / 钥匙扣 / 编号卡 / 贴纸 ×8
07. 可替换造型    → 黑 / 灰 / 橙 / 绿 4 套服饰
08. 灯光效果      → 白光 / 暖光 2 张
09. 证书 + 编号卡 → 收藏卡
10. 社媒展示      → 明星种草 3 张
11. 系列款展示    → 6 个配色变体
12. 专利图纸      → 已完整的六视图
13. 产品信息      → ABS/PVC、高度 12cm、包装尺寸文字
14. 合作流程      → 流程图(非产品素材)

9.3 系统映射表

Lookbook 区块 系统 slot 数量 备注
01 核心形象 L0 主体图 → subject role 1 净化后做 L1 锚图
02 包装 mkt_packaging_render + prod_packaging_structure 2 切出
03 三视图 patent_front / patent_left / patent_back 3 直接占用
04 细节 patent_detail_face + patent_detail_accessory + mkt_detail_face + mkt_detail_material 4 切出
05 场景 mkt_scene_bedroom/desk/gift + 新增「街头 / 车载 / 包挂」slot 6 拓展模板
06 配件 acc_inventory_sheet + 8 个配件孤立锚图 9 触发 8 个 AccessoryGroup
07 服饰变体 新 slotvariant_outfit 4 拓展(系列变体)
08 灯光变体 新 slotvariant_lighting 2 拓展
09 证书卡 新 slotcert_card 1 收藏品需要
10 社媒 mkt_social_vertical 3 占用
11 系列款 新 slotseries_lineup 1 拓展
12 专利六视图 patent_front/back/left/right/top/bottom 6 完全占满
13 产品信息 OCR 后填到 text_production_brief / text_production_cmf - 文字 slot
14 合作流程 忽略 - 非素材

9.4 用户操作流程

1. 上传 lookbook 整图role: 'lookbook-composite'
2. 系统检测到合成图 → 弹出区块切割界面
   - Vision 识别"01."至"14."编号定位分区线
   - 用户可手动调整裁剪框
   - 每块标 role
3. 切完得到 30-40 张独立图,写入 data/uploads/
4. 系统按 role 自动分配 slot
5. 调 Vision 看 L0 + 三视图 + 配件清单 → 自动推断 CharacterSpec
6. 用户进入 PackPanel
   - 已占用 slot 显示 ✓
   - 缺失 slot 显示「待补生成」
7. 用户决定一键补全 / 挑重要 slot 补全

9.5 算力节省

对这张 lookbook 来说:

Pack 全量生成需要 上传图已占 实际需补生成
专利包 12 张 7 张 5 张(右/上/下/立体×2
配件包 9 张(清单)+ 6×8 = 57 张 9 张(清单 + 各 1 视图) ~48 张(每件还缺 5 视图 + 组合图)
生产包 18 张 0 张lookbook 没生产图) 18 张全补
宣发包 22 张 11 张KV/包装/场景/社媒) 11 张
合计 ≈118 张 ≈40 张 ≈82 张

省下约 34% API 调用。更重要的是:用户自己的图是最强 anchor前后一致性最高。

9.6 需要新增的模板 / 数据结构

为支撑 lookbook 场景,建议扩展:

// 新增 role 类型
export type UploadRole =
  | 'subject' | 'reference'
  | 'view-front' | 'view-back' | 'view-left' | 'view-right' | 'view-top' | 'view-bottom'
  | 'accessory-isolated' | 'accessory-named'
  | 'scene-bedroom' | 'scene-desk' | 'scene-gift'
  | 'scene-street' | 'scene-car' | 'scene-bag'    // 新增场景
  | 'detail-face' | 'detail-accessory' | 'detail-material'
  | 'social-vertical' | 'social-square'
  | 'packaging-overview' | 'packaging-structure'
  | 'variant-outfit' | 'variant-lighting'         // 新拓展
  | 'cert-card' | 'series-lineup'                 // 新拓展
  | 'lookbook-composite';                          // 整张 lookbook

新增模板templates.ts 里追加):

  • mkt_scene_street / mkt_scene_car / mkt_scene_bag(场景包补 3 个)
  • variant_outfit_* × 4服饰变体包
  • variant_lighting_white / variant_lighting_warm(灯光变体)
  • cert_card(收藏品类附件)
  • series_lineup(系列陈列图)

新增 API

POST /api/uploads/split-composite
  Body: { uploadedImageId, regions: Array<{ role, bbox, accessoryName? }> }
  Resp: { sessionId, splitImages: UploadedImage[] }

9.7 这个实例对实施顺序的影响

如果用户主要场景是"已有完整或半完整 lookbook",那 §4 实施 Checklist 的优先级应该调整:

  1. 优先做 §8 上传图模式Mode B 复刻)
  2. 其次做 §1 锚图链
  3. 再做 §9 区块切割 + role 标注 + slot 自动占用
  4. 最后做风格库、Vision 配件识别等增强功能

因为 lookbook 用户根本不需要"从 prompt 生意向图",他们要的是"把这套素材合理拆分填进系统,缺什么补什么"。


10. 完整 Agent 编排:从任意输入到完整 lookbook

10.1 目标

用户无论上传什么(一句话 / 单张主角图 / 完整 lookbook 大图 / 几张零碎参考图),系统都能自动跑到同一个终态:一套完整的专利包 + 配件包 + 生产包 + 宣发包 + 视频任务 + 设计说明文字并显式区分「已占用」「AI 补生成」「需人工确认」三种状态。

10.2 三层 Agent 架构

┌──────────────────────────────────────────────────────────┐
│ Orchestrator Agent — 决策总指挥                              │
│  · 决定走哪条路径Mode A/B/C                                │
│  · 调度拓扑生成顺序                                            │
│  · 触发自检 & 重做                                             │
└──────────────────────────────────────────────────────────┘
          │                    │                    │
          ▼                    ▼                    ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ Vision Analyst   │ │ Generation Worker│ │ Quality Checker  │
│  · 识图分类       │ │  · 调 GPT 生图    │ │  · 角色一致性     │
│  · 区块切割       │ │  · 调 Seedance   │ │  · 视角正确性     │
│  · 推断 Spec     │ │  · multipart 上传 │ │  · 风格统一       │
│  · 配件识别       │ │  · 锚图链解析     │ │  · 标红需重做      │
└──────────────────┘ └──────────────────┘ └──────────────────┘

实现层面:

  • 三个 Agent 可以是同一个 GPT 模型不同 prompt
  • 也可以分别用:gpt-5.5-vision 做识图、gpt-image-2 做生图、gpt-5.5 做质检
  • 编排可以用 Vercel AI SDK / LangChain也可以纯 TypeScript 状态机(推荐先用后者,可控性强)

10.3 完整流程状态机

┌────────────────────────────────────────────────────────────┐
│ STATE: idle                                                 │
│   用户输入prompt? upload? both?                            │
└────────────────────────────────────────────────────────────┘
                       ▼
┌────────────────────────────────────────────────────────────┐
│ STATE: input-analysis                                       │
│   Vision Agent 看输入图(如有)                                │
│   输出 InputClassification                                  │
│     { mode: 'prompt-only' | 'single-subject' | 'lookbook'   │
│            | 'multi-reference',                              │
│       blocksDetected?: BlockBBox[],                          │
│       detectedSubject?: SubjectGuess,                        │
│       detectedAccessories?: AccessoryGuess[],                │
│       confidence: 0..1 }                                     │
│   confidence < 0.7 → 询问用户                                 │
└────────────────────────────────────────────────────────────┘
                       ▼
            ┌──────────┴──────────┐
            ▼                     ▼
┌──────────────────┐   ┌──────────────────┐
│ Path A: prompt   │   │ Path B: image    │
│ → 批量生意向图     │   │  ┌──────────────┤
│ → 九宫格筛选      │   │  ▼              │
│ → 选中            │   │ Mode B 单图     │
│                   │   │ Mode C lookbook │
│                   │   │ Mode A multi-ref│
└──────────────────┘   └──────────────────┘
            └──────────┬──────────┘
                       ▼
┌────────────────────────────────────────────────────────────┐
│ STATE: anchor-preparation                                   │
│   · L0 = 选中图或主体图                                       │
│   · L1 = L0 经 cleanup 净化preserveLevel=strict 复刻;      │
│           normal 二创可允许微调)                             │
│   · 若是 lookbook先做区块切割 → slot 自动占用                │
└────────────────────────────────────────────────────────────┘
                       ▼
┌────────────────────────────────────────────────────────────┐
│ STATE: character-inference                                  │
│   Vision Agent 看 L1 + 已占用 slot                            │
│   输出 CharacterSpec含 accessoriesDetected[]              │
│   用户确认/编辑                                               │
└────────────────────────────────────────────────────────────┘
                       ▼
┌────────────────────────────────────────────────────────────┐
│ STATE: pack-generation拓扑                                │
│                                                              │
│   Wave 1并行                                            │
│     · patent_front用 L1                                   │
│     · acc_inventory_sheet用 L1                            │
│     · mkt_white_front用 L1                                │
│                                                              │
│   Wave 2并行                                            │
│     · patent_back/left/right/top/bottom用 patent_front    │
│     · 每个配件 accessory_isolated用 acc_inventory         │
│     · mkt_white_45/back用 mkt_white_front                 │
│     · prod_front_spec/back_spec/...(用 patent_front        │
│                                                              │
│   Wave 3并行                                            │
│     · patent_perspective_front/back / detail_*                │
│     · 每个配件的 6 视图(用对应 accessory_isolated           │
│     · mkt_scene_* / mkt_detail_*                              │
│     · prod_material_board / color_board / part_breakdown      │
│                                                              │
│   Wave 4                                                   │
│     · acc_with_doll_assembly用 L1 + 各 isolated           │
│     · mkt_size_lifestyle / longpage / packaging_render        │
│                                                              │
│   Wave 5                                                   │
│     · 设计说明文字GPT text基于 CharacterSpec + 各 anchor│
│     · 视频任务(用 mkt_white_front                          │
└────────────────────────────────────────────────────────────┘
                       ▼
┌────────────────────────────────────────────────────────────┐
│ STATE: quality-check                                        │
│   Quality Checker Agent 看每张产物                            │
│   对比 anchor → 一致性评分                                    │
│   标记需重做的图(红色)                                       │
└────────────────────────────────────────────────────────────┘
                       ▼
┌────────────────────────────────────────────────────────────┐
│ STATE: review                                               │
│   用户在 PackPanel 看完整产出                                  │
│   每张图状态:✓ 已占用 / ✨ AI 生成 / 🔴 待重做 / ⚠ 需人工确认 │
│   一键重做标红的图 / 手动重做某张                              │
└────────────────────────────────────────────────────────────┘
                       ▼
┌────────────────────────────────────────────────────────────┐
│ STATE: export                                               │
│   导出 ZIP / PDF / manifest.json                             │
└────────────────────────────────────────────────────────────┘

10.4 关键 Agent 函数(不写代码,只列接口)

// === Vision Analyst ===

inferInputClassification(uploads: UploadedImage[], prompt?: string): InputClassification
  // 决定走 prompt / single-subject / lookbook / multi-reference

detectLookbookBlocks(imageUrl: string): BlockBBox[]
  // 返回每个区块的 bbox + 自动建议 role

inferCharacterSpec(anchorImageUrl: string, userHint?: string): CharacterSpec
  // 看图推断完整 CharacterSpec

detectAccessories(anchorImageUrl: string): DetectedAccessory[]
  // 看图识别所有独立配件

// === Generation Worker ===

generateImage({ prompt, anchorBuffer, maskBuffer?, size, negative }): GenImage
  // 真图生图multipart /images/edits

generateText({ prompt, format: 'json' | 'markdown' | 'plain' }): string
  // GPT text

generateVideo({ prompt, anchorImageUrl, duration, ratio }): VideoTask
  // Seedance

// === Quality Checker ===

assessConsistency({ generatedImage, anchorImage }): {
  score: 0..1,                  // 角色一致性评分
  drifts: string[],              // 漂移点说明
  needsRedo: boolean
}

assessViewAccuracy({ image, expectedView: 'front' | 'left' | ... }): {
  score: 0..1,
  notes: string[]
}

// === Orchestrator ===

planTopologicalGeneration(session): GenerationWave[]
  // 计算各 wave 依赖关系

runGenerationLoop(session): AsyncGenerator<ProgressEvent>
  // 跑完整生成 + 自检 + 重试

10.5 Topological Generation 详解

每个 AssetTemplateanchorTemplateId 字段后,可以构建 DAG

type GenerationNode = {
  templateId: string;
  packKind: PackKind;
  dependsOn: string[];          // 上游 templateIds
  alreadySatisfied: boolean;    // 已由上传图占用?
};

function buildDAG(session): GenerationNode[]
function topologicalSort(nodes): GenerationNode[][]   // 分波次

关键:每个 Wave 内的节点可以并行执行concurrency=4 或 8跨 Wave 必须串行(因为下游需要上游图作为 anchor

实测一张主角图全量生成(专利 12 + 配件清单 9 + 配件六视图 48 + 生产 18 + 宣发 22 + 视频 5 = 114 张图)+ 16 段文字,按 5 Wave 并行concurrency=4用时大约

  • Wave 13 张并行 → ~10s
  • Wave 2~20 张并行(分 5 批)→ ~50s
  • Wave 3~70 张并行(分 18 批)→ ~3min
  • Wave 4~10 张 → ~25s
  • Wave 5文字 + 视频提交(视频是异步任务)→ ~30s

总计约 5 分钟出完整 lookbook(视频是异步任务还要等几分钟)。比串行生成(每张 3s × 114 = 5.7min 还要排队)快不少,且一致性最强。

10.6 Quality Check 的具体策略

让 Vision Agent 做 4 项检查:

  1. 角色一致性:把生成图和 L1 锚图拼成一张图,问 GPT "这两张是同一个角色吗?打分 0-1列出差异"
  2. 视角正确性:问 "这张图是正面/左视图/俯视图吗?"
  3. 背景清洁度(专利图必须):问 "是否有水印、文字、场景道具?"
  4. 配件完整性:问 "源图上的 X 配件在这张里是否清晰可见?"

每项分数 < 0.7 → 标红待重做。重做时把上一次的差异点写进 userRefinement 反馈给 prompt

追加约束:上次生成中 ${drifts} 出现问题,本次必须修正。

10.7 UI 上的 Agent 进度展示

PackPanel 顶部加一条生成总进度条

┌─────────────────────────────────────────────────────┐
│ 🤖 Agent 工作中 · Wave 3/5 · 已生成 47/114 张        │
│ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 41%   │
│ 当前批次:配件六视图(帽子/耳机/滑板...              │
│ 已完成自检 ✓ 33 张 · 🔴 待重做 2 张                  │
└─────────────────────────────────────────────────────┘

每个 Pack 内的 AssetRow 显示状态徽章:

  • ✓ 绿色 = 已占用(来自上传图)
  • 紫色 = AI 已生成(通过自检)
  • 🔴 红色 = AI 生成但自检不过,建议重做
  • ⚠ 黄色 = 自检不确定,需人工确认
  • 灰色 = 等待生成

点单张图可看详情:anchor 来源 / prompt / 自检评分 / 漂移点

10.8 Agent 配置(环境变量补充)

# Agent 并发度
AGENT_CONCURRENCY=4               # 单 Wave 并行数
AGENT_MAX_RETRY=2                 # 自检失败最多重试次数
AGENT_AUTO_REDO_THRESHOLD=0.7     # 自检分数低于此值自动重做

# Vision 模型
GPT_VISION_MODEL=gpt-5.5          # 用于识图、自检

10.9 失败恢复

Agent 跑到中途失败API 超时、Key 限流)的处理:

  • 每个 Wave 完成后写一次 session.json 到 data/sessions/
  • Wave 中单张失败 → 标记 status: 'failed',记录错误,不阻塞其它节点
  • 用户刷新页面看到失败的 slot 显示红色,可一键重做
  • 全 Wave 完成后Orchestrator 输出失败摘要

10.10 Agent 输入两种输入的对比

输入 Vision 分析判定 走的路径 实际工作量
一张单主角图(普通玩具照) single-subject Mode B 复刻 L1 净化 → 推断 Spec → 全量补 ~114 张 + 文字
lookbook 大图 lookbook Mode C 拆解+补全 切 30-40 块 → 自动占用 → 补 ~80 张
多张参考图(同一角色多视角) multi-reference 自动分发 + 复刻 已有视角占用 → 补缺失
概念参考 + Prompt multi-reference + prompt Mode A 二创 批量变体 → 选 → 复刻流程
纯文字 prompt prompt-only 原 prompt-first 批量生意向图 → 选 → 复刻流程

无论哪种入口,都最终汇入同一个 anchor-preparation → character-inference → pack-generation 状态机,输出统一

10.11 实施 Checklist 增量(在 §4 和 §8.10 基础上)

  • 10.A 设计 InputClassification + inferInputClassification Vision 调用
  • 10.B 实现 buildDAG + topologicalSort 拓扑生成
  • 10.C 实现 runGenerationLoop 异步生成器emit ProgressEvent
  • 10.D 实现 assessConsistency / assessViewAccuracy 质量检查
  • 10.E PackPanel 顶部加总进度条 + 每张图状态徽章
  • 10.F session.json 增量写入(每 Wave 完成后保存)
  • 10.G 失败恢复 UI红色 slot 一键重做)
  • 10.H 自动重做循环(自检不过 → 加 refinement → 最多重试 N 次)

10.12 推荐实施分期

第 1 期:手动模式跑通(不上 agent

  • 完成 §1真图生图+ §8 Mode B单图复刻+ §9 lookbook 拆解
  • 用户手动点每个包的"生成"按钮
  • 没有自动拓扑、没有自检

第 2 期:拓扑批量生成

  • 完成 §10.5buildDAG + topologicalSort+ §10.CrunGenerationLoop
  • 用户点一次"一键全包"agent 按 wave 并行跑完
  • 还没有自检

第 3 期:自检 + 自动重做

  • 完成 §10.6 + §10.H
  • agent 自检不过的图自动重试 N 次

第 4 期:完全自主 agent

  • 完成 §10.AInputClassification+ 自动路径选择
  • 用户只需上传图,剩下全部 agent 自主完成
  • 用户只看进度条和最终结果

建议:先做完第 1+2 期,能覆盖 80% 场景;第 3+4 期是质量优化和体验升级,可以按用户反馈再迭代。