两层防卡审
This commit is contained in:
@@ -368,6 +368,7 @@ def emit_prompt_gate(
|
|||||||
return []
|
return []
|
||||||
prompt = apply_product_voice_visual_guard(conversation, prompt)
|
prompt = apply_product_voice_visual_guard(conversation, prompt)
|
||||||
prompt = apply_product_reality_guard(prompt)
|
prompt = apply_product_reality_guard(prompt)
|
||||||
|
prompt = apply_video_platform_safety_guard(prompt)
|
||||||
messages = []
|
messages = []
|
||||||
prompt_file = append_message(
|
prompt_file = append_message(
|
||||||
conversation,
|
conversation,
|
||||||
@@ -406,6 +407,7 @@ def emit_final_confirm_gate(
|
|||||||
return None
|
return None
|
||||||
prompt = apply_product_voice_visual_guard(conversation, prompt)
|
prompt = apply_product_voice_visual_guard(conversation, prompt)
|
||||||
prompt = apply_product_reality_guard(prompt)
|
prompt = apply_product_reality_guard(prompt)
|
||||||
|
prompt = apply_video_platform_safety_guard(prompt)
|
||||||
credits = 0
|
credits = 0
|
||||||
if context is not None:
|
if context is not None:
|
||||||
try:
|
try:
|
||||||
@@ -516,6 +518,8 @@ video_prompt 是交给出片模型的完整制作文件,不是方案摘要、
|
|||||||
- 画面中不出现新增字幕、花字、标题贴片、弹幕、角标、水印、购物浮层或说明性文字;口播只存在于声音,包装本身原有印刷字除外。
|
- 画面中不出现新增字幕、花字、标题贴片、弹幕、角标、水印、购物浮层或说明性文字;口播只存在于声音,包装本身原有印刷字除外。
|
||||||
- 结尾单列「全片一致性与禁用项」:重申角色、商品、场景、光线、服装/材质的连续性,以及本片最重要的画面禁用项。
|
- 结尾单列「全片一致性与禁用项」:重申角色、商品、场景、光线、服装/材质的连续性,以及本片最重要的画面禁用项。
|
||||||
- 用户说「商品说话 / 商品自述 / 商品拟人」时,默认无脸拟人:商品声音是画外角色声,商品本体不做口型、不新增卡通五官;性格只通过整体倾斜、转向、弹跳、进退、镜头和音效表达。只有用户明确要求可见卡通五官时才例外。
|
- 用户说「商品说话 / 商品自述 / 商品拟人」时,默认无脸拟人:商品声音是画外角色声,商品本体不做口型、不新增卡通五官;性格只通过整体倾斜、转向、弹跳、进退、镜头和音效表达。只有用户明确要求可见卡通五官时才例外。
|
||||||
|
- 平台安全优先于戏剧冲突:不要撰写或照抄暴力伤害、血腥、裸体或性暗示、违法犯罪、危险挑战、政治敏感、仇恨歧视、真实名人/IP 模仿等内容。若用户原意涉及上述内容,保留原来的情绪转折和商品卖点,改成成年人之间安全、非暴力、无违法的日常误会、压力或竞争,并采用原创人物与场景。儿童只能出现在安全的日常家庭场景,绝不参与危险、成人或营销煽动情节。
|
||||||
|
- 不写医疗诊断、治愈/根治、绝对效果、虚构权威背书或夸大功效;把卖点改为真实可见的使用动作、材质细节和日常体验。最终 video_prompt 必须是可直接提交审核和出片的安全版本。
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
@@ -546,6 +550,42 @@ PRODUCT_REALITY_GUARD = (
|
|||||||
"材质等能力拍成已被验证的结果。若关键信息不足,使用可观察的正常操作替代夸张测试。"
|
"材质等能力拍成已被验证的结果。若关键信息不足,使用可观察的正常操作替代夸张测试。"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# 这一层不是替代平台审核,而是在脚本落成最终 video_prompt 前先把最容易被视频模型
|
||||||
|
# 拦截的明确高风险表述改成等价的安全叙事。模型仍会收到下方完整约束,避免只靠关键词替换。
|
||||||
|
VIDEO_PLATFORM_SAFETY_GUARD = (
|
||||||
|
"【平台安全出片约束·最高优先级】全片仅呈现安全、合法、适合公开传播的原创商业内容。"
|
||||||
|
"不出现或暗示暴力伤害、血腥、自残、裸体、性内容、违法犯罪、赌博、毒品、武器、危险挑战、"
|
||||||
|
"政治敏感、仇恨歧视、真实名人或受保护 IP 模仿。若原剧情有冲突,只用成年人之间安全、"
|
||||||
|
"非暴力的日常误会、压力或竞争来表达,并以沟通或轻松反转收束。儿童仅可出现在安全的日常家庭场景,"
|
||||||
|
"不得参与危险、成人或煽动性情节。商品功效只写已知事实和可见使用体验,不作医疗、治愈、"
|
||||||
|
"绝对化或虚构权威承诺。"
|
||||||
|
)
|
||||||
|
_VIDEO_PLATFORM_SAFETY_REWRITES: tuple[tuple[re.Pattern[str], str], ...] = (
|
||||||
|
(
|
||||||
|
re.compile(
|
||||||
|
r"暴打|殴打|群殴|互殴|动手伤人|打伤|捅伤|刺伤|砍伤|见血|鲜血(?:直流)?|血泊|"
|
||||||
|
r"杀人|杀死|自杀|自残|割腕|跳楼|爆炸|绑架|虐待"
|
||||||
|
),
|
||||||
|
"强烈情绪冲突以安全、非暴力方式化解",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
re.compile(r"裸体|裸露|色情|性爱|性行为|性暗示|挑逗|床戏"),
|
||||||
|
"得体着装下的自然成年人互动",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
re.compile(r"吸毒|毒品交易|贩毒|赌博|赌钱|诈骗|抢劫|偷窃|枪战|持枪|开枪"),
|
||||||
|
"不涉及违法或危险行为的日常情节",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
re.compile(r"治愈|根治|药到病除|包治|抗癌|无副作用|百分之百(?:有效|治愈)|永久(?:有效|瘦)"),
|
||||||
|
"真实、可观察的日常使用体验",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
re.compile(r"(?:模仿|复刻|扮演|像).{0,16}(?:明星|艺人|名人|网红|演员)"),
|
||||||
|
"采用原创人物设定与表演",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def apply_product_voice_visual_guard(conversation: CreationConversation, prompt: str) -> str:
|
def apply_product_voice_visual_guard(conversation: CreationConversation, prompt: str) -> str:
|
||||||
"""商品拟人默认不长脸;用户明确要求可见卡通五官时尊重其创作选择。"""
|
"""商品拟人默认不长脸;用户明确要求可见卡通五官时尊重其创作选择。"""
|
||||||
@@ -576,6 +616,16 @@ def apply_product_reality_guard(prompt: str) -> str:
|
|||||||
return f"{base}\n{PRODUCT_REALITY_GUARD}".strip()
|
return f"{base}\n{PRODUCT_REALITY_GUARD}".strip()
|
||||||
|
|
||||||
|
|
||||||
|
def apply_video_platform_safety_guard(prompt: str) -> str:
|
||||||
|
"""将最终出片指令收束为较不易触发视频模型审核的安全版本,且可重复调用。"""
|
||||||
|
base = str(prompt or "").strip()
|
||||||
|
if not base or VIDEO_PLATFORM_SAFETY_GUARD in base:
|
||||||
|
return base
|
||||||
|
for pattern, replacement in _VIDEO_PLATFORM_SAFETY_REWRITES:
|
||||||
|
base = pattern.sub(replacement, base)
|
||||||
|
return f"{base}\n{VIDEO_PLATFORM_SAFETY_GUARD}".strip()
|
||||||
|
|
||||||
|
|
||||||
class AgentError(Exception):
|
class AgentError(Exception):
|
||||||
"""Agent 循环里的业务错误,已经是可以直接给用户看的中文。"""
|
"""Agent 循环里的业务错误,已经是可以直接给用户看的中文。"""
|
||||||
|
|
||||||
@@ -1748,6 +1798,7 @@ def _video_submit_params(context: AgentContext, prompt: str) -> tuple[dict, list
|
|||||||
prompt = apply_video_preset_prompt(context.conversation.preset, prompt)
|
prompt = apply_video_preset_prompt(context.conversation.preset, prompt)
|
||||||
prompt = apply_product_voice_visual_guard(context.conversation, prompt)
|
prompt = apply_product_voice_visual_guard(context.conversation, prompt)
|
||||||
prompt = apply_product_reality_guard(prompt)
|
prompt = apply_product_reality_guard(prompt)
|
||||||
|
prompt = apply_video_platform_safety_guard(prompt)
|
||||||
prompt = apply_plot_twist_story_contract(
|
prompt = apply_plot_twist_story_contract(
|
||||||
context.conversation.preset,
|
context.conversation.preset,
|
||||||
active_plot_twist_story_depth(context.conversation),
|
active_plot_twist_story_depth(context.conversation),
|
||||||
@@ -3132,6 +3183,7 @@ def _dispatch_tool(
|
|||||||
video_prompt = apply_video_preset_prompt(context.conversation.preset, video_prompt)
|
video_prompt = apply_video_preset_prompt(context.conversation.preset, video_prompt)
|
||||||
video_prompt = apply_product_voice_visual_guard(context.conversation, video_prompt)
|
video_prompt = apply_product_voice_visual_guard(context.conversation, video_prompt)
|
||||||
video_prompt = apply_product_reality_guard(video_prompt)
|
video_prompt = apply_product_reality_guard(video_prompt)
|
||||||
|
video_prompt = apply_video_platform_safety_guard(video_prompt)
|
||||||
video_prompt = apply_plot_twist_story_contract(
|
video_prompt = apply_plot_twist_story_contract(
|
||||||
context.conversation.preset,
|
context.conversation.preset,
|
||||||
active_plot_twist_story_depth(context.conversation),
|
active_plot_twist_story_depth(context.conversation),
|
||||||
@@ -3202,6 +3254,7 @@ def _dispatch_tool(
|
|||||||
video_prompt = apply_video_preset_prompt(context.conversation.preset, video_prompt)
|
video_prompt = apply_video_preset_prompt(context.conversation.preset, video_prompt)
|
||||||
video_prompt = apply_product_voice_visual_guard(context.conversation, video_prompt)
|
video_prompt = apply_product_voice_visual_guard(context.conversation, video_prompt)
|
||||||
video_prompt = apply_product_reality_guard(video_prompt)
|
video_prompt = apply_product_reality_guard(video_prompt)
|
||||||
|
video_prompt = apply_video_platform_safety_guard(video_prompt)
|
||||||
video_prompt = apply_plot_twist_story_contract(
|
video_prompt = apply_plot_twist_story_contract(
|
||||||
context.conversation.preset,
|
context.conversation.preset,
|
||||||
active_plot_twist_story_depth(context.conversation),
|
active_plot_twist_story_depth(context.conversation),
|
||||||
|
|||||||
@@ -1503,6 +1503,32 @@ class PresetGuidanceTests(CreationAgentBaseTests):
|
|||||||
# 重复走闸门不会把同一条约束堆进 Prompt 两遍。
|
# 重复走闸门不会把同一条约束堆进 Prompt 两遍。
|
||||||
self.assertEqual(apply_product_reality_guard(prompt), prompt)
|
self.assertEqual(apply_product_reality_guard(prompt), prompt)
|
||||||
|
|
||||||
|
def test_video_platform_safety_guard_rewrites_high_risk_story_terms(self):
|
||||||
|
from .creation_agent import apply_video_platform_safety_guard
|
||||||
|
|
||||||
|
prompt = apply_video_platform_safety_guard(
|
||||||
|
"妈妈发现孩子被欺负后冲进去暴打对方,鲜血直流;产品能药到病除。"
|
||||||
|
)
|
||||||
|
|
||||||
|
self.assertIn("平台安全出片约束", prompt)
|
||||||
|
self.assertNotIn("暴打", prompt)
|
||||||
|
self.assertNotIn("鲜血直流", prompt)
|
||||||
|
self.assertNotIn("药到病除", prompt)
|
||||||
|
self.assertIn("安全、非暴力方式化解", prompt)
|
||||||
|
self.assertIn("真实、可观察的日常使用体验", prompt)
|
||||||
|
# 方案卡、Prompt 文件、最终提交会多次经过这层,规则只能追加一次。
|
||||||
|
self.assertEqual(apply_video_platform_safety_guard(prompt), prompt)
|
||||||
|
|
||||||
|
def test_video_system_prompt_requires_audit_safe_script(self):
|
||||||
|
conversation = CreationConversation.objects.create(
|
||||||
|
team=self.team, created_by=self.user, mode="video", params={},
|
||||||
|
)
|
||||||
|
|
||||||
|
system = build_system_prompt(AgentContext(conversation=conversation, user=self.user, model_config=self.model))
|
||||||
|
|
||||||
|
self.assertIn("平台安全优先于戏剧冲突", system)
|
||||||
|
self.assertIn("最终 video_prompt 必须是可直接提交审核和出片的安全版本", system)
|
||||||
|
|
||||||
def test_image_preset_style_is_added_only_to_the_actual_image_prompt(self):
|
def test_image_preset_style_is_added_only_to_the_actual_image_prompt(self):
|
||||||
from .creation_presets import apply_image_preset_prompt
|
from .creation_presets import apply_image_preset_prompt
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user