v110-v112 自定义模式完善 + 模板导出增强 + 多模态兼容优化
- 自定义模式:分析模型输出 delta 唯一改动指令,生图模板 custom_image_prompt.md({delta} 占位符),不再使用负向提示词;generate_design 按 custom_mode 分支,Pinterest 模式保留原创化指令,两模式互不影响
- 多模态分析 response_format 三级回退(json_schema → json_object → none),兼容 DeepSeek
- 模板导出:details 扩展列(细节1/2/3)、target_audience 扩展列(适用人群1)、固定值风格1=休闲/风格2=运动
- 童装特征库更新 + 标题模板外部化 + 图源映射增强
This commit is contained in:
+33
-18
@@ -39,9 +39,9 @@ REVIEW_REBRAND_HINT = (
|
||||
"a generic, non-infringing homage in the same mood, clearly distinct from the original."
|
||||
)
|
||||
|
||||
# —— 自定义模式(custom)生图模板:固定前缀 + 分析模型 image_prompt + 固定负向 ——
|
||||
# 自定义模式分析模型产出的是「新设计描述」,生图时套用这套固定模板(含防复制/防服装约束),
|
||||
# 负向用固定文本(写入 composite_negative,compose 生图时作为负向参数传给图像后端)。
|
||||
# —— 自定义模式(custom)生图模板:固定前缀 + 分析模型 image_prompt + delta 改动指令 ——
|
||||
# 自定义模式分析模型产出的是「新设计描述 + 唯一改动指令 delta」,生图时套用这套固定模板
|
||||
# (含防复制/防服装约束),不再使用负向提示词——约束已全部内置进模板。
|
||||
CUSTOM_IMAGE_PROMPT_TEMPLATE = (
|
||||
"Use the attached bestseller product photo only as loose inspiration for "
|
||||
"overall mood, theme, era and style genre — do NOT reproduce, trace, "
|
||||
@@ -53,11 +53,6 @@ CUSTOM_IMAGE_PROMPT_TEMPLATE = (
|
||||
"base the new design on THOSE observed traits. Ignore the model, background "
|
||||
"and photo quality. Then: {image_prompt}"
|
||||
)
|
||||
CUSTOM_NEGATIVE_PROMPT = (
|
||||
"copy of reference artwork, lookalike of the bestseller print, characters, "
|
||||
"mascots, likenesses, logos, trademarks, watermark, photorealistic shirt, "
|
||||
"apparel, product mockup, model, garment, hanger, busy background"
|
||||
)
|
||||
|
||||
# 图像生成策略敏感词 → 安全等效描述(生成设计稿前清洗 motif,
|
||||
# 避免 gpt-image 等内容策略频繁拦截导致"生图限制多")
|
||||
@@ -84,6 +79,18 @@ def _safe_motif(motif: str) -> str:
|
||||
return motif
|
||||
|
||||
|
||||
def _read_custom_prompt_md(filename: str) -> str:
|
||||
"""读取 prompts/<filename>(自定义模式生图模板),优先运行根 exe 旁、回退数据根;无/空返回空串。"""
|
||||
from graph.paths import project_root, runtime_root
|
||||
for base in (runtime_root(), project_root()):
|
||||
p = base / "prompts" / filename
|
||||
if p.exists():
|
||||
t = p.read_text(encoding="utf-8").strip()
|
||||
if t:
|
||||
return t
|
||||
return ""
|
||||
|
||||
|
||||
@with_fallback("prompt_build")
|
||||
def prompt_node(state: Dict[str, Any]) -> Dict[str, Any]:
|
||||
screened: List[Dict[str, Any]] = state.get("screened") or []
|
||||
@@ -101,8 +108,11 @@ def prompt_node(state: Dict[str, Any]) -> Dict[str, Any]:
|
||||
print_suffix = (pp.get("print_suffix") or "").strip() or PINTEREST_PRINT_SUFFIX
|
||||
spelling_rule = (pp.get("spelling_rule") or "").strip() or SPELLING_RULE
|
||||
review_rebrand_hint = (pp.get("review_rebrand_hint") or "").strip() or REVIEW_REBRAND_HINT
|
||||
custom_ip_tpl = (pp.get("image_prompt_template") or "").strip() or CUSTOM_IMAGE_PROMPT_TEMPLATE
|
||||
custom_neg = (pp.get("negative_prompt") or "").strip() or CUSTOM_NEGATIVE_PROMPT
|
||||
# 自定义模式生图模板优先读 prompts/custom_image_prompt.md(可编辑),
|
||||
# 其次 config.custom.prompt_pieces,最后回退代码内置默认。
|
||||
# 自定义模式不再使用负向提示词(约束已内置进模板),不再读取 custom_negative_prompt.md。
|
||||
custom_ip_tpl = _read_custom_prompt_md("custom_image_prompt.md") \
|
||||
or (pp.get("image_prompt_template") or "").strip() or CUSTOM_IMAGE_PROMPT_TEMPLATE
|
||||
|
||||
briefs: List[Dict[str, Any]] = []
|
||||
for r in screened:
|
||||
@@ -122,15 +132,20 @@ def prompt_node(state: Dict[str, Any]) -> Dict[str, Any]:
|
||||
|
||||
prompts = assemble_prompts(motif, art_style, palette, composition, tpls, country)
|
||||
llm_ip = (r.get("image_prompt") or "").strip()
|
||||
if r.get("source") == "pinterest" and llm_ip:
|
||||
delta = (r.get("delta") or "").strip()
|
||||
if r.get("source") == "pinterest":
|
||||
if bool(state.get("custom_mode")):
|
||||
# —— 自定义模式:固定模板(前缀 + 分析 image_prompt),负向用固定文本 ——
|
||||
# 模板含防复制/防服装约束,不再追加 print_suffix;负向写入 composite_negative,
|
||||
# compose 生图时作为负向参数传给图像后端。
|
||||
prompts["image_prompt"] = custom_ip_tpl.replace("{image_prompt}", llm_ip)
|
||||
prompts["composite_negative"] = custom_neg
|
||||
print(f"[prompt] 自定义模式按固定模板拼 image_prompt(含固定负向): 「{r['topic']}」")
|
||||
else:
|
||||
# —— 自定义模式:固定模板(前缀 + 分析 image_prompt + delta 改动指令),负向留空 ——
|
||||
# 新分析模板只产出 delta(无 image_prompt),生图模板也只引用 {delta};
|
||||
# 只要 delta 或 image_prompt 任一存在即可装配,不再使用负向提示词
|
||||
# (约束已全部内置进模板),composite_negative 置空避免后端追加 Negative 段。
|
||||
if llm_ip or delta:
|
||||
prompts["image_prompt"] = (
|
||||
custom_ip_tpl.replace("{delta}", delta).replace("{image_prompt}", llm_ip)
|
||||
)
|
||||
prompts["composite_negative"] = ""
|
||||
print(f"[prompt] 自定义模式按固定模板拼 image_prompt(含 delta 改动指令,无负向): 「{r['topic']}」")
|
||||
elif llm_ip:
|
||||
# —— Pinterest 参考模式:跳过四要素模板,按 3 段结构拼 image_prompt ——
|
||||
# ① image_prompt(分析模型产出) + 固定输出形态后缀 PINTEREST_PRINT_SUFFIX
|
||||
# ② 拼写锁定句 SPELLING_RULE(仅当 LLM image_prompt 已含引号文字段时)
|
||||
|
||||
Reference in New Issue
Block a user