POD 趋势感知 Agent:缓存热点模式 + 三图合成 + 热点去重/风格去重 + review 兜底

- 缓存热点批量流程(有采集缓存不触发 Google)
- 简报不足直接从采集缓存生成(轻量补齐)
- 三图合成(模特/印花/底图)+ 底图压缩 <2MB
- 热点去重→风格去重自动切换 + 不适合类目 review 兜底
- 透明背景(background=transparent)+ 提示词清洗(敏感词/背景描述)
- 任务前 basemap 校验 + 模板国家校验 + 模特任务级分配
This commit is contained in:
2026-08-22 14:14:01 +08:00
commit f493bde8a9
98 changed files with 10280 additions and 0 deletions
+76
View File
@@ -0,0 +1,76 @@
# -*- coding: utf-8 -*-
"""JP 流程测试:JPTM001 黑色 × 2 个产品(缓存热点模式)。
步骤:
1) 用 mock 种子(6 style + 6 related)生成 JP 主题简报(JP-market 模板装配)→ 写入 output/JP/design_briefs.json 作为缓存
2) run_product_batchtasks=[JPTM001-BL01 × 2]count=2 → 2 个产品各绑一个热点
3) 验证:选色/热点分配/used 去重/JP 标题模板路由/模板导出
"""
import json
import sys
import time
from pathlib import Path
BASE = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(BASE))
import yaml
from graph.templates import assemble_prompts
config = yaml.safe_load(open(BASE / "config.yaml", encoding="utf-8"))
# 种子词 6 个
config["seed_provider"] = "mock"
cfg = config.setdefault("seed_provider_cfg", {})
cfg["max_style_seeds"] = 6
cfg["max_related_seeds"] = 6
# 图像后端 mock、不上传图床
config["compose"]["backend"] = "mock"
config["product"]["backend"] = "mock"
config["oss"]["enabled"] = False
config["seed_shot"]["count"] = 1
jp_topics = [
("kawaii cat cafe", "Style", "original kawaii cat with latte art", "kawaii style, soft rounded shapes", "pink, cream, caramel", "centered mascot"),
("tokyo neon night", "Style", "original neon street lamps silhouette", "retro cyberpunk flat vector", "magenta, cyan, black", "symmetrical emblem"),
("shiba inu summer", "Style", "original shiba inu with watermelon slice", "cute japanese mascot illustration", "orange, red, white", "centered"),
("sakura spring", "Style", "original cherry blossom branch with petals", "soft minimal japanese print", "sakura pink, white, mint", "corner flourish"),
("osaka takoyaki food", "Style", "original takoyaki balls with bonito flakes", "playful food illustration", "golden brown, red, green", "centered badge"),
("mt fuji sunrise", "Style", "original mt fuji with rising sun rays", "ukiyo-e inspired flat design", "indigo, red, cream", "symmetrical"),
]
tpls = config.get("prompt_templates") or {}
briefs = []
for topic, cat, motif, style, palette, comp in jp_topics:
prompts = assemble_prompts(motif, style, palette, comp, tpls, "JP")
briefs.append({
"country": "JP", "topic": topic, "design_category": cat, "risk_level": "safe",
"score": 80 - len(briefs) * 3, "motif": motif, "art_style": style,
"color_palette": palette, "composition": comp,
"image_prompt": prompts["image_prompt"],
"composite_prompt": prompts["composite_prompt"],
"composite_negative": prompts["composite_negative"],
})
out_dir = BASE / "output" / "JP"
out_dir.mkdir(parents=True, exist_ok=True)
(out_dir / "design_briefs.json").write_text(
json.dumps({"generated_at": time.strftime("%Y-%m-%dT%H:%M:%S"), "total": len(briefs),
"design_briefs": briefs}, ensure_ascii=False, indent=2), encoding="utf-8")
print(f"[setup] JP 缓存热点已写入: {len(briefs)} 条(mock 种子 6/6")
p0 = briefs[0]["image_prompt"]
print("[setup] 模板校验: JP-market 风格段 =", "JP-market" in p0, "| 尺寸上限 26x32 =", "26x32" in p0)
from graph.product_batch import run_product_batch
tasks = [{"spu": "JPTM001", "skus": "JPTM001-BL01"}, # 黑色
{"spu": "JPTM001", "skus": "JPTM001-BL01"}] # 数量 2:同一款号生成 2 个产品
out = run_product_batch("JP", config, BASE, BASE, tasks, 2, log_q=None)
print("\n=== 测试结果 ===")
prods = out.get("product") or []
print("产品数:", len(prods))
for r in prods:
print(f" {r.get('spu_code')} | {r.get('sku_code')} | 色={r.get('color')} | topic={r.get('topic')} | "
f"template={bool(r.get('template_path'))} | design={bool(r.get('design_path'))}")
print("errors:", [e.get("message", "")[:80] for e in out.get("errors") or []])
used = json.loads((out_dir / "used_designs.json").read_text(encoding="utf-8")).get("used", []) if (out_dir / "used_designs.json").exists() else []
print("used_designs 记录:", len(used), "条 →", [u.get("topic") for u in used])