雨天小六

读懂 Codex(3.9):TurnContext 每个字段的来源与冻结时机

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

#Codex#Agent Runtime#生命周期#软件架构

TurnContext 不是 SessionState 的别名,也不是一个绝对不可变的深拷贝。它把一次 Turn 必须稳定的配置值冻结下来,同时保留少量通过 Arc 共享的运行期记录器。理解字段来源比背字段清单更重要。

字段按来源分成五组

代表字段来源/冻结时机
身份与追踪sub_id、trace_id、metadata创建 Turn 时
模型与协议config、model_info、provider、reasoning应用 settings update 后
策略与权限mode、approval、permission、network同一配置事务中
环境与上下文environments、cwd、date、timezone、skillsTurnContext 构造时
可变记录器timing、terminal_error、一次性 flagsArc/Atomic,Turn 内持续更新
TurnContext 字段从 SessionConfiguration、环境、模型目录和运行期记录器汇合
图 3.9-1:先在 SessionState 锁内形成一致配置,再在锁外解析模型和服务派生值;TurnContext 是这次 Turn 的决策基线。

new_turn_with_sub_id 在 SessionState 锁内克隆当前 SessionConfiguration,应用本次 SessionSettingsUpdate,验证约束,必要时更新 ThreadEnvironment selections,再把 next configuration 写回 SessionState。校验失败会用该 sub id 发 BadRequest,不启动 Task。

锁释放后才通知配置 contributor、刷新 MCP 预热或网络代理,最后调用 new_turn_context_from_configuration。长 I/O 不占 SessionState 锁,但 Context 使用的是已经确定的配置版本。

async def new_turn_with_sub_id(sub_id, update):
    async with session_state.lock() as state:
        try:
            next_cfg = state.session_configuration.apply(update)
            thread_environments.update_selections(next_cfg.environment_selections)
            state.session_configuration = next_cfg.clone()
        except ValidationError as err:
            await emit_bad_request(sub_id, err)
            raise InvalidRequest(err)

    await notify_config_contributors(next_cfg)
    await maybe_refresh_runtime_services(next_cfg)
    return await build_turn_context(sub_id, next_cfg)

“冻结”具体意味着什么

模型 slug、reasoning effort、approval policy、协作模式、dynamic tools 和 final schema 一旦进入 Context,本 Turn 后续采样都以这份值为准。ThreadSettings 的新提交会改变下一次 Turn 的 SessionConfiguration,不回写已经运行的 Context。

环境是细化的例外:Context 保存选中环境的 TurnEnvironmentSnapshot,其中 Starting 状态可以在 Step 捕获时提升为 Ready,但不会采用后来改变的 selection。也就是说“同一组选择可以变就绪”,“选择本身不在 Turn 中漂移”。

可变记录器是另一类例外。terminal_error 是 Arc<Mutex<Option<_>>>,timing state 在采样、重试和完成时累积;server warning flags 用 AtomicBool 保证只发一次。这些字段没有改变 Turn 的决策,只记录执行事实。

TurnContext 冻结决策字段但允许记录器和环境就绪状态更新
图 3.9-2:冻结的是决策输入,不是把整棵对象图复制成永不变化;运行指标、终态错误和 Starting→Ready 仍可更新。

为什么不在每个 Step 重读全部 SessionConfiguration

若第二次采样突然采用新模型或新权限,第一次采样产生的工具调用可能在另一套策略下执行,审计无法回答“这个 Turn 到底以什么配置运行”。TurnContext 把这类关键选择固定;真正应该热刷新的 MCP catalog、AGENTS.md 和环境 readiness 则放进 StepContext。

def may_change_between_steps(field):
    return field in {
        "mcp_binding", "tool_router", "loaded_agents_md",
        "environment_readiness", "capability_discovery"
    }

评论


← 返回文章列表