Files
cmshoppe/docs/tasks/T-637.md
T
chengmaandClaude Fable 5 2abde42862 docs(tasks): refine T-637 prompt dialog spec after review
- promote {套图分类} to required placeholder
- forbid literal braces in v1 instead of escape rules
- restore-default only refills editor; disk write goes through save
- pin preview index placeholder values
- degrade differentiation text and collapse blank lines when count is 1
- add pure-logic-first implementation order note

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 14:43:35 +08:00

15 KiB
Raw Blame History

id, title, status, phase, deps, created
id title status phase deps created
T-637 商品套图提示词设置弹窗与实时最终预览 TODO 7
T-634
T-636
2026-07-16

T-637 商品套图提示词设置弹窗与实时最终预览

问题 / 背景

⑥「商品套图」当前在「商品卖点与要求」标题行右侧放置「AI 帮写」和运行时「取消」按钮,套图最终提示词则由 app/product_suite.py::build_suite_prompt() 硬编码。用户只能填写商品卖点,无法查看或调整平台、分类、比例、参考图及商品一致性等上下文最终如何组合,也无法确认实际提交给 cmhub 的完整提示词。

现有硬编码还存在三个明确缺口:

  1. 界面显示的「白底主图,多角度呈现商品细节」等分类说明没有进入生成提示词;
  2. 同一分类生成多张时没有把分类内序号、总数或差异化要求写进提示词,同源同类任务可能使用完全相同的文本;
  3. 提示词预览若在 GUI 内另写一套拼接逻辑,后续容易与真实生成内容漂移。

需求是在标题同行调整按钮布局,并增加一个可编辑、可恢复默认、支持占位符插入和实时最终预览的套图提示词设置弹窗。用户原提议入口名为「提示词列表」,但第一版没有多个命名模板或列表选择;为避免名称误导,入口统一使用「提示词设置」。本任务只管理一份全局套图基础模板,不实现多模板 CRUD。

目标

  1. 将「AI 帮写」移动到「商品卖点与要求」label 右侧,运行时「取消」紧随其后;标题行最右侧增加「提示词设置」。
  2. 提供左右等宽的提示词设置弹窗:左侧编辑基础模板,右侧只读预览最终请求,默认预览白底图。
  3. 通过受控占位符菜单在光标处插入变量,编辑后实时刷新预览;未知或缺失必需占位符时不能保存。
  4. 提示词预览与真实套图生成调用同一个纯逻辑渲染函数,保证所见即所提交。
  5. 内置默认模板随安装包发布,用户模板保存到 data/;恢复默认不会依赖网络,也不会覆盖其他提示词。
  6. 价格、尺码、虚构参数、商品一致性等强制规则由代码追加,用户不能在模板编辑器中删除。

实现方案

推进顺序建议:先完成纯逻辑(renderer、占位符校验、默认模板、分类说明迁移进 build_job_specs())并测试绿,再动弹窗 GUI,最后补打包断言;避免 20 条验收项一次性集中风险。

1. 主界面标题行

  • 调整 ProductSuiteTab._build_prompt_section() 的标题行顺序:

    商品卖点与要求  [AI帮写] [取消]                    [提示词设置]
    
  • 保留现有用户文案「AI帮写」,不改成「AI编写」;保持现有 AI 帮写请求、取消和状态管理不变。

  • 「取消」继续只在 AI 帮写运行时显示,必须紧邻「AI帮写」,不能因最右侧新增入口而跳动到无关位置。

  • 「提示词设置」放在标题行最右侧,使用次要命令样式;不与底部「生成套图」争夺主按钮层级。

  • 在 1180x760 和项目支持的最小窗口尺寸下,标题、两个操作入口和运行时取消按钮不得重叠或截断。

