Codex 源码解析 · 第 13 讲
Codex 源码解析系列 第 13 讲:Context Manager 与历史管理 基于 OpenAI Codex 源码 · 2026-10-07 💡 本讲一句话: Codex 的对话历史不是"一个数组",而是三层结构——模型可见窗口(会被压缩/回滚)、独立于窗口的保留上下文(用户授权事实,跨压缩存活)、以及每次发请求前的归一化流水线。本讲逐行拆 ContextManager 的核心字段、record_items 写入路径、normalize_history 的三条不变量、token 估算启发式与回滚语义,读完你能说清"历史被压缩后,为什么模型还能记得你批准过哪些操作"。 一、ContextManager:一个结构体,三种"历史" 第 10 讲我们看过 Agent Loop 每轮把 prompt 发给模型,但"prompt 里的历史从哪来、怎么存、压缩后剩什么"是另一个问题。答案在 codex-rs/core/src/context_manager/history.rs (1144 行)里的 ContextManager 。先看它的字段定义——每个字段的注释都透露了设计意图: 📄 codex-rs/core/src/context_manager/history.rs (第 69-99 行) #[derive(Debug, Clone, Default)] // 派生三个 trait:可打印、可克隆(快照靠它)、有零值默认 pub(crate) struct ContextManager { // 会话级历史管理器,crate 内可见;"Transcript of thread history" // The oldest items are at the beginning of the vector. Snapshots share the vector until a // caller needs to mutate it, avoiding deep copies for read-only history consumers. items: Arc<Vec<ResponseItemEnvelope>>, // 核心历史:最旧在前;Arc 让快照共享同一份 Vec,读多写少免深拷贝 // Legacy-only history, started at first compaction. Thread-owned mode reads parent context. review_history: Option<TranscriptHistory>, // Guardian 审查用的"原始转录":首次压缩时建立,Legacy 模式专属 // Host facts independent of the model window; snapshots share immutable state. retained_context: Arc<RetainedContext>, // 宿主侧事实(用户授权等):独立于模型窗口,压缩不丢它 // Capture, replay, and snapshot selection share the immutable session mode. guardian_context_mode: GuardianContextMode, // Guardian 上下文模式:Legacy / ThreadOwned,决定快照暴露哪些字段 retain_inherited_user_messages: bool, // 是否保留"继承来的用户消息"(worker→root 晋升场景) // Bumped whenever history is rewritten, such as compaction or rollback. history_version: u64, // 历史版本号:每次重写(压缩/回滚/reset)+1,供下游判断缓存失效 // Monotonic user-input/reset revision, independent of compaction's history generation. user_messag…
阅读全文:Codex 源码解析 第 13 讲