Files
beige/backend/app/services/ai_engine/constants.py
yangqianqian df1856d793 上线版: 产品表单统一+form嵌套修复+用户管理+部署+三套叙事
- 产品编辑入口统一走 ProductFormFull(卖点/风格/人群/品牌词全字段);
  修复开任务页 <form> 套 <form> 致"编辑产品"报错、改不了、跳回首个产品
- dashboard 入口卡片对齐实际路由: 系统管理(/config) 与 工作配置(/settings) 分开;
  settings ?tab=products 直达改用挂载后读 URL, 消除 hydration mismatch
- 新增用户管理(users API/admin service/改密页) + alembic 022/023/024
- 上线部署: Dockerfile / docker-compose.prod+https / nginx https / .env.example
- A8 三套正交叙事(痛点/场景/成分背书) + beige 调色去AI化 + 飞轮 text_import 高权重信号

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-30 18:08:13 +08:00

210 lines
16 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
AI 引擎中心常量
扒自worker/src/copy.js + image.js 上线版
业务参数不写死基石A——分值权重可由产品档案配置覆盖
"""
# ── 合规红线 ──────────────────────────────────────────────
# 初始默认词库(数据库 banned_words 表可覆盖updatable=True
BANNED_WORDS_DEFAULT = ["美白", "祛斑", "速效", "医用", "药妆"]
BANNED_VISUAL_WORDS = [
"前后对比", "使用前后", "用前用后",
"before", "after", "变白", "瑕疵消失", "治疗前后",
]
# 内部提示词(不能混入正文 content 字段)
INTERNAL_COPY_HINTS = [
"配图建议", "图片方向", "内页规划", "适合做成",
"不要做促销海报", "配图说明", "封面建议",
]
# ── 机械五维打分基线仅轨B导入文案/降级回退用轨A已切 AI 评委 llm_score_copy─────
# 历史注轨A原用此5维2026-06-15切至7维AI评委(6维+合规)后此处只作轨B+回退占位。
# 关键词维度(keyword20)因 products 表无 keywords 字段导致 matched 恒空已知不准;
# 轨A不再依赖此权重轨B展示参考可接受。不按此调分真过关靠北哥抽检。
SCORE_WEIGHTS = {
"title": 25,
"emotion": 25,
"selling": 25,
"keyword": 20,
"compliance": 5,
}
# ── AI 评委 7 维满分分布倩倩姐2026-06-22拍板补标签精准·与 llm_scorer._DIM_MAX/_score_prompt 三处同步)──
# 7维AI读分(痛点16+情绪16+买点16+钩子13+标题13+真实感11+标签精准10=95) + 合规5 = 100
# 标签精准度=北哥要害⑤出单命门(精准购买意向埋词)分从原6维各匀出总分仍95合格线80不动非降门槛
AI_DIM_WEIGHTS = {
"痛点人群精准": 16,
"情绪张力": 16,
"买点转化": 16,
"开头钩子": 13,
"标题点击力": 13,
"真实感": 11,
"标签精准度": 10,
"compliance": 5, # 机械硬拦,不进 AI 评委
}
# 过线分。倩倩姐2026-06-15拍板80是临时观察值(AI评委给分克制84文案实为合格)。
# 倩倩姐2026-06-15再次拍板维持80临时线不准擅自调85。方向=提生成质量顶分数,不降标准。
# 真过关靠北哥抽检;提质量方向=优化生成 prompt不靠提高门槛凑数。
QUALITY_PASS_SCORE = 80
# ── 文案去重阈值 ──────────────────────────────────────────
DEDUP_TITLE_THRESHOLD = 0.82 # 标题相似度≥此值判重
DEDUP_TITLE_CONTENT_TITLE = 0.65 # 标题+正文联合判重时的标题阈值
DEDUP_TITLE_CONTENT_BODY = 0.72 # 标题+正文联合判重时的正文阈值
# ── 自动优化循环 ──────────────────────────────────────────
MAX_OPTIMIZE_ROUNDS = 2 # 最多重生成轮次
# ── storyboard 分镜角色(枚举不写死数量)────────────────
# Q6: 北哥6张套路顺序 ①封面痛点大字 ②单品特写+品牌词 ③成分 ④质地 ⑤效果证明(按品类) ⑥促单
PAGE_ROLES = [
{"role": "hook", "name": "封面痛点大字", "focus": "负责点击:强情绪大字标题压痛点,产品露出,真实生活场景,像用户主动分享,不像广告海报"},
{"role": "product_closeup", "name": "单品特写", "focus": "负责种草锚点:单品高清特写+品牌词自然植入第2/6张都带品牌词强化记忆"},
{"role": "ingredient", "name": "成分拆解", "focus": "负责信任:核心成分信息、作用说明,避免医疗化和绝对化表达,信息清晰可信"},
{"role": "texture", "name": "质地展示", "focus": "负责种草:质地近景、涂抹过程、肤感说明,真实手部/桌面/日常光线"},
{"role": "applied_proof", "name": "效果证明", "focus": "负责证明:可感知的真实使用效果,按品类展示使用过程/状态变化(护肤=上脸肤感/食品=入口口感/家居数码=使用顺手等不做违规功效暗示第5张"},
{"role": "closer", "name": "促单收尾", "focus": "负责转化:转化句+品牌词引导搜索品牌词成交软性收尾不硬广第6张再带一次品牌词"},
# 扩展角色8张链路用
{"role": "pain_scene", "name": "痛点共鸣", "focus": "负责共鸣:展示目标人群的真实困扰和使用前情境,但不做功效前后对比"},
{"role": "social_proof","name": "信任背书", "focus": "负责背书:多人反馈、囤货、复购等真实社交证据"},
{"role": "scenario", "name": "多场景演示", "focus": "负责代入:多场景使用展示,不做夸大效果承诺"},
{"role": "tutorial", "name": "使用教程", "focus": "负责降低门槛:简洁步骤、用量、注意事项"},
]
PAGE_ROLE_MAP = {r["role"]: r for r in PAGE_ROLES}
# ── R5多图分镜role → 优先产品图场景(scene) 偏好表 ──────────
# 生图时按分镜 role 选该场景的产品图当参考;取不到回落主图(primary)。
# scene 取值见 enums.ProductImageSceneprimary/scene/texture/ingredient/model
ROLE_SCENE_PREFERENCE = {
"hook": ["scene", "primary"], # 封面:真实生活场景优先
"pain_scene": ["scene", "primary"], # 痛点共鸣:使用前情境
"product_closeup": ["primary"], # 单品特写:白底主图
"ingredient": ["ingredient", "primary"], # 成分拆解:成分/包装细节
"texture": ["texture", "primary"], # 质地展示:质地特写
"applied_proof": ["model", "scene", "primary"], # 效果证明:使用场景/上身/上脸图
"social_proof": ["scene", "primary"], # 社交背书:场景
"closer": ["primary"], # 促单收尾:主图
"scenario": ["scene", "primary"],
"tutorial": ["model", "scene", "primary"],
}
# ── 生图风格预设(扒 image.js STYLE_PROMPTS:26-29──────────
# 按 style 参数选小红书风格调性,注入 base_prompt 的"视觉风格"行
STYLE_PROMPTS = {
"xiaohongshu_cover": "小红书种草风独立3:4图文海报/素材图1024×1536构图明亮干净真实实拍质感醒目中文短标题文字在安全区内",
"comparison": "小红书说明对比风独立3:4图文海报/素材图1024×1536构图质地/场景/使用状态左右或上下对比,信息层级清晰",
"ingredient": "小红书信息科普风独立3:4图文海报/素材图1024×1536构图成分/参数卡片布局,浅色干净商务风,避免医疗化表达",
}
STYLE_DEFAULT = "xiaohongshu_cover"
# ── 叙事链路说明(扒 image.js planImageSet narrativeText:677-681──
# 按图数告诉模型整组图的种草节奏,让每张各司其职不雷同
NARRATIVE_BY_COUNT = {
3: "3张极速链路第1张负责点击第2张是按品类变化的核心证明页第3张负责软性转化。",
6: "6张标准种草链路封面点击、单品特写带品牌词、成分/参数信任、质地/细节种草、按品类的真实效果证明、促单转化,每张画面和文字各司其职不重复。",
8: "8张沉浸测评链路点击、痛点共鸣、单品特写、成分/参数、质地/细节、按品类的真实效果证明、背书、软性转化。",
}
# ── 3套正交叙事策略倩倩姐2026-06-15起草北哥过目版──────────────
# A痛点先行/B场景先行/C成分背书先行三套正交轴拉开差异
# 每套叙事链路注入 base_prompt 叙事链路段,替换 NARRATIVE_BY_COUNT 默认值
NARRATIVE_BY_STRATEGY = {
"A": (
'【套A·痛点先行】整组基调紧迫感、强对比、情绪共鸣文字短促带感叹号直戳产品要解决的核心痛点痛点取自上文产品卖点/人群,不要套用别的品类)。'
'6张链路①痛点暴击封面强情绪大字直击该产品核心痛点→ ②痛点实拍对比(感叹号+对比词制造紧迫感)'
'→ ③单品特写+品牌词 → ④核心成分为什么能解决该痛点(成分拆解+信任) → ⑤使用效果实证 → ⑥用痛点收束的软性促单。'
),
"B": (
'【套B·场景先行】整组基调轻松、生活化、代入感突出该产品的真实使用场景与"快/省时/省心"卖点,点到性价比不堆砌。'
'6张链路①真实使用场景封面取该产品最高频的生活场景做钩子 → ②场景代入(还原用户在该场景里的困扰)'
'→ ③单品特写+品牌词 → ④核心成分支撑该场景卖点 → ⑤使用效果展示 → ⑥用场景化卖点收束的软性促单。'
),
"C": (
'【套C·成分背书先行】整组基调专业、可信、真实测评感强调成分逻辑+前后对比+像有用户实证背书。'
'6张链路①成分权威封面该产品核心成分信息锚定信任 → ②核心成分图解(作用说明+清晰可信)'
'→ ③单品特写+品牌词 → ④使用前后时间线对比 → ⑤真实使用细节 → ⑥用成分可信度收束的软性促单。'
),
}
# ── 文案3套正交叙事策略倩倩姐2026-06-18过目版与图片侧同A/B/C轴──────
# 注入 build_prompt让三套文案各走不同叙事主线避免套路化重复
# 与 NARRATIVE_BY_STRATEGY图片侧同根套A文案痛点先行↔套A图也痛点先行同套内文图一致
TEXT_NARRATIVE_BY_STRATEGY = {
"A": (
"【本条叙事主线·痛点先行】开篇第一句必须直接说出'使用前的困扰/焦虑情绪'本身"
"(取自本产品要解决的那个具体痛点,以及试过很多没用的挫败感),先有情绪再有场景,"
"痛点取自上文产品卖点/目标人群、不要套用别品类;情绪强、句子短促带感叹。"
"⚠️开篇禁止从'时间/场景'切入如一天里的某个时刻、赶时间、通勤那是套B的开法必须先抛情绪/痛点。"
"▶中段背书方式=自己反复挣扎后的转折(试错→死心→偶然回购/被一个生活细节打动),"
"靠自己使用前后的真实变化来自证,不要用'闺蜜/同事/家人种草'来背书。"
"▶卖点要带着'这个困扰被解决了'的情绪逐个讲emoji用情绪向😭🥹💛"
"▶收尾用该痛点的释然收束('现在不慌了'类),禁止用'被身边人夸/被问起'桥段那是套B的尾"
),
"B": (
"【本条叙事主线·场景先行】开篇用一个具体的生活使用场景白描切入"
"(最真实高频的那个使用时刻,画面感优先),痛点藏在场景里自然带出、不喊口号,"
"突出'快/省时/省心'类卖点,点到平价性价比但不堆砌。"
"▶中段背书方式=身边人(同事/家人)在场景里的一句随口反馈,轻松不刻意。"
"▶成分融在使用场景里一两句带过即可不要单独列大段成分清单emoji用场景向☕🚇✨"
"▶收尾用场景延续('下次再有人问…我知道怎么答了'类)。"
),
"C": (
"【本条叙事主线·专业背书先行】开篇必须从'成分/参数/原理/测评对比'等专业依据切入"
"(按本产品品类对应:护肤食品讲成分配方、数码家居讲参数原理、服饰讲材质工艺,"
"如翻配料/参数表、对比实验、为什么这个设计/成分有用),先讲可信度再讲使用。"
"⚠️开篇禁止从'时间/场景'切入如赶时间、通勤、被人问起那是套A/B的开法必须从专业依据入手。"
"▶中段背书方式=理性自证(参数/成分对比/和踩过的雷横向比/前后时间线实测/参考测评博主的拆解分析),"
"靠数据和亲测说话,不要用'闺蜜/同事/家人种草'来背书。"
"▶专业依据要讲得比A/B更深为什么这项关键/感知差异/和别家差在哪),是本套的差异优势,"
"emoji用理性向🔍💧🧪收尾用专业可信度收束。"
),
}
IMAGE_RETRY_ATTEMPTS = 3 # 生图重试总次数(含首次)
IMAGE_RETRY_BACKOFF_BASE = 2.0 # 指数退避底数(秒)
IMAGE_SIZE_DEFAULT = "1024x1536"
# ── 生图合规负向约束(方法层常量,全品类共用,可扩展)───────────────────────
# 追加到每个 base_prompt 末尾,防模型脑补违禁词/真实品牌到包装
IMAGE_NEGATIVE_CONSTRAINTS = (
"【包装合规硬性禁止——必须严格遵守】"
"①包装/瓶身/标签上禁止出现任何违禁词:美白/whitening/祛斑/brightening/"
"医用/medical/drug/药妆/速效/instant中英文全禁"
"②禁止脑补任何真实品牌名或logo如水密码/WETCODE/兰蔻/SK-II等"
"产品包装只允许出现用户传入的指定品牌词,未传则画无字素瓶;"
"③英文功效词(ANTI-AGING/TONE-UP/BRIGHTENING/FIRMING等)禁止印在包装;"
"④如果提供了产品参考图,包装文字以参考图为准,不得自行添加或修改任何文字。"
"⑤背景纯净:禁止出现电子设备/笔记本电脑/键盘/手机/桌面杂物等无关物体(参考图若含此类背景一律不沿用),"
"只保留浅色简洁台面或产品定制场景,主体聚焦产品本身。"
)
# ── 小红书素人感正向约束C7反电商摆拍对齐真实笔记观感──────────────
# 追加到 base_prompt 末尾,与 IMAGE_NEGATIVE_CONSTRAINTS 互补:前者管合规,本条管"像不像小红书"
IMAGE_XHS_STYLE_CONSTRAINTS = (
"【小红书素人感——必须像真人随手拍后简单排版,不是电商详情页】"
"①禁止纯白底影棚摆拍、居中正打光、官方产品主图那种电商感;"
"②要有生活气:自然光/窗边光、桌面或梳妆台真实场景、可带手持或局部环境,像朋友分享而非广告;"
"③构图随性不刻意对称,允许轻微景深虚化,避免过度精修的塑料光泽和磨皮假面感;"
"④文字排版克制像博主手作:主标题手写感或简洁无衬线,避免大字促销价签/打折标/电商角标;"
"⑤整体观感=真实测评/日常分享,宁可朴素也不要假亮假精致。"
)
# C3 代码叠字开关先留口子不实现倩倩姐2026-06-12拍板
# True 时由 PIL 在模型出的干净底图上叠主标题/品牌词,彻底解决 gpt-image-2 中文乱码;
# 当前 False=仍由模型画字(偶发错别字为已知问题)。接入点见 image_gen._gen_one 的 TODO。
OVERLAY_TEXT_RENDER_ENABLED = False
# ── 飞轮信号权重(初始默认,北哥可校准)────────────────
FLYWHEEL_WEIGHTS = {
"text_select": 3,
"image_select": 3,
"text_edit": 5, # 改稿=用户真动手改字=最强真实意图,与approve同级(倩倩姐2026-06-16拍板)
"text_import": 8, # 导入=客户实跑验证过的范本,权重最重(倩倩姐2026-06-26拍板),与enums.SIGNAL_WEIGHTS对齐
"approve": 5,
"reject_with_reason": -3,
"regenerate": -1,
}
FLYWHEEL_LOOKBACK = 50 # 聚合最近N条事件
FLYWHEEL_COLD_START = 5 # 信号不足N条时用产品档案冷启动