Files
cmshoppe/docs/tasks/T-637.md
T
chengmaandClaude Fable 5 613950c9f3 docs: simplify T-637 prompt template structure
- drop {分类要求}, {差异化要求}, {分类序号}, {分类总数} placeholders
  and the 商品ID line from the default template
- rename {套图分类} to {套图名称}, add {补充描述} (populated for
  白底图/场景图/卖点图, empty for custom categories)
- remove the now-purposeless 预览第 X 张 stepper; v1 no longer does
  per-image differentiation for same-category multiples
- placeholders 17 -> 14, required 12 -> 9; {商品ID}/{主参考图序号}
  become optional insertable variables
- sync mockup SVG and README

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 15:48:34 +08:00

234 lines
23 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
id: T-637
title: 商品套图提示词设置弹窗与实时最终预览
status: TODO
phase: 7
deps: [T-634, T-636]
created: 2026-07-16
---
# T-637 商品套图提示词设置弹窗与实时最终预览
## 问题 / 背景
⑥「商品套图」当前在「商品卖点与要求」标题行右侧放置「AI 帮写」和运行时「取消」按钮,套图最终提示词则由 `app/product_suite.py::build_suite_prompt()` 硬编码。用户只能填写商品卖点,无法查看或调整平台、分类、比例、参考图及商品一致性等上下文最终如何组合,也无法确认实际提交给 cmhub 的完整提示词。
现有硬编码还存在两个明确缺口:
1. 界面显示的「白底主图,多角度呈现商品细节」等分类说明没有进入生成提示词;
2. 提示词预览若在 GUI 内另写一套拼接逻辑,后续容易与真实生成内容漂移。
(源项目「同一分类多张不做序号与差异化区分、依赖模型随机性」的现象,第一版按用户决定沿用,暂不引入分类内序号、总数和差异化占位符。)
需求是在标题同行调整按钮布局,并增加一个可编辑、可恢复默认、支持占位符插入和实时最终预览的套图提示词设置弹窗。用户原提议入口名为「提示词列表」,但第一版没有多个命名模板或列表选择;为避免名称误导,入口统一使用「提示词设置」。本任务只管理一份全局套图基础模板,不实现多模板 CRUD。
## 目标
1. 将「AI 帮写」移动到「商品卖点与要求」label 右侧,运行时「取消」紧随其后;标题行最右侧增加「提示词设置」。
2. 提供左右等宽的提示词设置弹窗:左侧编辑基础模板,右侧只读预览最终请求,默认预览白底图。
3. 通过受控占位符菜单在光标处插入变量,编辑后实时刷新预览;未知或缺失必需占位符时不能保存。
4. 提示词预览与真实套图生成调用同一个纯逻辑渲染函数,保证所见即所提交。
5. 内置默认模板随安装包发布,用户模板保存到 `data/`;恢复默认不会依赖网络,也不会覆盖其他提示词。
6. 尺寸与长图、禁用内容、价格、尺码等强制规则由代码渲染为**必需只读占位符**内联在模板中(位置对齐调研笔记的组装顺序),用户可移动位置但不能修改内容或删除;商品一致性与不编造约束并入 `{参考图规则}` 渲染文本。
## 实现方案
> 推进顺序建议:先完成纯逻辑(renderer、占位符校验、默认模板、分类说明迁移进 `build_job_specs()`)并测试绿,再动弹窗 GUI,最后补打包断言;避免 20 条验收项一次性集中风险。
### 1. 主界面标题行
- 调整 `ProductSuiteTab._build_prompt_section()` 的标题行顺序:
```text
商品卖点与要求 [AI帮写] [取消] [提示词设置]
```
- 保留现有用户文案「AI帮写」,不改成「AI编写」;保持现有 AI 帮写请求、取消和状态管理不变。
- 「取消」继续只在 AI 帮写运行时显示,必须紧邻「AI帮写」,不能因最右侧新增入口而跳动到无关位置。
- 「提示词设置」放在标题行最右侧,使用次要命令样式;不与底部「生成套图」争夺主按钮层级。
- 在 `1180x760` 和项目支持的最小窗口尺寸下,标题、两个操作入口和运行时取消按钮不得重叠或截断。
### 2. 弹窗布局与交互
- 新增独立 `ProductSuitePromptDialog`(或等价职责清晰的类),不要继续扩张 `ProductSuiteTab` 为一个大方法。
- 弹窗使用可调整的左右分栏,初始比例 `1:1`,设置合理最小尺寸;左侧是可编辑模板,右侧是只读最终提示词预览。
- 第一行从左到右提供:
- 「保存」:校验通过后原子写入用户模板,并显示轻量中文成功提示;
- 「恢复默认」:二次确认后读取安装包内置模板,写盘前先执行与「保存」完全相同的占位符和结构校验——校验失败(打包缺陷、资源损坏)时显示中文错误、不写盘、不改动用户模板和编辑区;校验通过后调用与「保存」完全相同的原子写入服务立即覆盖用户套图模板,成功后同步更新编辑区、预览区和已保存基线,不要求再次点击「保存」。确认弹窗需明示会丢弃编辑区当前未保存修改;恢复或写盘失败时保留原用户模板和当前编辑内容;
- 右侧「预览分类」下拉框:默认选中「白底图」,可切换当前固定分类和当前项目已有自定义分类。
- 左侧编辑区顶部提供「插入变量」菜单或按钮菜单。用户选择变量后,在当前光标位置插入,不要求手工记忆占位符。
- 右侧预览区不可编辑、不可获得保存语义;内容使用当前商品任务的真实平台、地区、语言、比例、分类、参考图序号、商品 ID 和卖点。预览默认使用 `{主参考图序号}`=1;当前值为空时使用明确的中文示例值,内部 `draft_` 标识不得出现在预览中。
- 编辑内容变化后使用约 `200ms` 单次防抖刷新,连续输入不得触发大量重复渲染或造成界面卡顿。
- 关闭存在未保存修改的弹窗时,提供「保存」「不保存」「取消」三种中文选择;保存校验失败时保持弹窗打开。
### 3. 占位符契约
- 第一版只允许以下单层中文占位符,沿用项目现有 `{变量名}` 风格:
```text
{套图名称}
{补充描述}
{平台}
{国家地区}
{输出语言}
{图片比例}
{商品ID}
{主参考图序号}
{参考图规则}
{商品卖点与要求}
{尺寸与长图规则}
{禁用内容规则}
{价格信息规则}
{尺码信息规则}
```
- `{套图名称}`、`{补充描述}`、`{图片比例}`、`{参考图规则}`、`{商品卖点与要求}`、`{尺寸与长图规则}`、`{禁用内容规则}`、`{价格信息规则}`、`{尺码信息规则}`为必需占位符;缺失时预览区显示中文校验结果,「保存」禁用。
- `{套图名称}`为必需,渲染为当前分类名称(固定分类名或自定义分类名),保证分类信息一定进入提示词。
- `{补充描述}`为必需,渲染为该分类的固定说明文本:白底图、场景图、卖点图有对应说明,其他自定义分类渲染为空字符串。它跟随 `{套图名称}` 位于同一行,为空时不产生空行,因此不要求独占一行。
- `{商品ID}`、`{主参考图序号}`为可选占位符:默认模板不含,用户可从「插入变量」菜单插回;不插入不影响保存。
- `{尺寸与长图规则}`、`{禁用内容规则}`、`{价格信息规则}`、`{尺码信息规则}`为**只读规则占位符**:渲染文本由业务常量提供且可能为多行,必须独占一行;用户可在模板中调整其位置,但不能修改渲染内容。
- 未知占位符、未闭合花括号和渲染后仍残留的占位符都视为错误,不得静默原样发送给模型。
- 重复使用合法占位符允许保存;第一版模板**不支持字面花括号**,任何非合法占位符形式的花括号一律校验报错,不定义转义规则,也不做字符串猜测。
- 占位符替换必须使用结构化上下文字典和统一 renderer,不允许在 GUI 中连续手写 `.replace()` 拼接另一套规则。
### 4. 默认模板和分类说明
- 新增安装包内置默认模板,例如 `app/default_prompts/product_suite/base.txt`。行序对齐调研笔记《虾皮圈电商图生成器提示词组装分析》第三节的组装顺序(分类目标 → 平台上下文 → 尺寸/禁用/价格/尺码规则 → 参考图规则 → 用户需求 → 末行比例强调),该结构已被用户验证接受;同时按 cmshopee 当前字段和单参考图事实收口:
```text
套图名称:{套图名称}{补充描述}
平台:{平台};国家地区:{国家地区};输出语言:{输出语言}。
{尺寸与长图规则}
{禁用内容规则}
{价格信息规则}
{尺码信息规则}
{参考图规则}
商品卖点与要求:
{商品卖点与要求}
本次生成比例:{图片比例}。请严格按此比例输出,不能改成其他长宽比。
```
- 与调研笔记源结构一致,比例强调保留在末行(源项目由 worker 二次追加,本版直接写进默认模板,`{图片比例}`为必需占位符保证不丢)。
- `{套图名称}`渲染为当前分类名称;`{补充描述}`渲染为该分类的固定说明,二者位于同一行,例如白底图渲染为「套图名称:白底图,白底主图,多角度呈现商品细节」。`{补充描述}`非空时自带前导分隔符(如「,」)与套图名称衔接,为空时为纯空串。
- 将当前仅存在于 GUI 的固定分类说明迁移或集中到业务层,渲染为 `{补充描述}`;GUI 通过同一来源显示说明,不能复制另一份字典。白底图、场景图、卖点图有对应说明文本,其他自定义分类 `{补充描述}`渲染为空——自定义分类名本身由 `{套图名称}` 带入提示词,不再要求补充描述含名称。
- `{商品ID}`、`{主参考图序号}`保留为合法可插入变量,但默认模板不再单列一行;参考图序号信息由 `{参考图规则}` 渲染文本带出。
- `{参考图规则}`必须与当前实际请求一致。每个 `image_studio_job` 只有一个 `source_asset_id` 时,应明确表述当前图片是本任务唯一主参考图,不得声称未提交的其他图片也参与参考。
### 5. 强制保护规则
- 为对齐调研笔记的组装顺序(规则内联在平台上下文与用户需求之间,而非文末追加),强制规则以**必需只读占位符**呈现,渲染文本由业务常量提供:
- `{尺寸与长图规则}`:最终输出必须严格符合所选比例的单张完整构图电商图,禁止海报长图、详情页长图和多宫格拼接版面。cmhub 尺寸参数已锁定画布比例,此规则真正防的是模型在正确画布内画出详情页式拼接构图;
- `{禁用内容规则}`:禁止国旗、旗帜、国徽、地图轮廓、政治符号或类似国家/地区标识(台湾站高风险项,随包默认启用);
- `{价格信息规则}`:除非用户明确提供价格、折扣或活动价,禁止自行添加价格、币别符号、折扣数字或促销金额;
- `{尺码信息规则}`:除非用户或参考图明确提供尺码、尺寸或规格,禁止自行编造尺码、尺寸、适用身高体重等内容。
- 商品主体一致性与不编造约束并入 `{参考图规则}` 的渲染文本:当前图片为本任务唯一主参考图;保持商品主体、款式、颜色和关键细节准确;不编造用户与参考图均未提供的信息。
- 用户可以在模板中移动规则占位符的位置,但不能修改渲染内容;删除任何一个都会校验失败、「保存」禁用,因此保护规则始终出现在最终提示词中。
- 右侧预览显示规则占位符展开后的完整最终文本,让用户看到真实提交内容;本版**不再有文末统一追加环节**。
- 规则文本应作为业务常量或只读内置资源集中维护,不得分别散落在弹窗、worker 和 `build_suite_prompt()`。
### 6. 持久化、初始化与恢复
- 用户模板建议保存为 `data/prompts/product_suite/base.txt`,路径必须通过 `appconfig` 统一解析,不能依赖当前工作目录。
- 安装包内置模板只读;首次运行仅在用户模板不存在或为空时准备初始化,已有用户模板不得被版本升级静默覆盖。
- 首次初始化写入前必须先读取并执行与「保存」「恢复默认」相同的完整校验:
- 校验通过后才调用统一原子写入服务创建用户模板;
- 内置模板缺失、不可读或校验失败时不得创建空文件、半成品文件或无效用户模板;
- 初始化失败时显示中文错误 `内置套图提示词模板无效,请重新安装软件或联系技术支持。`,并保持商品套图生成不可启动;
- 初始化失败不得修改其他用户提示词、配置、数据库、商品图片或历史任务。
- 扩展现有 `app/prompts.py` 的模板读写能力或增加职责单一的套图提示词模块,复用路径防越界、UTF-8 和文件名安全纪律。
- 保存采用同目录临时文件后原子替换,写入失败时保留原用户模板并给出中文错误。
- 「保存」和「恢复默认」必须调用同一个原子写入服务;统一写盘服务不等于只允许「保存」按钮触发,禁止为恢复默认另写非原子的覆盖路径。
- 「恢复默认」只覆盖商品套图基础模板,不影响②AI生成标题/封面模板、AI工场模板、商品卖点、图片或生成历史。
- 用户模板每次加载后都必须执行与保存前相同的占位符和结构校验,覆盖用户手工编辑文件、文件损坏及未来模板契约升级等情况。
- 用户模板无效时不得静默改用内置默认模板,也不得把残留占位符提交给 cmhub:
- 打开设置弹窗时保留并展示当前无效内容及中文校验错误,允许用户修复或恢复默认;
- 点击「生成套图」时在创建 job、启动 worker 或调用 cmhub 前中止,并提示 `套图提示词模板无效,请在提示词设置中修复或恢复默认。`;
- 中止不得修改用户文件、项目卖点、图片、历史 job 或当前分类设置。
- PyInstaller 构建脚本/spec 必须显式包含内置套图默认模板;开发环境和打包程序使用同一资源读取入口。
### 7. 预览与真实生成共用渲染
- 抽取纯逻辑接口,例如:
```python
render_product_suite_prompt(template_text, context) -> str
```
- `ProductSuitePromptDialog` 只负责组装预览 context 并调用 renderer;`build_job_specs()`/`build_suite_prompt()`也必须调用相同 renderer。
- 点击「生成套图」时只读取一次当前模板,并在建立本轮 job specs 前冻结。生成过程中修改或恢复模板只能影响下一轮,不能改变已经创建或提交的任务。
- 每个 job 继续把最终渲染后的完整提示词保存到 SQLite;历史任务查看、恢复和重试使用原任务快照,不用新模板重算旧任务。
- 预览切换分类只改变预览 context,不修改当前项目分类数量、用户模板或商品卖点。
## 验收标准
- [ ] 「AI帮写」紧邻「商品卖点与要求」,运行时「取消」紧随其后;「提示词设置」位于同行最右侧。
- [ ] 点击「提示词设置」打开左右等宽弹窗,左侧可编辑、右侧只读,默认预览白底图最终提示词。
- [ ] 预览分类下拉可以切换固定分类和当前自定义分类;切换只刷新预览,不修改项目配置。
- [ ] 从「插入变量」菜单选择每个合法变量,都会插入到当前光标位置并在约 200ms 后刷新预览。
- [ ] 当前商品数据完整时,预览正确替换套图名称、补充描述、平台、地区、语言、比例和商品卖点;主参考图序号默认为 1。
- [ ] 临时草稿预览使用 `未绑定商品` 或等价中文值,不显示内部 `draft_` 标识。
- [ ] 删除任一必需占位符(含套图名称、补充描述和四个规则占位符)、输入未知变量、花括号未闭合、规则占位符未独占一行、渲染残留变量时不能保存,并显示中文校验错误。
- [ ] 固定分类(白底图/场景图/卖点图)的补充描述实际进入提示词;自定义分类补充描述渲染为空,但套图名称行仍带出自定义分类名。
- [ ] 参考图规则与实际单个 `source_asset_id` 一致,不声称未提交图片参与参考。
- [ ] 尺寸与长图(禁多宫格拼接)、禁用内容(政治符号)、价格、尺码四条规则和参考图规则携带的商品一致性/不编造约束始终出现在最终预览和真实请求中;规则占位符内容不可编辑,删除任一都无法保存。
- [ ] 默认模板行序与《虾皮圈电商图生成器提示词组装分析》第三节组装顺序一致:套图名称在首行,规则内联在平台行与参考图规则之间,末行为比例强调。
- [ ] 保存后关闭并重启程序仍加载用户模板;已有用户模板不会被启动初始化或软件升级覆盖。
- [ ] 「恢复默认」经确认后通过统一原子写入服务立即落盘,并刷新编辑区和预览;关闭弹窗不再提示该次恢复为未保存修改,且只影响商品套图模板。
- [ ] 「恢复默认」写盘前校验内置模板;内置模板无效时显示中文错误、不写盘、不改动用户模板和编辑区。
- [ ] 弹窗存在未保存修改时关闭会出现保存/不保存/取消三选项,任何失败都不损坏原模板。
- [ ] 同一 context 下右侧预览文本与新建 job 保存的最终 prompt 完全一致。
- [ ] 生成开始后再修改模板不影响本轮已经冻结的 job;历史重试继续使用历史 prompt 快照。
- [ ] 打包程序首次运行能初始化套图默认模板,且用户无需手工创建文件即可打开弹窗和生成。
- [ ] 首次运行时内置模板缺失、不可读或校验失败,不会创建无效用户模板;程序显示指定中文错误,并在创建 job 和调用 cmhub 前阻断生成。
- [ ] 用户手工把模板改成缺失必需变量、未知变量或未闭合花括号后,程序不会崩溃或静默回退;点击生成会在创建 job 和调用 cmhub 前中止,并引导用户修复或恢复默认。
- [ ] `1180x760` 及项目最小窗口尺寸下,标题行和弹窗控件不重叠、文字不截断。
- [ ] SQLite schema、cmhub API、计费、并发、CDP 和③「更新蝦皮」不受影响。
## 测试要求
- 新增纯逻辑测试覆盖全部合法占位符、必需变量(含 `{套图名称}`、`{补充描述}`和四个规则占位符)、未知变量、未闭合/字面花括号报错、任一规则占位符未独占一行报错、重复变量、规则占位符只读渲染和 Unicode 文本。
- 断言最终 prompt 包含禁政治符号与禁多宫格拼接文本,且默认模板渲染结果的行序与调研笔记组装顺序一致、末行为比例强调。
- 覆盖白底图/场景图/卖点图补充描述非空、自定义分类补充描述为空但套图名称带出分类名、正式商品、临时草稿,以及单参考图 context。
- 覆盖用户模板首次初始化、不覆盖已有文件、原子保存失败保持原文件、保存和恢复默认共用写入服务、恢复成功更新已保存基线、内置模板无效时恢复默认报错且不写盘。
- 覆盖首次初始化时内置模板缺失、不可读、缺少必需变量或包含非法占位符,断言不创建用户文件、显示中文错误且生成前中止。
- 覆盖用户文件被外部改成无效模板时的加载校验、弹窗修复入口和生成前中止,断言无 job、worker、cmhub 或文件覆盖副作用。
- `tests/test_product_suite_gui.py` 覆盖标题行按钮顺序、AI 帮写运行时取消按钮、弹窗初始分栏、默认白底图、分类切换、变量插入、防抖刷新、只读预览、保存校验和未保存关闭三选项。
- 覆盖预览 renderer 与 `build_job_specs()` 最终 prompt 相等,以及生成运行中模板变更不污染本轮 job。
- 更新构建测试或脚本断言,确认内置套图模板进入 PyInstaller 数据文件。
## 文档同步
- 实现时同步更新 `docs/04-architecture.md` 的商品套图提示词事实来源、占位符契约、强制规则、模板路径和任务冻结语义。
- 在对应任务执行记录中说明内置模板和用户模板路径;不得修改冻结的 `docs/06-tasks.md`。
## 验证
```bash
py -3.10 -m unittest tests.test_prompts
py -3.10 -m unittest tests.test_product_suite
py -3.10 -m unittest tests.test_product_suite_gui
py -3.10 -m unittest discover -s tests
py -3.10 -m ruff check app tests main.py
py -3.10 -m compileall app main.py
git diff --check
```
## 非目标
- 不实现多个命名套图模板的新增、重命名、删除、排序或导入导出,因此入口不命名为「提示词列表」。
- 不允许用户编辑或移除强制商品一致性和禁止虚构内容规则。
- 不调用 AI 自动改写基础模板,预览不会产生 cmhub 请求或点数消耗。
- 不修改商品卖点 AI 帮写模型、别名、超时、重试或计费。
- 不修改图片生成模型、cmhub submit/poll/download 协议、并发和超时。
- 不修改 SQLite schema、图片目录、CDP、蝦皮主图拉取或③「更新蝦皮」。
- 不在本任务中增加详情图提示词编辑器;第一版只覆盖⑥「商品套图」。
## 执行记录
- 2026-07-16 补:按全栈评审调整规格——`{套图分类}`升为必需占位符;第一版禁止字面花括号(不做转义规则);曾提出「恢复默认」只回填编辑区及预览序号固定值方案,相关两项已被后续补充覆盖;分类总数为 1 时差异化要求退化为空;补充纯逻辑先行的推进顺序建议。
- 2026-07-16 补:修正评审后仍存在的契约缺口——分类序号/总数/差异化要求升为必需变量;预览总数最小为 1,并增加分类内序号步进器;「恢复默认」改为复用统一原子写入服务立即落盘;补充无效用户模板的加载校验和生成前阻断;空行处理限定为只删除空的差异化占位符所在行。
- 2026-07-16 补:封堵两处剩余小洞——「恢复默认」写盘前先校验内置模板,校验失败报错不写盘(防打包缺陷/资源损坏写入坏模板);`{差异化要求}`必须独占一行,校验层强制,杜绝渲染为空时的内联残句。
- 2026-07-16 补:按用户要求把默认模板行序对齐 obsidian《虾皮圈电商图生成器提示词组装分析》第三节的组装顺序(用户接受的结构)——强制规则从「文末代码追加」改为四个必需只读占位符(尺寸与长图/禁用内容/价格/尺码)内联在平台行与参考图规则之间;比例强调移至末行;商品一致性与不编造并入 `{参考图规则}` 渲染文本;占位符总数 13→17,必需 8→12。
- 2026-07-16 补:补齐首次初始化和重复占位符语义——内置模板首次复制前同样必须校验,失败时不创建用户文件并阻断生成;重复 `{差异化要求}`的每次出现都必须独占一行,总数为 1 时定点删除全部对应行;历史执行记录标注已被后续结论覆盖。
- 2026-07-16 简:按用户要求简化模板结构——删除 `{分类要求}`、`{差异化要求}`、`{分类序号}`、`{分类总数}`四个占位符及默认模板中的「商品ID:{商品ID}」行;`{套图分类}`改名为 `{套图名称}`并新增 `{补充描述}`(白底图/场景图/卖点图有说明、自定义分类为空);连带去掉弹窗「预览第 X 张」步进器和同类多张差异化机制(第一版沿用源项目依赖模型随机性区分同类多张);占位符 17→14、必需 12→9;`{商品ID}`、`{主参考图序号}`降为可选可插入变量。