2. 弹窗布局与交互

  • 新增独立 ProductSuitePromptDialog(或等价职责清晰的类),不要继续扩张 ProductSuiteTab 为一个大方法。
  • 弹窗使用可调整的左右分栏,初始比例 1:1,设置合理最小尺寸;左侧是可编辑模板,右侧是只读最终提示词预览。
  • 第一行从左到右提供:
    • 「保存」:校验通过后原子写入用户模板,并显示轻量中文成功提示;
    • 「恢复默认」:二次确认后仅把内置模板回填到编辑区并刷新预览,不直接写盘;确认弹窗需明示会丢弃编辑区当前未保存修改。落盘仍走「保存」,未保存关闭时由统一的三选项流程兜底,保证全程只有「保存」一条原子写盘路径;
    • 右侧「预览分类」下拉框:默认选中「白底图」,可切换当前固定分类和当前项目已有自定义分类。
  • 左侧编辑区顶部提供「插入变量」菜单或按钮菜单。用户选择变量后,在当前光标位置插入,不要求手工记忆占位符。
  • 右侧预览区不可编辑、不可获得保存语义;内容使用当前商品任务的真实平台、地区、语言、比例、商品 ID、分类、参考图序号和卖点。预览的序号类占位符使用固定值:{主参考图序号}=1、{分类序号}=1、{分类总数}=该分类当前配置数量,不随预览分类切换之外的因素变化。当前值为空时使用明确的中文示例值,内部 draft_ 标识不得出现在预览中。
  • 编辑内容变化后使用约 200ms 单次防抖刷新,连续输入不得触发大量重复渲染或造成界面卡顿。
  • 关闭存在未保存修改的弹窗时,提供「保存」「不保存」「取消」三种中文选择;保存校验失败时保持弹窗打开。

3. 占位符契约

  • 第一版只允许以下单层中文占位符,沿用项目现有 {变量名} 风格:

    {分类要求}
    {套图分类}
    {平台}
    {国家地区}
    {输出语言}
    {图片比例}
    {商品ID}
    {主参考图序号}
    {分类序号}
    {分类总数}
    {差异化要求}
    {参考图规则}
    {商品卖点与要求}
    
  • {分类要求}、{套图分类}、{图片比例}、{参考图规则}、{商品卖点与要求}为必需占位符;缺失时预览区显示中文校验结果,「保存」禁用。{套图分类}列为必需是因为固定分类的说明文案不保证包含分类名,删掉后最终提示词可能丢失分类信息。

  • 未知占位符、未闭合花括号和渲染后仍残留的占位符都视为错误,不得静默原样发送给模型。

  • 重复使用合法占位符允许保存;第一版模板不支持字面花括号,任何非合法占位符形式的花括号一律校验报错,不定义转义规则,也不做字符串猜测。

  • 占位符替换必须使用结构化上下文字典和统一 renderer,不允许在 GUI 中连续手写 .replace() 拼接另一套规则。

4. 默认模板和分类要求

  • 新增安装包内置默认模板,例如 app/default_prompts/product_suite/base.txt,结构参考已完成的外部源码调研,但按 cmshopee 当前字段和单参考图事实收口:

    {分类要求}
    平台:{平台};国家地区:{国家地区};输出语言:{输出语言}。
    图片比例:{图片比例}。
    套图分类:{套图分类};当前为本分类第 {分类序号}/{分类总数} 张。
    当前主参考图序号:{主参考图序号}。
    {参考图规则}
    {差异化要求}
    商品ID:{商品ID}
    商品卖点与要求:
    {商品卖点与要求}
    
  • 将当前仅存在于 GUI 的固定分类说明迁移或集中到业务层,渲染为 {分类要求};GUI 通过同一来源显示说明,不能复制另一份字典。

  • 自定义分类的 {分类要求}必须明确包含自定义分类名称,例如「生成商品套图中的『使用方法图』,按照该分类名称表达用途」,不能使用不含分类名的泛化文案。

  • {差异化要求}至少包含分类内序号和“与本分类其他图片采用不同构图、角度或场景”的约束。若第一版没有可靠的商品语义,不自动编造具体卖点、参数或使用场景。

  • 退化规则:分类总数为 1 时 {差异化要求}渲染为空,最终提示词不得出现“与本分类其他图片不同”这类无意义残句;renderer 需折叠占位符独占一行且替换为空后产生的空白行。

  • {参考图规则}必须与当前实际请求一致。每个 image_studio_job 只有一个 source_asset_id 时,应明确表述当前图片是本任务唯一主参考图,不得声称未提交的其他图片也参与参考。

5. 强制保护规则

  • 以下规则不得放入可删除的用户模板中,由业务 renderer 在模板渲染完成后统一追加:
    • 保持商品主体、款式、颜色和关键细节准确;
    • 不添加无依据的功能、参数、认证、价格、折扣或尺码;
    • 用户和参考图均未提供的信息不得自行编造;
    • 项目既有的其他内容安全约束。
  • 右侧预览必须显示「用户模板渲染结果 + 强制保护规则」的完整最终文本,让用户看到真实提交内容。
  • 强制规则应作为业务常量或只读内置资源集中维护,不得分别散落在弹窗、worker 和 build_suite_prompt()。

