# 世界 Profile 映射优化方案(2026-04-18) 更新时间:`2026-04-18` ## 0. 文档目标 这份文档基于以下结论继续推进: - `docs/audits/CUSTOM_WORLD_PROFILE_MAPPING_AUDIT_2026-04-18.md` 已确认,当前世界 `profile` 已打通主干映射,但还没有成为“所有预设内容与实时生成规则共同优先读取的单一真相源”。 - 当前最主要的缺口不是“没有世界设定”,而是“世界设定没有被所有运行时链路以同等强度消费”。 - 优化重点应优先放在后端运行时消费链、跨题材兼容链、世界级内容对象化三条主线上,而不是继续堆新预设内容。 本文目标不是重复审计结论,而是把问题整理成: 1. 分优先级的落地改造项 2. 每一项的目标状态 3. 需要修改的关键模块 4. 具体实施步骤 5. 验收标准 6. 风险与回滚策略 --- ## 1. 目标状态 本轮优化完成后,系统应达到以下状态: 1. `CustomWorldProfile` 成为预设内容和实时生成规则的统一主数据源。 2. 前端剧情链、后端任务链、后端物品链消费的是同一套世界语义,而不是“前端懂世界、后端只懂摘要”。 3. `templateWorldType` 只承担兼容字段职责,不再主导跨题材世界的角色、场景、怪物和视觉映射。 4. `items / factions / conflicts / threads` 不再只是文本种子,而是能驱动运行时行为的结构对象。 5. landmark、场景、怪物、掉落、任务、奖励之间的对应关系优先由世界 profile 决定,模板补位只在缺口场景下触发。 --- ## 2. 优先级总览 ## P0:先补“真实消费不完整”的运行时主链 - 让后端 `runtimeItemModule` / `runtimeQuestModule` 接入完整可控的世界 profile 子集。 - 去掉后端运行时里“伪线程 id 冒充真实线程”的弱映射。 - 建立后端世界消费 contract,统一前后端字段裁剪方式。 ## P1:再补“世界设定被模板压扁”的兼容链与物品链 - 把 `templateWorldType` 退回兼容层,不再主导真实映射。 - 为世界级 `items` 建立 seed 与引用链,补齐“世界物件图谱”。 - 让任务奖励、场景宝藏、运行时物品生成优先读取世界物品种子。 ## P2:把文本种子升级为游戏对象 - 把 `majorFactions / coreConflicts` 升级成可索引、可关联、可推进的结构对象。 - 调整 landmark 场景怪物注入逻辑,停止“模板怪物硬补丁”主导场景内容。 - 让世界冲突、势力归属真正影响任务、场景压力、敌对关系。 ## P3:补齐长尾映射与创作层沉淀 - 扩展 `referenceProfile.roleArchetypes` 的来源覆盖,补上 `storyNpcs` 长尾 archetype。 - 重新定义 `creatorIntent / anchorPack / lockState / anchorContent` 中哪些字段需要进入运行时。 - 为后续第四阶段的世界编辑器、运行时回写和世界演化能力预留稳定接口。 --- ## 3. 设计原则 1. 前端只做表现与编排,世界规则解释、任务生成、物品生成、状态持久化都在 Express 后端完成。 2. 优先改造现有链路与现有类型,不新造平行系统。 3. 兼容字段只做 fallback,不反向主导真实世界内容。 4. 所有新增结构都必须能同时服务“预设内容生成”和“运行时规则生成”,避免再次分叉。 5. 每一个优化项都必须带测试入口、验收口径和回滚开关。 --- ## 4. P0 优化方案:补齐后端真实世界消费链 ## P0-1:建立统一的运行时世界消费 Contract ### 问题定义 当前前端剧情主链可以拿到较完整的 `customWorldProfile`,但后端任务与物品模块只消费 `{ name, summary }` 这类瘦身字段,导致同一个世界在不同链路里语义强度不一致。 ### 目标状态 - 后端所有运行时生成模块统一读取 `RuntimeWorldContext`。 - `RuntimeWorldContext` 来源于 `CustomWorldProfile` 的受控裁剪,而不是各模块各自手写轻量字段。 - 前后端消费世界信息时,共享同一套字段分层。 ### 关键文件 - `E:\Repos\Genarrative\server-node\src\modules\ai\customWorldOrchestrator.ts` - `E:\Repos\Genarrative\server-node\src\modules\runtime-item\runtimeItemModule.ts` - `E:\Repos\Genarrative\server-node\src\modules\quest\runtimeQuestModule.ts` - `E:\Repos\Genarrative\src\types\customWorld.ts` - `E:\Repos\Genarrative\src\hooks\story\storyContextBuilder.ts` ### 实施步骤 1. 在后端新增统一的 `RuntimeWorldContext` 类型与构建函数。 2. 首批纳入字段: - `name` - `summary` - `themePack` - `storyGraph` - `knowledgeFacts` - `threadContracts` - `majorFactions` - `coreConflicts` - `ownedSettingLayers.ruleProfile` - `referenceProfile` 3. 在 orchestrator 层完成一次裁剪与归一化,禁止 `runtimeItemModule`、`runtimeQuestModule` 自己拼 world summary。 4. 为后端 prompt 构造器增加“世界上下文来源检查”,缺字段时直接走 fallback 分支并记录日志。 5. 将前端剧情链现有世界裁剪逻辑与后端世界裁剪逻辑对齐,避免出现同字段两套解释。 ### 前后端职责 - 前端:只传递当前线程、当前场景、当前 encounter、当前角色状态等调用上下文。 - 后端:解释世界 profile、构造任务 prompt、构造物品 prompt、产出最终结构化结果。 ### 验收标准 - 后端任务和物品生成日志中可看到相同世界的 `themePack / activeThreads / ruleProfile` 已进入 prompt 上下文。 - 同一世界下,前端剧情 prompt 与后端任务/物品 prompt 的核心势力、冲突、世界基调不再明显割裂。 - 缺失字段时有稳定 fallback,不会因为世界 profile 某块为空直接报错。 ### 风险与回滚 - 风险:一次性带入字段过多,可能导致 prompt 膨胀。 - 回滚策略:保留 `RuntimeWorldContextLite` 开关,出现 token 或稳定性问题时,可按模块退回精简字段集。 --- ## P0-2:让后端 active threads 读取真实故事线程 ### 问题定义 当前后端运行时物品模块里的 `activeThreadIds` 只是 `thread:${encounter.id}` 或 `thread:${scene.id}` 这类伪 id,不是真正来自 `storyGraph` 的线程对象。 ### 目标状态 - 后端运行时统一读取真实 `storyGraph` 线程。 - 若当前 scene / encounter 未命中真实线程,再进入显式 fallback。 - 运行时物品、任务奖励、事件物件都能解释“为什么此刻出现”。 ### 关键文件 - `E:\Repos\Genarrative\server-node\src\modules\runtime-item\runtimeItemModule.ts` - `E:\Repos\Genarrative\src\services\storyEngine\worldStoryGraph.ts` - `E:\Repos\Genarrative\src\services\storyEngine\threadContract.ts` ### 实施步骤 1. 在后端新增 `resolveActiveWorldThreads(...)`,输入 scene、encounter、knowledge facts、runtime memory。 2. 线程命中优先顺序: - 当前 scene 关联线程 - 当前 encounter / npc 关联线程 - 当前已激活 `threadContracts` - 当前 `knowledgeFacts` 所属线程 - fallback synthetic thread 3. synthetic thread 必须显式标记 `source: fallback`,防止伪装成真实世界线程。 4. 物品与任务模块统一消费 `ResolvedThreadRef[]`,不再直接消费裸字符串 id。 ### 验收标准 - 后端日志中可区分真实线程与 fallback 线程。 - 运行时物品说明、任务目标和世界冲突有明确对应,不再只围绕当前场景 id 即时拼接。 ### 风险与回滚 - 风险:现有 scene / encounter 到 thread 的映射不完整,可能导致命中率不高。 - 回滚策略:保留 synthetic fallback,但必须在日志和结构体中显式标识来源。 --- ## P0-3:先补基础验证链,避免后端世界消费升级后失控 ### 问题定义 世界上下文一旦进入后端主链,后续所有任务和物品生成都将更依赖字段质量;若没有结构化校验,很容易引入“字段有了但解释不一致”的新问题。 ### 目标状态 - 为 `RuntimeWorldContext` 建立结构校验与测试样例。 - 世界映射升级后可以快速回归。 ### 实施步骤 1. 为 `RuntimeWorldContext` 增加 schema 校验或最小断言层。 2. 建立 3 组回归世界: - 武侠 - 现代都市 - 科幻/魔法混合 3. 增加任务模块、物品模块的世界消费快照测试。 4. 对“缺 `storyGraph`、缺 `items`、缺 `factions`”的情况补边界测试。 ### 验收标准 - 世界消费链新增测试可稳定通过。 - 新增字段不会让现有预设世界直接失效。 --- ## 5. P1 优化方案:弱化模板主导,补齐世界物件图谱 ## P1-1:把 `templateWorldType` 退回兼容层 ### 问题定义 当前 `templateWorldType / compatibilityTemplateWorldType` 仍然过度参与角色模板、场景视觉、怪物池、fallback 映射,导致跨题材世界被粗暴压回 `WUXIA/XIANXIA`。 ### 目标状态 - `templateWorldType` 仅用于兼容旧模板与最低保底 fallback。 - 真实映射优先读取 `ownedSettingLayers`、`themePack`、`referenceProfile`、世界表达层信号。 - 新世界生成不再被强制压成二元题材。 ### 关键文件 - `E:\Repos\Genarrative\server-node\src\modules\ai\customWorldOrchestrator.ts` - `E:\Repos\Genarrative\src\services\customWorldTheme.ts` - `E:\Repos\Genarrative\src\data\customWorldVisuals.ts` - `E:\Repos\Genarrative\src\data\customWorldNpcMonsters.ts` - `E:\Repos\Genarrative\src\data\characterPresets.ts` ### 实施步骤 1. 梳理所有直接读取 `templateWorldType` 的模块,按用途拆成: - 必须兼容旧内容 - 实际主导内容生成 2. 新增 `worldFlavorProfile` 或等价归一层,从以下信号综合得出世界风味: - 世界主题摘要 - `themePack` - `expressionProfile` - `ownedSettingLayers` - `referenceProfile.sceneBuckets` - `referenceProfile.creatureArchetypes` 3. 将视觉、怪物、角色模板选择改为优先读取 `worldFlavorProfile`。 4. `templateWorldType` 只在真实信号不足时参与兜底。 5. 补 5 类题材测试样本: - 现代金融 - 赛博 AI 战争 - 校园悬疑 - 海洋奇幻 - 仙侠科技混合 ### 验收标准 - 非武侠/仙侠世界不再默认掉进 `WUXIA/XIANXIA` preset 池。 - 视觉、怪物、角色原型对同一世界的选择结果更加一致。 - 旧世界内容仍能被兼容字段兜住。 ### 风险与回滚 - 风险:移除模板主导后,部分老世界可能暂时失去稳定视觉锚点。 - 回滚策略:保留兼容开关,允许单模块临时回退到旧模板选择逻辑。 --- ## P1-2:建立世界级 Item Seed 与 World Item Graph ### 问题定义 `CustomWorldProfile.items` 虽然在类型层存在,但主链会主动清空,导致世界级物品图谱缺席,任务奖励、宝藏、掉落、交易更依赖运行时临时生成。 ### 目标状态 - 世界生成阶段可产出一批结构化 `item seeds`。 - `item seeds` 能挂接到 `knowledgeFacts`、`landmarks`、`factions`、`threads`、`treasure hints`。 - 运行时物品生成优先从世界级物件图谱中取材,而不是完全现场即兴。 ### 关键文件 - `E:\Repos\Genarrative\server-node\src\modules\ai\customWorldOrchestrator.ts` - `E:\Repos\Genarrative\src\services\customWorldBuilder.ts` - `E:\Repos\Genarrative\src\data\customWorldRuntime.ts` - `E:\Repos\Genarrative\src\services\storyEngine\knowledgeGraph.ts` - `E:\Repos\Genarrative\server-node\src\modules\runtime-item\runtimeItemModule.ts` ### 实施步骤 1. 停止在主链里无条件把 `items` 压空。 2. 新增 `WorldItemSeed` 结构,最少包含: - `id` - `name` - `category` - `rarity` - `originType` - `relatedFactionIds` - `relatedThreadIds` - `relatedLandmarkIds` - `knowledgeSummary` 3. 世界生成阶段只产出“有限世界物件 seed”,不预生成全量成品装备。 4. 运行时物品模块新增两段式生成: - 先从 `WorldItemSeed` 中挑选相关 seed - 再根据当前场景和奖励语境编译成最终 runtime item 5. 任务奖励、宝藏提示、交易货单优先引用世界 item seed。 ### 验收标准 - 同一世界内的物品来源能够被追溯到特定势力、地标或线程。 - 宝藏、任务奖励和偶发掉落之间开始出现统一世界物件语义。 - 即使不预生成大量装备,系统也已具备稳定的世界物件骨架。 ### 风险与回滚 - 风险:若 seed 太多,会拖慢世界生成与存档体积。 - 回滚策略:限制每个世界的 seed 上限,只保留高价值世界物件骨架。 --- ## P1-3:统一“任务奖励 / 宝藏 / 掉落 / 交易”的物品取材顺序 ### 问题定义 即使补上世界 `items`,如果各入口仍各自即时生成,世界物件图谱仍然无法变成真实运行时约束。 ### 目标状态 - 物品相关入口统一读取同一套 world-first 取材顺序。 ### 实施步骤 1. 制定统一物品取材优先级: - 世界线程相关 seed - 当前场景相关 seed - 当前势力相关 seed - 当前角色 build / 属性补位型 seed - 程序化 fallback 2. 将该顺序接入: - runtime item - quest reward - treasure hint - shop inventory 3. 为每种入口记录 `itemSourceType`,便于后续审计。 ### 验收标准 - 不同入口产出的物品不再像来自多个无关池子。 - 同一阶段的奖励和世界冲突、场景语境具有明显一致性。 --- ## 6. P2 优化方案:把文本世界升级成可操作对象世界 ## P2-1:把 `majorFactions / coreConflicts` 升级成结构对象 ### 问题定义 当前势力与冲突已能进入 `ThemePack`、`StoryGraph`、`FactionTensionState`,但本质仍偏文本语义层,尚未形成可索引、可归属、可推进的游戏对象。 ### 目标状态 - faction 成为正式实体。 - conflict 成为正式实体。 - NPC、scene、shop、quest、thread 可以明确挂接到 faction/conflict。 ### 关键文件 - `E:\Repos\Genarrative\src\services\storyEngine\themePack.ts` - `E:\Repos\Genarrative\src\services\storyEngine\worldStoryGraph.ts` - `E:\Repos\Genarrative\src\services\storyEngine\factionTensionState.ts` - `E:\Repos\Genarrative\server-node\src\modules\quest\runtimeQuestModule.ts` ### 实施步骤 1. 新增 `WorldFaction`、`WorldConflict` 结构类型。 2. `majorFactions` 进入标准化流程,最少补: - `id` - `name` - `publicImage` - `stanceTags` - `homeLandmarkIds` - `relatedNpcIds` 3. `coreConflicts` 进入标准化流程,最少补: - `id` - `title` - `parties` - `stakes` - `relatedThreadIds` - `pressureLevel` 4. 任务模块改为先选 conflict,再派生 quest intent。 5. scene / npc / 商店 / 敌对阵营状态优先读取 faction 归属。 ### 验收标准 - 任一任务都可追溯到某个 faction 或 conflict,而不只是笼统“世界 tension”。 - NPC 与场景可以明确展示势力归属或冲突立场。 ### 风险与回滚 - 风险:结构化后,旧世界数据可能缺字段。 - 回滚策略:保留旧字符串字段作为输入源,通过标准化编译器补齐对象字段。 --- ## P2-2:修正 landmark 场景中的模板怪物硬注入 ### 问题定义 当前 landmark scene 在放入 `landmark.sceneNpcIds` 对应实体之外,还会从模板怪物池额外拼入敌对实体,导致地标设定与实际战斗实体池出现偏移。 ### 目标状态 - landmark 场景内容优先由 `landmark + storyNpcs + factions + conflicts` 决定。 - 模板怪物仅在内容缺口时补位。 - 补位结果也必须受世界题材和当前线程约束。 ### 关键文件 - `E:\Repos\Genarrative\src\data\scenePresets.ts` - `E:\Repos\Genarrative\src\data\customWorldNpcMonsters.ts` ### 实施步骤 1. 将场景实体池拆成三层: - 显式指定实体 - 世界关系推导实体 - 模板补位实体 2. 补位触发条件必须显式化,例如: - 当前场景无敌对实体 - 当前任务需要战斗对象 - 当前地标存在压力标签但无实体承载 3. 模板补位时必须额外经过: - 世界风味过滤 - faction/conflict 过滤 - landmark 标签过滤 4. 记录实体来源,供后续审计。 ### 验收标准 - landmark 场景中的实体构成更忠于世界原始设定。 - 非武侠/仙侠世界不再被模板怪物池轻易拖偏。 --- ## P2-3:让冲突与势力真实进入任务和场景状态推进 ### 问题定义 即使 faction/conflict 对象化,如果任务与场景状态推进仍然只吃文本 tension,总体改善也会有限。 ### 目标状态 - 冲突和势力状态能驱动任务来源、场景压力、敌我关系和奖励语境。 ### 实施步骤 1. 任务生成先选 conflict,再根据 `pressureLevel`、`party`、`stakes` 生成目标和阶段。 2. 场景压力读取当前 `conflict` 和 `faction tension`,决定: - 敌对出现概率 - 商店风格 - 场景描述张力 3. 奖励语义优先与 conflict/faction 绑定。 ### 验收标准 - 同一冲突升温后,任务、场景、物品奖励能出现同步变化。 --- ## 7. P3 优化方案:补齐长尾 archetype 与创作层沉淀 ## P3-1:扩展 `referenceProfile.roleArchetypes` 来源 ### 问题定义 当前 `roleArchetypes` 主要从 `playableNpcs.slice(0, 6)` 派生,导致可玩角色映射稳定,但长尾 `storyNpcs`、平民、敌对成员、怪物的 archetype 覆盖不足。 ### 目标状态 - `roleArchetypes` 来源覆盖 `playableNpcs + storyNpcs`。 - 长尾角色也能沉淀为稳定 archetype。 ### 关键文件 - `E:\Repos\Genarrative\src\services\customWorldOwnedSettingLayers.ts` - `E:\Repos\Genarrative\src\services\customWorldReferenceSignals.ts` - `E:\Repos\Genarrative\src\data\characterPresets.ts` ### 实施步骤 1. 调整 archetype 编译输入,加入 `storyNpcs`。 2. 按角色用途拆 archetype 桶: - playable - civilian - hostile - monster - faction member 3. 为长尾 archetype 增加抽样上限与去重规则,避免噪声过大。 ### 验收标准 - 非主角型角色在模板选择时命中率更高。 - 长尾场景角色的表现更稳定,不再过度依赖 heuristics fallback。 --- ## P3-2:重新定义哪些创作层元数据需要进入运行时 ### 问题定义 `creatorIntent / anchorPack / lockState / anchorContent` 当前主要停留在创作与编辑器链路,对正式运行时作用较弱。 ### 目标状态 - 明确区分“只服务创作编辑”的元数据和“应进入运行时约束”的元数据。 - 防止未来编辑器功能越做越多,但运行时仍读不到关键锚点。 ### 实施步骤 1. 对四类元数据逐项分层: - 创作态专用 - 编译态可消费 - 运行时必须消费 2. 首批建议进入运行时的内容: - 不可违背的世界禁令 - 必须保留的主势力/主线锚点 - 必须保留的世界表达边界 3. 将运行时需要消费的部分编译进 `ownedSettingLayers` 或 `RuntimeWorldContext`,不要让运行时直接读取编辑器原始字段。 ### 验收标准 - 世界编辑器中被锁定的高优先级设定,能在任务、剧情、物品和场景中持续生效。 - 创作层字段不会原样泄漏进运行时,仍保持清晰编译边界。 --- ## 8. 推荐实施顺序 ## 第一阶段:先打通后端世界消费主链 1. `P0-1` 统一 `RuntimeWorldContext` 2. `P0-2` 接入真实线程解析 3. `P0-3` 补回归验证链 ## 第二阶段:弱化模板主导,补齐世界物件骨架 1. `P1-1` 模板退回兼容层 2. `P1-2` 建立世界 item seed 3. `P1-3` 统一物品入口取材顺序 ## 第三阶段:把世界对象化 1. `P2-1` faction/conflict 对象化 2. `P2-2` 修正 landmark 怪物注入 3. `P2-3` 接入任务与场景状态推进 ## 第四阶段:补齐长尾映射与创作层沉淀 1. `P3-1` 扩展 archetype 来源 2. `P3-2` 明确创作层入运行时边界 --- ## 9. 里程碑拆分建议 ## M1:世界消费对齐 - 输出物:`RuntimeWorldContext`、后端任务/物品世界消费升级、真实线程解析 - 结果判定:前后端都能围绕同一世界线程与规则说话 ## M2:跨题材映射纠偏 - 输出物:`worldFlavorProfile`、模板兼容层瘦身、跨题材测试集 - 结果判定:现代/科幻/混合题材不再被压回武侠/仙侠 ## M3:世界物件与势力冲突对象化 - 输出物:`WorldItemSeed`、`WorldFaction`、`WorldConflict` - 结果判定:任务、场景、物品奖励开始围绕世界对象图谱运转 ## M4:长尾稳定化 - 输出物:扩展 archetype、运行时锚点编译边界 - 结果判定:长尾 NPC 与世界编辑器高优先级设定都能稳定进入运行时 --- ## 10. 验收口径 本轮优化建议至少按以下 8 条验收: 1. 后端任务与物品模块都已消费统一 `RuntimeWorldContext`。 2. 后端 `activeThreadIds` 已能区分真实线程与 fallback 线程。 3. 非武侠/仙侠世界的视觉、怪物、角色模板选择明显更加合理。 4. 世界 profile 中的 `items` 已形成有限但真实可用的 `item seed` 图谱。 5. faction/conflict 已可被任务、场景、物品奖励直接引用。 6. landmark 场景的实体池优先由地标与世界对象决定,不再被模板怪物硬主导。 7. `storyNpcs` 已进入 archetype 编译链。 8. 高优先级创作锚点已通过编译层进入运行时,而不是停留在编辑器态。 --- ## 11. 本轮不建议优先做的事 - 不建议先扩充更多世界 preset、怪物 preset、场景 preset。 - 不建议先美化编辑器文案或增加说明性 UI 文本。 - 不建议在前端直接补更多规则判断,避免继续把世界逻辑留在表现层。 - 不建议在没有统一后端世界 contract 之前分别微调 quest prompt 和 item prompt。 原因很明确: **当前最缺的不是内容数量,而是“世界设定是否真的被一致消费”。在这一层没补齐前,继续加内容只会把映射偏差放大。** --- ## 12. 一句话结论 这轮优化最应该优先做的,不是继续往世界编辑器里加更多设定项,而是先把 `CustomWorldProfile -> 后端运行时任务/物品 -> 场景/NPC/奖励` 这条真实消费主链补齐;只有先把世界 profile 收束成单一真相源,后续跨题材世界、世界级物件、势力冲突和长尾 NPC 映射才会越做越稳。