雨天小六

读懂 Codex(8.22):Previous Turn Settings 与 Context Window Identity 恢复

· 更新于 2026-08-03 · 专栏:读懂 Codex

#Codex#Agent Runtime#持久化#Rollout#软件架构

恢复不只得到消息数组;它还要找出最近一个存活且完成的用户 Turn 设置,并恢复 compaction window number/ID 链,才能让下一 Turn 正确比较配置和延续请求缓存作用域。

本节解决的不是“把对象存一下”这种抽象问题,而是把问题限定在:研究 PreviousTurnSettings、reference TurnContext 与窗口 ID 的选择优先级。输入:TurnContext、Turn terminal events、SessionMeta 与 CompactedItem window 字段;状态所有者:RolloutReconstructionResult 和 Session state;成功结果:previous settings、reference context、window_number 与 first/previous/current IDs。先把这些边界钉住,后面的顺序、失败和恢复才不会混成一句“持久化失败后重试”。

状态边界

问题本节答案
输入TurnContext、Turn terminal events、SessionMeta 与 CompactedItem window 字段
状态所有者RolloutReconstructionResult 和 Session state
成功产物previous settings、reference context、window_number 与 first/previous/current IDs
研究范围研究 PreviousTurnSettings、reference TurnContext 与窗口 ID 的选择优先级

正常路径:先看顺序点

Previous Turn Settings 与 Context Window Identity 恢复的正常路径时序图,展示排除 rollback/incomplete segments、选择最新完成用户 TurnContext、选择最新有效 compact window、必要时回退 SessionMeta/legacy count、安装到新 Session
图 8.22-1:排除 rollback/incomplete segments → 选择最新完成用户 TurnContext → 选择最新有效 compact window → 必要时回退 SessionMeta/legacy count → 安装到新 Session。这张图标出本节的实际顺序点与状态所有者。

这条路径可以压缩成五步:

  1. 排除 rollback/incomplete segments。
  2. 选择最新完成用户 TurnContext。
  3. 选择最新有效 compact window。
  4. 必要时回退 SessionMeta/legacy count。
  5. 安装到新 Session。

图中的箭头不是“可能调用”的依赖图,而是源码中决定可见性和所有权转移的先后关系。前一步没有确认时,后一步不能替它作出更强的成功承诺。

源码机制拆解

Previous settings 服务差异比较

它保留上个有效 Turn 的 model、effort、approval/sandbox 等设置。下一 Turn 能据此判断 model switch、上下文更新和警告,而不是把当前 config 误当成过去事实。

Reference context 有三态

NeverSet 表示历史从未建立 diff 基线;Cleared 表示 compaction/rollback 明确要求下次全量注入;Latest(item) 才允许相对 TurnContext 计算增量。用 Option 无法完整表达扫描中的未知与明确清除。

窗口身份来自新式 CompactedItem

checkpoint 可携带 window_number、first_window_id、previous_window_id、window_id。恢复优先采用最新 surviving checkpoint 的完整组合,使后续 Responses metadata 延续正确窗口。

SessionMeta 是初始窗口后备

从未 compact 的 Thread 可以使用 SessionMeta 的 initial context window identity。若发现 Legacy compaction 缺 window number,旧记录的身份链不可靠,算法退回以 compact 次数估算窗口编号。

Rollback 同时回退设置和窗口相关基线

被排除 Turn 的 TurnContext、WorldState 和 compaction metadata 不能继续影响结果。反向 segment 选择把这些元数据与有效历史一起裁剪。

Python 风格伪代码

下面的伪代码只保留设计职责、状态和失败顺序;它不逐行翻译 Rust,也不借 Python 语法虚构源码中不存在的事务:

def recover_settings_and_window(segments, session_meta):
    previous = None
    reference = NEVER_SET
    latest_checkpoint = None
    legacy_compact_count = 0

    for segment in surviving_segments_newest_first(segments):
        if previous is None and segment.is_completed_real_user_turn:
            previous = PreviousTurnSettings.from_context(segment.turn_context)
        reference = update_reference_state(reference, segment)
        if latest_checkpoint is None and segment.compacted:
            latest_checkpoint = segment.compacted
        legacy_compact_count += segment.legacy_compaction_count

    if latest_checkpoint and latest_checkpoint.has_window_identity():
        window = latest_checkpoint.window_identity()
    elif legacy_compact_count == 0:
        window = session_meta.initial_window_identity
    else:
        window = legacy_window_fallback(legacy_compact_count)
        reference = CLEARED
    return previous, reference, window

阅读时要特别看三处:哪个对象拥有可变状态,哪一个 await 是可观察屏障,以及失败后保留的是已提交前缀、未提交后缀,还是完全独立的外部副作用。

失败、取消与恢复

Previous Turn Settings 与 Context Window Identity 恢复的失败路径图,区分最新 Turn 未完成、Rollback 删除最新用户 Turn、Legacy compact 缺 window number、把 Cleared 当 NeverSet
图 8.22-2:同一操作在不同故障点留下的状态不同,恢复责任必须回到拥有该状态的组件。
故障点已留下的状态可观察结果恢复责任
最新 Turn 未完成TurnContext 已写但无可靠终态不能作为 previous settings继续找更旧完成用户 Turn
Rollback 删除最新用户 Turn其设置仍在物理日志不得泄漏到恢复结果segment skip 同时排除元数据
Legacy compact 缺 window number窗口 ID 链不完整不能伪造新式 identity计数 fallback 并清除不可靠 reference
把 Cleared 当 NeverSet两者下一步都可能全量注入但原因不同调试和后续选择失真内部保留三态再映射

这里没有统一的“回滚一切”。内存状态、日志行、SQLite 投影、父子拓扑和工具造成的文件/网络变化分别有自己的提交点。恢复代码只能根据已经存在的权威证据继续,不能用较弱的投影替较强的事实背书。

必须保持的不变量

  • previous settings 来自最新存活完成用户 Turn
  • 被 rollback 的 metadata 不参与恢复
  • 新式 checkpoint 优先于 SessionMeta 初始窗口
  • 不完整窗口身份不能被标记为可靠 cache lineage

这些不变量比“最终能 Resume”更严格:正常路径要成立,Writer 竞争、任务取消、坏尾行、投影落后和旧格式兼容时也必须成立。

设计取舍

记录窗口 ID 与设置快照增加 Rollout 元数据,但让恢复后的第一条请求延续与热 Session 相同的差异计算和缓存语义。

源码可以直接证明字段、分支、调用顺序和测试期望;“为什么这样设计”的表述是基于这些事实作出的工程归纳,不把它包装成未公开的产品承诺。

Mini Codex 复刻

在 checkpoint 中保存 window tuple;恢复器把 settings/reference/window 作为一个结果对象返回,测试 rollback 和 incomplete turn 不污染任何字段。

复刻时先验证协议不变量,再补性能优化。一个能在故障注入下说明“留下了什么”的小实现,比一个只在正常路径调用 save() 的演示更接近真实 Runtime。

源码导航

相邻测试也很重要:

本节结论

恢复不只得到消息数组;它还要找出最近一个存活且完成的用户 Turn 设置,并恢复 compaction window number/ID 链,才能让下一 Turn 正确比较配置和延续请求缓存作用域。

阅读导航

上一节:8.21 · 下一节:8.23

评论


← 返回文章列表