初始上下文是 Runtime 在新上下文窗口中建立的“模型视图基线”。它包含 Developer Instructions、Skills 元数据、扩展贡献、完整 World State 和部分窗口元数据;普通用户消息只记录一个真实输入事件。两者即使都表现为 ResponseItem::Message,也不能共享同一种生命周期。
初始上下文是一组编译产物
构造器依次收集静态指令、Thread/Turn Extension 贡献、Token Budget 上下文和 world_state.render_full()。模型切换片段被提前放到 Developer bundle 首部;Multi-Agent Mode 在 usage hint 之后单独插入,使当前模式能够覆盖通用提示。
async def build_initial_context(turn, world_state):
dev = collect_developer_instructions(turn)
dev += render_skill_catalog(turn.skills)
dev += await extension_thread_and_turn_fragments(turn)
dev += render_token_budget_context(turn)
dev, user, isolated = route(world_state.render_full(), dev)
return compile_role_items(dev, user, isolated)
构造完成后,每个 item 会补上当前 Turn ID。压缩创建新窗口时可以直接把这组 items 安装进替代 History,并仍能知道它属于哪个上下文边界。
与普通用户消息的四个差别
| 维度 | 初始上下文 | 普通用户消息 |
|---|---|---|
| 事实语义 | 当前仍成立的状态与规则 | 某时刻发生的用户输入 |
| 角色 | developer 与 contextual user 混合 | user |
| 更新 | 可差分、替换、撤销 | 追加保存 |
| 压缩后处理 | 必须重建完整基线 | 可被摘要保留语义 |
async def record_first_turn(session, turn):
world = await build_world_state(turn.step)
context = await session.build_initial_context(turn, world)
session.history.set_world_state_baseline(world.snapshot())
session.history.record_items(context)
session.history.record_items([Message.user(turn.input)])
为什么需要引用基线
History 保存了初始上下文,并不自动证明 Runtime 仍知道它对应哪份 Snapshot。Session 还会持有引用上下文项和 World State baseline;缺少引用或 History 整体替换时,下一边界必须再次完整注入。否则 Runtime 可能只发“权限从 A 改为 B”,而模型实际已经看不到 A。
测试不能只断言字符串出现,还应验证首次记录顺序、World State full item、TurnContext 基线和重复调用时的去重。
源码与测试锚点
codex-rs/core/src/session/mod.rs::build_initial_context_with_world_state。codex-rs/core/src/session/world_state.rs:首个 Step 状态构造。codex-rs/core/src/session/tests.rs:基线缺失、清空后重注入和无差异场景。codex-rs/core/src/compact.rs:压缩后初始上下文安装。
评论
登录后即可评论