This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
# M2 第七波:当前分支上下文检查点
|
||||
|
||||
日期:2026-07-29
|
||||
|
||||
## 本轮结果
|
||||
|
||||
本轮完成了长分支上下文主链:运行时按实际 LAPP 模型预算编排 prompt schema v3;
|
||||
超出预算时使用当前选中的同一个模型生成玩家安全的滚动摘要;摘要与来源指纹组成
|
||||
非权威检查点,并在最终回合成功时与新故事节点原子提交。历史不会为了适配窗口而被
|
||||
静默截断。
|
||||
|
||||
这套机制适用于普通继续与重生成。它不引入导演 Agent、独立摘要模型、向量记忆库或
|
||||
跨分支记忆。
|
||||
|
||||
## SQLite schema v3
|
||||
|
||||
- 新增 `context_checkpoints` 缓存表,以不可变的故事节点作为 host,保存覆盖范围、
|
||||
prompt / checkpoint schema 版本、稳定前缀哈希、摘要和叙事来源哈希。
|
||||
- schema v1 与 v2 数据库都能迁移至 v3;迁移不会修改故事节点、线路头、物化状态或
|
||||
活动线路。
|
||||
- Memory 与 SQLite Store 使用同一检查点语义:只沿目标节点的 `parent_id` 祖先链
|
||||
查找最近的可达检查点,兄弟分支和其他故事不可见。
|
||||
- 缓存行的类型、版本、大小、规范 SHA-256、host 和覆盖范围都会被校验。损坏或未知
|
||||
版本的行被当作可重建的 cache miss,并继续查找更早的有效祖先;权威祖先链损坏仍是
|
||||
硬错误。
|
||||
- 删除全部检查点不会改变节点、线路、状态哈希或 `PlayerView`。
|
||||
- 内存和 SQLite 后端均覆盖 500 节点祖先链读取与检查点查找,长线路不再受界面层
|
||||
200 节点展示限制。
|
||||
|
||||
## 缓存友好的 prompt schema v3
|
||||
|
||||
模型输入固定分成三段:
|
||||
|
||||
```text
|
||||
stable_prefix
|
||||
branch_context
|
||||
checkpoint?
|
||||
raw_tail[]
|
||||
dynamic_tail
|
||||
```
|
||||
|
||||
- `stable_prefix` 只包含角色、Persona、剧情模块、绑定世界书的版本来源及稳定安全
|
||||
规则;资源未变化时保持字节一致,便于供应商前缀缓存命中。
|
||||
- `branch_context` 使用一个已验证的祖先检查点加最近原文;至少保留最新的已提交节点,
|
||||
节拍文本不会被截断。
|
||||
- `dynamic_tail` 保留本轮输入、实际触发的世界书条目、剧情事件、可见状态与重生成的
|
||||
固定定性结果,不允许被摘要替代。
|
||||
- 输入预算来自当前 LAPP 模型的 `context_window` 和 `max_output_tokens`;缺失元数据
|
||||
使用显式标记的保守回退。输出、system、工具 schema、消息 framing、一次隐藏检定
|
||||
续调用与安全余量都会先从窗口中扣除。
|
||||
- 完整请求在发给 provider 前再次预检。动态尾部、固定部分或单个历史节点本身无法
|
||||
容纳时会失败关闭,而不是删字、截断或越过模型窗口。
|
||||
- V1 每次玩家行动最多进行一次隐藏检定;这使为工具调用及其续写保留的预算存在明确
|
||||
上界。初始请求会明确提示该限制,检定结果返回后以及重生成回合只向模型暴露
|
||||
`submit_turn_plan`,不会再提供第二次检定工具。
|
||||
- 可继续的候选节点会在 `begin_commit` 前,以提交后的状态、同一资源编译器和同一
|
||||
模型预算验证一次最小“下一轮继续”上下文。即使回复满足静态字段上限,只要它作为
|
||||
强制保留的最新原文会让下一轮无法编排,本轮就整体失败且不移动线路头。
|
||||
|
||||
## 同模型滚动摘要
|
||||
|
||||
- 压缩复用当前 TurnPlan provider 的同一 LAPP executor、模型、调用闸门和
|
||||
`TurnControl`,不会暗中切换模型或绕过供应商配置。
|
||||
- 每次摘要请求都是新的单用途会话,只开放一个严格的 `submit_context_summary`
|
||||
工具;正常文本、额外工具调用、未知字段、空白或超大摘要都会被拒绝。
|
||||
- 首次加载超长分支时按有界块滚动摘要;后续压缩把上一个自包含摘要与新增的连续节点
|
||||
一起压成新的自包含摘要,不在 prompt 中嵌套摘要链。
|
||||
- 摘要来源仅包含当前根到覆盖节点路径上的实际玩家输入、公开场景、角色视觉状态和
|
||||
已提交演出节拍。
|
||||
- 精确关系值、骰点和难度、状态 delta、NPC 私物和私密知识、未触发世界书、未选择
|
||||
建议、兄弟分支、凭据、原始供应商响应与推理过程都不进入摘要请求。
|
||||
- 摘要分类由运行时固定为 `non_authoritative_narrative`;模型只能提供文本,摘要不能
|
||||
作为规则触发、状态恢复或判定事实来源。
|
||||
|
||||
## 原子提交与中断边界
|
||||
|
||||
- 压缩发生在模型生成正式 TurnPlan 之前。生成的检查点先停留在内存中,不会立即写库。
|
||||
- 普通回合使用 `append_node_with_checkpoint`,重生成使用
|
||||
`append_regenerated_node_with_checkpoint`;节点、物化状态、线路头与待提交检查点
|
||||
在同一 Store 原子操作中落库。
|
||||
- 检查点必须 host 在提交前的历史头上,并与该祖先链的覆盖范围一致。陈旧线路、
|
||||
错误故事、无效范围或状态不一致都会使整次写入失败,节点与检查点均不落库。
|
||||
- 取消或超时可发生在摘要、正式模型调用或最终提交边界之前。只要中断先于
|
||||
`begin_commit`,待提交检查点与故事节点都会被丢弃,线路头保持不变。
|
||||
- 一旦 `begin_commit` 成功,取消不再与写入竞争;调用方接收该原子提交的确定结果。
|
||||
- 重生成继续复用原玩家行动、权威 delta、隐藏检定与终局状态;检查点只覆盖待替换
|
||||
节点的父路径,旧节点及旧分支保持不可变。
|
||||
|
||||
## 验证
|
||||
|
||||
- Rust workspace:**215** 项测试通过。
|
||||
- Contracts:1。
|
||||
- Domain:5。
|
||||
- Engine:21。
|
||||
- Runtime:106。
|
||||
- Store:65。
|
||||
- Tauri 后端:17。
|
||||
- `cargo clippy --workspace --all-targets -- -D warnings`:通过。
|
||||
- Web:5 个测试文件 / **29** 项测试、TypeScript 严格检查与生产构建通过。
|
||||
- 契约:**25** 份 JSON Schema 与 TypeScript DTO 无漂移。
|
||||
|
||||
测试覆盖包括预算边界、prompt schema v3 编排、同模型严格摘要工具、滚动与增量摘要、
|
||||
检查点哈希和失效、兄弟分支隔离、schema v1 / v2 迁移、缓存删除、500 节点祖先链、
|
||||
节点与检查点原子提交、压缩后取消不移动线路头、隐藏检定工具单次暴露,以及合法但
|
||||
会阻断后续上下文的超长回复在提交前被拒绝。
|
||||
|
||||
## 尚未关闭
|
||||
|
||||
- 尚未使用用户实际 LAPP profile、Vault 凭据和在线模型完成端到端调用;本报告不宣称
|
||||
在线 LAPP 冒烟通过。
|
||||
- 本轮没有完成窗口截图或人工视觉检查;本报告不宣称视觉验收通过。
|
||||
- Gitea SSH 推送在当前执行环境中仍未验证;本轮成果当前只能视为本地工作树状态,
|
||||
不能宣称已经同步到远端。
|
||||
Reference in New Issue
Block a user