POD 趋势感知 Agent:缓存热点模式 + 三图合成 + 热点去重/风格去重 + review 兜底
- 缓存热点批量流程(有采集缓存不触发 Google) - 简报不足直接从采集缓存生成(轻量补齐) - 三图合成(模特/印花/底图)+ 底图压缩 <2MB - 热点去重→风格去重自动切换 + 不适合类目 review 兜底 - 透明背景(background=transparent)+ 提示词清洗(敏感词/背景描述) - 任务前 basemap 校验 + 模板国家校验 + 模特任务级分配
This commit is contained in:
@@ -0,0 +1,90 @@
|
||||
"""节点 5/6:提示词构造(prompt_build)。
|
||||
|
||||
读取 prompts/<country>/ 的 extra 风格规则,用固定模板装配四种最终提示词
|
||||
(image_prompt / wearable_prompt / composite_prompt / composite_negative)。
|
||||
四要素缺失时用 derive_style_palette 动态兜底,保证每条提示词结构一致、有规则。
|
||||
"""
|
||||
from typing import Any, Dict, List
|
||||
import random
|
||||
|
||||
from graph.style_rules import derive_style_palette, derive_composition
|
||||
from graph.templates import assemble_prompts
|
||||
from graph.validate import validate_brief, with_fallback
|
||||
|
||||
# 图像生成策略敏感词 → 安全等效描述(生成设计稿前清洗 motif,
|
||||
# 避免 gpt-image 等内容策略频繁拦截导致"生图限制多")
|
||||
_IMG_RISKY_SWAP = {
|
||||
"skull": "smiley mascot", "skeleton": "cute mascot", "blood": "red accents",
|
||||
"gore": "bold shapes", "gun": "star", "weapon": "tool", "bomb": "firework",
|
||||
"drug": "confetti", "demon": "cute monster", "devil": "mischievous imp",
|
||||
"occult": "mystic pattern", "satanic": "dark pattern", "nazi": "retro emblem",
|
||||
"hitler": "retro emblem", "zombie": "friendly ghoul", "horror": "spooky-cute",
|
||||
"vampire": "night owl", "politics": "abstract shapes", "political": "abstract",
|
||||
"president": "captain", "army": "team", "police": "officer",
|
||||
}
|
||||
|
||||
|
||||
def _safe_motif(motif: str) -> str:
|
||||
"""清洗 motif 中的图像策略敏感词(替换为安全等效描述),降低生图内容政策拦截率。"""
|
||||
low = motif.lower()
|
||||
for k, v in _IMG_RISKY_SWAP.items():
|
||||
if k in low:
|
||||
# 按词边界替换(避免误伤 "letterhead" 等)
|
||||
import re
|
||||
motif = re.sub(rf"\b{re.escape(k)}\b", v, motif, flags=re.IGNORECASE)
|
||||
low = motif.lower()
|
||||
return motif
|
||||
|
||||
|
||||
@with_fallback("prompt_build")
|
||||
def prompt_node(state: Dict[str, Any]) -> Dict[str, Any]:
|
||||
screened: List[Dict[str, Any]] = state.get("screened") or []
|
||||
config = state["config"]
|
||||
country = state["country"]
|
||||
cc = state["country_config"]
|
||||
extra_rules = cc.get("extra_style_rules") or []
|
||||
tpls = config.get("prompt_templates") or {}
|
||||
|
||||
briefs: List[Dict[str, Any]] = []
|
||||
for r in screened:
|
||||
r = validate_brief(r)
|
||||
art, pal = derive_style_palette(
|
||||
r["topic"], country, extra_rules=extra_rules, category=r.get("design_category")
|
||||
)
|
||||
motif = (r.get("motif") or "").strip() or r.get("topic", "")
|
||||
cleaned = _safe_motif(motif)
|
||||
if cleaned != motif:
|
||||
print(f"[prompt] motif 敏感词清洗: 「{motif}」→「{cleaned}」(降低生图内容政策拦截)")
|
||||
r["motif"] = cleaned
|
||||
motif = cleaned
|
||||
art_style = (r.get("art_style") or art).strip()
|
||||
palette = (r.get("color_palette") or pal).strip()
|
||||
composition = (r.get("composition") or derive_composition(r["topic"], r.get("design_category"))).strip()
|
||||
|
||||
prompts = assemble_prompts(motif, art_style, palette, composition, tpls, country)
|
||||
# 文字印花(约 30% 概率):简报有 slogan 时,随机注入文字段到设计稿提示词
|
||||
slogan = (r.get("slogan") or "").strip()
|
||||
if slogan and random.random() < float(config.get("prompt_templates", {}).get("text_ratio", 0.3)):
|
||||
text_seg = (f', with the text "{slogan}" rendered as bold retro typography, '
|
||||
f'lettering clean and correctly spelled, high contrast, as the focal text of the print')
|
||||
prompts["image_prompt"] = prompts["image_prompt"] + text_seg
|
||||
r["used_slogan"] = slogan
|
||||
# review(疑似商标/受保护主题)→ 动态注入「原创化魔改」引导:只做风格参考,禁止复刻品牌/商标/角色,
|
||||
# 换名换细节,生成通用非侵权的致敬式设计
|
||||
if str(r.get("risk_level", "")).strip().lower() == "review":
|
||||
prompts["image_prompt"] = (prompts["image_prompt"]
|
||||
+ " IMPORTANT: this theme is ONLY a loose stylistic reference. "
|
||||
"Do NOT reproduce any brand logo, trademark, character, mascot, copyrighted artwork or real person. "
|
||||
"Create a fully ORIGINAL design with a different name and distinct visual details and colors — "
|
||||
"a generic, non-infringing homage in the same mood, clearly distinct from the original.")
|
||||
print(f"[prompt] review 简报注入原创化魔改引导: 「{r['topic']}」")
|
||||
r.update(prompts)
|
||||
r["motif"] = motif
|
||||
r["art_style"] = art_style
|
||||
r["color_palette"] = palette
|
||||
r["composition"] = composition
|
||||
briefs.append(r)
|
||||
|
||||
stats = dict(state.get("stats") or {})
|
||||
stats["prompt"] = {"briefs": len(briefs)}
|
||||
return {"briefs": briefs, "stats": stats}
|
||||
Reference in New Issue
Block a user