- 缓存热点批量流程(有采集缓存不触发 Google) - 简报不足直接从采集缓存生成(轻量补齐) - 三图合成(模特/印花/底图)+ 底图压缩 <2MB - 热点去重→风格去重自动切换 + 不适合类目 review 兜底 - 透明背景(background=transparent)+ 提示词清洗(敏感词/背景描述) - 任务前 basemap 校验 + 模板国家校验 + 模特任务级分配
112 lines
4.9 KiB
Python
112 lines
4.9 KiB
Python
"""动态策略:以 yaml 静态种子为基础,叠加动态种子(统一池 + 加权随机 + 用完全用)。
|
||
|
||
种子词机制(v49 起):
|
||
1. 全部类型放一起(统一池):静态 style + 静态 related + 月份主题 + 节日 + LLM 动态
|
||
——合并去重(跨类型同词只保留一个,权重累加 = 多来源更受重视);
|
||
2. 节日种子词提供权重:节日权重 3.0 > 月份主题 2.0 > 静态/动态 1.0,随机抽取时加权;
|
||
3. 每次随机取:从池中按权重随机抽取(不重复),limit 内数量;
|
||
4. 用完全用:池中种子数 ≤ 需要数时全部使用(不再随机限量/截断);
|
||
5. 每个国家独立配置:configs/countries/<country>.yaml 的 style.seeds / related.seed_keywords。
|
||
|
||
limit 由 seed_node 从 context 注入(max_style_seeds / max_related_seeds,0 或缺失=不限)。
|
||
LLM 后端生成失败时自动回退到静态+节日主题,保证不中断。
|
||
"""
|
||
import random
|
||
from typing import Any, Dict, List
|
||
|
||
from .base import SeedStrategy
|
||
|
||
|
||
def _weighted_sample(pool: List[Dict[str, Any]], k: int) -> List[Dict[str, Any]]:
|
||
"""按权重随机不重复取 k 个;池数量 ≤ k(或用完)时全部返回(不随机限量)。"""
|
||
if k <= 0 or len(pool) <= k:
|
||
return list(pool)
|
||
out: List[Dict[str, Any]] = []
|
||
rest = list(pool)
|
||
for _ in range(k):
|
||
weights = [max(float(it["weight"]), 0.0) for it in rest]
|
||
if sum(weights) <= 0:
|
||
out.extend(rest)
|
||
break
|
||
idx = random.choices(range(len(rest)), weights=weights)[0]
|
||
out.append(rest.pop(idx))
|
||
return out
|
||
|
||
|
||
class DynamicStrategy(SeedStrategy):
|
||
name = "dynamic"
|
||
|
||
def resolve(
|
||
self,
|
||
country: str,
|
||
cc: Dict[str, Any],
|
||
context: Dict[str, Any],
|
||
llm_backend: Any = None,
|
||
) -> Dict[str, Any]:
|
||
base_style = list((cc.get("style", {}) or {}).get("seeds", []) or [])
|
||
base_related = list((cc.get("related", {}) or {}).get("seed_keywords", []) or [])
|
||
month_style = list(context.get("month_themes", []) or [])
|
||
holidays = list(context.get("upcoming_holidays", []) or [])
|
||
holiday_style = [f"{h.lower()} aesthetic" for h in holidays]
|
||
# 节日主题同时扩充 related 源(提高节日权重 + 增加 related 扩展)
|
||
holiday_related = [f"{h.lower()} tee" if not h.lower().endswith("day") else f"{h.lower()} gift"
|
||
for h in holidays]
|
||
|
||
# LLM 动态种子(失败回退,不影响静态/节日)
|
||
dyn_style: List[str] = []
|
||
dyn_related: List[str] = []
|
||
if llm_backend is not None and hasattr(llm_backend, "generate_seeds"):
|
||
try:
|
||
res = llm_backend.generate_seeds(context) or {}
|
||
dyn_style = list(res.get("style_seeds", []) or [])
|
||
dyn_related = list(res.get("related_seeds", []) or [])
|
||
except Exception as e: # noqa: BLE001
|
||
print(f"[seed] LLM 生成种子失败,仅用静态+节日主题: {e}")
|
||
|
||
# 1) 统一池:全部类型合并,跨类型去重(同词权重累加 = 多来源更受重视)
|
||
pool: Dict[str, Dict[str, Any]] = {}
|
||
|
||
def add(items: List[str], weight: float, src: str) -> None:
|
||
for it in items:
|
||
it = (it or "").strip()
|
||
if not it:
|
||
continue
|
||
key = it.lower()
|
||
if key in pool:
|
||
pool[key]["weight"] += weight
|
||
pool[key]["sources"].append(src)
|
||
else:
|
||
pool[key] = {"word": it, "weight": weight, "sources": [src]}
|
||
|
||
add(base_style, 1.0, "static")
|
||
add(base_related, 1.0, "static")
|
||
add(month_style, 2.0, "month")
|
||
add(holiday_style, 3.0, "holiday")
|
||
add(holiday_related, 3.0, "holiday")
|
||
add(dyn_style, 1.0, "dynamic")
|
||
add(dyn_related, 1.0, "dynamic")
|
||
|
||
items = list(pool.values())
|
||
limit_style = int(context.get("max_style_seeds") or 0)
|
||
limit_related = int(context.get("max_related_seeds") or 0)
|
||
|
||
# 2) 每次随机取(加权,不重复);池不足 → 全部用
|
||
style_pick = _weighted_sample(items, limit_style)
|
||
style_keys = {id(it) for it in style_pick}
|
||
remaining = [it for it in items if id(it) not in style_keys]
|
||
related_pick = _weighted_sample(remaining, limit_related)
|
||
|
||
return {
|
||
"style_seeds": [it["word"] for it in style_pick],
|
||
"related_seeds": [it["word"] for it in related_pick],
|
||
"dynamic": True,
|
||
"pool_size": len(items),
|
||
"pool": [it["word"] for it in items],
|
||
"llm_style_seeds": dyn_style,
|
||
"llm_related_seeds": dyn_related,
|
||
"holiday_style_seeds": holiday_style,
|
||
"holiday_related_seeds": holiday_related,
|
||
"static_style_seeds": base_style,
|
||
"static_related_seeds": base_related,
|
||
}
|