Files
nana-story/docs/status/2026-07-29-m2-wave7-context-checkpoints.md
T
2026-07-29 10:14:21 +08:00

6.6 KiB
Raw Blame History

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

模型输入固定分成三段:

stable_prefix
branch_context
  checkpoint?
  raw_tail[]
dynamic_tail
  • stable_prefix 只包含角色、Persona、剧情模块、绑定世界书的版本来源及稳定安全 规则;资源未变化时保持字节一致,便于供应商前缀缓存命中。
  • branch_context 使用一个已验证的祖先检查点加最近原文;至少保留最新的已提交节点, 节拍文本不会被截断。
  • dynamic_tail 保留本轮输入、实际触发的世界书条目、剧情事件、可见状态与重生成的 固定定性结果,不允许被摘要替代。
  • 输入预算来自当前 LAPP 模型的 context_windowmax_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 workspace215 项测试通过。
    • Contracts1。
    • Domain5。
    • Engine21。
    • Runtime106。
    • Store65。
    • Tauri 后端:17。
  • cargo clippy --workspace --all-targets -- -D warnings:通过。
  • Web5 个测试文件 / 29 项测试、TypeScript 严格检查与生产构建通过。
  • 契约:25 份 JSON Schema 与 TypeScript DTO 无漂移。

测试覆盖包括预算边界、prompt schema v3 编排、同模型严格摘要工具、滚动与增量摘要、 检查点哈希和失效、兄弟分支隔离、schema v1 / v2 迁移、缓存删除、500 节点祖先链、 节点与检查点原子提交、压缩后取消不移动线路头、隐藏检定工具单次暴露,以及合法但 会阻断后续上下文的超长回复在提交前被拒绝。

尚未关闭

  • 尚未使用用户实际 LAPP profile、Vault 凭据和在线模型完成端到端调用;本报告不宣称 在线 LAPP 冒烟通过。
  • 本轮没有完成窗口截图或人工视觉检查;本报告不宣称视觉验收通过。
  • Gitea SSH 推送在当前执行环境中仍未验证;本轮成果当前只能视为本地工作树状态, 不能宣称已经同步到远端。