Align context projection defaults with gm-first play model.

Richer synth fallbacks and context-order examples: gm gets narrative guide and history; narrator and auditor skip history; auditor reads settlement at turn end.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-08-25 00:51:47 +08:00
co-authored by Cursor
parent 8360e885bb
commit ac474bcd1a
7 changed files with 66 additions and 44 deletions
+2 -2
View File
@@ -26,8 +26,8 @@
| `narrator` | `narrator` | 叙事转述 | 开 |
| `perspective` | `role-decide` | 角色视角 | 关 |
推荐游玩调度:`auditor → perspective? → gm → narrator`。
旁观维护默认**不注入**「对话.历史」;主世界层 / 转述按投影排序表裁剪历史。
推荐游玩调度:`gm → perspective? → narrator → auditor`。
旁观维护与叙事转述默认**不注入**「对话.历史」;主世界层按投影排序表裁剪历史。
## 3. 上下文片段:`context-fragment.v1`
@@ -36,7 +36,7 @@ feeds: design_only
```opening
按已验收产物的概括,给每个固定执行单元分配上下文顺序(只排序,不改设定、不演游玩)。
名册由程序钉死:旁观维护(表格)/ 主世界层 / 叙事转述 / 可选角色视角 / 按需机遇。
名册由程序钉死:主世界层 / 叙事转述 / 旁观维护(回合末)/ 可选角色视角 / 按需机遇(已并入主世界层工具)。
若前面产物够用,直接回复「按已有概括排序」。
```
@@ -55,7 +55,9 @@ feeds: design_only
1. 禁止发明白名单外 id(含画图等未入册槽)。
2. 禁止重写上游长文;只写顺序与投影。
3. 每轮槽:order 0=该槽固定人设;其后按「稳→对话.历史→易变」软排。
4. 主世界层与转述必须含 ref=`对话.历史`(默认 projection=summary);旁观维护默认不含历史。
4. 主世界层必须含 ref=`对话.历史`(默认 projection=summary);转述与旁观维护默认不含历史。
5. 主世界层应双挂「设计.叙事指南与故事推进」等 mount 到 gm 的块;转述只读裁决+文风/壳。
6. 旁观维护在回合末:须含「运行.本轮.裁决」与变量合同,不含历史。
5. 按需槽(机遇)enabled 时 inserts 可空。
6. 越稳越靠前;本轮输入/真值/裁决通常在历史之后。
7. 同一内容可挂多槽;chance 不必排进每轮 inserts。
@@ -93,20 +95,6 @@ feeds: design_only
"schema": "context-order.v1",
"brief": "一句话:本局有哪些执行单元、各自上下文怎么排",
"agents": [
{
"id": "auditor",
"label": "旁观维护",
"enabled": true,
"when": "every_turn",
"duty": "查表/补规则,不写正文、不写真相",
"inserts": [
{ "order": 0, "ref": "worker.persona", "projection": "fixed", "note": "人设" },
{ "order": 1, "ref": "设计.变量设计与更新规则", "projection": "summary" },
{ "order": 2, "ref": "设计.生成规则", "projection": "summary" },
{ "order": 3, "ref": "变量.当前", "projection": "fields" },
{ "order": 4, "ref": "用户.最新输入", "projection": "full" }
]
},
{
"id": "gm",
"label": "主世界层",
@@ -116,9 +104,13 @@ feeds: design_only
"inserts": [
{ "order": 0, "ref": "worker.persona", "projection": "fixed" },
{ "order": 1, "ref": "设计.舞台骨架", "projection": "summary" },
{ "order": 2, "ref": "对话.历史", "projection": "summary" },
{ "order": 3, "ref": "变量.当前", "projection": "fields" },
{ "order": 4, "ref": "用户.最新输入", "projection": "full" }
{ "order": 2, "ref": "设计.实现机制", "projection": "summary" },
{ "order": 3, "ref": "设计.变量设计与更新规则", "projection": "summary" },
{ "order": 4, "ref": "设计.生成规则", "projection": "summary" },
{ "order": 5, "ref": "设计.叙事指南与故事推进", "projection": "summary" },
{ "order": 6, "ref": "对话.历史", "projection": "summary" },
{ "order": 7, "ref": "变量.当前", "projection": "fields" },
{ "order": 8, "ref": "用户.最新输入", "projection": "full" }
]
},
{
@@ -130,10 +122,26 @@ feeds: design_only
"inserts": [
{ "order": 0, "ref": "worker.persona", "projection": "fixed" },
{ "order": 1, "ref": "设计.叙事指南与故事推进", "projection": "summary" },
{ "order": 2, "ref": "对话.历史", "projection": "summary" },
{ "order": 2, "ref": "设计.正文组成", "projection": "summary" },
{ "order": 3, "ref": "运行.本轮.裁决", "projection": "full" }
]
},
{
"id": "auditor",
"label": "旁观维护",
"enabled": true,
"when": "every_turn",
"duty": "回合末查表/补规则,不写正文",
"inserts": [
{ "order": 0, "ref": "worker.persona", "projection": "fixed" },
{ "order": 1, "ref": "设计.变量设计与更新规则", "projection": "summary" },
{ "order": 2, "ref": "设计.生成规则", "projection": "summary" },
{ "order": 3, "ref": "设计.变量控制上下文", "projection": "summary" },
{ "order": 4, "ref": "运行.本轮.裁决", "projection": "full" },
{ "order": 5, "ref": "变量.当前", "projection": "fields" },
{ "order": 6, "ref": "用户.最新输入", "projection": "full" }
]
},
{
"id": "perspective",
"label": "角色视角",
@@ -162,7 +170,8 @@ feeds: design_only
- [ ] 未重写上游长文,只有排序/投影
- [ ] 未把游玩选项示例当成当前提问
- [ ] 已启用的每轮槽有 order 0 人设位
- [ ] 主世界层与转述含「对话.历史」;旁观维护默认无历史
- [ ] 主世界层含「对话.历史」;转述与旁观维护默认无历史
- [ ] 旁观维护含「运行.本轮.裁决」;转述含裁决且不含历史
- [ ] 少变块整体靠前、本轮/真值靠后(软规则)
- [ ] 与游玩拓扑勾选一致
```
@@ -54,7 +54,7 @@ boundary: |
核心操作:让用户勾选固定槽,写成 `play_slots`(世界模拟)或 `writing_slots`(扩写)。**禁止**新建未在固定列表中的 ref。
固定 ref 白名单:
- 世界模拟每轮:`auditor`(旁观维护)、`world-simulator`(gm)、`narrator`、`role-decide`(perspective,默认关)
- 世界模拟每轮:`world-simulator`(gm)、`narrator`、`auditor`(回合末)、`role-decide`(perspective,默认关)
- 世界模拟按需:`chance`(机遇裁定,默认关;invocation=on_demand)
- 扩写:`outline`、`chapter-writer`
- 禁止:`variable-update`、自造 kebab、为世界观/性格再拆槽
@@ -62,7 +62,7 @@ boundary: |
执行顺序:
1. 读配方与体验契约,判断路径:世界模拟 vs 写手分段。
2. 默认世界模拟:`auditor: true, gm: true, narrator: true, perspective: false, chance: false`;
调度序 auditor → perspective? → gm → narrator;
调度序 gm → perspective? → narrator → auditor;
仅信息隔离才开 perspective;需要骰子/抽签/比点等真随机时开 chance。
3. 写手路径:`outline` + `chapter-writer` 默认都开;用户明确只要正文则可关 outline。
4. 可写简短 `mount_notes`(哪类上游产物挂哪槽),不粘贴长文。
@@ -2,26 +2,26 @@ id: auditor
label: 旁观维护
role: auxiliary
duty: >
副 LLM:每轮检查表字段与生成规则是否需要补充;默认空操作。
副 LLM:回合末检查表字段与生成规则是否需要补充;默认空操作。
读本轮裁决 + 变量合同 + 当前表;改表结果供下一轮主世界层读取。
只出 maintain.v1(运行.本轮.旁观);不写用户正文、不写真相权威。
上下文几乎不要对话历史——合同 + 表 + 本轮工单即可。
when: 每轮用户输入后、主世界层裁决之前
when: 叙事转述完成后(回合末)
suggested_context:
static:
- 设计.worker集
- 设计.变量设计与更新规则
- 设计.生成规则
- 设计.变量控制上下文
dynamic:
- 运行.本轮.裁决
- 用户.最新输入
- 变量.当前
- 上下文.旁观.状态摘要
- 运行.本轮.工单
suggested_outputs:
- 运行.本轮.旁观
prompt_excerpt: |
你是旁观维护(副 LLM),不是主世界层,也不是叙事作者。
读合同(生成规则/变量规则/旁观摘要)与当前表,对照「用户.最新输入」判断本轮要不要补表或触发规则。
读合同(生成规则/变量规则/旁观摘要)、当前表,以及本轮主世界层裁决包。
不读对话历史。表维护合并后供下一轮主世界层读取,不在本轮重裁。
「运行.本轮.旁观」必须是 JSON,schema 为 maintain.v1:
{
"schema": "maintain.v1",
@@ -2,20 +2,16 @@ id: narrator
label: 叙事转述
role: transcription
duty: >
只读「运行.本轮.裁决」结构化包 + 文风/叙事常驻 + 设计.正文组成(壳适配),
组装「输出.用户展示」。只改表达,不改事实、不补裁决。
when: 主世界层裁决包已写入
只读「运行.本轮.裁决」结构化包 + 叙事指南/正文组成(壳由程序套用),
组装「输出.用户展示」。只改表达,不改事实、不补裁决;不读对话历史。
when: 主世界层裁决包已写入后
suggested_context:
static:
- 设计.worker集
- 设计.叙事指南与故事推进
- 设计.叙事指南
- 设计.正文组成
- 设计.监控栏
dynamic:
- 运行.本轮.裁决
- 用户.最新输入
- 变量.当前
suggested_outputs:
- 输出.用户展示
presentation_hints:
@@ -23,6 +19,7 @@ presentation_hints:
tone: 依 Worker 集 presentation / 叙事指南 / 正文组成壳
prompt_excerpt: |
你是面向用户的叙事转述。输入是结构化裁决包(settlement.v1),不是自由发挥的世界真相。
不读对话历史;连续性来自裁决包内的 visible_now / resolved / npc_moves。
先读「设计.正文组成」的呈现壳 shell_id(prose|chat_monitor|spotlight|turn_panel|split_board|choice_dock|chapter_reader):
- prose:可直接输出 Markdown 正文(程序会落入 body)。
- 其它壳:优先输出 JSON,schema 为 present.v1:
+21 -5
View File
@@ -498,20 +498,36 @@ const SYNTH_FALLBACK_CONTEXT: Record<
"设计.变量控制上下文",
],
dynamic: [
"运行.本轮.裁决",
"用户.最新输入",
"变量.当前",
"上下文.旁观.状态摘要",
"运行.本轮.工单",
],
skipHistory: true,
},
"world-simulator": {
static: ["设计.变量设计与更新规则"],
dynamic: ["变量.当前", "运行.事件流", "用户.最新输入", "上下文.角色态度"],
static: [
"设计.舞台骨架",
"设计.实现机制",
"设计.变量设计与更新规则",
"设计.生成规则",
"设计.叙事指南与故事推进",
],
dynamic: [
"变量.当前",
"运行.事件流",
"上下文.角色态度",
"用户.最新输入",
],
},
narrator: {
static: ["设计.叙事指南"],
dynamic: ["运行.本轮.裁决", "用户.最新输入"],
static: [
"设计.叙事指南与故事推进",
"设计.正文组成",
"设计.监控栏",
],
dynamic: ["运行.本轮.裁决"],
skipHistory: true,
},
"role-decide": {
static: [],
+1 -1
View File
@@ -90,7 +90,7 @@ export const PLAY_SLOT_ORDER: PlaySlotId[] = [
/** 这些槽的默认上下文不注入「对话.历史」长聊 */
export const PLAY_SLOTS_WITHOUT_DIALOGUE_HISTORY: ReadonlySet<PlaySlotId> =
new Set(["auditor"]);
new Set(["auditor", "narrator"]);
export function playSlotIdForRef(ref: string): PlaySlotId | undefined {
const trimmed = ref.trim();