v92-v105 多国适配 + 模板导出增强 + 生图可靠性优化

- 新增韩国(KR)适配:countries/pinterest 种子词、K-pop 提示词、UI 国家列表
- 爬虫跨运行持久化已采集 URL(.collected_urls.json),同关键词重复搜索采新图
- 模板导出增强:SPU 商品属性列名前缀剥离匹配、尺码下拉框 INDIRECT 动态引用、
  SPU 字段映射(袖长/门襟/胸垫等)、季节/印花图案女装映射、建议售价统一必填、
  SKU 分类/数量/单位直接填默认值
- 自定义模式:多模态提示词独立(custom_analyze_*)、生图提示词模板可配置
- Pinterest:空选品守卫、连续空分析保护(max_empty_analyze)、flat_prompt 配置覆盖
- 生图可靠性:开始/完成进度日志、异步任务轮询超时 60s→300s
This commit is contained in:
2026-08-31 18:35:51 +08:00
parent 71a48e4ed5
commit 3dc594cf57
29 changed files with 1369 additions and 321 deletions
+44 -6
View File
@@ -1,6 +1,6 @@
# POD 热点抓取 AgentLangGraph 工程化版)
自动抓取海外各国(US / GB / JP / AU / MX / DE / BR / SA / PL / ES / IT / CA)实时热点 + 风格趋势,
自动抓取海外各国(US / GB / JP / AU / MX / DE / BR / SA / PL / ES / IT / CA / KR)实时热点 + 风格趋势,
过滤侵权风险,产出可直接用于 AI 生图的印花设计提示词,并完成 **设计稿 → 三合一模特试穿 → OSS 图床 →
种草图 → 商品上传模板** 的完整 POD 生产链路。本版本用 **LangGraph** 重写,强调**工程化、节点兜底、可插拔**。
@@ -61,7 +61,8 @@ START → pinterest_init → pinterest_search → pinterest_scrape → pinterest
**并发控制**`config.yaml``pinterest:`):`analyze_concurrency`(分析线程数)、`analyze_batch`
(每轮取图数,0=自动补齐让 pipeline 队列满并发)、`max_designs`(每搜索词简报上限)、
`scrape_concurrency`(爬图并发,必须=1)、`err400_limit`400 超限放弃当前种子词)
`scrape_concurrency`(爬图并发,必须=1)、`err400_limit`400 超限放弃当前种子词)
`max_empty_analyze`(连续空分析轮次上限,0=自动)。
**每个节点都用 `graph/validate.with_fallback` 包裹**:任何未预料异常都被捕获、记入
`state['errors']`、返回最小更新,整图继续往下走,单点故障不中断流水线。致命图像服务错误(503 /
@@ -97,6 +98,14 @@ START → pinterest_init → pinterest_custom_load → pinterest_analyze
保证用户每次重新上传/选择的所有有效图片都会被重新多模态分析;分析批上限按「选品清单总数」截断,
避免对多余图片浪费配额。`pinterest_custom_route` 只在 wait / analyze / done 间流转,从不 search。
**自定义模式提示词独立**
- **多模态分析提示词**`prompts/custom_analyze_system.md` / `prompts/custom_analyze_user.md`
(与 Pinterest 模式的 `pinterest_analyze_*` 完全独立,互不影响);
- **生图提示词模板**`config.yaml``custom.prompt_pieces``image_prompt_template` /
`negative_prompt`)可编辑——以参考图片的整体氛围/主题/时代/风格类型为灵感,**明确禁止复制或模仿**
参考图片的印刷 artwork、角色、布局、文字及服装/模特等元素,仅基于观察到的主题/技术/调色板/布局
生成新设计;留空回退代码内置 `CUSTOM_IMAGE_PROMPT_TEMPLATE` / `CUSTOM_NEGATIVE_PROMPT`
## 目录结构
```
@@ -105,7 +114,7 @@ pod_trend_agent/
├── ui_app.py # 桌面 UITkinter
├── config.yaml # 全局配置(数据源、权重、黑名单、LLM、模板、compose/product/oss/seed_shot
├── configs/
│ ├── countries/ # 各国 Google Trends 种子词(US|GB|JP|AU|MX|DE|BR|SA|PL|ES|IT|CA.yaml
│ ├── countries/ # 各国 Google Trends 种子词(US|GB|JP|AU|MX|DE|BR|SA|PL|ES|IT|CA|KR.yaml
│ ├── pinterest/ # 各国 Pinterest 种子词池(<CC>.yaml
│ ├── model_features.yaml # 模特特征库(按性别分组 female/male,种草图用)
│ ├── seed_shot_templates.yaml # 种草图提示词模板
@@ -115,6 +124,8 @@ pod_trend_agent/
│ └── aesthetics.yaml # 审美 hint + 风格-配色 extra 规则 + 额外黑名单
├── prompts/pinterest_analyze_system.md # 多模态分析系统提示词(Pinterest/自定义模式),可配置
├── prompts/pinterest_analyze_user.md # 多模态分析用户提示词,可配置
├── prompts/custom_analyze_system.md # 自定义模式多模态分析系统提示词(独立于 Pinterest)
├── prompts/custom_analyze_user.md # 自定义模式多模态分析用户提示词(独立于 Pinterest)
├── graph/
│ ├── state.py # AgentState(共享状态)
│ ├── validate.py # with_fallback 兜底 + 数据校验
@@ -142,7 +153,7 @@ pod_trend_agent/
├── basemap/ # 平铺衣服底图(<款号>/<SKU.code>/
├── material_library/ # 模特图(<品类>/
├── db/spu_sku.db # SPU/SKU 数据库
├── pinterest_scraper/ # Playwright 爬虫 + Chrome 登录态
├── pinterest_scraper/ # Playwright 爬虫 + Chrome 登录态(含跨运行持久化 .collected_urls.json
└── output/<country>/ # ★ 每个国家的产物独立文件夹
├── design_briefs.json/md # 设计简报(含 image_prompt / composite_prompt
├── designs/ # 纯印花设计稿
@@ -156,6 +167,9 @@ pod_trend_agent/
2. **按需搜索**:每次只生成 1 个搜索词(`search_terms_per_run=1`),自动追加「 t-shirt design」后缀
(保证爬到的图是真实印花艺术,而非生活方式/风景图);爬取成功才标记已用,失败不拉黑。
3. **爬图**Playwright 打开 Pinterest 搜索页截图采集(共享 `.chrome_session` 登录态,并发强制=1)。
每个关键词维护**跨运行持久化已采集 URL 集合**(`save_dir/.collected_urls.json`):滚动采集时跳过
历史 URL 旧图(不计入 count),继续下拉直至凑满新图或滚动到底(连续 10 轮无新图停止)——同一关键词
重复搜索也能采到新图,而非永远返回顶部旧图。
4. **图池 + MD5 去重**:图片注册 `image_pool.json`;分析过的 md5 一律拉黑(`used_images.json`);
设计稿生成后全局 MD5 去重(`.cache/global_design_md5.json`),跨国家生效。
5. **多模态分析**:大图先压缩(max 1024px / 1.5MB)再送 LLM,产出原创设计简报(motif/风格/配色/构图 +
@@ -166,6 +180,11 @@ pod_trend_agent/
生成 设计稿 → 三合一 → OSS 上传 → 种草图,边分析边生成,不等全部分析完。
每完成一个产品立即追加落盘到 `output/<country>/<ts>/products_pending.jsonl`(中断/崩溃也不丢已
完成产品),全部完成后统一合并写模板。
7. **空选品守卫**:任务清单(`self._tasks`)为空时直接弹窗拦截并提示「请先添加选品(款号 → 颜色 →
+添加选品)」;`run_pinterest_pipeline` 也有空选品守卫,即使绕过 UI 直接调用也会拒绝启动。
8. **连续空分析保护**:图片分析连续多轮无新增简报(分析失败 / 图片均不适合印花)时,达到
`pinterest.max_empty_analyze` 上限(0=自动:目标 SPU 数+2,至少 3)即终止分析直接收尾,
避免「逐一取下一张参考图」式无限空转。
## 多模态分析提示词(可配置)
@@ -182,7 +201,8 @@ Pinterest 参考模式与自定义图片模式的多模态分析提示词已**
3. 内置默认常量(兜底,向前兼容)。
直接编辑这两份文件即可自定义分析与生图引导规则;`pinterest_analyze_system.md` 里可调整
`image_prompt` 二段式结构 / `negative_prompt` / `suitable_for_print` 判定标准等约束
`image_prompt` 二段式结构 / `suitable_for_print` 判定标准等约束(多模态分析不再产出
`negative_prompt`,生图负向约束由固定 `print_suffix` 承担)。
## 生成可靠性 / 错误处理
@@ -192,6 +212,10 @@ Pinterest 参考模式与自定义图片模式的多模态分析提示词已**
- **图像 API 重试退避**`graph/backends/openai_image_backend.py`):429 尊重网关 `Retry-After`
头,否则指数退避;5xx500/502/503/504 超时)与网关空响应(JSON 解析失败)均退避 3/6/9s 重试、
最多 3 次,避免空响应/超时风暴触发限流。
- **生图进度日志**:每次生图调用提交前打印 `[img] 开始图生图/文生图(模型,尺寸,参考图 N 张)→ 文件名`
保存后打印 `[img] 已生成(耗时 Xs`——同步成功不再静默,UI 日志区能实时看到生图进度,避免"看起来卡死"。
- **异步任务轮询超时**`_wait_task` 轮询超时 60s → 300s(与提交请求 timeout 一致)。网关异步任务实际
需 30s~6 分钟(设计稿/三图合成),60s 轮询超时会把仍在处理中的任务误判为失败而重复提交,白白消耗配额和时间。
- **yunfei / 标准 OpenAI 网关适配**`compose.execution_mode``background` 参数默认不再传入——
yunfei 等网关不认识它们会返回空 body;`base_url` 需带 `/v1` 前缀(如
`https://img.yunfei.best/v1`),否则请求错误路径得到空响应。
@@ -200,6 +224,8 @@ Pinterest 参考模式与自定义图片模式的多模态分析提示词已**
两种模式统一走该映射:在「有图的文件夹」间按**任务序号**独立随机抽图,抽到模特图用模特三图提示词
(图1模特+图2印花+图3底图),抽到平铺图用平铺三图提示词(图1平铺实拍+图2印花+图3底图)。
同一 SPU 的多款不再共用同一张图;某类目录无图则只用另一类。每张种草图随机取不同模特特征。
**合成提示词可配置覆盖**`mark_dirs` 下配置 `flat_prompt` / `model_prompt` 时优先生效
`product_node._active_prompt`),留空才回退内置 `FLAT_LAY_PROMPT` / `MODEL_WEAR_PROMPT`
## 模特性别分组
@@ -234,7 +260,19 @@ Pinterest 参考模式与自定义图片模式的多模态分析提示词已**
- **申报价格**:模糊匹配所有含「申报价格」的列,统一按加价后价格填写(`price × (1+markup_percent%)`);
- **款式来源**:SPU 行「款式来源」统一填「现货款」;
- **商品产地**:所有国家统一填「中国大陆」;新增「产地省份」精确匹配列,统一填「广东省」(不再读站点/做字典映射);
- **SKU 分类 / SKU 数量 / SKU 数量单位**按「建议售价」同一套路检测——关键词模糊匹配定位列,读取列头下一行备注判断是否必填(含「非必填」才跳过),检测到且为必填时统一填固定值:`SKU分类=单品``SKU数量=1``SKU数量单位=件`
- **SKU 分类 / SKU 数量 / SKU 数量单位**模板检测到这些列即统一填固定值(不再检测「非必填」备注):
`SKU分类=单品``SKU数量=1``SKU数量单位=件`
- **建议售价 / 建议售价单位**:模板存在对应列且 `suggested_price_ratio > 0` 时统一必填——
建议售价 = 申报价格 ×(1+比例%),单位统一填 `CNY`(不再检测模板备注);
- **SPU 商品属性列名兼容**`resolve_col` 支持「SPU商品属性-袖型」前缀剥离匹配——列名带前缀的模板
(如沙特女装模板)精确匹配,列名不带前缀的模板(如黑白CasualNest Shop)自动剥离前缀后匹配;
- **尺码下拉框动态引用**`_read_size_options` 识别 `INDIRECT(...)` 动态引用公式,能解析则按下拉选项
过滤 SKU 行(尺码不在下拉内跳过),无法解析(空单元格/跨表)时返回 None 不启用过滤,避免误杀全部 SKU 行;
- **SPU 商品属性字段映射**`placket_type→门襟类型``sleeve_type→袖型``sleeve_length_type→袖长`
`breast_pad→胸垫``layout→版型``silhouette→廓形``length_type→长度``belt→腰带`
`occasion→场合``scene→场景``hemline_shape→下摆形状`,各字段独立不覆盖;
- **季节映射(女装)**`spu.season` 的「四季」→「ALL/全球/所有」(`config.yaml``season_map.female` 可配置);
- **印花图案映射(女装)**`spu.pattern` 为「印花」时 →「卡通」(`pattern_map` 可配置);
- **详情图文**:由全部主图 + 种草图组成(不再拼接 img_url_2);
- 规格类型2 = `{size}*{color}`;币种=CNY;发货仓1~N 取模板顶头按「、」分隔,库存均 200;
- 模板文件被占用(打开中)时自动换名 `<SKU>_已填写_N.xlsx`,不中断导出;