feat: rename bundled cover prompt template
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
商品标题:{新标题}
|
||||
你是一名专业电商主图视觉设计师,请根据“商品标题”和“随请求一起上传的原产品主图”,直接生成一张新的电商商品主图。
|
||||
这张图片主要用于 Shopee / 虾皮手机端商品展示。生成目标是:在严格还原商品本体的基础上,重新设计背景、构图、模特、姿势、光线、道具和排版,生成一张与原图明显不同、但商品一致的全新电商主图,让商品在手机端浏览时清晰、醒目、真实、有购买欲。
|
||||
|
||||
一、【用户可配置字段】
|
||||
商品分类:【可选填写;不填则根据商品标题和原图判断,例如:女装 / 3C配件 / 家居用品 / 母婴用品 / 宠物用品 / 美妆个护 / 小百货;不用可以删除本行】
|
||||
|
||||
目标平台:【默认 Shopee;如不是 Shopee,请改成你的目标平台,例如:Shopee / 淘宝 / 拼多多 / Amazon / 独立站;不用可以删除本行】
|
||||
|
||||
目标地区与语言:【默认台湾地区,繁体中文;如不是台湾地区,请改成你的目标地区和语言,例如:中国台湾,繁体中文 / 马来西亚,中文和英文 / 新加坡,英文 / 泰国,泰文;不用可以删除本行】
|
||||
|
||||
图片比例:【可选填写;不填则根据目标平台和商品类目判断,Shopee 默认优先 1:1,例如:1:1 / 3:4 / 4:5;不用可以删除本行】
|
||||
|
||||
目标人群:【可选填写;不填则根据商品标题、商品分类和原图判断,例如:台湾年轻女生 / 上班族 / 宝妈 / 宠物主人 / 租房人群 / 3C用户;不用可以删除本行】
|
||||
|
||||
候选风格词库:【可选填写;只能从中选择适合当前商品的 1-3 个风格方向,不要全部硬塞,例如:干净质感 / 韩系极简 / 生活场景 / 轻营销 / 高级棚拍 / 科技感 / 居家感 / 可爱风 / 自然光 / 清爽收纳 / 轻奢质感;不用可以删除本行】
|
||||
|
||||
必须保留的信息:【可选填写;填写图片中必须保留的商品特征,例如:保留原图商品颜色、保留包装盒、保留套装数量、保留透明材质、保留拉链设计、保留原图商品角度;不用可以删除本行】
|
||||
|
||||
禁止出现的信息:【可选填写;填写图片中不希望出现的内容,例如:不要出现价格、不要出现折扣、不要出现品牌 Logo、不要出现医疗功效、不要出现模特、不要出现英文、不要改变商品颜色;不用可以删除本行】
|
||||
|
||||
二、【商品输入信息】
|
||||
商品标题:{新标题}
|
||||
商品原图:请参考随请求一起上传的原产品主图。当前上传图片是商品本体的最高优先级参考。
|
||||
三、【生成目标】
|
||||
请直接生成一张新的电商商品主图。
|
||||
生成前先根据商品标题和原产品主图判断商品类目、商品本体、颜色、结构、材质、数量、包装、配件、可见卖点、适合的主图风格、是否需要人物或模特、是否需要少量文字标签、适合的背景和构图。
|
||||
四、【商品还原与画面重构规则】
|
||||
原产品主图只用于识别和还原商品本体,不要复刻原图整体画面。
|
||||
必须保留的是商品本体:商品颜色、款式、版型、结构、领口、袖型、长度、图案、材质质感、包装、数量、配件和其他可见核心特征。
|
||||
可以并且应该重新设计的是非商品元素:背景、场景、光线、构图、拍摄角度、人物长相、人物发型、人物表情、人物姿势、鞋子、包包、手持道具、陈列道具、文字排版和整体氛围。
|
||||
如果商品是服装、鞋包、饰品等模特展示类商品,只参考原图中模特身上的商品本体,不参考原图模特的脸、发型、身材、姿势、表情、鞋子、包包、背景和拍摄构图。请重新生成一个自然真实、适合目标人群的新模特,使用新的姿势、新的表情、新的场景和新的构图来展示同一件商品。
|
||||
如果商品标题和原图发生冲突,商品外观、颜色、结构、数量、款式、包装等视觉信息优先以原图为准,标题只作为类目、用途和卖点理解的辅助信息。
|
||||
不得虚构商品原图和标题中没有的信息。不要编造材质、功能、规格、尺寸、颜色、品牌、认证、功效、适用人群、价格、折扣、销量、排名、平台活动或官方授权。
|
||||
五、【主图风格与构图规则】
|
||||
这不是原图微调,也不是原图局部修复,而是基于原图商品本体重新设计一张新的电商主图。
|
||||
新图必须与原图形成明显差异,至少在以下方面重新设计:背景场景、光线氛围、构图角度、人物姿势、人物表情、画面排版、道具搭配。
|
||||
禁止生成与原图高度相似的图片。不要照搬原图背景,不要照搬原图模特脸,不要照搬原图姿势,不要照搬原图表情,不要照搬原图鞋子和道具,不要只做轻微换背景或局部美化。
|
||||
允许保留的只有商品本体本身,例如服装的款式、颜色、版型、材质、图案和核心设计。其他画面元素都应重新设计,让新主图看起来像同一件商品的全新拍摄图,而不是原图的复制版。
|
||||
如果商品是女装、男装、童装、鞋包、饰品等需要模特展示的商品,可以使用模特展示,但必须重新生成新的模特和新的拍摄画面。
|
||||
模特要求:符合目标地区和目标人群审美,真实自然,不网红化,不夸张摆拍。模特脸部、发型、表情、姿势、鞋子、包包和背景都不要参考原图。只需要让模特穿着与原图一致的商品,展示商品的版型、长度、垂坠感、穿着效果和核心卖点。
|
||||
姿势要求:重新设计自然站姿、微侧身、轻松行走、手拿咖啡、整理衣摆、自然插袋、轻扶包包等适合商品的动作。不要复刻原图姿势。
|
||||
鞋子和配饰:除非鞋子、包包、配饰本身就是商品的一部分,否则不要照搬原图鞋子和配饰,可根据新场景重新搭配简洁、低干扰的鞋包配饰。
|
||||
主图必须适合手机端电商浏览,尤其适合 Shopee 手机端。商品主体要清晰、醒目、居中或位于视觉焦点,缩略图状态下也要让用户一眼看清商品是什么。
|
||||
商品主体永远是画面第一重点,背景、人物、道具、文字都只能服务商品,不能抢商品。根据商品类型自动决定商品占比,但必须保证手机端清晰识别。
|
||||
默认不要使用纯白底,除非目标平台、用户要求或商品特性明显适合白底展示。优先选择干净、低干扰、有质感的背景,例如浅色棚拍背景、柔和渐变背景、极简生活化背景、桌面/台面轻场景、居家轻场景、低饱和场景背景。背景要提升商品质感和点击率,但不能复杂、杂乱或喧宾夺主。
|
||||
如果商品适合人物或模特展示,例如服装、鞋包、饰品、美妆、母婴用品等,可以加入人物或模特,但人物只能用于展示商品效果,不能抢商品主体,不能让脸部、姿势或背景成为主要视觉焦点。如果商品不适合人物展示,不要强行添加人物,改用质感棚拍、轻场景、组合展示或商品特写。
|
||||
整体画面要偏真实电商摄影质感,高清、干净、自然光感、商业感强,避免过度艺术化、过度杂志化、过度夸张营销、低质拼贴感和廉价广告感。
|
||||
六、【图中文字规则】
|
||||
根据商品标题、原图、目标平台和目标地区判断是否需要图中文字。不是所有商品都必须加文字。如果文字不能明显提升点击率,保持干净无文字。
|
||||
如果需要添加文字,只允许加入 1-2 个短卖点或克制的情绪价值词,文字必须真实、简短、清晰,适合手机端阅读。文字区域不超过画面面积的 15%,不得遮挡商品主体和关键细节。
|
||||
图中文字语言必须根据“目标地区与语言”决定;如果用户没有填写,默认使用台湾地区繁体中文。
|
||||
禁止自动生成价格、折扣、销量、排名、限时活动、官方认证、授权标识、医疗疗效、绝对化承诺等不可验证内容,除非这些信息由用户明确提供。
|
||||
七、【品牌、Logo 与平台标识规则】
|
||||
原图中已经存在的真实商品 Logo、包装文字、品牌细节或产品标识,默认作为商品细节保留,除非用户在“禁止出现的信息”中明确要求去掉。
|
||||
禁止新增或虚构品牌 Logo、平台 Logo、官方认证、授权标识、正品标识、奖章图标、销量图标、排行榜图标或任何可能造成侵权和误导的视觉元素。
|
||||
八、【负面约束】
|
||||
不要改变商品本体,不要改变商品颜色,不要改变商品结构,不要增加原图没有的核心商品配件,不要减少原图中的套装数量。
|
||||
不要复刻原图背景,不要复刻原图模特脸,不要复刻原图发型,不要复刻原图姿势,不要复刻原图表情,不要复刻原图鞋子,不要复刻原图包包,不要复刻原图道具,不要复刻原图构图,不要生成与原图几乎一样的画面。
|
||||
不要虚构功能,不要虚构材质,不要虚构品牌,不要生成价格折扣,不要生成销量排名,不要生成夸大功效,不要生成医疗疗效,不要生成虚假认证,不要让背景抢商品,不要让文字遮挡商品,不要让人物抢主体,不要生成低清晰度图片,不要生成畸形人体、畸形手指、错误透视、商品变形、文字乱码、杂乱排版或廉价广告感。
|
||||
九、【最终生成要求】
|
||||
直接生成一张新的电商商品主图,不要生成提示词,不要输出分析过程,不要输出多方案,不要输出解释说明,不要输出文字描述。
|
||||
图片应符合目标平台和图片比例要求,商品真实清晰,主图点击吸引力强,手机端浏览体验好,商品本体还原准确,背景干净有质感,整体适合电商销售使用。
|
||||
@@ -1,36 +0,0 @@
|
||||
商品标题:{新标题}
|
||||
【核心執行指令:韓系極簡大碼電商主圖】
|
||||
|
||||
1. 畫面風格與氛圍 (視覺基調)
|
||||
|
||||
場景化生活感: 捨棄死板的工廠掛拍或雜亂背景,全面升級為「韓系生活氛圍感」的實穿場景。採用高級「韓系極簡風」,以奶茶色調、莫蘭迪色系、鼠尾草綠等低飽和色彩為主。搭配明亮柔和的自然光影,營造輕鬆的日常氛圍(如質感街道、室內一隅)。
|
||||
|
||||
情緒價值: 營造讓買家在 1 秒內產生共鳴的畫面,傳遞「這件衣服適合我、穿起來修身又優雅」的視覺感受。
|
||||
|
||||
2. 模特兒設定與人體結構防錯 (重點規範)
|
||||
|
||||
精準人體結構 (防錯機制): 【最高權重】確保人體骨骼與四肢結構 100% 符合真實人類解剖學。嚴格禁止生成多餘肢體(如三隻手、三條腿、多根手指)、禁止關節扭曲、肢體融合或殘缺。手部抓握物品(如持咖啡杯)的姿勢必須極度自然逼真。
|
||||
|
||||
目標受眾樣貌: 模特兒限定為 30 歲以上及樂齡世代、具備台灣女性氣質的微胖/大碼身形(能完美展現大至 80 公斤身形的自信與修身美感)。
|
||||
|
||||
動態與多樣性: 展現自然微笑與自信優雅姿態,透過不經意的動態(如轉身、微側身)展現衣服垂墜感。臉部樣貌需具備多樣性,絕對避免每次生成同一張臉。
|
||||
|
||||
3. 產品還原與細節保留 (商品核心)
|
||||
|
||||
100% 實物還原: 完美保留原圖衣服的款式、材質與設計亮點(如紫色螺紋花朵刺繡、新中式盤扣、不規則下擺、藍色暈染字母、V領抽繩褶皺等),禁止擅自改變服裝結構,並承襲原圖的靈魂單品搭配(如小棕包、手鐲、項鍊等配件)。
|
||||
|
||||
版面佔比: 服裝必須佔據整體版面 60% 以上。
|
||||
|
||||
4. 排版、文案與浮水印 (後製規範)
|
||||
|
||||
極簡文案: 畫面保持 90% 以上的純淨度。需要添加核心賣點文字,可以根據對應標題獲取核心詞,但絕對不可遮擋服裝細節。
|
||||
|
||||
隱蔽防盜浮水印: 強制在圖片「正左上角」添加「PAPA」浮水印。字體總寬度嚴格限制在圖片總寬度的 5% 以內,透明度絕對鎖定在 3%。確保其極度低調、無侵入性,絕不破壞 4K 高清細節與畫面留白美感。
|
||||
|
||||
5. 輸出與交付標準 (系統設定)
|
||||
|
||||
免選方案直接輸出: 未來的對話中,接收商品圖與標題後,請自動篩選並「直接輸出」最具點擊率潛力的唯一優化主圖,無需提供多種方案挑選。
|
||||
|
||||
規格限制: 輸出為 4K 高清畫質的 JPEG 格式,比例 1:1(建議解析度 1024x1024 或以上),且單張檔案大小不超過 2MB。
|
||||
|
||||
6.圖片展示【台灣出貨】等時效性詞,请设计一个突出,吸睛的标签。
|
||||
@@ -457,7 +457,7 @@ data/images/<batch_id>/<slug>/<task_id>_<item_id>_new.<ext> # AI 生成的新
|
||||
提示词管理:
|
||||
|
||||
- **标题提示词**:`data/title_prompt.txt` 是当前工作文本,「保存标题提示词」写入该文件;软件启动时加载该文件回显到输入框(缺失则空)。标题命名模板另存于 `data/prompts/title/*.txt`,左侧模板行提供下拉、新建、保存模板、另存为、重命名、删除;模板只负责被用户选中后载入编辑框,或把当前编辑框内容保存为命名模板,不改变生成读取路径,也不在启动时覆盖 `title_prompt.txt`。T-549 后标题提示词支持 `{旧标题}` 占位符:若提示词含 `{旧标题}`,生成前替换为该任务旧标题且不再自动追加旧标题块;若不含,则保持旧行为自动追加“旧标题:...”块。两种情况都会保留“请只返回新标题,不要解释。”输出约束。
|
||||
- **封面提示词**:多模板。左侧模板行提供下拉(读 `data/prompts/cover/*.txt`)、新建、保存模板、模板操作(另存为/重命名/删除);重名校验、删除二次确认、删空给默认。
|
||||
- **封面提示词**:多模板。左侧模板行提供下拉(读 `data/prompts/cover/*.txt`)、新建、保存模板、模板操作(另存为/重命名/删除);重名校验、删除二次确认、删空给默认。T-661 后内置首次播种资源为 `app/default_prompts/cover/cover_prompt.txt`,全新用户初始化为 `data/prompts/cover/cover_prompt.txt`,下拉显示 `cover_prompt`;已有任意用户模板(包括历史 `papa1.txt`)不覆盖、不重命名、不迁移。
|
||||
- **商品套图提示词**:单一全局基础模板,用户文件为 `data/prompts/product_suite/base.txt`,内置恢复源为 `app/default_prompts/product_suite/base.txt`。商品套图中的「商品卖点与要求」标题行提供「提示词设置」;弹窗左侧编辑模板、右侧按白底图或其他当前分类只读预览最终请求,默认模板首行是“生成目标:{套图名称},{生成目标}”,编辑使用 200ms 防抖。保存与「恢复默认」共用同一个 UTF-8 原子写入服务;恢复默认会先校验内置资源并经确认立即落盘。用户可移动只读规则占位符位置,但不能修改规则内容或删除必需变量;预览和新 job prompt 必须逐字一致。旧版用户模板中的 `{套图名称}` 与 `{补充描述}` 继续兼容,不被启动升级静默替换。
|
||||
- **变量**:标题提示词本阶段只支持 `{旧标题}`,左侧按钮「插入旧标题」在标题提示词光标处插入 `{旧标题}`。封面提示词支持占位符 `{旧标题}`、`{新标题}`、`{商品id}`、`{店铺}`,生成前用该任务真实值替换(`render_prompt`)。「插入标题」= 在封面提示词光标处插入 `{新标题}`;「预览」= 用某条任务的值替换封面变量后展示,确认实际发送给 AI 的内容。
|
||||
|
||||
|
||||
+1
-1
@@ -358,7 +358,7 @@ render_prompt(template_text, task) -> str
|
||||
- 「插入旧标题」在标题提示词光标处插入 `{旧标题}`;「插入标题」在封面提示词光标处插入 `{新标题}`;「预览」对选中任务调用 `render_prompt` 后展示封面提示词。
|
||||
- 生成封面时 `gen_cover` 的 prompt = `render_prompt(当前封面模板, task)`。
|
||||
- 模板与 `data/title_prompt.txt` 均为可手改的纯文本文件。
|
||||
- `list_cover_templates()` 不会在启动时创建文件;只有保存/新建/另存为才写 `data/prompts/cover/*.txt`。
|
||||
- `list_cover_templates()` 本身不创建文件;②AI生成页调用 `ensure_default_prompts()` 时,封面模板目录为空才将内置 `app/default_prompts/cover/cover_prompt.txt` 播种为 `data/prompts/cover/cover_prompt.txt`。已有任意用户模板(包括历史 `papa1.txt`)不覆盖、不重命名、不迁移。
|
||||
- 模板名不可为空,不允许路径分隔符、`..` 或 Windows 非法文件名字符;重命名时目标重名会报错。
|
||||
|
||||
## 商品套图模块(`app/product_suite.py` + `app/image_studio*.py`,已建)
|
||||
|
||||
+6
-3
@@ -1,7 +1,7 @@
|
||||
---
|
||||
id: T-661
|
||||
title: 图生图内置默认提示词改为 cover_prompt 模板
|
||||
status: TODO
|
||||
status: DONE
|
||||
phase: 7
|
||||
deps: [T-579]
|
||||
created: 2026-07-17
|
||||
@@ -36,7 +36,7 @@ created: 2026-07-17
|
||||
|
||||
## 文档同步
|
||||
|
||||
- 实现时更新 `docs/04-architecture.md`、`docs/api.md` 及 T-579 中与首次播种默认模板相关的当前事实表述。
|
||||
- 实现时更新 `docs/04-architecture.md` 与 `docs/api.md` 中与首次播种默认模板相关的当前事实表述;T-579 保持为历史执行记录,不回写。
|
||||
- 不修改冻结的 `docs/06-tasks.md`。
|
||||
|
||||
## 边界(不改什么)
|
||||
@@ -57,4 +57,7 @@ git diff --check
|
||||
|
||||
## 执行记录
|
||||
|
||||
- 待实现。
|
||||
- 2026-07-17:将提供的 `default_prompts/cover/cover_prompt.txt` 内容复制为正式打包资源 `app/default_prompts/cover/cover_prompt.txt`,SHA-256 一致;移除旧正式资源 `papa1.txt`。
|
||||
- 2026-07-17:默认播种后全新用户目录生成 `data/prompts/cover/cover_prompt.txt`,模板下拉显示 `cover_prompt`;`ensure_default_prompts()` 仍只在封面模板目录为空时播种,历史 `papa1` 和其他用户模板均不覆盖、不重命名、不迁移。
|
||||
- 2026-07-17:更新 prompts、GUI 和 PyInstaller 资源回归测试;同步架构与 API 当前事实。根目录 `default_prompts/` 保持为本次提供的来源,不作为运行时资源或提交内容。
|
||||
- 验证通过:`py -3.10 -m unittest tests.test_prompts tests.test_gui tests.test_packaging`(214 项)、`py -3.10 -m unittest discover -s tests`(592 项)、`py -3.10 -m ruff check app tests main.py`、`py -3.10 -m compileall app main.py`、`git diff --check`。离屏 GUI 测试有 Qt 字体/插件告警,但无测试失败。
|
||||
|
||||
+3
-3
@@ -3290,7 +3290,7 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
["另存为", "重命名", "删除"],
|
||||
[action.text() for action in tab.title_template_actions_menu.actions()],
|
||||
)
|
||||
self.assertEqual("papa1", tab.cover_template_combo.currentText())
|
||||
self.assertEqual("cover_prompt", tab.cover_template_combo.currentText())
|
||||
self.assertIn("商品标题:{新标题}", tab.cover_prompt_edit.toPlainText())
|
||||
self.assertEqual("保存模板", tab.save_cover_template_button.text())
|
||||
self.assertEqual("模板操作", tab.cover_template_actions_button.text())
|
||||
@@ -3934,11 +3934,11 @@ class GuiTests(TempDirMixin, unittest.TestCase):
|
||||
self.addCleanup(tab.close)
|
||||
|
||||
self.assertIn("蝦皮台灣站", tab.title_prompt_edit.toPlainText())
|
||||
self.assertEqual("papa1", tab.cover_template_combo.currentText())
|
||||
self.assertEqual("cover_prompt", tab.cover_template_combo.currentText())
|
||||
self.assertIn("商品标题:{新标题}", tab.cover_prompt_edit.toPlainText())
|
||||
self.assertTrue(os.path.exists(title_prompt_path))
|
||||
self.assertTrue(os.path.exists(os.path.join(title_templates_dir, "默认.txt")))
|
||||
self.assertTrue(os.path.exists(os.path.join(cover_prompts_dir, "papa1.txt")))
|
||||
self.assertTrue(os.path.exists(os.path.join(cover_prompts_dir, "cover_prompt.txt")))
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
|
||||
@@ -32,6 +32,9 @@ class PackagingTests(unittest.TestCase):
|
||||
self.assertIn("datas=default_prompt_datas", normalized)
|
||||
self.assertIn("COLLECT(", spec)
|
||||
self.assertIn('name="cmshopee"', normalized)
|
||||
cover_prompt = self.read_text("app/default_prompts/cover/cover_prompt.txt")
|
||||
self.assertIn("商品标题:{新标题}", cover_prompt)
|
||||
self.assertFalse((REPO_ROOT / "app/default_prompts/cover/papa1.txt").exists())
|
||||
suite_prompt = self.read_text("app/default_prompts/product_suite/base.txt")
|
||||
self.assertIn("生成目标:{套图名称},{生成目标}", suite_prompt)
|
||||
self.assertIn("{生成目标}", suite_prompt)
|
||||
|
||||
+16
-2
@@ -120,10 +120,10 @@ class PromptTests(TempDirMixin, unittest.TestCase):
|
||||
prompts.load_title_prompt(title_path),
|
||||
prompts.load_title_template("默认", title_templates_dir),
|
||||
)
|
||||
self.assertEqual(["papa1"], prompts.list_cover_templates(cover_dir))
|
||||
self.assertEqual(["cover_prompt"], prompts.list_cover_templates(cover_dir))
|
||||
self.assertIn(
|
||||
"商品标题:{新标题}",
|
||||
prompts.load_cover_template("papa1", cover_dir),
|
||||
prompts.load_cover_template("cover_prompt", cover_dir),
|
||||
)
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
@@ -153,6 +153,20 @@ class PromptTests(TempDirMixin, unittest.TestCase):
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_ensure_default_prompts_keeps_legacy_papa1_template_unchanged(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
title_path = os.path.join(temp_dir, "title_prompt.txt")
|
||||
cover_dir = os.path.join(temp_dir, "prompts", "cover")
|
||||
prompts.save_cover_template("papa1", "历史封面提示词", cover_dir)
|
||||
|
||||
prompts.ensure_default_prompts(title_path, cover_dir)
|
||||
|
||||
self.assertEqual(["papa1"], prompts.list_cover_templates(cover_dir))
|
||||
self.assertEqual("历史封面提示词", prompts.load_cover_template("papa1", cover_dir))
|
||||
self.assertFalse(os.path.exists(os.path.join(cover_dir, "cover_prompt.txt")))
|
||||
|
||||
self.assert_removed(temp_dir)
|
||||
|
||||
def test_ensure_default_prompts_accepts_explicit_title_templates_dir(self):
|
||||
with self.make_temp_dir() as temp_dir:
|
||||
title_path = os.path.join(temp_dir, "custom", "title_prompt.txt")
|
||||
|
||||
Reference in New Issue
Block a user