6. 持久化、初始化与恢复

  • 用户模板建议保存为 data/prompts/product_suite/base.txt,路径必须通过 appconfig 统一解析,不能依赖当前工作目录。
  • 安装包内置模板只读;首次运行仅在用户模板不存在或为空时复制默认值,已有用户模板不得被版本升级静默覆盖。
  • 扩展现有 app/prompts.py 的模板读写能力或增加职责单一的套图提示词模块,复用路径防越界、UTF-8 和文件名安全纪律。
  • 保存采用同目录临时文件后原子替换,写入失败时保留原用户模板并给出中文错误。
  • 「恢复默认」只覆盖商品套图基础模板,不影响②AI生成标题/封面模板、AI工场模板、商品卖点、图片或生成历史。
  • PyInstaller 构建脚本/spec 必须显式包含内置套图默认模板;开发环境和打包程序使用同一资源读取入口。

7. 预览与真实生成共用渲染

  • 抽取纯逻辑接口,例如:

    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 后刷新预览。
  • 当前商品数据完整时,预览正确替换平台、地区、语言、比例、商品 ID 和商品卖点;序号类占位符按约定固定为主参考图序号 1、分类序号 1/该分类配置总数。
  • 临时草稿预览使用 未绑定商品 或等价中文值,不显示内部 draft_ 标识。
  • 删除必需占位符、输入未知变量、花括号未闭合或渲染残留变量时不能保存,并显示中文校验错误。
  • 固定分类说明实际进入提示词;自定义分类提示词明确包含自定义分类名称。
  • 同一分类多张任务的最终提示词包含各自序号/总数和差异化要求,不再完全相同。
  • 分类总数为 1 时,该分类最终提示词不含差异化残句,也不留悬空空行。
  • 参考图规则与实际单个 source_asset_id 一致,不声称未提交图片参与参考。
  • 强制商品一致性、禁止虚构参数/价格/尺码等规则始终出现在最终预览和真实请求中,用户不能从编辑器删除。
  • 保存后关闭并重启程序仍加载用户模板;已有用户模板不会被启动初始化或软件升级覆盖。
  • 「恢复默认」经确认后回填编辑区并刷新预览,不直接写盘;经「保存」后才落盘,且只影响商品套图模板。
  • 弹窗存在未保存修改时关闭会出现保存/不保存/取消三选项,任何失败都不损坏原模板。
  • 同一 context 下右侧预览文本与新建 job 保存的最终 prompt 完全一致。
  • 生成开始后再修改模板不影响本轮已经冻结的 job;历史重试继续使用历史 prompt 快照。
  • 打包程序首次运行能初始化套图默认模板,且用户无需手工创建文件即可打开弹窗和生成。
  • 1180x760 及项目最小窗口尺寸下,标题行和弹窗控件不重叠、文字不截断。
  • SQLite schema、cmhub API、计费、并发、CDP 和③「更新蝦皮」不受影响。

测试要求

  • 新增纯逻辑测试覆盖全部合法占位符、必需变量(含 {套图分类})、未知变量、未闭合/字面花括号报错、重复变量、强制规则追加和 Unicode 文本。
  • 覆盖白底图、其他固定分类、自定义分类、正式商品、临时草稿、分类多张、分类总数为 1 的差异化退化与空行折叠,以及单参考图 context。
  • 覆盖用户模板首次初始化、不覆盖已有文件、原子保存失败保持原文件和恢复默认。
  • tests/test_product_suite_gui.py 覆盖标题行按钮顺序、AI 帮写运行时取消按钮、弹窗初始分栏、默认白底图、分类切换、变量插入、防抖刷新、只读预览、保存校验和未保存关闭三选项。
  • 覆盖预览 renderer 与 build_job_specs() 最终 prompt 相等,以及生成运行中模板变更不污染本轮 job。
  • 更新构建测试或脚本断言,确认内置套图模板进入 PyInstaller 数据文件。

文档同步

  • 实现时同步更新 docs/04-architecture.md 的商品套图提示词事实来源、占位符契约、强制规则、模板路径和任务冻结语义。
  • 在对应任务执行记录中说明内置模板和用户模板路径;不得修改冻结的 docs/06-tasks.md。

验证

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 时差异化要求退化为空并折叠空行;补充纯逻辑先行的推进顺序建议。
  • 待实现。