feat: 修改AI规划出图

This commit is contained in:
R524809
2026-08-27 16:12:56 +08:00
parent 0e8fc4ebe0
commit 4fb37bb45a
+19 -12
View File
@@ -22,23 +22,27 @@ ALLOWED_KINDS = [
"size_chart", "sku_collection", "custom", "size_chart", "sku_collection", "custom",
] ]
# 方案总张数硬上限(提示词预算 + 代码兜底裁减都用它)
MAX_PLAN_TOTAL = 8
SYSTEM_PROMPT = """你是一名资深电商视觉策划。根据商品信息规划一套电商套图的出图方案。 SYSTEM_PROMPT = """你是一名资深电商视觉策划。根据商品信息规划一套电商套图的出图方案。
## 输出硬性约束(违反即失败) ## 输出硬性约束(违反即失败)
1. 输出必须是**单行紧凑 JSON**:无换行、无缩进、无空格填充、无注释、无 markdown 围栏。 1. 输出必须是**单行紧凑 JSON**:无换行、无缩进、无空格填充、无注释、无 markdown 围栏。
2. 顶层只有 summary 和 items 两个字段;每个 item 严格只有 kind/title/detail/prompt_hint/count/variant_name 六个字段,不得增删。 2. 顶层只有 summary 和 items 两个字段;每个 item 严格只有 kind/title/detail/prompt_hint/count/variant_name 六个字段,不得增删。
3. 文本长度上限(中文字符/英文单词数):summary ≤ 25 字;title ≤ 8 字;detail ≤ 20 字;prompt_hint ≤ 15 个英文词。超限必须删减,不得省略号截断。 3. 文本长度上限(中文字符/英文单词数):summary ≤ 25 字;title ≤ 8 字;detail ≤ 20 字;prompt_hint ≤ 15 个英文词。超限必须删减,不得省略号截断。
4. count 默认 1,仅当该类图确需多个变体时才 >1,最大 3。总张数 8-15 4. count 默认 1,仅当该类图确需多个变体时才 >1,最大 3。总张数(所有 count 之和)不得超过 8,这是硬性上限
5. variant_name 只能从「SKU规格」列表原样照抄;没有绑定就输出 null。 5. variant_name 只能从「SKU规格」列表原样照抄;没有绑定就输出 null。
## 规划规则 ## 规划规则(总预算 8 张,按优先级分配)
1. SKU 主图:每个带图 SKU 出 1 张独立主图(kind=white_bg),variant_name 填对应规格名;单 SKU 出 1 张(variant_name=null 1. 总预算:所有项 count 之和 ≤ 8。空间不足时砍低优先级项,优先级从低到高:尺寸标注图 / SKU 合集图 / 细节图 → 场景图;SKU 主图不砍
2. 场景图(kind=lifestyle):按核心使用场景出 2-4 张,每张聚焦一个场景 2. SKU 主图:每个带图 SKU 出 1 张独立主图(kind=white_bg),variant_name 填对应规格名;单 SKU 出 1 张(variant_name=null
3. 细节图(kind=material 或 custom):按关键细节/材质/结构2-3 张,每张聚焦一个卖点 3. 场景图(kind=lifestyle):预算内1-3 张,每张聚焦一个场景
4. 尺寸标注图(kind=size_chart):参数含长宽高/尺寸时出 1 张 4. 细节图(kind=material 或 custom):预算内出 1-2 张,每张聚焦一个卖点
5. SKU 合集图(kind=sku_collection):SKU >1 时出 1 张。 5. 尺寸标注图(kind=size_chart):参数含长宽高/尺寸且预算富余时出 1 张。
6. kind 枚举:white_bg / key_features / selling_pt / material / lifestyle / multi_scene / ecommerce_detail / size_chart / sku_collection / custom 6. SKU 合集图(kind=sku_collection):SKU >1 且预算富余时出 1 张
7. title 用中文短语(如「主图·粉色」「浴室壁挂」);detail 中文说明这张图展示什么;prompt_hint 用英文描述构图要点 7. kind 枚举:white_bg / key_features / selling_pt / material / lifestyle / multi_scene / ecommerce_detail / size_chart / sku_collection / custom
8. title 用中文短语(如「主图·粉色」「浴室壁挂」);detail 中文说明这张图展示什么;prompt_hint 用英文描述构图要点。
## 输出示例(紧凑单行) ## 输出示例(紧凑单行)
{"summary":"三色收纳盒全套图","items":[{"kind":"white_bg","title":"主图·粉色","detail":"粉色SKU白底主视觉","prompt_hint":"front view on white background","count":1,"variant_name":"粉色"}]}""" {"summary":"三色收纳盒全套图","items":[{"kind":"white_bg","title":"主图·粉色","detail":"粉色SKU白底主视觉","prompt_hint":"front view on white background","count":1,"variant_name":"粉色"}]}"""
@@ -214,14 +218,17 @@ async def generate_plan(
items = _normalize_items(data.get("items") or [], sku_variants) items = _normalize_items(data.get("items") or [], sku_variants)
if not items: if not items:
raise RuntimeError("规划器未返回有效方案项") raise RuntimeError("规划器未返回有效方案项")
# 总量保护:超过 18 张时按比例截断 # 总量保护:超过上限时从尾部(低优先级项)裁减,SKU 主图排在前面不受影响
total = sum(i["count"] for i in items) before_trim = sum(i["count"] for i in items)
while total > 18 and items: total = before_trim
while total > MAX_PLAN_TOTAL and items:
last = items[-1] last = items[-1]
if last["count"] > 1: if last["count"] > 1:
last["count"] -= 1 last["count"] -= 1
else: else:
items.pop() items.pop()
total = sum(i["count"] for i in items) total = sum(i["count"] for i in items)
if total < before_trim:
log.info("规划方案 %d 张超出上限 %d,已裁减至 %d 张(从尾部低优先级项开始)", before_trim, MAX_PLAN_TOTAL, total)
return {"summary": str(data.get("summary") or "").strip()[:100], "items": items} return {"summary": str(data.get("summary") or "").strip()[:100], "items": items}