Skip to content

feat(prompt): 攻击提示词按运动拓扑分四支 - #320

Open
johnnyzhang-eng wants to merge 1 commit into
1024XEngineer:mainfrom
johnnyzhang-eng:feat/attack-archetypes-v2
Open

feat(prompt): 攻击提示词按运动拓扑分四支#320
johnnyzhang-eng wants to merge 1 commit into
1024XEngineer:mainfrom
johnnyzhang-eng:feat/attack-archetypes-v2

Conversation

@johnnyzhang-eng

Copy link
Copy Markdown
Contributor

Refs #310

问题

attack.md 里三处措辞合起来断言了角色的身体构造和手里拿的东西:

  • the leading arm —— 断言有手臂,且发力主语是手臂
  • downward crescent arc —— 断言挥动轨迹是弧线
  • broad side facing the viewer —— 断言手里那件东西有"宽面"

三条合起来 = "双足 + 有手臂 + 手握一件有宽面的长条物"。喂法杖 / 空手 / 四足角色时,
图文矛盾会被模型自己调和掉,凭空补出那件宽面长条物。#195 那次修复只清了装备名词
(the weapon / the sword),没清装备形状先验,所以同一个坑从名词层退到了形状层。

改法

身体怎么发力分四支运动拓扑,而不是按手里拿什么分:

拓扑 适用 起手
sweep 长条持物:横挥 / 下劈 横向蓄力,发力侧拉到身后腰际
thrust 短持物或空手:直出 / 戳刺 低位蓄力,发力侧收在腰际待发
project 远程:身体前压、送到位、终态保持 双脚站定,双手收在胸前
lunge 非双足:整体前扑,头部 / 前肢领先 四肢收在身下,胸压低

attack.md 拆成 <拓扑>.<朝向> 八节,master_poses.md 的 attack 节同步拆成四节。
母版姿态必须跟着拆:四支的起手姿态互不兼容 —— 拿横挥蓄力母版跑直刺,模型会先把收在
腰际的那侧重新抡起来再做。所以 ATTACK_MASTER_POSES 不放行空值,缺一支就炸,不退回
中性站立。

build_attack_promptarchetype 关键字参数,默认 THRUST:四支里只有 SWEEP
要求手里有一件有宽面的长条物,拿它当默认等于对每个未知角色继续断言持械。
ActionSpec.archetype 是可选字段,非攻击动作带它会被 validator 拒收(它只被攻击提示词
消费,传了不生效,静默忽略比报错更坏)。缺省值只在 build_attack_prompt 定义一处,
ActionSpec 侧留 None,避免同一个缺省两处各写一份后各自漂移。

顺带把构图约束抽进 prompt/_framing.py,由代码统一追加到 walk / jump / idle / attack /
custom 五个动作,不再抄进每份 md —— 同一条约束抄 N 份会各自漂移。只写正向计数句
("恰好一个角色在画面里"),不写否定句:该 i2v 接口没有 negative_prompt,否定句里的名词
会被 latch 进画面。

怎么验证的

新增 backend/tests/test_attack_archetypes.py(57 个用例),按结构性质断言而不是背文案:

  • 八个 拓扑×朝向 组合都解析到真正文,两两互不相同
  • 每一支都不含形状先验词(crescent / broad side / blade / shaft 等),母版姿态同样查
  • 每一支的发力主语是身体部位不是 the leading arm
  • 每一支都写了整体位移(whole body / torso / hips)—— i2v 强跟身体、弱跟持物
  • 默认支是 THRUST 不是 SWEEP;非法拓扑当场抛错,不静默落到某一支
  • ActionSpec 对非攻击动作拒收 archetype;派生层真的把 archetype 传下去了

本地闸门(backend/):

uv run ruff check .    All checks passed
uv run lint-imports    Contracts: 2 kept, 0 broken
uv run pytest -q       740 passed, 14 skipped

没跑任何付费生成,断言都是纯文本结构检查。

范围

只含后端。_framing.py 会被后续几个动作相关 PR 共用,但本 PR 自带完整实现,可独立合入。

attack.md 拆成 sweep/thrust/project/lunge × side/front 八节,去掉 crescent /
broad side 这类形状先验 —— 它们等于断言角色手握一件有宽面的长条物,喂法杖 /
空手 / 四足角色时模型会凭空补出那件东西(1024XEngineer#195 只清了装备名词,没清形状先验)。

build_attack_prompt 新增 archetype(默认 THRUST,SWEEP 是唯一要求持有长条物的
一支),ActionSpec 加同名字段并对非攻击动作拒收;母版姿态同步分四支。
构图约束抽到 _framing 由代码统一追加到五个动作,只写正向计数句。

Refs 1024XEngineer#310
@vercel

vercel Bot commented Aug 14, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
windup Ignored Ignored Preview Aug 14, 2026 9:50am

@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@fennoai fennoai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review conclusion

我检查了请求入口 → ActionSpec → 攻击提示词,以及拓扑对应母版姿态这两条契约。提示词八分支本身结构一致,但当前生产调用链没有把拓扑选择送进来,新增的四套母版姿态也没有进入任何生成路径,因此除默认 thrust 外的行为尚未真正落地。GitHub 的 lint-and-test 已通过;当前沙箱缺少 uv/pytest,未能本地复跑测试。

View job run

# attack 同样进不了那张表:它还要按运动拓扑选提示词分支。archetype 缺省时不在这里
# 兜一个默认值 —— 缺省只由 build_attack_prompt 定义一次,写两处会各自漂移。
if action.action is ActionType.ATTACK:
if action.archetype is None:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] 把 archetype 贯通到生产请求模型

生产入口 CharacterActionGenerateRequestCharacterActionInputActionTaskExecutor._produce_action 都没有 archetype 字段或转发逻辑,所以所有 API 提交的 attack 最终都会走这里的 None 分支并固定使用默认 THRUST;客户端即使提交 archetype: "sweep"/"project"/"lunge",Pydantic 请求模型也会把这个未知字段忽略。请将该枚举从请求层贯通到 ActionSpec(并对非 attack 拒收),否则新增的三个非默认拓扑在实际产品路径中不可达。

# attack 按运动拓扑取母版姿态:四支的起手姿态互不兼容(横挥蓄力母版跑不出直刺),
# 而"母版姿态决定动作"对 attack 最狠 —— 见本模块开头。这里不放行空值:
# 四支都必须有自己的蓄力姿态,缺一支就该炸,不能退回中性站立。
ATTACK_MASTER_POSES = {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] 让拓扑专用母版姿态进入生成路径

这张新映射目前只被测试导入,生产代码没有任何消费者;VideoFrameStrategy.derive 仍直接使用同一份调用方 master,并且只按动作字符串调用 prepare_master(master, "attack"),完全不知道所选 archetype。于是即使直接构造 ActionSpec(archetype=LUNGE/PROJECT/...),运行时也只是换了视频提示词,不会使用这里声明的互不兼容的起手姿态,正好违背本 PR 所述“母版姿态决定动作”的核心约束。请在母版生成/选择链路中按 archetype 消费该映射,或把对应姿态随动作规格明确传入。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant