379
docs/audits/CHARACTER_ASSET_PROMPT_CHAIN_AUDIT_2026-04-20.md
Normal file
379
docs/audits/CHARACTER_ASSET_PROMPT_CHAIN_AUDIT_2026-04-20.md
Normal file
@@ -0,0 +1,379 @@
|
||||
# 角色资产 Prompt 链路审计(2026-04-20)
|
||||
|
||||
更新时间:`2026-04-20`
|
||||
|
||||
## 0. 本次审计回答什么问题
|
||||
|
||||
本次只回答角色资产相关的 4 个问题:
|
||||
|
||||
1. `characterAssetPrompts.ts` 里的 `visualPromptText` 和 `animationPromptText`,是不是“生成角色形象 / 动作形象的默认描述”。
|
||||
2. 生成角色形象的系统提示词在哪个文件,生成默认角色形象描述文本的提示词在哪个文件。
|
||||
3. 生成角色动作的系统提示词在哪个文件,生成默认角色动作描述文本的提示词在哪个文件。
|
||||
4. 当前链路里是否存在冗余流程、保留接口或无效代码。
|
||||
|
||||
---
|
||||
|
||||
## 1. 先说结论
|
||||
|
||||
结论不是“只有一套 prompt”,而是:
|
||||
|
||||
**当前角色资产链路至少有两层 prompt,且这两层在仓库里被不同文件承担。**
|
||||
|
||||
### 1.1 默认描述文本层
|
||||
|
||||
这层的目标是:
|
||||
|
||||
**先给资产工坊里的输入框一个默认可编辑文本。**
|
||||
|
||||
这层不直接拿去生成图片或动作视频。
|
||||
|
||||
当前实际主链来源:
|
||||
|
||||
- `src/prompts/customWorldRolePromptDefaults.ts`
|
||||
|
||||
它会把角色已有字段映射成:
|
||||
|
||||
- `visualPromptText`
|
||||
- `animationPromptText`
|
||||
- `scenePromptText`
|
||||
|
||||
其中:
|
||||
|
||||
- `visualPromptText` 优先取 `visualDescription`
|
||||
- `animationPromptText` 优先取 `actionDescription`
|
||||
- `scenePromptText` 优先取 `sceneVisualDescription`
|
||||
|
||||
这层是**默认描述文本**,不是正式图像模型 prompt。
|
||||
|
||||
### 1.2 正式模型 prompt 层
|
||||
|
||||
这层的目标是:
|
||||
|
||||
**把“默认描述文本”进一步编译成正式给图像模型 / 动作模型的完整 prompt。**
|
||||
|
||||
当前主链来源:
|
||||
|
||||
- `server-node/src/prompts/characterAssetPrompts.ts`
|
||||
- `packages/shared/src/prompts/qwenSprite.ts`
|
||||
|
||||
也就是说:
|
||||
|
||||
1. 前端先有一段短文本
|
||||
2. 后端再用正式 prompt builder 把它扩成模型真正使用的完整 prompt
|
||||
|
||||
---
|
||||
|
||||
## 2. 角色形象生成链路
|
||||
|
||||
## 2.1 生成角色形象的系统提示词在哪
|
||||
|
||||
如果这里问的是“正式生成角色主图时,真正控制模型输出方向的 prompt 主源在哪”,答案是:
|
||||
|
||||
- `server-node/src/prompts/characterAssetPrompts.ts`
|
||||
- `packages/shared/src/prompts/qwenSprite.ts`
|
||||
|
||||
更准确说:
|
||||
|
||||
1. `buildNpcVisualPrompt`
|
||||
- 文件:`server-node/src/prompts/characterAssetPrompts.ts`
|
||||
- 作用:把短描述文本和角色摘要合并
|
||||
2. `buildMasterPrompt`
|
||||
- 文件:`packages/shared/src/prompts/qwenSprite.ts`
|
||||
- 作用:提供正式的角色主图 prompt 骨架
|
||||
|
||||
最终角色形象正式生成请求使用的是:
|
||||
|
||||
- `buildNpcVisualPrompt(...)`
|
||||
|
||||
调用位置:
|
||||
|
||||
- `server-node/src/modules/assets/characterAssetRoutes.ts`
|
||||
|
||||
即:
|
||||
|
||||
**角色主图正式生成的系统提示词主链,不在前端默认值文件,而在后端 `characterAssetPrompts.ts` + 共享 `qwenSprite.ts`。**
|
||||
|
||||
## 2.2 生成默认角色形象描述文本的提示词在哪
|
||||
|
||||
当前仓库需要分两种情况:
|
||||
|
||||
### 情况 A:当前自定义世界资产工坊真实主链
|
||||
|
||||
当前资产工坊默认输入框实际使用:
|
||||
|
||||
- `src/prompts/customWorldRolePromptDefaults.ts`
|
||||
|
||||
这不是 LLM system prompt,而是本地字段映射规则。
|
||||
|
||||
换句话说,当前页面上的默认“形象描述”主要来自:
|
||||
|
||||
- `role.visualDescription`
|
||||
- 或回退到 `role.description`
|
||||
|
||||
### 情况 B:仓库里保留的“默认 bundle 编译接口”
|
||||
|
||||
仓库里仍保留一条后端接口:
|
||||
|
||||
- `/api/assets/character-prompts/generate`
|
||||
|
||||
对应文件:
|
||||
|
||||
- `server-node/src/prompts/characterAssetPrompts.ts`
|
||||
|
||||
这条链使用:
|
||||
|
||||
- `CHARACTER_PROMPT_BUNDLE_SYSTEM_PROMPT`
|
||||
- `buildCharacterPromptBundleUserPrompt`
|
||||
|
||||
它的职责是:
|
||||
|
||||
**让 LLM 从角色卡摘要里编译出一组默认文本 bundle。**
|
||||
|
||||
但当前实际问题是:
|
||||
|
||||
**自定义世界角色资产工坊初始化默认值,并没有走这条接口。**
|
||||
|
||||
因此当前状态更准确地说是:
|
||||
|
||||
- 仓库里有一条“LLM 编译默认文本 bundle”的保留链
|
||||
- 但当前资产工坊真实初始默认值主链,走的是前端本地映射
|
||||
|
||||
---
|
||||
|
||||
## 3. 角色动作生成链路
|
||||
|
||||
## 3.1 生成角色动作的系统提示词在哪
|
||||
|
||||
当前正式动作生成主链在:
|
||||
|
||||
- `server-node/src/prompts/characterAssetPrompts.ts`
|
||||
- `packages/shared/src/prompts/qwenSprite.ts`
|
||||
|
||||
其中分两类:
|
||||
|
||||
1. `buildArkCharacterAnimationPrompt`
|
||||
- 当前图生视频动作链路主入口
|
||||
2. `buildNpcAnimationPrompt`
|
||||
- 通用动作视频 prompt builder
|
||||
3. `buildImageSequencePrompt`
|
||||
- 连续帧方案动作 prompt builder
|
||||
4. `buildVideoActionPrompt`
|
||||
- 共享动作模板骨架,在 `packages/shared/src/prompts/qwenSprite.ts`
|
||||
|
||||
当前主动作链路更偏向:
|
||||
|
||||
- `buildArkCharacterAnimationPrompt`
|
||||
|
||||
调用位置:
|
||||
|
||||
- `server-node/src/modules/assets/characterAssetRoutes.ts`
|
||||
|
||||
## 3.2 生成默认角色动作描述文本的提示词在哪
|
||||
|
||||
当前资产工坊真实默认“动作描述”来源:
|
||||
|
||||
- `src/prompts/customWorldRolePromptDefaults.ts`
|
||||
|
||||
规则是:
|
||||
|
||||
- 优先 `actionDescription`
|
||||
- 回退 `combatStyle`
|
||||
|
||||
这仍然是**默认描述文本层**,不是最终动作模型 prompt。
|
||||
|
||||
仓库里也保留了 LLM 编译 bundle 的接口链:
|
||||
|
||||
- `CHARACTER_PROMPT_BUNDLE_SYSTEM_PROMPT`
|
||||
- `buildCharacterPromptBundleUserPrompt`
|
||||
|
||||
这条链也会生成:
|
||||
|
||||
- `animationPromptText`
|
||||
|
||||
但当前资产工坊真实初始默认值并没有实际调用它。
|
||||
|
||||
---
|
||||
|
||||
## 4. `characterAssetPrompts.ts` 里的 `visualPromptText` / `animationPromptText` 到底是什么
|
||||
|
||||
这两个字段容易混淆,因为它们名字里带 `Prompt`。
|
||||
|
||||
但当前工程里它们更准确的定位是:
|
||||
|
||||
**“默认描述文本 bundle 字段名”,不是最终图像模型请求体里的最终 prompt 名称。**
|
||||
|
||||
也就是:
|
||||
|
||||
- `visualPromptText`
|
||||
- 在 UI 里更像“角色形象描述默认文本”
|
||||
- 之后会再被编译进正式图像 prompt
|
||||
- `animationPromptText`
|
||||
- 在 UI 里更像“角色动作描述默认文本”
|
||||
- 之后会再被编译进正式动作 prompt
|
||||
|
||||
所以对你的问题可以直接回答为:
|
||||
|
||||
**是,它们在当前语义上确实可以看作“默认角色形象 / 动作描述文本”。**
|
||||
|
||||
但需要补一句:
|
||||
|
||||
**它们不是最终一步的正式模型系统提示词,而是正式模型 prompt 的上游输入。**
|
||||
|
||||
---
|
||||
|
||||
## 5. 当前真实调用链
|
||||
|
||||
## 5.1 当前资产工坊页面初始默认值主链
|
||||
|
||||
当前真实主链:
|
||||
|
||||
1. 角色对象已有字段进入前端
|
||||
2. `src/prompts/customWorldRolePromptDefaults.ts`
|
||||
3. `CustomWorldRoleAssetStudioModal.tsx`
|
||||
4. 输入框初始值:
|
||||
- `visualPromptText`
|
||||
- `animationPromptText`
|
||||
|
||||
这条链:
|
||||
|
||||
- 快
|
||||
- 本地可控
|
||||
- 不依赖额外一次 LLM 调用
|
||||
|
||||
## 5.2 当前正式角色主图生成主链
|
||||
|
||||
1. 前端把输入框里的 `visualPromptText` 提交到后端
|
||||
2. `server-node/src/prompts/characterAssetPrompts.ts`
|
||||
- `buildNpcVisualPrompt`
|
||||
3. `packages/shared/src/prompts/qwenSprite.ts`
|
||||
- `buildMasterPrompt`
|
||||
4. 图像模型正式生成
|
||||
|
||||
## 5.3 当前正式角色动作生成主链
|
||||
|
||||
1. 前端把输入框里的 `animationPromptText` 提交到后端
|
||||
2. `server-node/src/prompts/characterAssetPrompts.ts`
|
||||
- `buildArkCharacterAnimationPrompt`
|
||||
- 或 `buildNpcAnimationPrompt`
|
||||
- 或 `buildImageSequencePrompt`
|
||||
3. `packages/shared/src/prompts/qwenSprite.ts`
|
||||
- `buildVideoActionPrompt`
|
||||
4. 动作模型正式生成
|
||||
|
||||
---
|
||||
|
||||
## 6. 冗余流程与当前问题
|
||||
|
||||
## 6.1 明确存在的冗余点:默认 bundle 双链并存
|
||||
|
||||
当前仓库里“默认描述文本”其实有两套来源:
|
||||
|
||||
### 第一套:前端本地字段映射
|
||||
|
||||
- `src/prompts/customWorldRolePromptDefaults.ts`
|
||||
|
||||
### 第二套:后端 LLM bundle 编译接口
|
||||
|
||||
- `server-node/src/prompts/characterAssetPrompts.ts`
|
||||
- `/api/assets/character-prompts/generate`
|
||||
|
||||
问题不在于“两套都存在”,而在于:
|
||||
|
||||
**当前自定义世界资产工坊真实默认值只走第一套,第二套保留但没有进入当前主 UI 链。**
|
||||
|
||||
这意味着:
|
||||
|
||||
1. 从业务视角看,默认描述文本存在双份真相。
|
||||
2. 从维护视角看,两个地方都在描述 `visualPromptText / animationPromptText / scenePromptText` 的生成语义。
|
||||
3. 从测试视角看,后端 bundle 接口仍有测试,但 UI 主链没有使用它。
|
||||
|
||||
判断:
|
||||
|
||||
**这是当前最明显的冗余流程。**
|
||||
|
||||
## 6.2 `scenePromptText` 结构存在,但当前资产工坊没有完整承接
|
||||
|
||||
当前这套链路里:
|
||||
|
||||
- `customWorldRolePromptDefaults.ts` 会返回 `scenePromptText`
|
||||
- `characterAssetPrompts.ts` 也会返回 `scenePromptText`
|
||||
|
||||
但当前资产工坊 UI 里并没有完整对应输入框链路。
|
||||
|
||||
这说明:
|
||||
|
||||
**场景描述文本在结构层存在,但在当前角色资产工坊里没有形成完整的用户可编辑闭环。**
|
||||
|
||||
## 6.3 共享模板与工具模板存在相似实现,但职责不同
|
||||
|
||||
仓库里同时有:
|
||||
|
||||
- `packages/shared/src/prompts/qwenSprite.ts`
|
||||
- `src/prompts/qwenSpriteSheetToolPrompts.ts`
|
||||
|
||||
它们都提供类似的主图 / 动作模板能力。
|
||||
|
||||
但当前定位不同:
|
||||
|
||||
- `packages/shared/src/prompts/qwenSprite.ts`
|
||||
- 正式角色资产主链共享模板
|
||||
- `src/prompts/qwenSpriteSheetToolPrompts.ts`
|
||||
- Qwen 工具链 prompt
|
||||
|
||||
它们不是同一条业务主链里的重复实现,但确实容易让人误读为“双份正式模板”。
|
||||
|
||||
判断:
|
||||
|
||||
**这是“职责上可解释,但认知上高混淆”的并行模板,不建议现在直接删,但需要文档明确边界。**
|
||||
|
||||
## 6.4 当前没有证据说明正式主图 / 动作 prompt builder 是无效代码
|
||||
|
||||
以下 builder 当前都有正式调用点:
|
||||
|
||||
- `buildNpcVisualPrompt`
|
||||
- `buildNpcVisualNegativePrompt`
|
||||
- `buildArkCharacterAnimationPrompt`
|
||||
- `buildNpcAnimationPrompt`
|
||||
- `buildImageSequencePrompt`
|
||||
|
||||
因此它们不能算“无效代码”。
|
||||
|
||||
真正更接近“保留接口但未进入当前 UI 主链”的,是:
|
||||
|
||||
- `CHARACTER_PROMPT_BUNDLE_SYSTEM_PROMPT`
|
||||
- `buildCharacterPromptBundleUserPrompt`
|
||||
- `/api/assets/character-prompts/generate`
|
||||
|
||||
这套链路仍有测试、仍可工作,但当前不属于自定义世界资产工坊的真实默认值主链。
|
||||
|
||||
---
|
||||
|
||||
## 7. 本次建议
|
||||
|
||||
如果后续要继续收口,建议按顺序处理:
|
||||
|
||||
1. 先明确“资产工坊默认值唯一主源”到底选前端本地映射还是后端 LLM bundle 接口。
|
||||
2. 如果继续保留前端本地映射为主链,则把后端 bundle 接口标注为备用 / 实验 / 非主链能力。
|
||||
3. 如果准备切回后端 bundle 接口为主链,则要把当前 UI 初始化逻辑真正接上,并补场景描述输入框闭环。
|
||||
4. 对 `scenePromptText` 做完整承接,不要继续停留在结构存在但 UI 不消费的状态。
|
||||
5. 继续保留 `packages/shared/src/prompts/qwenSprite.ts` 与工具链 prompt 分层,但在文档里强制写清“正式主链 / 工具链”边界。
|
||||
|
||||
---
|
||||
|
||||
## 8. 本次审计覆盖文件
|
||||
|
||||
- `server-node/src/prompts/characterAssetPrompts.ts`
|
||||
- `packages/shared/src/prompts/qwenSprite.ts`
|
||||
- `server-node/src/modules/assets/characterAssetRoutes.ts`
|
||||
- `src/prompts/customWorldRolePromptDefaults.ts`
|
||||
- `src/components/CustomWorldRoleAssetStudioModal.tsx`
|
||||
- `src/components/asset-studio/characterAssetWorkflowPersistence.ts`
|
||||
- `src/prompts/qwenSpriteSheetToolPrompts.ts`
|
||||
|
||||
---
|
||||
|
||||
## 9. 一句话版结论
|
||||
|
||||
一句话总结就是:
|
||||
|
||||
**当前角色资产系统把“默认描述文本”和“正式模型 prompt”拆成了两层,这是合理的;真正的问题不是有两层,而是“默认描述文本层”现在同时保留了前端本地映射和后端 LLM 编译两条链,而当前 UI 主链只用了前者,导致出现明显的冗余和认知混乱。**
|
||||
@@ -15,6 +15,7 @@
|
||||
- [FUNCTION_RUNTIME_FULL_TEST_AUDIT_2026-04-16.md](./FUNCTION_RUNTIME_FULL_TEST_AUDIT_2026-04-16.md):Function 运行时完整测试、服务端承接验证与当前门禁缺口。
|
||||
- [ITEM_AND_BUILD_PRD_AUDIT_2026-04-05.md](./ITEM_AND_BUILD_PRD_AUDIT_2026-04-05.md):物品生成与 Build 标签系统对 PRD 的落地情况。
|
||||
- [CUSTOM_WORLD_CREATOR_TOOL_AUDIT_2026-04-08.md](./CUSTOM_WORLD_CREATOR_TOOL_AUDIT_2026-04-08.md):自定义世界创作工具当前问题、体验断层和优化优先级审计。
|
||||
- [CHARACTER_ASSET_PROMPT_CHAIN_AUDIT_2026-04-20.md](./CHARACTER_ASSET_PROMPT_CHAIN_AUDIT_2026-04-20.md):角色资产默认描述文本、正式图像/动作 prompt、共享模板与保留接口的分层与冗余审计。
|
||||
- [engineering/ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-20.md](./engineering/ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-20.md):对 `2026-04-19` 工程清理审计的当前仓库复核,区分已完成项、仍存边界问题和新的热点迁移。
|
||||
- [engineering/ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-19.md](./engineering/ENGINEERING_CLEANUP_AND_BACKEND_BOUNDARY_AUDIT_2026-04-19.md):未引用垃圾、旧入口残留、前后端双份真相与后端迁移项的专项审计。
|
||||
|
||||
|
||||
Reference in New Issue
Block a user