Files
cmshoppe/docs/tasks/T-645.md
T

11 KiB
Raw Blame History

id, title, phase, deps, status, created
id title phase deps status created
T-645 商品套图AI帮写接入cmhub图片理解 7
T-637
DONE 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(),不影响其他套图任务。
  • 运行:
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点。待按本任务接入桌面端代码。
  • 2026-07-17:已实现 ai.analyze_product_images(),通过 POST /api/v1/analyze/images 使用独立 vision_alias,请求前校验 1 至 8 张本地原图、单图 10MiB、总计 32MiB,并以 120 秒读取等待和不自动重试处理结果未确认的超时。图片理解的文本与白名单计费元数据由商品套图 AI 帮写 worker 回填,保留已有的用户编辑冲突确认和协作取消语义。
  • 2026-07-17:⑤设置已增加「图片理解别名」并按已定价、需要图片的 vision 模型筛选;旧配置自动补 vision-standard。已同步更新架构、API、路由及 cmhub 集成设计文档。验证通过:py -3.10 -m unittest tests.test_ai tests.test_appconfig tests.test_gui tests.test_product_suite_gui tests.test_workers(318 项)、py -3.10 -m unittest discover -s tests(564 项)、py -3.10 -m ruff check app tests main.py、py -3.10 -m compileall app main.py、git diff --check。