# 生图链路重构交接文档 > 给后续 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` ```typescript 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 block(lighting、composition、color palette、material hint、negative prompt) - 只是简单拼成 `prompt + ", style: 机甲风"` ### Gap 3:所有后续图都参考"最初那张意向图",逐级漂移 **位置**:`src/lib/packGenerator.ts:144` ```typescript 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 直接参考 L0,**6-30 张图相互之间没有锚定,越生越漂**。 ### Gap 4:配件链路是假的 **位置**:`src/lib/packGenerator.ts:36-37` ```typescript 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` ```typescript imageUrl: image.url // 还是那张原始意向图 ``` **问题**:视频里的玩具和已定稿的电商图长得不一样。 **正确做法**:视频参考宣发白底主图(`mkt_white_front`),如果未生成就退到专利主图。 --- ## 3. 实施方案(按依赖顺序) ### 阶段 1:真图生图链路(最高优先级,1+2+3+5 是最小可用版本) #### 1.1 新增 `generateGptImageEdit`(providers.ts) ```typescript export async function generateGptImageEdit(opts: { prompt: string; anchorImage: Buffer | string; // 真实图片字节或本地路径 maskImage?: Buffer; // 可选 mask(局部重绘) size?: '1024x1024' | '1024x1536' | '1536x1024'; }): Promise ``` 实现要点: - 走 `https://api.openai.com/v1/images/edits` - `multipart/form-data`:`image` (Buffer)、`prompt`、`model=gpt-image-1`、`size` - **必须传图字节而不是 URL** - 返回 `b64_json` → 解码为 data URL 保留现有 `generateGptImages` 用于 **L0 意向图阶段**(无锚图,纯文本生图)。 #### 1.2 数据模型扩展(types.ts) ```typescript 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 模板加 anchorTemplateId(templates.ts) ```typescript { 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` - 调 `generateGptImageEdit`,prompt = "保持角色完全一致,把背景换成纯白色,产品居中,无任何文字水印,光线均匀" - 输出图 URL 写回 `session.characterSpec.cleanReferenceImageUrl` #### 1.5 改造 generateAssetPack(packGenerator.ts) ```typescript 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) - 走 `generateGptImageEdit`,prompt 末尾追加 `userRefinement` - 替换原 asset,保留 id 不变 - 更新 session JSON #### 2.2 UI `PackPanel.tsx` 里每个 `AssetRow` 加"重做"按钮和"refinement"输入框。 ### 阶段 3:风格库可视化 #### 3.1 新增 `src/lib/styles.ts` ```typescript 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` 单独传给 provider(GPT image edit 支持 negative) - `recommendedPalette/Materials` 自动填到 CharacterSpec 默认值 ### 阶段 4:配件 Vision 识别 #### 4.1 新增 `src/lib/accessoryDetector.ts` ```typescript 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 ``` 实现: - 走 `/responses` 端点 + vision input(GPT-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 组合) ``` 数据模型加: ```typescript export type AccessoryGroup = { id: string; name: string; isolatedAnchorUrl: string; views: ToyAsset[]; // 6+ 视图 }; export type AssetPack = { // ...existing accessoryGroups?: AccessoryGroup[]; // 仅 kind === 'accessories' 用 }; ``` ### 阶段 5:视频参考一致性 #### 5.1 改 `handleGenerateVideo`(page.tsx) ```typescript 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 上视频按钮旁边显示「参考:宣发白底图 / 专利主图 / 意向图」,用户清楚视频基于哪张。 如果宣发主图未生成,按钮可选「强制要求先生成宣发主图」或「使用专利主图」。 ### 阶段 6:UI 锚图链可视化 `PackPanel` 顶部"角色锁定 & 资产清单"卡片下方加一个可视化树: ``` L0 意向图 ──→ L1 白底锚图 ──┬──→ 专利主图 ──→ 专利右视图 / 左视图 / ... ├──→ 配件锚图 ──→ 帽子 6 视图 / 背包 6 视图 ├──→ 宣发白底图 ──→ 视频任务 └──→ 生产主图 ──→ 尺寸图 / 拆件图 ``` 让用户一眼看到每张图沿用哪张作为基准,重做某个节点会影响下游哪些。 可以用简单的 flexbox 树或 SVG 连线。 --- ## 4. 实施 Checklist ### 最小可用版本(先做这 4 项) - [ ] 1.1 新增 `generateGptImageEdit`(multipart 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 张 thumbnails(`public/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/video/generate/route.ts` | --- ## 6. 模型/环境变量约定 - 文本 / 结构化 / Vision:`OPENAI_API_KEY` + `GPT_TEXT_MODEL`(默认 `gpt-5.5`) - 图像生成 / 编辑:`OPENAI_API_KEY` + `GPT_IMAGE_MODEL`(默认 `gpt-image-2`,edits 端点可能要 `gpt-image-1`,按 OpenAI 实际支持调整) - 视频:`SEEDANCE_API_KEY` + `SEEDANCE_MODEL`(默认 `doubao-seedance-2-0-260128`) **重要**:本项目"文本 / 图片统一走 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` 写入 session,status='selected' - 自动触发 `/api/character/cleanup` 生成 L1 - 自动触发 `/api/character/lock`(CharacterSpec 让 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 上传图的元数据(共用) 每张上传图都要附带: ```typescript 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` 新增: ```typescript export async function inferCharacterSpecFromImage(opts: { imageUrl: string; userHint?: string; // 用户可选输入"这是我的 IP, 名字叫小桔" }): Promise ``` 实现: - 走 `/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 之外,额外加: - [x] 8.A 上传 API + 存储 `data/uploads/` - [x] 8.B `PromptPanel` 改 3-tab:想法 / 二创 / 复刻 - [x] 8.C Mode A(二创):multipart + `/images/edits` 批量变体 - [x] 8.D Mode B(复刻):跳过批量生图,直接 lock + cleanup - [x] 8.E `inferCharacterSpecFromImage` Vision 推断 - [ ] 8.F Mode C:上传图 role 标注 UI + `preFilledSlots` 合并 - [x] 8.G cleanup 加 `preserveLevel` 参数,复刻模式用 strict - [x] 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 服饰变体 | **新 slot:`variant_outfit`** | 4 | 拓展(系列变体) | | 08 灯光变体 | **新 slot:`variant_lighting`** | 2 | 拓展 | | 09 证书卡 | **新 slot:`cert_card`** | 1 | 收藏品需要 | | 10 社媒 | `mkt_social_vertical` | 3 | 占用 | | 11 系列款 | **新 slot:`series_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 场景,建议扩展: ```typescript // 新增 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 函数(不写代码,只列接口) ```typescript // === 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 // 跑完整生成 + 自检 + 重试 ``` ### 10.5 Topological Generation 详解 每个 `AssetTemplate` 加 `anchorTemplateId` 字段后,可以构建 DAG: ```typescript 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 1:3 张并行 → ~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 配置(环境变量补充) ```bash # 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.5(buildDAG + topologicalSort)+ §10.C(runGenerationLoop) - 从专利包开始逐步推进,前一包完成后才允许下一包进入队列 - 不提供"一键全包",避免跳过人工检查和误触高成本生成 **第 3 期:自检 + 自动重做** - 完成 §10.6 + §10.H - agent 自检不过的图自动重试 N 次 **第 4 期:完全自主 agent** - 完成 §10.A(InputClassification)+ 自动路径选择 - 用户只需上传图,剩下全部 agent 自主完成 - 用户只看进度条和最终结果 **建议**:先做完第 1+2 期,能覆盖 80% 场景;第 3+4 期是质量优化和体验升级,可以按用户反馈再迭代。 --- ## 11. 真人模特互动包(Talent Pack) ### 11.1 需求场景 潮玩宣发离不开"真人模特 × 玩具"的内容: - 帅气男孩/漂亮女孩手持玩具的合影 - 模特把玩、拥抱、肩扛玩具的生活方式图 - 短视频:开箱、日常陪伴、Vlog 把玩、自拍展示 - 类似 LABUBU / MOLLY / Sonny Angel 那种小红书爆款图 要求:**尽可能真实**——真人皮肤纹理、自然光、自然表情、玩具材质对、手指抓握自然。 当前系统的 `mkt_scene_*` 只有"玩具放在场景里",**完全没有真人模特出现**。需要把"真人互动"独立成 **Talent Pack(真人互动包)** —— 既不是单纯的宣发图,也不是社媒文案图,而是**模特 + 玩具同框**这一类特殊产物。 ### 11.2 为什么独立成包 | 维度 | 普通宣发图 | 真人互动图 | |---|---|---| | 主体 | 玩具 | 模特 + 玩具 | | 锚图 | 1 张(玩具 L1) | 2 张(模特参考 + 玩具 L1) | | 一致性挑战 | 单角色一致 | 同一模特跨多图一致 + 玩具一致 | | 合规风险 | 低 | 高(肖像权 / 儿童保护) | | 视频生成难度 | 中(玩具旋转/特写) | 高(模特动作 + 玩具互动) | 要素完全不同,必须作为独立 `PackKind: 'talent'`。 ### 11.3 数据模型扩展 ```typescript // types.ts export type PackKind = 'patent' | 'production' | 'marketing' | 'accessories' | 'talent'; export type ModelPersona = { id: string; label: string; // "帅气男孩 · 嘻哈风" category: 'male' | 'female' | 'kid' | 'couple' | 'group'; ageRange: '5-12' | '13-18' | '18-25' | '25-35' | '35-50'; styleTags: string[]; // ['街头', '嘻哈', '复古'] referenceImageUrl: string; // 预生成的合成模特参考图 characterPrompt: string; // 完整 persona prompt block negativePrompt: string; }; export type TalentAsset = ToyAsset & { modelPersonaId: string; // 用了哪个模特 modelAnchorUrl: string; // 该模特的参考图 URL scenarioId: string; // 互动场景模板 ID }; ``` ### 11.4 模特库 ModelPersona 类似风格库,做一组可视化的模特预设。建议初版 10-12 个: | ID | 类型 | 风格定位 | |---|---|---| | `male-street-cool` | 男 / 18-25 | 帅气男孩 · 街头嘻哈 | | `male-creative-warm` | 男 / 25-35 | 温柔创意人 · 治愈 | | `male-business-clean` | 男 / 25-35 | 都市精英 · 简洁 | | `female-cute-soft` | 女 / 18-25 | 治愈系女孩 · 软妹 | | `female-trendy-cool` | 女 / 18-25 | 潮酷女孩 · 街头 | | `female-elegant-fashion` | 女 / 25-35 | 时尚白领 · 优雅 | | `kid-boy-playful` | 童 / 5-12 | 活泼男孩 | | `kid-girl-curious` | 童 / 5-12 | 好奇女孩 | | `couple-young` | 情侣 / 18-25 | 青春情侣 | | `collector-male` | 男 / 25-35 | 潮玩藏家 | | `collector-female` | 女 / 25-35 | 潮玩藏家 | | `office-worker` | 中性 / 25-35 | 办公室桌搭 | 每个 persona 准备: 1. **参考图**(256×256 缩略 + 1024×1024 高清):合法合成肖像(**不能用真实明星**),存 `public/personas/` 2. **`characterPrompt` block**:完整描述脸型 / 发型 / 体型 / 服装 / 气质,给 GPT image-2 用 3. **`negativePrompt`**:明确禁止"识别为某真实明星"、"具体已知 IP 长相" ### 11.5 Talent Pack 模板槽位 新增模板(templates.ts 里加 `TALENT_TEMPLATES`): #### A 单人互动图(每个 persona 一组 6 张) | Template ID | 内容 | 画幅 | |---|---|---| | `talent_portrait_handheld` | 模特正面手持玩具,眼神对镜头 | 4:5 | | `talent_portrait_hug` | 模特怀抱玩具,温柔表情 | 4:5 | | `talent_lifestyle_desk` | 模特在书桌/办公桌前,玩具桌搭 | 4:5 | | `talent_lifestyle_outdoor` | 模特户外手持玩具(街头/咖啡店) | 4:5 | | `talent_selfie_phone` | 自拍式构图,玩具在画面前景 | 9:16 | | `talent_action_play` | 模特正在把玩玩具(互动动作) | 1:1 | #### B 多人/情侣互动图 | Template ID | 内容 | |---|---| | `talent_couple_share` | 情侣共享玩具 | | `talent_group_gift` | 朋友间赠送场景 | | `talent_parent_child` | 亲子陪伴 | #### C 视频脚本 视频走 Seedance,新增视频模板: | Template ID | 内容 | 时长 | |---|---|---| | `video_talent_unbox` | 模特开箱第一视角 | 6-8s | | `video_talent_play` | 模特把玩玩具 | 6s | | `video_talent_daily` | 模特日常带玩具出门 | 8s | | `video_talent_selfie` | 模特自拍 Vlog 展示 | 6s | ### 11.6 生成链路(关键) 真人互动图需要 **双锚图**: ``` 模特参考图(modelPersonaReferenceUrl) + 玩具锚图(L1 净化锚图) ↓ 合成 prompt + 调 GPT image-2 /images/edits ↓ talent_portrait_handheld ↓ (作为后续 talent 图的人物锚) talent_portrait_hug / talent_lifestyle_* (都参考此图保证模特一致) ↓ 视频任务(Seedance)参考 talent_portrait_handheld 当锚帧 ``` 技术实现: 1. **双图输入**:`/images/edits` 端点不原生支持多图,**用 image+mask 方式**或拼成"参考板"再生成 2. **更可靠方案**:先用 GPT-vision 看模特参考图 → 输出详细描述(脸型/发型/眼睛/嘴型),把这段描述拼进 prompt,再加玩具 L1 作为 image input 3. **第二选**:用 OpenAI 的 image-2 multi-image 入参(如果支持),分别标注 `[reference: model]` 和 `[reference: toy]` ### 11.7 模特一致性问题 最棘手:**同一个 persona 在多张图里要长得像同一个人**。 策略: 1. 第一张 `talent_portrait_handheld` 生成后,**它成为该 persona 在本项目的"人物锚图"** 2. 后续所有 talent_* 都把这张作为人物 anchor,玩具仍用 L1 锚 3. 添加更细致的 `characterPrompt`:脸型 / 发型 / 眼距 / 嘴角 / 标志性服饰 4. 用 Quality Checker 跨张比对模特相似度,相似度 < 0.6 标红重做 ### 11.8 真实感提升要点 prompt 模板必须包含的真实感要素: ``` photorealistic, shot on Sony A7IV with 50mm f/1.8 lens, natural daylight, soft shadows, skin texture visible, shallow depth of field, real environment, candid moment, authentic emotion, no AI-art artifacts, no plastic skin, hands holding toy naturally with realistic finger curvature ``` negative: ``` cartoon, anime, 3D render, plastic skin, perfect symmetry, glowing eyes, anime eyes, AI artifacts, deformed hands, extra fingers, distorted toy proportions ``` ### 11.9 合规与肖像权 **严格要求**: 1. **不允许使用真实明星 / 公众人物的样貌** - prompt 不允许包含明星名("长得像 XXX") - Vision Agent 检测生成图,如果识别为已知明星 → 自动拒绝并重做 2. **儿童 persona 需要额外标记** - UI 上显示 "⚠ 儿童形象,请确认有合法授权或仅用于内部参考" - 不允许儿童单独出现的不合适场景 3. **合成模特身份** - 所有生成图导出时 manifest 必须包含 `"talent_disclaimer": "本图模特为 AI 合成,非真实人物"` - 用户使用时需自行决定是否标注 4. **真实模特照片导入** - 如果用户上传自己拍的模特照片作为 reference,UI 要求确认 "我拥有/已获得该模特肖像使用授权" ### 11.10 UI 设计 `PackPanel` 加新的 Talent Pack section,结构和其它包类似但有特殊控件: ``` ┌────────────────────────────────────────────────────┐ │ 👤 真人互动包 · 模特 × 玩具 │ ├────────────────────────────────────────────────────┤ │ Step 1: 选模特类型(可多选) │ │ [🧑‍🎤帅气男孩-嘻哈] [👧治愈系女孩] [👨‍💼都市精英] │ │ [👶活泼男孩] [👩‍🎤潮酷女孩] [...] 共 12 款 │ │ │ │ Step 2: 选互动场景(默认 6 个,可勾选) │ │ [✓] 手持正面 [✓] 怀抱 [ ] 桌搭 │ │ [✓] 户外 [ ] 自拍 [ ] 把玩 │ │ │ │ Step 3: 视频任务(可选) │ │ [ ] 开箱 6s [ ] 把玩 6s [ ] 日常 8s │ │ │ │ [生成 talent pack(4 张 × 选中模特数 + 视频任务)] │ └────────────────────────────────────────────────────┘ ``` 每张生成图显示「模特:xxx」「场景:xxx」「自检评分:0.85 ✓」。 ### 11.11 实施 Checklist 增量 - [ ] 11.A `PackKind` 加 `'talent'`,类型扩展 `ModelPersona` / `TalentAsset` - [ ] 11.B 准备 12 个 ModelPersona + 缩略图(放 `public/personas/`) - [ ] 11.C `TALENT_TEMPLATES` 模板定义(单人 6 + 多人 3 + 视频 4) - [ ] 11.D 双锚图生成函数:`generateTalentImage({ modelPersona, toyAnchorUrl, scenario })` - [ ] 11.E 模特一致性自检(Quality Checker 扩展) - [ ] 11.F UI:模特选择卡片 + 场景勾选 + 进度 - [ ] 11.G 合规模块:明星人脸检测拒绝、儿童形象提示、肖像授权确认 - [ ] 11.H Seedance 视频任务支持 talent 锚图 ### 11.12 优先级建议 `talent` 包属于**第 2 阶段**功能(在主链路打通之后)。原因: - 主体(玩具)一致性都还没解决前,加真人会进一步放大漂移问题 - 必须先有稳定的 L1 锚图 + 真图生图链路(§1) - 视频部分必须有稳定的静态 talent 图作为锚帧 建议实施顺序: 1. 完成 §1(真图生图)+ §8 Mode B(单图复刻) 2. 实现 §11.B(模特库准备)+ §11.D(双锚图生成) 3. 再做视频 talent 任务 如果用户特别强调真人互动,可以**优先做最有传播力的 3 个 slot**: - `talent_portrait_handheld`(小红书爆款基础图) - `talent_lifestyle_outdoor`(生活方式种草) - `video_talent_play`(短视频把玩) 3 个 slot 跑通了,宣发素材就够发一波。