Files
cmshoppe/docs/reviews/2026-06-27-T301-T303-acceptance.md
chengma d0cd408126 docs: 延后Phase4真实冒烟到设置安全开关后
- 新增T-404真实单条更新冒烟任务,并依赖T-501c安全开关

- 新增T-501c Shopee更新安全开关任务,默认关闭真实提交和封面更新

- 补充Phase4验收复核、取消语义、真机冒烟范围和tab策略

- 纳入Phase3/Phase4验收报告并同步current-state与progress
2026-06-27 17:58:08 +08:00

49 lines
4.9 KiB
Markdown
Raw Permalink 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.
# 验收报告 · T-301 ~ T-303(含 T-302p + 采集关页修复)· Phase 3 AI 生成
- 日期:2026-06-27
- 范围:Codex 完成的 Phase 3——T-301 `app/ai.py` 生成接口、T-302 Tab② 左右布局、T-302p `app/prompts.py` 提示词管理、T-303 开始生成(两段并发)+停止+进度;附带修复 e6d7de3(采集后关闭自动新建商品页)
- 评审方式:编译检查 + 单元测试(本机实跑 ai/prompts)+ 逐模块源码阅读 + 对照 `docs/06-tasks.md` 验收要点
- 结论:**通过,质量偏上。AI 接口健壮(脱敏/重试/多 API 形态/两段并发/失败隔离),提示词管理有完整防穿越校验。**
## 一、验证方法与结果
```
python3 -m unittest discover -s tests -p "test_ai.py" # Ran 6 tests, OK(本机实跑)
python3 -m unittest discover -s tests -p "test_prompts.py" # Ran 3 tests, OK(本机实跑)
python3 -m unittest discover -s tests # Ran 53 tests, OK (skipped=2)
```
- 本评审在 WSL 沙箱进行:临时安装 openpyxl + Pillow 后,**ai/prompts 测试本机实跑通过**(含重试、脱敏、jpeg 分辨率/质量、两段并发持久化、失败隔离、停止保持 collected)。
- 仅 PySide6 的 `test_gui`/`test_workers` 在本机 skip;其“绿”以 Codex 在 Windows(`python` = PySide6 6.5.3)的运行为准。
## 二、逐任务核对
| 任务 | 结论 | 关键核对 |
| --- | --- | --- |
| T-301 `ai.py` | ✅ | `gen_title`/`gen_cover` 经 `get_model` 读 `config/ai_models.json` 明文 Key;角色模型校验类别/启用/必填字段;`gen_cover` 支持 `resolution`(512/1k/2k/4k)+`jpg_quality`+Pillow 存盘;`_call_with_retry` 退避重试;错误中文化;`_redact` 把 api_key 从异常/HTTP body 抹成 `***`;兼容两种图像 API(`images_edits` multipart / chat `image_url`),图片提取覆盖 b64/data-url/远程 url 下载 |
| T-302 Tab② 布局 | ✅ | 左提示词(标题/封面多行)、右 批次/店铺/状态 三筛选 + 任务列表(店铺/商品id/旧/新标题/状态);筛选变更即刷新 |
| T-302p `prompts.py`+管理 | ✅ | 标题 `title_prompt.txt` 存/启动回显;封面多模板下拉 + 新建/保存/另存为/重命名/删除(存 `prompts/cover/`,模板名做非法字符 + `.`/`..` + 路径穿越校验、重名保护);「插入标题」插 `{新标题}`;「预览」走 `render_prompt`;`render_prompt` 已接入 `generate_batch` 封面渲染 |
| T-303 开始生成 | ✅ | 单「开始生成」+「停止」+进度 `标题/封面/失败`;`generate_batch` 先 `title_concurrency` 并发标题、再 `image_concurrency` 并发封面;每条封面成功即 `set_generated` 立即写库;停止取消未开始项(ThreadPoolExecutor 语义,符合“可取消未开始项”);双击弹窗左右对照旧/新封面 |
| 修复 e6d7de3 | ✅ | 区分“断开 CDP”与“关闭 target”,采集只关本轮自动新建的商品页,保留用户原有 tab。良好卫生修复 |
## 三、设计上做得好
1. **失败隔离**:某条标题失败→该条不进封面阶段、`mark_failed("generate")` 后其余继续;`summary.ok=False` 但不阻塞(test 实测覆盖)。
2. **脱敏贯穿**:错误信息、HTTP 错误体、URLError 全走 `_redact`,不泄 Key。
3. **两段式并发**严格按文档:标题全部完成→只对成功标题的任务并发生成封面。
## 四、小问题(不影响验收)
1. **标题提示词不做变量替换**:`generate_batch` 把 `title_prompt` 原样喂给 `gen_title`,只有封面提示词走 `render_prompt`。与设计自洽(新标题此时尚不存在,旧标题由 user 消息单独传入),但若用户在标题提示词里写 `{旧标题}` 不会被替换。建议在 Tab② 标题框旁注明“标题提示词不支持变量”,或也接入 `render_prompt`(仅旧标题/商品id/店铺)。
2. `_call_once` 用单一 `timeout=max(connect, read)`(urllib 不分连接/读超时),取最大值合理,但 `connect_timeout_seconds` 语义偏弱。可接受。
3. `_looks_base64` 是启发式判断,已先用 `data:`/`http` 前缀挡掉,误判风险低。
## 五、待办 / 边界
- ⚠️ `gen_title`/`gen_cover` 对真实 AI 服务商仍是 mock(urllib 全程打桩),未真连过一次;`config/ai_models.json` 里的真实 Key 仅本地、gitignore。
- **建议**:进 Phase 4(③ 更新 shopee)前,做一次端到端真机冒烟——账号④登录 → ① 真机采集 1~2 条出图 → ② 用真实模型各生成 1 条标题 + 1 张封面 → 看 `images/<slug>/<id>_new.jpg` 落盘且分辨率/质量正确。这同时验掉之前累计的 CDP + AI 两条未冒烟链路。
## 六、总评
合格偏上的工程交付:ai.py 健壮(脱敏/重试/多 API 形态/两段并发/失败隔离)且本机实测通过,prompts 文件操作有完整防穿越校验,Tab② 提示词管理与生成闭环按文档落地。可推进 Phase 4(T-401 Tab③ 列表 + 筛选 + 开始更新确认弹窗)。