# POD 趋势感知 Agent · 对接文档 > 面向开发者/维护者的适配与扩展指南。覆盖:项目架构、**如何适配新国家**、核心流程、缓存机制、合规红线、常见问题与打包发布。 > 适用版本:dist_v67 / 源码 `pod_trend_agent/` --- ## 1. 项目概览 **目标**:为 POD(Print on Demand)出海业务自动捕捉海外热点 → 生成可打印的 T 恤印花设计 → 三图合成模特图 → 多语言标题 → 导出商品上传模板。 **技术栈**:Python 3.13 · LangGraph(7 节点流水线)· tkinter 桌面 UI · requests · Pillow · PyInstaller 打包 **两条运行路径**: | 路径 | 触发条件 | 行为 | |---|---|---| | **缓存热点模式**(日常) | `output/<国>/collected_keywords.json` 存在 | 直接用采集缓存分配热点;简报不足时**从采集缓存自动生成简报**(轻量补齐),**绝不触发 Google** | | **完整流水线**(首次) | 完全无缓存 | `seed → fetch → filter → score → screen → prompt_build → compose → product → seed_shot → template_export → oss_upload` | --- ## 2. 目录结构 ``` pod_trend_agent/ ├── ui_app.py # 桌面 UI:选品/采集/运行/模板/结果表格 ├── cli.py # 命令行入口 ├── config.yaml # 全局配置(countries/sources/llm_screen/prompt_templates/compose/oss/product…) ├── configs/countries/.yaml# ★每国独立配置:种子词/related 种子/采集限额 ├── prompts// # ★每国提示词:system_prompt.md + aesthetics.yaml ├── graph/ │ ├── agent.py # LangGraph 流水线编排(START→seed→fetch→…→END) │ ├── nodes/ # 各节点实现(seed/fetch/filter/score/screen/prompt/compose/product/seed_shot/template/oss) │ ├── product_batch.py # 缓存热点批量流程:分配/三级去重/review 兜底/轻量补齐 │ ├── backends/ # 图像后端:openai_image_backend / mock_image_backend │ ├── llms/ # LLM 后端:openai_compat_backend(多模态标题)/ mock_backend │ ├── seeds/ # 种子策略:dynamic_strategy(统一池+加权随机)/ static / holidays │ ├── sources/ # 数据源注册表:google_trends(pytrends,429 兜底)/ pinterest │ ├── product.py # 底图/模特查找(IMG_EXTS 全格式)、SKU 逻辑 │ ├── style_rules.py # 风格/配色/构图规则 + sanitize_image_prompt + review 魔改引导 │ ├── paths.py # config_root / project_root / runtime_root 路径解析 │ └── validate.py # 校验 + with_fallback 兜底装饰器 ├── templates/ # 商品上传模板 + template_router.py(模板读写) ├── basemap/<款号>/<颜色>/ # 平铺底图(jpg/png…) ├── material_library/<品类>/ # 模特图(webp/jpg/png/avif…) ├── db/ # 商品数据库(sqlite) └── dist_vNN/ # PyInstaller 打包产物(含全部数据) ``` --- ## 3. ★适配新国家(核心章节) 以新增 **DE(德国)** 为例,完整步骤: ### 3.1 国家代码入列 `config.yaml`: ```yaml countries: - US - GB - JP - AU - MX - DE # ← 新增 ``` ### 3.2 每国配置 `configs/countries/DE.yaml` ```yaml # 德国专属数据源配置 trending: enabled: true limit: 40 # Google Trends 抓取上限 style: enabled: true seeds: # ★印花风格种子词(重点,越多越好,20~30 个) - lederhosen - alpine - berlin street art - bauhaus pattern - autobahn - ... related: enabled: true seed_keywords: - ... exclude_topics: [] # 黑名单热点(已用过/明确不分配的词,可选) ``` **种子词选词红线**(写配置时注意): - ❌ 会被 `review 兜底 _UNSUITABLE` 剔除的类目:`nails / recipes / lottery / weather / results / prices / jobs / mortgage / election…`(见 `graph/product_batch.py`) - ❌ 品牌/版权/真实人物:`nike / disney / margot robbie / prison break…` - ❌ 图像策略敏感词:`skull / skeleton / blood / gun / demon…`(生成时会被 `sanitize_image_prompt` 替换,主题会变味) - ✅ 用各国**本土流行 + 全球趋势**的印花主题(2026 参考:retro vintage / 极简 typography / 自然户外 / 手绘涂鸦 / Y2K / coquette / western / 幽默 quote / 星座塔罗 / 植物线稿) ### 3.3 每国提示词 `prompts/DE/` - **`system_prompt.md`**:screen 阶段 LLM 的角色/输出规则(风险判定、motif/art_style/color_palette/composition 四要素),**必须包含 "Return JSON…" 字样**(阿里云 MaaS 的 `response_format=json_object` 硬性要求)。 - **`aesthetics.yaml`**: ```yaml extra_style_rules: [...] # 该国风格倾向(配色/构图/审美) extra_blacklist: [...] # 该国合规红线词(德国:纳粹符号等) ``` ### 3.4 节假日 `graph/seeds/holidays.py` `_HOLIDAYS_BY_COUNTRY` 增加国家节日(名称/月/日/规则/窗口),节日种子词自动带权重 3.0 进入统一池: ```python "DE": [ ("Oktoberfest", 9, 21, "third_saturday", 30), # 啤酒节(9 月) ("Weihnachten", 12, 25, "fixed", 25), # 圣诞节 ... ] ``` ### 3.5 国家模板站点校验 `ui_app.py` `_check_template_site` 的 `country_sites` 字典加国家→站点关键词: ```python country_sites = { ... "DE": ("德国站", "德国"), } ``` (模板「模版」sheet 第 1 行定位「经营站点」列 → 第 2 行站点名 → 与所选国家不匹配则**导入失败**,提示重新导入) ### 3.6 图像提示词模板 `config.yaml → prompt_templates` `image_prompt` / `wearable_prompt` / `composite_prompt` 各加国家版本(`{motif}` 等占位符保持不变),注意: - **提示词中不得出现任何背景描述**("isolated on … background"、"no background scene")——透明背景只由 `background="transparent"` 参数控制(官方要求) - 不含安全规则段("no politics / no religion / no hate / no violence / no sexual"——这些词本身会触发图像 API 内容政策拦截) ### 3.7 验证清单 ```bash python cli.py -c DE --provider mock # mock 跑通全流程(不花钱) python -c "from graph.seeds.dynamic_strategy import DynamicStrategy; ..." # 验证种子池 # UI 打开 → 切 DE → 采集 → 运行 ``` --- ## 4. 核心流程详解 ### 4.1 完整流水线(LangGraph 7 节点) ``` START → seed(种子词) → fetch(采集) → filter(过滤) → score(打分) → screen(风险筛选+简报) → prompt_build(提示词) → compose(设计稿) → product(合成/标题) → seed_shot(种草图) → template_export(模板) → oss_upload(压缩上传) → END ``` 每个节点均套 `with_fallback` 兜底(失败不中断整体流程)。 ### 4.2 缓存热点模式(日常入口,`ui_app` / `run_product_batch`) ``` 判断:output/<国>/ 有 collected_keywords.json 或 design_briefs.json → 缓存模式 → load 简报(简报不足 → _rebuild_briefs_from_cache 从采集缓存生成,不碰 Google) → assign_hotspots 分配(三级去重 + review 兜底) → product 节点批量处理(并发 ≤5,每 SPU 一线程) → 模板导出 ``` ### 4.3 热点分配与去重(`assign_hotspots`) | 层级 | 逻辑 | |---|---| | ① 热点去重 | 本批优先不同 topic(热点1-风格1、热点2-风格1…) | | ② 风格去重 | 热点用完后自动切:热点1-风格2、热点2-风格2…(同 topic 不同 art_style) | | ③ 兜底 | 剩余未用指纹(低分热点也可);**历史已用 (topic, style) 指纹绝不重复出** | | review 兜底 | `_UNSUITABLE` 正则剔除不适合类目(美甲/食谱/彩票/天气/比分…),日志提示 | ### 4.4 种子词机制(`dynamic_strategy.py`) - **统一池**:静态 style + 静态 related + 月份主题 + 节日 + LLM 动态 → 全部合并去重(跨类型同词权重累加) - **权重**:节日 3.0 > 月份主题 2.0 > 静态/动态 1.0(加权随机抽取) - **每次随机取**(加权不重复);**用完全用**(池 ≤ 需要数时全部使用,不随机限量) - 每国独立配置(`configs/countries/.yaml`),种子缓存 `.cache/seeds/`(按 国家+provider+日期,防 Google 429) --- ## 5. 缓存文件 | 文件 | 位置 | 作用 | |---|---|---| | `collected_keywords.json` | `output/<国>/` | 采集热点池(关键词列表) | | `design_briefs.json` | `output/<国>/` | 简报池(topic/motif/risk/score/image_prompt…) | | `used_designs.json` | `output/<国>/` | 已用 (topic, art_style) 指纹(成功生成才写入) | | `.cache/seeds/` | 项目根 | 种子词日缓存(防 429 重采集) | | `.cache/llm_screen/` | 项目根 | LLM 筛查缓存 | > 注意:**失败产品不写 used_designs**(合成/设计失败的,热点下次仍可用)。 > 已用过不要的热点:直接从 `collected_keywords.json` / `design_briefs.json` 物理删除即可(如 8-22 的 18 个 GB 热点处理方式)。 --- ## 6. 合规红线(最重要) 1. **review 判定**:screen 阶段 LLM 判定疑似商标/版权/真实人物 → `risk_level=review`;openai 模式下生成设计时**自动注入原创化魔改引导**(`REVIEW_REBRAND_HINT`:只做风格参考、禁止复刻 logo/商标/角色、换名换细节) 2. **提示词清洗** `sanitize_image_prompt`(生成设计前必过): - 删除一切背景描述(透明背景由参数控制) - 删除内容策略触发段(`any text must be safe: no politics/religion/hate/violence/sexual…`) - 21+ 个敏感词安全替换(skull→smiley mascot、gun→star…) 3. **各国红线**:美国慎政治/宗教;德国慎纳粹符号(`aesthetics.yaml extra_blacklist` 扩展);中东整体保守;真实人物一律不进 4. **review 兜底 `_UNSUITABLE`**:不适合类目自动剔除(分配源头拦截) --- ## 7. 图像生成与合成 ### 7.1 设计稿生成(`compose` / `product` 的 `generate`) - **透明背景**:`background="transparent"` 参数(compose/product 配置均已设);**提示词不得提背景** - 并发:compose 并发生成(`compose.design_workers` 默认 5);product 阶段每 SPU 一线程,并发上限 5 - 底图/模特/设计 >2MB → 自动压缩到 <2MB 再上传网关(`_shrink_blob_to_2mb`) ### 7.2 三图合成(`product` 的 `print`,mark=1) - 上传顺序:**图1 模特图 → 图2 印花设计稿 → 图3 衣服平铺底图**(与提示词角色一一对应) - 图3 只提取衣服本身底色与面料材质(忽略平铺图背景/桌面/场景) - 合成失败 → 退避重试 3 次(5/20/40s);仍失败 → 跳过该产品(不生成标题、不写模板) - 网关处理约 2-6 分钟属正常(重负载 img2img) --- ## 8. 模型与网络配置(`config.yaml`) ```yaml llm_screen: # LLM(screen/种子/标题共用) model: "qwen3.7-..." # ★标题生成需视觉模型(qwen-vl 系列);纯文本模型会 400 base_url: "https://...maas.aliyuncs.com/compatible-mode/v1" api_key: "sk-..." # 或环境变量 LLM_API_KEY compose: # 设计稿图像网关 backend: "openai" model: "gpt-image-2" # 支持 background=transparent base_url: "https://api.tofastcode.xyz" background: "transparent" product: backend: "mock" # openai / mock background: "transparent" concurrency: 5 # 合成并发上限(默认 min(任务数,5)) ``` **代理策略**:模型调用(LLM + 图像)一律直连(`NO_PROXY` + 环境变量级 `no_proxy=*`,用户挂 VPN 也不走代理);**Google 采集(pytrends)走系统代理**(需要 VPN)。 --- ## 9. 打包发布(每版流程) ```bash # 1. 打包(不跑 self-test:会撞 Google 429,浪费 7-10 分钟) pyinstaller -y PODTrendAgent.spec --distpath dist_vNN --workpath build_cleanNN # 2. 补齐 dist 数据(必须,否则 exe 缺资源) cp -r templates db basemap material_library configs prompts .cache dist_vNN/ cp config.yaml dist_vNN/ # 3. 拷贝最近缓存(output/<国>/*.json),避免 exe 首次运行重新采集 # 4. 验证:find_first_model_folder 能查到模特(material_library 拷贝不完整是常见坑) ``` --- ## 10. 常见问题(FAQ) | 现象 | 根因 | 解决 | |---|---|---| | 有缓存还去采集(Google 429 刷屏) | UI 判断只看 design_briefs,忽略 collected | v60+ 已修:有 collected 即缓存模式,绝不触发 seed/fetch | | Google 429 / SSL EOF | 限流 | 换 VPN 节点;已采集后运行走缓存不再碰 Google | | 三图合成全部超时 | 并发过高压垮网关 / 底图过大 | 并发上限 5 + 输入图压缩 <2MB + 退避重试 | | 生成设计全是商标侵权 | review 简报未魔改 | v57+ 自动注入 REVIEW_REBRAND_HINT | | 内容政策拦截频繁 | 提示词含敏感词/安全规则段/背景描述 | sanitize_image_prompt 自动清理 | | 设计稿不透明(RGB 白底) | product 后端未配 background | `product.background: transparent` | | 标题 400 | 模型不支持图片输入(非视觉模型) | 换 qwen-vl 系列视觉模型 | | 模特找不到 | material_library 拷贝不全 / avif 不识别 | 全量拷贝;IMG_EXTS 已含 avif/gif/tiff | | 生成的设计 6 个重复 | compose 只生成 safe 简报的设计 | v48+ 为全部简报(含 review)生成设计 | --- ## 11. 开发环境 ```bash python -m venv .venv .venv/Scripts/pip install -r requirements.txt # 或 uv sync(uv.lock 已锁定) # 环境变量:LLM_API_KEY / LLM_BASE_URL / OSS_ACCESS_KEY_ID / OSS_ACCESS_KEY_SECRET ``` **对接新国家一句话总结**:`configs/countries/.yaml`(种子词)+ `prompts//`(提示词)+ `holidays.py`(节日)+ `config.yaml countries 列表` + UI 国家下拉 + 模板站点映射 → mock 跑通 → 真 LLM 验证。