Files
writing-agent/docs/briefs/dictate-only-creation.md
chenmoranzhiandCursor 1cc4ae557a 创作一轮改为先选题再填写,减少工具空转和重复覆盖。
上下文按规则、历史、产物分段拼装,便于吃提示缓存并核对费用。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-07 23:48:20 +08:00

48 KiB
Raw Permalink Blame History

对话落盘单一化 · 执行蓝图

状态:核心方向已确认,按本文依赖顺序实施;非工具节点仍须逐项审阅提示词。
修订:2026-09-30。
相关:docs/play-presentation-shells.md、docs/context-fragment-design.md、docs/world-simulator-modules.md。

执行状态(2026-09-28)

  • 基线扫尾:删除新建作品选配方的过时提示。
  • 工作包 A:本局创作方案、两态注入、能力覆盖校验、旧配方案例化。
  • 工作包 B:read_module、read_library_entry、提示版本门禁、按需读取库。
  • 工作包 C(进行中):内容节点、普通呈现链和 0 层呈现链均已迁移;user-requirements 经审阅决定删除;四个共用运行步骤已确认为自动工具节点,尚待补齐完整确定性编译。
  • 工作包 D:游玩投影与维护合同编译,未开始。
  • 工作包 E(进行中):楼层/0 层双呈现节点与数据合同已建立;壳参考库已按 7 种区、5 只壳写入 shell-refs/;隔离 iframe、持久槽位运行时和重 roll 尚未实现。
  • 工作包 F:库条目 schema、本局化与提示归属,部分完成;偏好/文风库按需读取;仓库 seeds/libraries/*.json 可 git 备份并 npm run libraries:restore 恢复。
  • 工作包 G:长程记忆、表维护与固定输入语法,未开始。

0. 已确认结论

  1. 新建作品只填写名称并直接进入对话落盘。这部分已经完成,不再列为工作包;旧工序编排书和后端 DAG 暂留兼容。
  2. 创作入口与设计清单合并为一份中间产物「本局创作方案」。它根据自然语言生成本局方法(下文称“本局配方”),并给全部能力分档。
  3. 旧配方不再供用户手动选择。修订后作为本局创作方案的参考案例,不作为固定路径。
  4. 不写死“先美学、再清单、再逐节点”的统一工作流。本局创作方案描述依赖与重要程度,模型根据当前材料灵活推进,并可在用户改口后整份重写。
  5. 创作对话保留一次用户输入触发多次 insert 的能力。逐节点审阅只约束本次程序改造:修改每份非工具节点提示词前必须给用户过目,不限制产品运行时一次只能写一个产物。
  6. 壳最终仍是正文组成节点读取的参考库。否定的是当前七个外观壳及其按产品原型换皮的分类,不是否定参考库本身。
  7. 正文前端采用隔离 iframe。它是显示容器,不提供 action 回传;用户仍从主输入框输入。
  8. 创作源产物、创作交互与评分、游玩投影分开。开玩时不得再把全部 设计.* 原样挂给主世界层。
  9. 长程记忆采用“写大总结”和“清空旧楼层”两个独立操作,不在大总结成功后自动删除历史。
  10. 输入语法写死:裸写表示上帝视角,单井号包裹的 #内容# 表示角色行动,引号包裹的内容表示角色说话。
  11. 新增“0 层卡”呈现模式:开场白所在气泡是持久前端;正文、指令、表盘、地图等都是其中的槽位,每轮就地更新,不继续向下叠加可见助手楼层。
  12. 普通楼层与 0 层卡不共用呈现节点;现已复制 回复呈现、正文组成、开场白与开场变量 三个显示强相关节点,其它内容能力继续共用。
  13. 0 层模式在“更多操作”中提供“重 roll 本轮”,复用本轮消息前 checkpoint;暂不提供任意历史回退。

1. 当前基线

以下内容已经落地,不再实施:

  • 新建作品弹窗只保留作品名称。
  • 新建作品固定 creationMode: "dictate"。
  • 新会话默认进入对话落盘。
  • 旧工序编排书仍可打开,DAG 后端和旧前端仅作兼容。

扫尾项(已完成):

  • 删除 web/agent-ui.js 中“请先在新建作品时选定配方”的过时提示;旧书展示所需的「工序编排」标签可保留。

现有但尚未达到本文目标的基础设施:

  • 文风库、偏好库和库注册表已经存在,但对话落盘仍会整库注入。
  • play-bind 已能自动装配部分运行上下文,但仍主要按 tag 分类并给主世界层全量投影。
  • auditor 和 maintain.v1 已存在,但默认关闭,也没有本文所需的阻塞、总结和清空交互。
  • 现有七个壳及预览器仍存在,只作为待替换旧实现。

2. 目标链路

用户自然描述
  → 本局创作方案〔中间产物,可反复重写〕
      - 生成本局配方:如何把本次需求做出来
      - 给全部能力分档并说明理由、缺口和建议实例
      - 只表达必要依赖,不生成固定流水线
  → 按当前材料灵活推进
      - 写某能力前 read_module
      - 需要库条目时 read_library_entry
      - 同轮只连续写入这句话已经说清的能力,通常 2~3 个
      - 每份写入携带独立 self_score
  → 回复呈现
  → 正文组成读取壳参考库,生成本局模板与数据契约
  → 开场白按数据契约生成 present.v1
  → 开玩时把源产物编译成各 Worker 的游玩投影

这不是硬编码流程:

  • 用户这句话已经说清的能力,同轮可以读取并连续 insert,通常 2~3 个。没提到的「必须」和「有必要」按已有材料给 2~3 个选项询问,选定后再写。写开场前用未落项问用户哪些还没设计。
  • 能力之间只有真实语义依赖。例如正文组成需要知道要呈现什么,开场白通常靠近创作收束;不能因此把所有作品强制塞进同一节点序列。
  • 文本创作、世界模拟、短局、长局、数据化跑团等只是本局配方案例,不是程序分支。
  • 用户改变目标时,先更新本局创作方案,再按新方案增删或改写产物。

3. 工作包 A · 本局创作方案〔已完成〕

3.1 能力与产物

新增 modules/creation-plan/prompt.md,目录登记:

- id: creation-plan
  name: 本局创作方案
  layer: intermediate
  artifact: 设计.本局创作方案

该产物同时承担原“创作入口”和“本局设计清单”的职责:

{
  "schema": "creation-plan.v1",
  "技能": "本局创作方案",
  "brief": "一句话说明本局靠什么兑现体验",
  "recipe": {
    "primary": "主要创作方法",
    "secondary_traits": ["可混合的次要体验特征"],
    "method": ["针对本局的做法,不是固定节点顺序"],
    "references": ["采用或改造过的旧配方案例 id"]
  },
  "items": [
    {
      "module_id": "variable-design",
      "tier": "必须",
      "why": "任务时限与暴露度必须跨轮保存",
      "missing": "暴露度达到哪一档会被识破尚未确定",
      "instances": []
    }
  ]
}

items 覆盖对话落盘可见的全部内容能力,但排除:

  • 本局创作方案自身。
  • 变量声明、变量映射、上下文排序等机械工具节点。
  • 只供旧工序编排使用的节点。

四档含义:

档位 含义 默认行为
必须 缺少后无法运行或核心体验会崩 收口前问清。用户没提到时给 2~3 个选项,选定后再写
有必要 缺少仍可运行,但体验明显受损 同样先问再写;用户明确不要时可降档
有一定效果 有了更好 用户提及时做;可顺带询问一次
没有意义 本局用不上 不主动推进

四档是收口前的核对清单,不是本轮待办,也不是 DAG。程序不按照数组顺序强制执行节点。本轮通常只写用户这句话已经说清的 2~3 个能力。

3.2 旧配方改为案例

  • 删除新建阶段和创作页中的手动配方选择。
  • 修订现有对话落盘配方,只保留各自有辨识度的方法、适用信号和能力档位倾向。
  • 本局创作方案可以引用、混合或改写多个案例;引用结果写入 recipe.references。
  • 案例不能复制总提示的公共规则,也不能恢复成隐藏的固定工作流。

3.3 注入

buildDictateSystemPrompt 分两态:

  • 没有方案:提供能力目录的短声明、使用边界和配方案例目录,要求根据用户当前材料形成方案。
  • 已有方案:注入完整本局配方;能力按档分组,显示已落/未落和最低自评分。前三档附带该能力的何时用 / 何时不用(方案改写或补全后仍保留;可反复能力已落一条也保留),供本轮选型。不附带执行规格。「没有意义」只列名称。

用户改口、新增方向,或现有方案明显不再成立时,允许覆盖 设计.本局创作方案。

3.4 程序约束与验收

  • 写入方案时校验能力覆盖;漏项则拒绝并列出 id。
  • 插入开场白时,如仍有“必须”项未落,只提醒,不拒绝。
  • 不要求体验锚定达到固定计数,也不要求先经过美学节点。
  • 方案落盘后系统提示应明显短于全目录注入。
  • 测试:tests/creation-plan.test.ts。

4. 工作包 B · 写产物前读取能力与参考〔已完成〕

4.1 read_module

src/dictate/tools.ts 新增:##

{
  "name": "read_module",
  "parameters": {
    "module_id": "能力 id,也接受中文名",
    "reason": "可选,一句话"
  }
}

返回该能力的:

  1. task、principles、output、score。
  2. 绑定库的条目目录与短说明,不返回整库正文。
  3. 正文组成所需的壳参考目录、正文安全子集和 iframe 数据契约说明。
  4. 该能力适用的程序约束。

会话记录已读取的能力及其提示版本。写某能力产物前未读该版本时,insert 拒绝并提示调用 read_module。同轮可以先读用户这句已经说清的能力(通常 2~3 个),再连续执行这些 insert。还没提到的先问,不先读后写。

机械工具产物不受此限制。

4.2 read_library_entry

仅返回库目录不足以完成选择,因此新增独立工具:

{
  "name": "read_library_entry",
  "parameters": {
    "library_id": "库 id",
    "entry_ids": ["本轮选中的 1~2 个条目 id"]
  }
}

约束:

  • 只能读取当前能力绑定库中的条目。
  • 默认最多读取两个;确需更多时必须给出原因。
  • 本局源产物记录条目引用和本局微调;未选条目不进入后续提示。
  • 用户提出库外新取向时,可先形成本局临时条目;是否回写全局库另行确认。

4.3 验收

  • 未读取能力就写对应产物会被拒绝。
  • 读取正文组成时能看到壳目录和 iframe 契约。
  • 对话落盘不再默认注入文风库、偏好库全文。
  • 测试:tests/dictate-read-module.test.ts、tests/dictate-read-library-entry.test.ts。

5. 工作包 C · 产物分层、评分与自然回复〔进行中〕

5.1 四类数据

  1. 中间产物:只服务创作决策,不进游玩。目前包括 设计.本局创作方案,以及 lifecycle_intent = seed_only 的生成规则。
  2. 源产物:能力形成的完整定稿,保留在黑板供编辑、验收和重新编译。
  3. 游玩投影:从源产物确定性提取、按 Worker 分发的运行时内容。
  4. 创作交互与评分元数据:回应、评价、启发、追问、缺口和分数;留在消息或元数据,不进入游玩投影。

DictateProduct 和黑板元数据新增 layer。目录的 layer 是默认值;生成规则根据产物中的 lifecycle_intent 覆盖默认值。

5.2 自评分

每个能力 prompt.md 新增 score fence,每个维度给出 5 / 3 / 1 分锚点。insert 新增:

{
  "self_score": {
    "dims": [
      {
        "name": "维度名",
        "score": 3,
        "gap": "当前缺口",
        "options": ["涉及用户偏好时提供的具体选项"]
      }
    ]
  }
}
  • 分数为 1~5。
  • score <= 3 必须写 gap;涉及用户选择时给 2~3 个 options。
  • 维度名必须与该能力 score fence 一致。
  • 分数存入黑板元数据,不再写进产物正文。
  • 追问、开放问题、完备度诊断同样不进入游玩投影。

迁移按 §9 逐节点审阅进行。过渡期兼容规则:

  • 已有 score fence 的能力使用新参数并严格校验。
  • 尚未迁移的能力继续接受旧 output 形状,不因缺少 score fence 阻塞写入。
  • 全部内容节点迁移完成后,统一删除旧自评解析和兼容分支。

5.3 用户可见回复

回复不使用固定标题、固定句数或逐模块仪式。按当轮内容自然覆盖:

  1. 回应用户输入中的有效判断、矛盾或值得保留之处。
  2. 说明本轮形成或改写了什么;完整 JSON 由产物卡展示。
  3. 用户没提到的「必须」或「有必要」,给 2~3 个根据原话推出的选项来问。这句话已经说清并写入的,不再强行追问。
  4. 简短说明强项和缺口。

写开场或结束创作前,用仍未落的「必须」和「有必要」问用户哪些还没设计。同轮写入多个已说清产物时综合回应整轮,不逐模块重复模板。

正文组成、0 层正文组成和开场的画面由产物卡按 frontend 渲染。完整 JSON 仍由产物卡展示。

6. 工作包 D · 游玩投影编译〔未开始〕

“游玩投影”指:创作时保存的完整产物不能直接塞进模型;开玩时先抽出每个 Worker 真正需要的字段,再分别装配。

6.1 编译入口

在 src/dictate/play-bind.ts 增加明确的编译阶段:

黑板源产物
  → resolve module / layer
  → intermediate 与 seed_only 跳过
  → compileDictateProjection
  → 按 mount 分发给 world-simulator / narrator / auditor
  → 各自按 context_order 装配

不要再用 tag 正则把几乎全部 设计.* 挂给主世界层。

6.2 投影契约

能力目录声明默认 mount;每个最终能力提供确定性的投影器或字段允许列表:

  • 主世界层:事实推进、角色扮演、输入解释、权限边界。
  • 转述:本局选中的文风、呈现规则、正文数据契约。
  • 副 Worker:表结构、当前值、维护规则及人物一致性所需的少量设定。

所有投影统一剥离:

  • 创作期回应与评价。
  • self_score、追问、开放问题、完备度和诊断依据。
  • 本局创作方案状态。
  • 不属于目标 Worker 的字段。

纯模型阅读内容优先生成有身份标题的 Markdown;变量、映射、数据契约和 present.v1 保持结构化。

这解决两个具体问题:

  1. layer 只回答“整份产物是否进入游玩”,不足以回答最终产物中哪些字段能进入。
  2. mount 只回答“给谁”,不足以回答“给这个 Worker 看哪些字段”。因此必须同时有分层、投影和分发。

6.3 验收

  • 本局创作方案和 seed_only 规则不出现在游玩请求中。
  • 主世界层、转述、副 Worker 得到不同且最小的投影。
  • 请求日志中不存在创作回应、评分、追问和诊断字段。
  • 具体实例暂时全量稳定注入,不引入关键词检索或 RAG。
  • 扩展 tests/dictate-play-bind.test.ts,覆盖分层、字段剥离和按 Worker 分发。

6.4 维护方式分流与条件式编译工具节点

维护不固定走副 LLM。创作收口时先按复杂度选择一种运行策略:

  1. none:没有跨轮可变内容,不挂维护能力。
  2. inline_tool:只有 1~2 个简单独立变量,或少量可由主世界层明确决定的标量更新。给主世界层挂原生 update_state tool call;正文仍输出普通 Markdown。
  3. inline_structured:模型不支持工具调用时,用 { body, state_ops } 结构化整包,程序只显示 body。这会牺牲自然流式体验,因此不是首选。
  4. auditor_bundle:变量较多、存在交叉依赖,或同时维护拓扑、补实例、其它备忘录时,运行 maintenance-compile 并启用统一维护副 Worker。

数量不是唯一判据:一个带扩展规则的关系图也应走 auditor_bundle;三个彼此独立、更新完全确定的计数器仍可走程序或 tool call。

update_state 只接受设计阶段声明过的变量、操作和 revision。主世界层先决定本轮事实并调用工具,程序校验、提交并返回结果,再输出用户可见正文。相比正文隐藏标签,它能在生成过程中报告拒绝或冲突;相比把长正文包进 JSON,它保留自然文本与流式输出。当前 GM harness 已有 chance tool loop,可沿用同一机制。

API 能力选路复用 profile 已有探测结果,但使用独立策略:

  • tools=ok:使用可选 tool call;不能用 forcedTool 强迫每轮更新,因为“本轮无变化”是正常结果。
  • strictTool=ok:动态工具带 strict: true;若供应商对实际 schema 拒绝,则降为普通 tool,并继续由本地校验全部参数。
  • tools 不可用而 jsonSchema / forcedTool / jsonObject 任一可用:通过现有 completeStructured 选路提交 { body, state_ops }。
  • 只有纯文本能力:可请求 JSON 并严格解析、失败后重试;解析失败则不写状态。新实现不使用正文隐藏标签或正则维护变量。

动态结构随请求生成,不需要向 API 预注册。inline_tool 只用于少量变量,因此优先为每个变量生成一个类型明确、结构简单的小工具:工具名使用稳定安全 id,description 携带该变量的更新条件,parameters 只含该类型允许的 set / delta、值、expected_rev 与简短依据。避免为所有变量动态拼一棵带大量 oneOf 的复杂 schema。

现有能力探测验证协议是否支持 tools、强制 tool、strict tool 与各类 JSON 输出;它不能证明供应商支持任意复杂 schema 方言。因此实现时需增加一个与状态更新工具同形的代表性探测,运行请求仍保留“strict 被拒绝 → 非 strict + 本地校验”的降级。

maintenance-compile 是条件式自动工具节点,不调用 LLM 创作内容。仅在策略为 auditor_bundle 时扫描所有最终产物,把分散的跨轮维护要求编译成一份 设计.维护合同:

{
  "schema": "maintenance-manifest.v1",
  "targets": [
    {
      "id": "目标短 id",
      "kind": "table | topology | generation | memo",
      "state_ref": "变量.当前 | 运行.拓扑#id | …",
      "rule_refs": ["来源产物及字段路径"],
      "allowed_ops": ["set", "delta"],
      "timing": "pre_narrative | post_narrative",
      "writers": ["program", "gm", "auditor", "user"],
      "visibility": "public | hidden",
      "rules": ["给维护者执行的短规则"],
      "invariants": ["不可破坏的约束"]
    }
  ]
}

主要来源包括:

  • 设计.变量设计与更新规则 的真值、写入源、更新时机、钳制和 side effects。
  • 设计.拓扑图谱#* 的动态模式、允许操作、写入者和一致性约束。
  • 设计.生成规则#* 中游玩期按需补实例的触发条件。
  • 后续明确声明“游玩期可修改”的其它备忘录;纯静态设定不进入维护合同。

编译规则:

  • 不复制整份创作产物,只提取维护所需字段并保留来源引用。
  • none / inline_tool / inline_structured 不生成聚合合同,也不启用 auditor。
  • 一旦启用 auditor,应把本轮所有需要其判断的维护目标、当前状态和更新规则一次性投影给它,不能让它只看到变量而漏掉拓扑或补实例规则。
  • inline_tool 只给主世界层简短工具 schema,不注入完整维护文档。
  • auditor_bundle 下正文生成者不承担隐藏维护清单;需要从正文事实推断的更新统一由回合末 auditor 处理。必须在正文前完成的机械更新单列为 pre_narrative,由程序或专门的前置调用处理。

运行期由程序从维护合同生成精简的 maintenance-context.v1,只包含本轮相关目标、当前状态、用户输入和最终正文。旁观输出升级为 maintain.v2,至少可携带:

  • table_ops
  • topology_patches
  • generation_requests
  • memo_ops
  • notes

旧 maintain.v1 继续作为仅含 table_ops / need_generate 的兼容输入。

验收:

  • 单个“用户存款”变量只挂 update_state,不启动 maintenance-compile 或副 LLM。
  • 工具调用成功后只显示正文;工具参数、结果和隐藏状态不混入气泡。
  • 工具不可用时结构化整包可正确分离正文与状态;纯文本解析失败不写状态。
  • 运行期变量维护不依赖正则;SillyTavern 正则只作为外部预设导入兼容能力,不能写权威状态。
  • 同一局既有变量、关系图和按需实例时,旁观一次收到完整合同并可在一份维护包中分别更新。
  • 主世界层提示不再塞入仅供维护使用的完整更新规则。
  • 每项操作都有目标 id、来源规则和 revision;未知目标或越权操作被拒绝。
  • 多数无变化回合仍可返回空维护包,不为“检查过”制造写入。

7. 工作包 E · 壳参考库与隔离 iframe〔未开始〕

7.1 壳参考库

壳是正文组成读取的参考。创作时选一只最接近的,按本局启用的区删掉多余区并重排,生成一次前端后固定。游玩只输出各区内容,由程序装配。

可见区有 6 种。隐藏的变量更新不参与分类,也不进壳。

区 里面是什么
抬头 页首一行短内容,例如标题、日期、天气、地点;条目一多或当前值一长,改用数据卡
正文 这一轮的主叙事
小故事 论坛上的一段,或正文地点以外其他重要角色的一小段;同一轮只写一种
数据卡 一组变量的卡片或表;只露出点名的列和行
结构 地图、关系或要对着看的长表
文字选项 几条下一步,只显示文字,始终直接可见,不放进标签或折叠

参考壳按主面来,写在 skills/dialogue/world-simulator/shell-refs/:

称呼 id 什么时候用
阅读 reading 只有正文、页首一行和选项
正文为主 dual-text 正文占满一栏。短文、地图用标签或折叠,点开才看。选项始终直接可见
数据常驻 data-cards 数据一直铺开,不替换正文。左栏是数百字正文,右栏是另一路短内容。选项始终直接可见
成稿 piece 一页一份能单独拿走的成品。内部小节在创作时按范例重排。选项在成稿下面

每只壳的备注只写两类:不替换的前端结构,以及可按本局用途替换的部位。备注不点名某一种应用场景。

alongside、paged 不再单独作为参考。另一篇长文不与正文左右对半。右栏是短内容时,可以和长正文并排。

美化用配色、字体层级、边框、间距,以及 CSS 或简单内联 SVG,按本次能写稳的程度完成。

7.2 正文组成产物

设计.正文组成 保存:

{
  "参考壳": ["按正文体验命名的参考 id"],
  "为何": "它如何服务本局的阅读体验",
  "数据契约": {
    "blocks": {
      "body": { "类型": "markdown", "职责": "主读正文" },
      "任意本局键": { "类型": "kv | list | markdown", "职责": "用途" }
    }
  },
  "frontend": {
    "html": "<div id=\"app\"></div>",
    "css": "",
    "js": "present.onData(render)"
  },
  "示例灌数": {
    "schema": "present.v1",
    "blocks": {}
  }
}
  • 创作期生成一次模板并固定。游玩每轮只生成内容块,由程序装配进该模板,不再生成壳。
  • 美化用配色、字体层级、边框、间距,以及 CSS 或简单内联 SVG,按本次能写稳的程度完成。
  • 壳只包含本局实际启用的区。参考壳多出来的区在创作时删掉并重排,不留到游玩再空着。
  • blocks 允许自定义键,前后端 normalization 不再吞掉未知键。
  • html + css + js 合计上限 60 KB。

7.3 最小隔离

新增 web/present-frame.js:

  • 使用 <iframe sandbox="allow-scripts">,不加 allow-same-origin。
  • 禁止网络、表单、弹窗和顶层导航。
  • 只提供 present.onData(cb)、安全 Markdown 渲染和自动高度回报。
  • 不提供 present.action,也没有“直接发送”设置。
  • 模板报错或 3 秒内未 ready 时,回退为安全的纯文本/基础块渲染;不回退到已否决的旧七壳。

这里是低成本故障隔离,不把自创模板当作敌对第三方脚本设计复杂权限系统。

7.4 接入与验收

  • 游玩终稿、开场候选、正文组成预览接入 iframe。
  • SessionView 下发 presentationFrontend。
  • 流式期间先显示纯文本,完成后灌入 iframe。
  • chat 型与长文阅读型参考必须肉眼显著不同。
  • 模板损坏时消息仍可读。
  • 测试:tests/present-frame.test.ts,覆盖 srcdoc、消息来源、ready/错误回退和自定义 blocks。

7.5 双呈现链

内容节点继续共用;只复制与显示形态直接耦合的三个节点:

  • 回复呈现:普通楼层版继续定义每轮消息区域;0 层版定义持久卡槽位及各槽内容规则。
  • 正文组成:普通楼层版生成每条消息的前端;0 层版生成开场时一次建立的持久前端、Tab 与槽位渲染器。
  • 开场白与开场变量:普通楼层版生成第一条消息;0 层版同时初始化持久前端和全部槽位初值。

当前实现:

  • 已建立 zero-layer-status / 设计.0层回复呈现、zero-layer-reply-format / 设计.0层正文组成、zero-layer-opening-setup / 设计.0层开场白与初态。
  • 本局创作方案.presentation_mode 必须在 message / zero_layer 中选一种;items 只包含所选模式的三项呈现能力,不把另一套写成“没有意义”占位。
  • 0 层更新合同使用 zero-layer.card.v1 与 zero-layer.update.v1;更新方式为 replace / append / data,并以 base_revision 原子提交。
  • 主世界层与转述不复制能力节点,只按呈现模式切换最终输出合同。

7.6 0 层卡、槽位更新与重 roll

0 层卡是开场白所在气泡内的持久前端,不是额外的上下文深度:

  • 正文也是一个槽位,可与“公司指令”“监控表盘”“地图”等槽位并列。
  • 每轮助手结果仍写入内部对话历史,但前端不新增可见助手楼层;程序把本轮更新应用到 0 层卡。
  • 槽位声明更新方式:replace(整块替换)、append(受上限约束的槽内日志)、data(结构化数据驱动渲染)。
  • 0 层初始状态与每轮槽位更新均持久化;刷新、续作、run 快照和重 roll 后可恢复。
  • 规范路径使用结构化 slot_updates;新增受限正则提取/替换兼容层,用于导入 SillyTavern 标签和显式声明的 <公司指令>…</公司指令> 一类输出,不以任意正则直接修改权威状态。
  • iframe 只接收规范化后的槽位数据;LLM 不直接生成或修改运行中的 DOM。

“更多操作”菜单新增:

  • 重 roll 本轮:恢复最新一轮助手输出前的 checkpoint,重新生成该轮并重新应用槽位更新。
  • 暂不提供任意历史回退:缺少稳定用户锚点前,不暴露多步撤销。
  • 既有消息分支 / swipe 数据仍保留;0 层前端只显示当前活动分支重放后的状态。

验收:

  • 连续多轮后仍只有一个可见 0 层前端,正文与其它槽位按合同更新。
  • 重 roll 不残留被废弃版本写入的槽位值。
  • 模板损坏时可查看本轮纯文本与结构化槽位数据。
  • 正则适配器失败不修改权威槽位状态。

8. 工作包 F · 库、本局化与提示归属〔部分完成〕

8.1 偏好库与文风库

  • 偏好库:输入用法、推进节奏、是否代演玩家、停笔方式、常用禁区。
  • 文风库:遣词、段落节奏、笔墨焦点、写法档和示范片段。
  • 故事推进和叙事指南改为“选择 + 本局化”节点,各读取最相关的 1~2 项,解决冲突并记录微调。
  • 未选条目不进入后续提示。

8.2 规则归属

  • 公共运行原则放总提示。
  • 配方案例只写有辨识度的方法和档位倾向。
  • 能力提示写使用边界、产物规格和评分。
  • 可程序校验的格式与依赖只在程序实现。
  • 删除面向用户的“落盘、收口、下一刀、模块”等内部流程腔。
  • 重复长例只留在一个权威位置,其余位置引用。

9. 非工具节点逐项审阅

本节只约束实施改造,不约束创作运行时的 insert 次数。

每份非工具节点提示词按以下流程处理:

  1. 一次讨论一个节点。
  2. 修改前完整展示审阅表。
  3. 用户批准后才修改该节点的 prompt.md、直接关联目录声明和测试。
  4. 修改后展示实际变化与验收结果,再进入下一节点。

审阅表:

项 内容
节点 id / 中文名
产物层 intermediate / final
本局职责 为什么存在,服务创作还是游玩
当前问题 现有提示、产物或消费链路的问题
使用边界 何时有用、何时没有意义、与相邻能力如何分工
产物形状 保留、删除、新增哪些字段
评分规则 维度及 5 / 3 / 1 锚点
用户可见交互 如何确认,何时根据缺口询问
程序消费 谁读取,怎样投影,是否进入游玩
待用户决定 尚有分歧的选项
审阅结论 未审 / 批准 / 修改后再审 / 否决

机械工具节点可以集中修改和测试,但不能借此改变内容节点的职责、语义或评分标准。

10. 工作包 G · 长程记忆、表维护与输入通道〔未开始〕

10.1 上下文拼装顺序

为尽量保留稳定前缀缓存,顺序调整为:

稳定系统提示
→ 静态游玩投影
→ 本局数据契约与工具说明
→ 可变记忆表 / 变量当前值 / 最新总结
→ 清空后保留的最近对话楼层
→ 当前用户输入

静态内容在前,可变表和对话放后。表格每轮变化时只破坏其后的缓存,不让整个稳定前缀失效。

10.2 副 Worker 维护

主世界层写出事实正文
  → 转述 / 呈现(若启用)
  → 副 Worker 根据已发生事实维护变量与记忆表
  → 维护完成后允许下一轮用户输入
  • 默认启用独立副 Worker;多数轮允许空操作。
  • 更新期间禁用发送,在输入区显示“正在更新记忆表…”。
  • 成功后恢复输入;失败时保留旧表并提供重试,不让半成品进入下一轮。
  • 表很少且规则简单时,未来可显式选择主世界层隐藏维护段;本阶段不做自动阈值切换。
  • 正文组成只决定如何显示,不修改变量和记忆。

10.3 动态二维表

按本局需要建立少而承重的表:

  • 事件账本:时间、地点、人物、事件、直接后果。
  • 承诺与债务:双方、内容、状态、到期或触发条件。
  • 人物关系:当前态度、公开关系、关键变化。
  • 线索与未决事项:内容、来源、可信度、解决状态。
  • 阶段事实:位置、目标、重要资源。

本局创作方案和变量设计决定需要哪些表,不要求每局全建。

10.4 大总结与清空

在输入框左侧“更多”菜单增加两个独立按钮:

写大总结

  • 总结 Worker 读取当前保留历史和记忆表。
  • 把仍有后续价值的事实更新进动态表。
  • 在消息流最新处插入一层用户可见的总结层。
  • 不删除任何旧楼层。
  • 总结期间与表维护一样阻止发送;失败时不插入总结层,也不修改表。

清空旧楼层

  • 只保留最新三层游玩消息,通常是最近用户输入、助手输出和总结层。
  • 不要求这三层具有固定角色;按时间保留最后三层。
  • 不删除动态表、源产物、静态游玩投影、开场实例或已保存快照。
  • 属于显式不可逆操作,执行前显示将删除的楼层范围并二次确认。

用户通常先写大总结、确认内容,再手动清空。两步不做自动绑定,允许少量信息重复。

10.5 固定输入语法

输入语法固定,不放进偏好库,也不允许按局反转:

  • 裸写表示上帝视角,用于提出推进、镜头、节奏和改写要求。
  • 单井号成对包裹的 #内容# 表示角色行动。
  • 中文或英文引号包裹的内容表示角色说话。
  • 同一条输入可以混合三种内容。

示例:

下一段加快节奏。#我推门进去#“你们在谈什么?”

程序拆成:

  1. 上帝视角:下一段加快节奏。
  2. 角色行动:我推门进去
  3. 角色说话:你们在谈什么?

只有首尾配对的单井号才构成行动标记;未配对井号按普通裸写处理。()、()、[]、【】 不承担系统语义。

10.6 动态拓扑状态

拓扑图谱 用于“只生成一个、但普通无规则实例不足以表达”的结构对象,例如一张迷宫地图、一所学校的固定空间、一棵升级树或一条人物关系链。

它不是 0 层卡专属产物,而是开场后仍可修改的运行备忘录。普通楼层和 0 层卡共享同一份权威拓扑状态,只采用不同的显示入口。

创作期:

  • 每个 设计.拓扑图谱#id 只定义一张图;能力可反复建立不同图。
  • 产物定义节点/连接字段、初始结构、扩展规则,以及 static | record | expand 动态模式。
  • 图数据与显示分离:拓扑节点只管权威结构,不要求提前实现渲染;是否显示、显示在哪里及采用何种形式,全部留给后续「正文组成」决定。

游玩期:

  • 从设计图初始化 运行.拓扑#id,保存节点、连接、当前位置/当前焦点、发现状态与 revision。
  • 新增 topology.patch.v1:支持增改删节点与连接、移动当前位置、揭示隐藏内容;带 base_revision,整批原子校验,禁止悬空连接。
  • 设计产物声明允许的写入者和可编辑字段;程序、维护副 Worker 或用户都必须通过同一 patch 与 revision 冲突检查修改,不能直接覆盖整张图。
  • 主世界层负责写正文事实,不在用户可见正文中夹带拓扑维护块。由正文事实产生的探索、关系等变化,在回合末交给统一维护副 Worker 记录。
  • 确实必须先改状态再写正文的机械操作标为 pre_narrative;其余默认 post_narrative,不得为了拓扑一律增加前置调用。
  • 语义位置属于图真相;纯显示坐标、缩放和折叠状态另存 运行.拓扑布局#id。
  • 若「正文组成」决定展示,渲染器与壳一样在创作期生成一次并固定。游玩只把 运行.拓扑 的节点与连接灌入该渲染器出图。模型不输出 SVG,壳也不写死一份地点名单。普通楼层放在辅助区或标签页,0 层卡投影到 data 槽。未决定展示时只保存备忘录。

当前已有的“表格”只支持 变量.当前 的扁平键值格和逐格 revision,不支持多张任意表、节点/连接或拓扑 patch。因此不能直接把现有表格当成拓扑实现;可复用其 revision、用户编辑和冲突保护思路,但只先新增独立的拓扑存储与更新接口。显示入口等「正文组成」实际选用后再实现。

验收:

  • 已访问节点和连接跨轮、刷新与 run 快照保持稳定。
  • 返回旧地点时只能沿已持久化连接,不重新生成冲突结构。
  • 旧 revision patch 被拒绝;非法 patch 不产生半次更新。
  • 固定学校地图保持稳定相对位置;动态迷宫只追加已探索部分。
  • 是否展示不影响存储;切换呈现模式不迁移或复制图数据。

10.7 随机数就是隐藏变量

随机数不另建表,也不另做协议。它是现有 变量.当前 里的行,玩家默认不可见,行名用「名称.随机数」,例如 敏捷.随机数、攻击.随机数。

这一行的值是还没用的数字。用掉第一个,就改写这一行;只剩 1 个时补到预备个数。程序出数,模型不编。重 roll 跟着这张表现有的检查点恢复。

与呈现模式的关系:

  • 0 层卡:创作与开场不写依赖随机数才能成立的玩法。开场落库时不应出现「没有随机数可用」的阻塞。
  • 普通楼层:随机行在第一次正式游玩回复前由程序按合同填入;若开场未预填,第一次回复也会正常补齐,不要求开场模型写出具体骰面。

11. 能力提示同步清单

文件 改动
modules/catalog.yaml 新增 creation-plan;增加默认 layer、mount;绑定库保持目录级声明
modules/creation-plan/prompt.md 新建本局配方 + 能力分档产物
modules/reply-format/prompt.md 读取新壳参考,生成前端与数据契约;删除渲染字段默认空
modules/opening-setup/prompt.md 按正文组成的数据契约输出 present.v1
modules/narrative-guide/prompt.md 从文风库选 1~2 项并本局化
modules/story-progression/prompt.md 从偏好库选 1~2 项,钉输入用法与停笔边界
modules/variable-design/prompt.md 增加按需建立记忆表及维护方式
modules/*/prompt.md 按 §9 逐节点确认,迁移 score fence
src/dictate/prompt.ts 方案驱动、读取工具、自然回复,删除固定路径与重复禁令
src/dictate/insert-feedback.ts 只提供关注点、缺口和启发,不生成固定回复模板
旧对话落盘配方 修订为本局创作方案可读取的案例
src/dictate/play-bind.ts 编译游玩投影,跳过中间层,按 Worker 分发
worker-templates/world-simulator.yaml 按固定输入语法解释裸写、#行动# 与引号;只读取自己的投影
worker-templates/narrator.yaml 按数据契约输出各块,只读本局文风选择
worker-templates/auditor.yaml 按统一维护合同处理变量、拓扑、补实例与可变备忘录;默认空操作

