Files
pod_trend_agent/README.md
T
3218485270 685b7b0862 更新 README + 模板导出新增面料弹性/沙特阿拉伯码识别
1) README 重写:双模式架构(热点采集/Pinterest 参考模式)、模特性别分组、生图尺寸配置、模板导出增强、一键打包脚本
2) template_export:识别「面料弹性」列填 spu.fabric;识别「尺码表-沙特阿拉伯码」列填 sku.size(均模糊匹配,检测到才填)
2026-08-26 18:32:33 +08:00

233 lines
15 KiB
Markdown
Raw 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.
# POD 热点抓取 AgentLangGraph 工程化版)
自动抓取海外各国(US / GB / JP / AU / MX / DE / BR / SA / PL / ES / IT / CA)实时热点 + 风格趋势,
过滤侵权风险,产出可直接用于 AI 生图的印花设计提示词,并完成 **设计稿 → 三合一模特试穿 → OSS 图床 →
种草图 → 商品上传模板** 的完整 POD 生产链路。本版本用 **LangGraph** 重写,强调**工程化、节点兜底、可插拔**。
## 两种运行模式
| 模式 | 入口 | 数据来源 | 适用 |
|---|---|---|---|
| **热点采集模式** | UI「热点采集」 | Google Trendstrending/style/related | 抓国家实时热点词,LLM 筛出可印花设计 |
| **Pinterest 参考模式** | UI「Pinterest 参考模式」 | Pinterest 爬图 + LLM 多模态分析 | 从真实图片提炼原创印花设计,侵权风险更低 |
## 架构:LangGraph 状态图
### 模式 A:热点采集模式
```
START → seed → fetch → filter → score → screen → prompt_build → compose → product
→ oss_upload → seed_shot → template_export → END
```
| 节点 | 职责 | 可插拔点 / 兜底 |
|---|---|---|
| `seed` | 动态生成种子词(trending 派生 + 历史热点 + 月份/节日 → LLM) | 策略可插拔(`graph/seeds/`);LLM 失败回退静态种子 |
| `fetch` | 抓取热点(Google Trends 多数据源汇总) | 数据源可插拔(`graph/sources/`);单源失败不影响其它源 |
| `filter` | 黑名单 + 真实人物 + 设计相关性三级过滤 | 各级独立 try,单级失败不影响其它级 |
| `score` | 归一化 + 跨源融合 + 综合分 | 纯逻辑,空数据返回空 |
| `screen` | LLM 合规筛查 + 结构化四要素 | LLM 后端可插拔(`graph/llms/`);调用失败降级 Mock |
| `prompt_build` | 用固定模板装配 image/wearable/composite 提示词 | 四要素缺失时动态推导兜底 |
| `compose` | 生成纯印花设计稿(白底,可直接打印) | 图像后端可插拔(`graph/backends/`);无底图只导出 |
| `product` | SPU/颜色选品 → 底图 → 三图合成(图1模特+图2设计稿+图3底图) | 缺底图/模特图自动跳过 |
| `oss_upload` | 压缩(3:4 / ≥1340×1785 / <2MB+ 上传阿里云 OSS | 可关闭(`oss.enabled=false` |
| `seed_shot` | 从三合一主图按颜色选取种草图 + 上传 | 按 `seed_shot.count` 随机选取 |
| `template_export` | 把 SPU/SKU 数据填入商品上传模板 | 模板列名模糊匹配,多语言变体兼容 |
### 模式 BPinterest 参考模式
```
START → pinterest_init → pinterest_search → pinterest_scrape → pinterest_analyze
→ [pinterest_route 循环:简报不足 → 回 pinterest_search]
→ pinterest_finalize(排空简报池,后台并发生成 设计→三合一→OSS→种草图)
→ template_export → END
```
| 节点 | 职责 |
|---|---|
| `pinterest_init` | 创建简报池 + 并发生成流水线(`graph/pinterest_pipeline.py` |
| `pinterest_search` | 按需生成搜索词(direct=种子词直接拼「 t-shirt design」;llm=LLM 按需生成,json_schema+防重复) |
| `pinterest_scrape` | 用 Playwright 爬取 Pinterest 图片(共享 Chrome 登录态,并发=1) |
| `pinterest_analyze` | 从图池取图 → 多并发 LLM 多模态分析 → 原创设计简报(侵权检测 + 原创化引导) |
| `pinterest_route` | 简报不足 → 图池有未消费图 → 继续分析;图池不足 → 新一轮搜索;轮次耗尽 → 结束 |
| `pinterest_finalize` | 排空简报池,后台线程池并发生成(设计→三合一→OSS→种草图),合并产品 |
**图池机制**:爬取的图片注册到 `image_pool.json`(路径+md5+搜索词);分析过的图片 md5 一律拉黑
`used_images.json`,合适/不合适都拉黑);图池有未消费图片 → 直接分析(不搜索);不足 → 新一轮搜索。
每个简报带 `image_index`/`source_md5` 全局 id 校验,保证简报、设计稿、三合一套图对应同一张图。
**并发控制**`config.yaml``pinterest:`):`analyze_concurrency`(分析线程数)、`analyze_batch`
(每轮取图数,0=自动补齐让 pipeline 队列满并发)、`max_designs`(每搜索词简报上限)、
`scrape_concurrency`(爬图并发,必须=1)、`err400_limit`400 超限放弃当前种子词)。
**每个节点都用 `graph/validate.with_fallback` 包裹**:任何未预料异常都被捕获、记入
`state['errors']`、返回最小更新,整图继续往下走,单点故障不中断流水线。
## 目录结构
```
pod_trend_agent/
├── cli.py # 命令行入口
├── 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
│ ├── pinterest/ # 各国 Pinterest 种子词池(<CC>.yaml
│ ├── model_features.yaml # 模特特征库(按性别分组 female/male,种草图用)
│ ├── seed_shot_templates.yaml # 种草图提示词模板
│ └── style_features.yaml
├── prompts/<country>/ # ★ 每个国家不同的提示词单独文件夹
│ ├── system_prompt.md # 该国 LLM 系统提示(补充段,叠加到默认规则)
│ └── aesthetics.yaml # 审美 hint + 风格-配色 extra 规则 + 额外黑名单
├── graph/
│ ├── state.py # AgentState(共享状态)
│ ├── validate.py # with_fallback 兜底 + 数据校验
│ ├── loader.py # 配置/提示词加载与合并
│ ├── scoring.py # 归一化/融合/过滤(纯逻辑)
│ ├── style_rules.py # 动态风格/配色推导
│ ├── templates.py # 固定提示词模板(按国家区分,文字敏感规则)
│ ├── classify.py # 热点分类
│ ├── pinterest.py # Pinterest 图池/黑名单/压缩/MD5 去重
│ ├── pinterest_pipeline.py # 简报池 + 并发生成流水线(Pinterest 模式核心)
│ ├── product.py / product_batch.py # 三合一合成 / 批量
│ ├── seed_shot.py # 种草图选取 + 模特特征(性别分组)
│ ├── template_export.py # 商品上传模板导出(列名模糊匹配)
│ ├── oss_upload.py # 图片压缩 + 阿里云 OSS 上传
│ ├── sources/ # 数据源可插拔(google_trends + 注册表)
│ ├── llms/ # LLM 后端可插拔(mock / openai_compat + 注册表)
│ ├── backends/ # 图像后端可插拔(openai / mock
│ ├── seeds/ # 种子词策略可插拔(static / dynamic + holidays
│ ├── nodes/ # 流水线节点(seed/fetch/.../pinterest_*/product/oss/seed_shot/template_export
│ └── agent.py # 构建并编译 StateGraphbuild_graph / build_pinterest_graph
├── templates/
│ └── template_router.py # 商品上传模板路由(列名定位、数据写入)
├── scripts/
│ └── package.py # 一键打包脚本(PyInstaller → dist_vXX
├── basemap/ # 平铺衣服底图(<款号>/<SKU.code>/
├── material_library/ # 模特图(<品类>/
├── db/spu_sku.db # SPU/SKU 数据库
├── pinterest_scraper/ # Playwright 爬虫 + Chrome 登录态
└── output/<country>/ # ★ 每个国家的产物独立文件夹
├── design_briefs.json/md # 设计简报(含 image_prompt / composite_prompt
├── designs/ # 纯印花设计稿
├── product/ # 三合一合成图 + 已填写商品模板 <SKU>_已填写.xlsx
└── report.md # 各阶段统计 + 兜底错误记录
```
## Pinterest 参考模式详解
1. **种子词池**`configs/pinterest/<CC>.yaml` 存各国风格化种子词(含节日词),偏向印花设计。
2. **按需搜索**:每次只生成 1 个搜索词(`search_terms_per_run=1`),自动追加「 t-shirt design」后缀
(保证爬到的图是真实印花艺术,而非生活方式/风景图);爬取成功才标记已用,失败不拉黑。
3. **爬图**Playwright 打开 Pinterest 搜索页截图采集(共享 `.chrome_session` 登录态,并发强制=1)。
4. **图池 + MD5 去重**:图片注册 `image_pool.json`;分析过的 md5 一律拉黑(`used_images.json`);
设计稿生成后全局 MD5 去重(`.cache/global_design_md5.json`),跨国家生效。
5. **多模态分析**:大图先压缩(max 1024px / 1.5MB)再送 LLM,产出原创设计简报(motif/风格/配色/构图 +
risk_levelsafe/review/blocked)。blocked 拦截、review 加原创化魔改引导、safe 直接生成。
6. **并发生成**:简报推入 `PinterestPipeline`,后台线程池(`product.concurrency`,默认 5)逐条
生成 设计稿 → 三合一 → OSS 上传 → 种草图,边分析边生成,不等全部分析完。
## 模特性别分组
`configs/model_features.yaml` 的模特特征按性别分组(`female` / `male`)。种草图生成时读取商品上传
模板的「类目」表头值:
- 类目含「男」(如 `男士时尚>男装>男装T恤`)→ 固定从 **male** 组随机取模特
- 类目含「女」→ 固定从 **female** 组随机取模特
- 都不含 → 男女混合随机
## 生图尺寸(读 config,不硬编码)
| 图片类型 | 配置项 | 默认 |
|---|---|---|
| 纯印花设计稿 | `compose.design_size` | 1024x10241:1 |
| 三合一合成图 | `compose.size` | 1536x20483:4 |
| 种草图 | `seed_shot.size` | 1536x20483:4 |
## 商品上传模板导出
生成产品图后,从 db 读该 SPU/SKU 信息(材质/成分/图案/领型/面料/克重/印花类型/尺码表/边长/包装重量…),
`templates/template_router.py` 的路由函数填入商品上传模板,输出 `<SKU>_已填写.xlsx`
`output/<国家>/product/`。模板已自包含在项目 `templates/``config.product.template_path`,可改为自由上传)。
- 数据从模板第 6 行(数据区空行)开始填,SPU 与各尺码 SKU 紧邻;
- **列名模糊匹配**:模板列名按名称匹配(非固定行列),支持中/英/日变体;
- **胸围识别**:识别「基码表-胸围(cm)」「胸围全围(cm)」等含「胸围」的列,全部填 `sku.bust` 值;
- **申报价格**:模糊匹配所有含「申报价格」的列,统一按加价后价格填写(`price × (1+markup_percent%)`);
- **款式来源**:SPU 行「款式来源」统一填「现货款」;
- **商品产地**:国家简称映射正式名称(如「沙特」→「沙特阿拉伯」,`_COUNTRY_NAME_MAP` 可扩展);
- **详情图文**:由全部主图 + 种草图组成(不再拼接 img_url_2);
- 规格类型2 = `{size}*{color}`;币种=CNY;发货仓1~N 取模板顶头按「、」分隔,库存均 200;
- 模板文件被占用(打开中)时自动换名 `<SKU>_已填写_N.xlsx`,不中断导出;
- **多颜色 + 模式**`sku_code` 支持逗号分隔多颜色;`spu_per_color`true=每颜色一个 SPU 块 /
false=单 SPU 挂多颜色变体);CLI 用 `--single-spu` 切单 SPU 模式,UI 用「颜色多选 + 模板模式」。
## 用法
```bash
# 跑全部国家(热点采集模式,默认 US GB JP AU)
python cli.py
# 只跑英国,Mock 兜底 LLM
python cli.py -c GB --provider mock
# 跑美国 + 真实 LLMprovider 已在 config.llm_screen 配好时可不传)
python cli.py -c US
# 提供平铺衣服底图,把设计印上去(需 config.compose.backend + api_key
python cli.py -c US --base path/to/flatlay.png
# 查看 db 可选款号 / 某款颜色
python cli.py --list-spus
python cli.py --list-colors DG004
# 指定款号+颜色跑流水线(product.backend=mock 占位 / openai 真生图需 compose.api_key
python cli.py -c GB --spu DG004 --sku DG004-BL01
```
## 桌面 UITkinter 轻量版)
```bash
# 开发模式直接跑
python ui_app.py
# 无 GUI 自检(验证环境/核心链路,结果写入运行根 self_test_result.txt
python ui_app.py --self-test
```
UI 功能:国家多选、**流程选择(热点采集 / Pinterest 参考模式)**、LLM 后端选择、种子上限、
**SPU/颜色选品**、运行(后台线程 + 实时日志)、结果表格(双击看完整提示词)、打开产物目录。
## 打包
```bash
# 一键打包(自动取下一个版本号)
python scripts/package.py
# 指定版本号
python scripts/package.py 84
```
产物:`dist_vXX/PODTrendAgent.exe`。打包流程:PyInstaller 构建(不跑自检)→ 同步数据目录
config.yaml / configs / prompts / templates / basemap / material_library / db / output / logs)→
复制当前 Chrome 登录态到 exe 同目录(`pinterest_scraper/.chrome_session`)→ 同步上一个版本的 `.cache`
exe 运行时优先读 exe 旁这份配置(改了就生效),exe 内置的作为兜底默认。
## 数据流要点
0. `seed`(动态种子词):收集 trending 派生(去噪 + 人名 + 风险护栏过滤)、上轮 safe 历史热点、
当前月份/临近节日,由 LLM 后端(mock 规则 / 真 LLM)生成动态种子词,与 yaml 静态种子合并注入抓取配置。
1. `fetch``gt_trending`(国家 RSS 实时榜)+ `gt_style`/`gt_related`(风格/行业种子关联词)。
2. `filter` 三级过滤:合规黑名单(全局 + 各国 `extra_blacklist`)→ 真实人物 → 泛新闻/科技/赛事词。
3. `score` 按 (source,kind) 分组 min-max 归一化、跨源融合加权重。
4. `screen` LLM 合规筛查,产出 risk_level / 四要素;`keep_review=false` 时丢弃待复核。
5. `prompt_build` 用四要素 + 固定模板装配 image/wearable/composite 提示词(结构一致、可复用 img2img)。
6. `compose` 生成纯印花设计稿(白底,可直接打印),product 取第一张作为图2 复用。
7. `product` SPU/颜色选品 → basemap 底图 → 三图合成(图1模特 + 图2设计稿 + 图3底图)→ 模板。
8. `oss_upload` 压缩(3:4 / ≥1340×1785 / <2MB+ 上传阿里云 OSSURL 写回 `*_url` 字段。
9. `seed_shot` 从三合一主图按颜色选取种草图(模特性别分组),上传 OSS,URL 写入模板「详情图文」。
10. `template_export` 把 SPU/SKU 数据填入商品上传模板,输出 `<SKU>_已填写.xlsx`
> 合规红线(最重要):版权/商标/真实人物/敏感内容一律拦截或降级;二创/重绘仍有风险,
> 拿不准进"待复核"。各国侵权盲区不同(如英国 WWE/游戏/乐队、日本动漫 IP),放在
> `prompts/<country>/aesthetics.yaml` 的 `extra_blacklist` 按国家隔离。