From 56d6b59a00a8c8e6cc69ec38b18dda4d925bec0c Mon Sep 17 00:00:00 2001 From: chengma Date: Fri, 17 Jul 2026 08:48:31 +0800 Subject: [PATCH] docs(task): plan product suite vision AI write --- docs/tasks/T-645.md | 124 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 124 insertions(+) create mode 100644 docs/tasks/T-645.md diff --git a/docs/tasks/T-645.md b/docs/tasks/T-645.md new file mode 100644 index 0000000..44babf5 --- /dev/null +++ b/docs/tasks/T-645.md @@ -0,0 +1,124 @@ +--- +id: T-645 +title: 商品套图AI帮写接入cmhub图片理解 +phase: 7 +deps: [T-637] +status: TODO +created: 2026-07-17 +--- + +## 问题 / 背景 + +⑥「商品套图」的「AI 帮写」当前虽然要求用户先添加至少一张商品原图,但实际只把商品 ID、平台、站点、语言和已有卖点文本传给 `ai.gen_title()`。它调用的是 cmhub 生文别名和标题接口,**不会读取商品图片内容**,因此生成结果无法根据款式、颜色、图中文字和可见细节补全卖点。 + +cmhub 已提供独立的图片理解能力: + +- 能力别名:`vision-standard`; +- 路由:`POST /api/v1/analyze/images`; +- 输入:一张或多张有序本地图片的 base64 数据; +- 输出:完整文字; +- 当前网关实测:单张商品主图可在约44秒内成功返回商品品类、颜色、款式、可见卖点和图中文字,单次扣1点。 + +用户决定将⑥「AI 帮写」改为以 `vision-standard` 理解当前商品原图,再生成可直接编辑的「商品卖点与要求」。②「AI生成」的标题生成仍使用 `title-standard`,商品套图正式生图仍使用 `image-hd` 或⑤设置中的生图别名,三类能力不得混用。 + +## 方案 + +### 1. 新增独立的图片理解客户端 + +修改 `app/ai.py`,新增供⑥使用的公开 helper,例如 `analyze_product_images()`: + +- 仅在 `backend=cmhub` 时调用 cmhub 图片理解接口;不把 `vision-standard` 塞进现有 `gen_title()` 或 `/generate/title` 路径; +- 使用 `POST /api/v1/analyze/images`,请求体固定包含: + - `prompt`:要求模型用当前任务的输出语言,基于图片提炼可用于商品套图生图的商品名称/品类、颜色、款式、可见细节、卖点、目标人群、使用场景和禁用/避免虚构要求; + - `model`:⑤设置保存的 `ai.cmhub.vision_alias`; + - `images`:按用户原图 `source_order` 排序的本地 `image_base64` 数据; + - 可选低随机度参数,确保卖点输出稳定。 +- 成功只返回文本及经过白名单筛选的元数据(别名、扣点、余额、调用 ID);不得返回 API Key、完整请求体、base64 图片、上游 URL 或 Provider 原始响应。 +- 复用既有 cmhub Base URL 规整、Bearer Key、禁用系统代理、连接超时、结构化中文错误和脱敏日志机制;新增 `vision` 操作时,`_cmhub_runtime()` 必须明确映射 `vision_alias`,不能把未知操作静默落到 `image_alias`。 +- 图片理解读取等待单独定义有界超时,默认不少于实测44秒并建议120秒;连接超时继续复用⑤设置的 `connect_timeout`。一次 HTTP 读超时后不自动盲重试,避免用户不确定是否已扣点;由用户再次点击重新发起。 +- 客户端在请求前校验:至少一张本地可用图片、最多8张、单张不超过10MiB、总计不超过32MiB。超过上限时在本地用中文提示,不能先发请求再依赖服务端拒绝。 + +### 2. ⑥「AI 帮写」改为真实读取商品原图 + +修改 `app/gui/tabs/product_suite.py` 和 `app/gui/workers.py`: + +- `start_ai_write()` 从当前任务可用原图中按 `source_order` 取前8张,传给 `ProductSuiteAiWriteWorker`;原图超过8张时状态提示明确「已使用前8张商品原图进行理解」,不静默假装全部使用。 +- 已有「商品卖点与要求」作为补充约束传给视觉提示词,不能被当作图片事实;模型返回内容必须以图片可见信息为主,避免在没有依据时虚构材质、尺寸、功能、认证、价格或物流承诺。 +- `ProductSuiteAiWriteWorker` 调用新的图片理解 helper,成功后沿用现有“用户输入期间有修改则确认是否覆盖”的结果回填逻辑;用户始终可以继续手工编辑。 +- 原图缺失、远程图尚未下载、超过本地大小上限、未配置视觉别名、点数不足、模型不支持视觉、接口超时或上游失败时,保持当前任务和用户已输入卖点不变,显示脱敏中文错误。 +- 运行中保留既有「取消」入口和多任务不阻塞语义。取消只在请求前或请求返回后安全生效;不得强杀网络线程或误报“已取消且未扣点”。 +- 成功状态展示中文摘要,例如「AI帮写完成:已理解3张商品原图,图片理解扣点1,当前余额231」,不展示接口路径、完整提示词、图片路径、API Key 或 Provider 信息。 + +### 3. ⑤设置新增“图片理解别名” + +修改 `app/appconfig.py`、`app/gui/tabs/settings.py` 和 cmhub 模型发现逻辑: + +- `ai.cmhub` 新增 `vision_alias`,新配置默认 `vision-standard`;旧配置缺失该字段时迁移为该默认值,已保存的用户值必须保留。 +- ⑤设置在 cmhub 模型区域新增中文组件「图片理解别名」,与「生文别名」「生图别名」职责并列。 +- 刷新模型时只列出 `operation_type=vision`、`requires_image=true` 且已定价的别名;保留当前保存但暂时不可用的值并显示明确中文状态,避免保存时无声丢失。 +- 保存/生成前校验 `vision_alias`。缺失时提示「请到⑤设置配置图片理解别名」,不能退回 title 或 image 别名。 +- ②标题生成继续只读 `title_alias`,封面和套图生成继续只读 `image_alias`;不要扩大⑤设置的 direct 兼容入口。 + +### 4. 计费、日志与异常语义 + +- 图片理解是一次独立 cmhub 调用,按 cmhub 返回的 `points_cost` / `points_balance` 显示;不把它计入②生文/生图进度,也不写入商品套图正式生成 job。 +- 对网络读超时或客户端连接中断,状态文案必须表达“结果未确认,请先查看点数余额或稍后重试”,不得断言未扣点。 +- 对 cmhub 已返回明确 `upstream_error`、`insufficient_points`、`model_not_allowed`、`no_pricing_rule` 等结构化错误,沿既有中文映射提示,不裸露英文技术信息。 +- 诊断日志可记录耗时、图片张数、别名、扣点、余额和调用 ID;不得记录 base64、完整本地路径、图片 URL、API Key、完整提示词或上游原始响应。 + +### 5. 文档与手工验证 + +同步更新: + +- `docs/04-architecture.md`:⑥AI帮写的视觉理解调用、最多8张本地原图、取消/超时语义和三别名职责; +- `docs/api.md`:客户端对 cmhub `/api/v1/analyze/images` 的请求/响应最小契约和脱敏边界; +- `docs/routes.md`:⑥AI帮写的用户路径、图片数量上限、余额/超时可见状态; +- `docs/cmhub-integration-design.md`:在现有标题/生图/模型发现契约外补充图片理解接口与 `vision_alias`。 + +手工使用当前测试主图验证:请求 `vision-standard` 应返回可读商品理解文本;确认结果不会覆盖用户在请求期间修改的卖点,且在无图、未配置、余额不足、超时和模型不可用时不丢原文本。 + +## 验收要点 + +- [ ] ⑥「AI 帮写」不再调用标题生成接口,而是用 `vision_alias` 调用图片理解接口。 +- [ ] 默认/迁移后的 `vision_alias` 为 `vision-standard`;⑤可刷新和选择视觉能力别名。 +- [ ] `vision_alias` 缺失、不可用或未定价时有明确中文提示,不回退到生文/生图别名。 +- [ ] 1至8张可用本地原图按 `source_order` 发送,超过8张明确提示只使用前8张。 +- [ ] 无本地可用原图、远程图未下载、单图/总大小超限时不发 cmhub 请求且保留用户原卖点。 +- [ ] 返回文本能根据图片提炼商品事实,并保留用户已有要求作为补充约束;用户请求期间编辑文本时仍走确认覆盖。 +- [ ] 成功显示图片张数、扣点和余额;日志、弹窗和状态栏不泄露图片 base64、路径、接口 URL、Key、完整提示词或 Provider 原始响应。 +- [ ] 取消、超时和连接中断不强杀线程、不篡改原卖点、不谎称未扣点。 +- [ ] ②AI生成标题、②生图、⑥正式生成套图、Shopee CDP/更新流程行为不回归。 + +## 测试 + +- `tests/test_ai.py`: + - 图片理解请求使用 `/api/v1/analyze/images`、`vision_alias`、有序 data URL 图片和受限超时; + - 成功响应文本/计费元数据映射; + - 缺少视觉别名、结构化错误、读超时不盲重试、图片数量/大小超限和日志脱敏。 +- `tests/test_appconfig.py` / `tests/test_gui.py`: + - `vision_alias` 默认值、旧配置迁移、保存和模型发现只筛选已定价视觉别名。 +- `tests/test_product_suite_gui.py` / `tests/test_workers.py`: + - AI帮写按原图顺序传入1至8张、超过8张提示、无图不启动 worker; + - 成功回填、用户编辑冲突确认、取消、错误和状态文案; + - 不调用 `ai.gen_title()`,不影响其他套图任务。 +- 运行: + +```bash +py -3.10 -m unittest tests.test_ai tests.test_appconfig tests.test_gui tests.test_product_suite_gui tests.test_workers +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 +``` + +## 边界(不改什么) + +- 不将 `vision-standard` 伪装成标题或生图别名,不改 cmhub 服务端 API、计费规则、上游模型配置或点数余额。 +- 不修改②AI生成的标题/封面调用链、批量进度、重试、SQLite 任务状态或 Excel 回写。 +- 不修改⑥正式套图生图的 job、轮次、历史、终选或导出逻辑。 +- 不修改Shopee页面采集、CDP、标题/封面更新或账号登录流程。 +- 不保存API Key、base64图片、完整图片路径、Cookie、完整提示词或Provider原始响应到版本库、SQLite业务字段或用户可见日志。 + +## 执行记录 + +- 2026-07-17:根据真实 cmhub 网关验证创建任务。`vision-standard` 已出现在模型发现接口中,声明为已定价的独立 `vision` 能力;单张商品主图理解请求成功返回中文商品事实,耗时约44秒、扣1点。待按本任务接入桌面端代码。