写提示词时遵循 prompt-writing 技能口径。

12. 实施顺序

扫尾旧配方提示
  → 本局创作方案 + 旧配方案例化
  → read_module / read_library_entry
  → layer / self_score / 自然回复
  → 剩余非工具节点逐项审阅
  → 按复杂度选择维护策略;仅 auditor_bundle 运行 maintenance-compile
  → 游玩投影编译

正文体验分类讨论
  → 壳参考库重建
  → 源「回复呈现 / 正文组成 / 开场白」审阅完成
  → 复制 0 层呈现链
  → iframe、普通 present.v1 与 0 层 slot_updates
  → 0 层卡持久化、正则兼容层与“重 roll 本轮”

动态表规格
  → topology.patch.v1 与运行拓扑
  → 副 Worker 默认维护与输入阻塞
  → 上下文顺序调整
  → 大总结 / 清空旧楼层
  → 固定输入语法解析

实施约束:

  • 非工具节点严格执行 §9;程序基础设施可以按工作包集中实现。
  • 先完成游玩投影再允许新产物直接开玩,避免继续污染运行上下文。
  • 具体实例当前保持全量注入;本阶段不做 RAG。
  • 旧七壳在新参考库和安全回退渲染就绪后删除。

13. 决策状态

  • 本局创作方案引用 4 份已修订案例:快穿短局、数据化跑团体验、文本生成器、交互式长文生成器;删除“正文组成”案例。
  • 删除独立的“用户需求”节点;偏好库、文风库改由相关节点绑定并通过 read_library_entry 按需读取。
  • 生成规则:名称/用途→字段→池或提示→填写工作流;两份以上,或一份但字段多、需要先审字段与工作流时使用;一条字段很少的具名内容通常不建规则也不落实例;一产物一条规则;只预生成 为中间层。不因开场后是否继续生成而改道。
  • 具体实例:按规则填一条记录,一份产物一条;写入多条时程序按记录拆开。无规则只留下用户点名的一条字段很少的内容。给人读的键和专名用中文,英文专名音译。
  • 叙事指南:读文风库 1~2(最多 3)并本局化;产物用风格推荐与要求,少禁多做;推进仍归故事推进+偏好库。
  • 故事推进:全局唯一输入用法;一次输出单轮目标字数及扩写/续写定义、占比和字数预算;含 OOC 处理策略;其它节点不重复定义篇幅。
  • 实现机制:一个产物可含多条共同作用的稳定因果;用于推演事件与人物反应;缺失后果只作内部移除检验。
  • 库种子:seeds/libraries/*.json 进 git;libraries:restore / libraries:export。
  • 0 层卡:开场气泡内的持久前端;正文也是槽位,每轮就地更新;内部历史仍逐轮保存。
  • 双呈现链:所有源节点审阅完成后,只复制 回复呈现 / 正文组成 / 开场白与开场变量;内容能力共用。
  • 动态拓扑方向:一产物一张图,运行期用版本化 patch 持久扩展;它是呈现无关的可变备忘录,是否渲染完全由正文组成决定;节点提示已迁移。
  • 维护分流:简单状态优先原生 update_state tool call;工具不可用时按 profile 能力走结构化整包;运行期变量维护不依赖正则;复杂维护才编译合同并启用副 LLM。
  • 普通回复呈现:只定义实际启用的语义区域、出现条件、权威来源与内容要求;内联变量更新作为隐藏语义区,具体投递由 API 能力选路;篇幅只归故事推进。
  • 随机数:现有变量表里的隐藏行,行名为「名称.随机数」;用掉一个就改行,只剩 1 个时补。
  • 普通正文组成:把回复呈现的可见区域落成完整 HTML/CSS/JS、present.v1 数据契约和区域渲染;隐藏维护区不进 DOM,权威数据只由程序投影。
  • 普通开场白:默认 1 条(用户要求时 2~3);全部保存,默认条开玩;每条自带初态与可选角色;不写随机数具体值。
  • 0 层与随机:0 层不写依赖随机的玩法;随机行在第一次正式回复时由程序补齐。
  • 0 层“重 roll 本轮”复用消息前 checkpoint;暂不实现任意历史回退。
  • 壳按展示的区分类。参考壳三种称呼:阅读、正文为主、数据常驻。正文为主把短文和地图收进标签或折叠;数据常驻把数据一直摊开。选项始终直接可见。隐藏变量更新不进壳。
  • 各最终能力的 mount 和字段投影允许列表。
  • 文风库、偏好库条目 schema,以及临时条目回写全局库的权限。
  • “清空旧楼层”是否提供快照恢复;当前方案按不可逆二次确认处理。
  • 生图任务的独立输出契约和插入时机;不纳入本轮执行范围。

14. 剩余执行清单

按依赖顺序继续:

  1. 完成内容节点审阅与迁移

    • topology:一产物一张图、扩展合同和五维评分。
    • variable-design:真值、更新规则与维护复杂度判据。
    • status-bar:普通楼层版语义区域、权威来源与隐藏更新区。
    • random-range:变量表隐藏随机行、预备个数与补数规则。
    • reply-format:普通楼层版前端、区域落点与数据契约。
    • opening-setup:普通楼层开场候选、初态、角色与收口。
  2. 完成共用运行工具审阅

    • 运行时固定顺序:用户需要填写的内容节点全部完成 → 单独调用 prepare_opening → 信息可见范围 → 游玩执行方式 → 上下文排序 → 运行配置组装 → 下一步才生成并写入开场白。开场候选选定后只落初态并重投影,不首次创建运行配置。
    • variable-context / 信息可见范围:程序从上游公开性、秘密与揭示声明编译谁能看到什么;不另造状态摘要。
    • worker-spec / 游玩执行方式:程序整理前面已经确认的独立转述、复杂维护、秘密隔离或写手路径需求,只选择固定执行单元。
    • context-order / 上下文排序:程序先按变化频率分组,再在同组内按重要性排列;稳定前缀在前,历史居中,当前状态与本轮输入靠后。
    • refine / 运行配置组装:把执行方式、上下文排序、变量表与所选呈现合同打包成运行期读取的 设计.worker集;不承担正文润色。
    • narrative 仅服务旧工序编排,不属于本轮对话落盘迁移。
  3. 完成 0 层呈现链

    • 为 回复呈现 / 正文组成 / 开场白与开场变量 建 0 层版本,确定 id、artifact tag、目录声明和测试。
    • 扩展本局创作方案,使普通楼层与 0 层卡互斥选型。
    • 定义 zero-layer.card.v1、zero-layer.update.v1、slot_updates、三种更新方式和初始槽位状态。
  4. 实现游玩投影与运行合同

    • 把四个共用运行工具全部改为确定性程序调用;旧工序路径不得再用 LLM 猜执行槽、上下文顺序或最终运行配置。
    • 实现 none / inline_tool / inline_structured / auditor_bundle 维护策略选择,并复用 profile 能力探测。
    • 扩展代表性状态工具探测;实际 strict schema 被拒绝时降级为非 strict tool + 本地校验。
    • 为简单变量新增受白名单、操作范围和 revision 约束的 update_state GM tool。
    • 新增条件式 maintenance-compile,只为 auditor_bundle 产出 maintenance-manifest.v1。
    • 编译最终产物的字段白名单和 Worker 分发,剥离评分、追问与中间层。
    • 运行期生成精简 maintenance-context.v1,扩展 maintain.v2 的表、拓扑、补实例和备忘录操作。
    • 普通楼层输出 present.v1;0 层模式输出槽位更新。
    • 保持旧书、旧多规则产物和旧呈现数据可读。
  5. 实现动态拓扑

    • topology.v1、topology.patch.v1、revision 与原子校验。
    • 运行图、写入者权限、用户编辑,以及默认由回合末副 Worker 维护。
    • 本阶段不预做图谱 UI;后续正文组成选择展示时,再实现所需入口和渲染器。
  6. 实现前端与重 roll

    • 重建壳参考库:shell-refs/ 五只壳供正文组成与 0 层正文组成读取。隔离 iframe 与自定义 blocks 运行时尚未接入。
    • 0 层持久前端、Tab、槽位重放与正则兼容适配器。
    • “更多操作”增加“重 roll 本轮”;恢复 checkpoint 后重新生成,不提供任意历史回退。
    • 新前端和安全回退就绪后删除旧七壳。
  7. 实现长程运行能力

    • 动态二维表与副 Worker 维护阻塞。
    • 随机数行:在 变量.当前 增加「名称.随机数」隐藏行;用掉队首就改行;只剩 1 个时补数。
    • 稳定前缀、可变表和对话的上下文顺序。
    • 写大总结、清空旧楼层及二次确认。
    • 固定输入解析:裸写 OOC / 上帝视角、#行动#、引号对话。
  8. 最终验收

    • 普通楼层与 0 层模式端到端测试。
    • 重 roll、续作、run 快照、分支和拓扑持久化测试。
    • 全量测试、lint、构建基线与迁移文档。