feat: 生图增加商品尺寸填报
This commit is contained in:
@@ -23,10 +23,9 @@ ALLOWED_KINDS = [
|
||||
]
|
||||
|
||||
# 方案总张数安全上限(仅防模型跑飞,不干预正常规划;生图按张计费):
|
||||
# 默认 AI 自主决定张数(prompt 建议 8 张左右),上限 15;
|
||||
# 「生图要求」明确写了「N 张」时按用户指定的来,上限放宽到 24。
|
||||
PLAN_SAFETY_MAX = 15
|
||||
PLAN_REQUIREMENTS_MAX = 24
|
||||
# AI 智能规划最多生成 8 张;即使用户在要求中指定更高张数也不突破此上限。
|
||||
PLAN_SAFETY_MAX = 8
|
||||
PLAN_REQUIREMENTS_MAX = 8
|
||||
MAX_VARIANT_MAIN_IMAGES = 2
|
||||
|
||||
# 规划器的图类归并。不同模型会把“细节图”写成材质图、卖点图或详情图,
|
||||
@@ -53,7 +52,7 @@ SYSTEM_PROMPT = """你是一名资深电商视觉策划。根据商品信息规
|
||||
1. 输出必须是**单行紧凑 JSON**:无换行、无缩进、无空格填充、无注释、无 markdown 围栏。
|
||||
2. 顶层只有 summary 和 items 两个字段;每个 item 严格只有 kind/title/detail/prompt_hint/count/variant_name 六个字段,不得增删。
|
||||
3. 文本长度上限(中文字符/英文单词数):summary ≤ 25 字;title ≤ 8 字;detail ≤ 20 字;prompt_hint ≤ 15 个英文词。超限必须删减,不得省略号截断。
|
||||
4. count 默认 1,仅当该类图确需多个变体时才 >1,最大 3。总张数由你根据商品复杂度与信息量自主决定,不设硬性数量,但建议 8 张左右;若「生图要求」明确指定了张数,必须严格按指定张数输出。
|
||||
4. count 默认 1,仅当该类图确需多个变体时才 >1,最大 3。总张数由你根据商品复杂度与信息量自主决定,最多 8 张;若「生图要求」明确指定了张数,按指定张数输出但仍不得超过 8 张。
|
||||
5. variant_name 只能从「SKU规格」列表原样照抄;没有绑定就输出 null。
|
||||
|
||||
## 规划规则
|
||||
@@ -126,6 +125,9 @@ def _normalize_items(raw_items: list, sku_variants: list[str]) -> list[dict]:
|
||||
|
||||
def _has_dimensions(product_info: dict) -> bool:
|
||||
"""仅在已采集到尺寸信息时规划尺寸图,避免模型编造数值。"""
|
||||
dimensions = product_info.get("dimensions") or {}
|
||||
if isinstance(dimensions, dict) and all(dimensions.get(key) is not None for key in ("length", "width", "height")):
|
||||
return True
|
||||
for param in product_info.get("params") or []:
|
||||
if not isinstance(param, dict):
|
||||
continue
|
||||
|
||||
@@ -133,6 +133,12 @@ def build_context(raw: dict, fallback_name: str = "", fallback_desc: str = "") -
|
||||
if len(selling_points) >= 5:
|
||||
break
|
||||
|
||||
dimensions = raw.get("dimensions") or {}
|
||||
dimension_values = (dimensions.get("length"), dimensions.get("width"), dimensions.get("height")) if isinstance(dimensions, dict) else ()
|
||||
dimensions_line = ""
|
||||
if len(dimension_values) == 3 and all(value is not None for value in dimension_values):
|
||||
unit = dimensions.get("unit") or "mm"
|
||||
dimensions_line = "L × W × H: " + " × ".join(str(value) for value in dimension_values) + f" {unit}"
|
||||
params_line = "; ".join(
|
||||
f"{p.get('key')}: {p.get('value')}" for p in (raw.get("params") or [])[:8]
|
||||
)
|
||||
@@ -141,13 +147,16 @@ def build_context(raw: dict, fallback_name: str = "", fallback_desc: str = "") -
|
||||
"title_en": title, # 采集源多为中文标题,英文场景直接用原词避免乱翻译
|
||||
"desc": desc,
|
||||
"selling_points": selling_points[:3],
|
||||
"params_line": params_line,
|
||||
"params_line": "; ".join(filter(None, (params_line, dimensions_line))),
|
||||
# 俄文图片里不能直接渲染中文参数;保留不含汉字的规格(型号、数字、单位)供尺寸图使用。
|
||||
"params_line_non_cjk": "; ".join(
|
||||
f"{p.get('key')}: {p.get('value')}"
|
||||
for p in (raw.get("params") or [])[:8]
|
||||
if not re.search(r"[\u3400-\u9fff]", f"{p.get('key')} {p.get('value')}")
|
||||
),
|
||||
"params_line_non_cjk": "; ".join(filter(None, (
|
||||
"; ".join(
|
||||
f"{p.get('key')}: {p.get('value')}"
|
||||
for p in (raw.get("params") or [])[:8]
|
||||
if not re.search(r"[\u3400-\u9fff]", f"{p.get('key')} {p.get('value')}")
|
||||
),
|
||||
dimensions_line,
|
||||
))),
|
||||
"price": raw.get("price") or "",
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user