在长程智能体系统中,上下文窗口 $W$ 是有限资源,其分配遵循线性规划模型。将窗口划分为多个互斥组分,在满足约束条件下最大化有效信息容量。
设上下文窗口被划分为 $n$ 个组分,第 $i$ 组分的 token 占用为 $x_i$,则预算分配问题可表述为:
$$ \begin{aligned} \max_{\boldsymbol{x}} \quad & I(\boldsymbol{x}) = \sum_{i=1}^{n} w_i I_i(x_i) \\ \text{s.t.} \quad & \sum_{i=1}^{n} x_i \leq \theta W \\ & x_i \geq 0, \quad i = 1, 2, \ldots, n \end{aligned} $$
其中 $I_i(x_i)$ 为组分 $i$ 在占用 $x_i$ tokens 时提供的信息量,$w_i$ 为权重系数,$\theta \in (0,1)$ 为占用率阈值。典型组分包括:
| 组分 | 符号 | 典型占用 | 优先级 |
|---|---|---|---|
| 系统提示词 | $x_{\text{sys}}$ | 2,000-5,000 | 最高 |
| 前缀材料(环境/Git/智能体) | $x_{\text{prefix}}$ | 500-5,500 | 高 |
| 对话历史 | $x_{\text{hist}}$ | 动态增长 | 中 |
| 实时上下文 | $x_{\text{rt}}$ | 5,500(分节预算) | 中 |
| 工具输出 | $x_{\text{tool}}$ | 可截断 | 低 |
| 输出预留 | $x_{\text{out}}$ | $(1-\theta)W$ | 保障 |
余量保护约束要求为模型输出预留足够空间,避免输入占满窗口导致无法生成响应。Codex 通过压缩触发阈值 $\theta \approx 0.75-0.8$ 间接保证余量(见第15章),而非显式计算 $x_{\text{out}}$。
多模态内容的 token 估算采用启发式规则。对于图像内容,定义压缩估算函数:
$$ T_{\text{img}} = \begin{cases} 7{,}373 \text{ bytes} \approx 1{,}844 \text{ tokens}, & \text{detail} \in \{\text{auto}, \text{low}\} \\ \min\left(\frac{H \times W}{32^2}, 10{,}000\right) \times k, & \text{detail} = \text{original} \end{cases} $$
其中 $H \times W$ 为图像尺寸,$k$ 为单位 patch 的 token 系数,32为 patch 像素尺寸。该估算使用 LRU 缓存避免重复解码(见第13章)。
压缩触发可建模为最优停点问题。给定历史序列 $h = (h_1, h_2, \ldots, h_t)$ 和 token 估算函数 $T(\cdot)$,定义触发条件为:
$$ \tau = \min\{t \geq 1 : T(h_t) \geq \theta W\} $$
其中 $\tau$ 为触发时刻,$\theta$ 为预设阈值。过早触发导致任务线索丢失,过晚触发则面临硬截断风险。该权衡可通过效用函数 $U(\tau)$ 评估:
$$ U(\tau) = \alpha \cdot L(h_{\tau}) - \beta \cdot C(h_{\tau}) - \gamma \cdot \mathbb{E}[\Delta_{\tau}] $$
其中 $L(h_{\tau})$ 为保留的信息量,$C(h_{\tau})$ 为压缩成本,$\Delta_{\tau}$ 为延迟惩罚,$\alpha, \beta, \gamma$ 为权重系数。
定义压缩算子 $\Gamma: \mathcal{H} \rightarrow \mathcal{H}$,将历史 $h$ 映射为摘要 $\hat{h}$,满足长度约束:
$$ \Gamma(h) = \hat{h}, \quad \text{s.t. } |\Gamma(h)| \leq \beta W $$
其中 $\beta$ 为压缩率参数,典型值 $\beta \in [0.1, 0.3]$。摘要生成的信息损失可通过互信息度量:
$$ \mathcal{L}(h, \hat{h}) = I(h; Y) - I(\hat{h}; Y) $$
其中 $Y$ 为模型预测目标,$I(\cdot; \cdot)$ 为互信息。实际实现中采用保留率 $\rho$ 作为代理指标:
$$ \rho = \frac{|\text{关键事实保留}|}{|\text{原始}|} $$
Codex 的压缩提示词引导模型保留:用户目标、重要决策、关键结果、待处理任务(见第15章),最大化 $\rho$。
压缩-收益权衡体现为损失-延迟边界。定义压缩频率 $f = 1/\mathbb{E}[\Delta \tau]$,在固定预算下存在最优频率 $f^*$ 使得:
$$ f^* = \arg\min_f \left\{ \mathcal{L}_{\text{cum}}(f) + \lambda \cdot \text{Latency}(f) \right\} $$
其中 $\mathcal{L}_{\text{cum}}$ 为累积信息损失,$\lambda$ 为延迟权重。
本地压缩与远程压缩构成双层架构,可建模为成本-质量博弈。设两种压缩算子的质量函数分别为 $Q_{\text{local}}(\cdot)$ 和 $Q_{\text{remote}}(\cdot)$,成本函数为 $C_{\text{local}}(\cdot)$ 和 $C_{\text{remote}}(\cdot)$,则选择策略为:
$$ \Gamma^*(h) = \begin{cases} \Gamma_{\text{local}}(h), & \text{if } T(h) \leq W_{\text{threshold}} \text{ and } C_{\text{local}} \leq C_{\text{budget}} \\ \Gamma_{\text{remote}}(h), & \text{otherwise} \end{cases} $$
本地压缩 $\Gamma_{\text{local}}$ 的特点:
远程压缩 $\Gamma_{\text{remote}}$ 的特点:
/responses/compact)→ v2 协议(CompactionTrigger 机制)v1 与 v2 的核心差异在于协议统一性和元数据处理。v2 使用 CompactionTrigger 标记触发服务端压缩,复用 /responses 流式端点,并通过 prompt_input_metadata 保留 harness metadata。形式化表示:
$$ \text{v2 输入} = \left(\text{history}, \text{metadata}\right), \quad \text{CompactionTrigger} \in \text{input} $$
$$ \text{v2 输出} = \text{CompactionItem}, \quad \text{metadata}_{\text{output}} = \text{metadata}_{\text{input}} \cap \text{retained} $$
其中 retained 根据 client_authored 标记过滤,保留客户端编写的 developer 消息。
双层架构的博弈均衡取决于历史规模 $T(h)$:
$$ (T(h) \leq T_{\text{local\_max}}) \rightarrow \Gamma_{\text{local}}, \quad (T(h) > T_{\text{local\_max}}) \rightarrow \Gamma_{\text{remote}} $$
阈值 $T_{\text{local\_max}}$ 由客户端模型上下文窗口和网络条件决定。
会话状态基于事件溯源模式,定义为事件序列的折叠:
$$ s_t = \text{fold}(e_1, e_2, \ldots, e_t) = s_0 \oplus e_1 \oplus e_2 \oplus \cdots \oplus e_t $$
其中 $s_0$ 为初始状态,$\oplus$ 为状态合并算子,$e_i \in \mathcal{E}$ 为事件类型集合。Codex 使用 JSONL 格式逐行追加事件,每行包含时间戳、序号和事件载荷:
$$ \text{RolloutLine}_i = \{\text{timestamp}: t_i, \text{ordinal}: i, \text{item}: e_i\} $$
事件类型包括:SessionMeta(会话元数据)、ResponseItem(模型响应)、Compacted(压缩历史)、TurnContext(回合上下文)、WorldState(世界状态快照/补丁)、EventMsg(事件消息)(见第17章)。
反向重放算法通过从最新到最旧扫描 Rollout 文件,找到"最新的完整历史基线",然后只重放该基线之后的事件。定义扫描状态为:
$$ \mathcal{S}_{\text{scan}} = (\text{turn_id}, \text{counts_as_user_turn}, \text{previous_turn_settings}, \text{world_state_replay}, \text{base_replacement_history}, \text{window}) $$
反向扫描终止条件为找到历史基线和所有必需元数据:
$$ \text{stop} \iff (\text{base_replacement_history} \neq \emptyset) \land (\text{previous_turn_settings} \neq \emptyset) \land (\text{window} \neq \emptyset) $$
该算法效率为 $O(k)$,其中 $k$ 为基线之后的事件数,通常 $k \ll n$(总事件数)。
正向重放构建按时间顺序重放基线后的事件,重建完整历史。状态重建复杂度为:
$$ \text{Complexity} = O(k \cdot \bar{c}) $$
其中 $\bar{c}$ 为单事件平均处理成本。世界状态重放支持增量更新:完整快照替换基线,增量补丁合并到基线。
崩溃恢复通过从检查点重放实现。检查点记录压缩前后的历史:
$$ \text{Checkpoint} = (\text{input_history}, \text{replacement_history}) $$
恢复时加载最新检查点,重放后续事件:
$$ s_{\text{restored}} = \text{fold}(s_{\text{checkpoint}}, e_{c+1}, \ldots, e_t) $$
其中 $c$ 为检查点对应的序号。崩溃恢复的正确性依赖于事件日志的确定性和幂等性。
Codex 的记忆系统遵循分层存储模型,包含三个时间尺度:
| 时间尺度 | 存储位置 | 访问延迟 | 容量 | 用途 |
|---|---|---|---|---|
| 工作记忆 | 上下文窗口内 | 毫秒级 | $W$ tokens | 当前回合推理 |
| 会话记忆 | Rollout JSONL | 秒级 | 无限(磁盘) | 会话状态重建 |
| 长期记忆 | AGENTS.md + memories/ | 分钟级 | 项目级 | 跨会话知识 |
工作记忆(Working Memory)对应于上下文窗口内的实时内容,包括:
工作记忆的注入策略为分节管理,通过 Token 预算控制每节大小:
$$ \sum_{i \in \{\text{CurrentThread}, \text{RecentWork}, \text{Workspace}\}} T(\text{section}_i) \leq T_{\text{total}} $$
其中 $T_{\text{total}} \approx 5{,}500$ tokens。
会话记忆(Session Memory)通过 Rollout 持久化实现,支持:
会话记忆的查询通过反向扫描优化,复杂度 $O(k)$。
长期记忆(Long-term Memory)通过 AGENTS.md 和 memories 系统实现:
.codex/memories/ 目录AGENTS.md 发现算法从项目根目录向当前目录遍历,收集所有文件并合并(见第19章):
$$ \text{agents_md}_{\text{merged}} = \text{merge}(\text{AGENTS.md}_{\text{root}}, \ldots, \text{AGENTS.md}_{\text{cwd}}) $$
合并规则:用户指令优先,使用分隔符区分不同来源。
记忆注入策略基于时间尺度和相关性:
$$ \text{Inject}(\text{memory}) \iff (\text{Relevance}(\text{memory}, \text{current_task}) > \tau_{\text{mem}}) \land (\text{TimeSinceLastAccess}(\text{memory}) < T_{\text{mem}}) $$
其中 $\tau_{\text{mem}}$ 为相关性阈值,$T_{\text{mem}}$ 为时间窗口。
"上下文是预算而非容器"的设计理念贯穿整个系统。传统视图将上下文视为固定容器,填满后溢出;Codex 将其视为有限预算,通过经济分配实现效用最大化。这体现为:
从信息瓶颈视角看,给定有限窗口 $W$,压缩算子 $\Gamma$ 的目标是最大化保留任务相关信息量:
$$ \max_{\Gamma} I(T; \Gamma(H) \mid Y) $$
其中 $T$ 为任务变量,$Y$ 为用户意图,$H$ 为完整历史。该优化等价于最小化损失信息:
$$ \min_{\Gamma} I(H; Y) - I(\Gamma(H); Y) $$
Codex 的实现通过以下策略近似求解:
双层压缩架构体现了延迟-质量权衡。本地压缩提供低延迟 baseline,远程压缩提供高质量上限。选择策略基于历史规模和成本约束,实现帕累托最优前沿:
$$ \{(\text{Latency}, \text{Quality}) : \text{Latency} = C_{\text{local}}^{-1}, \text{Quality} = Q_{\text{local}} \} \cup \{(\text{Latency}, \text{Quality}) : \text{Latency} = C_{\text{remote}}^{-1}, \text{Quality} = Q_{\text{remote}} \} $$
事件溯源架构支持状态重建和时间旅行。通过记录事件而非状态快照,系统可以从任意检查点重放,支持崩溃恢复、回滚和 Fork。JSONL 格式的增量写入支持高效追加,反向扫描算法优化重放性能。
分层记忆系统对应于人类认知的三个层次:工作记忆(意识)、情景记忆(近期事件)、语义记忆(长期知识)。这种分层既符合认知原理,也实现了工程上的性能优化:快速缓存、中等速度磁盘、慢速但可扩展的长期存储。
| 符号 | 含义 | 首次出现小节 |
|---|---|---|
| $W$ | 上下文窗口大小(tokens) | 2.1 |
| $x_i$ | 第 $i$ 组分的 token 占用 | 2.1 |
| $\theta$ | 占用率阈值 | 2.1 |
| $I(\cdot)$ | 信息量函数 | 2.1 |
| $T_{\text{img}}$ | 图像 token 估算 | 2.1 |
| $T(\cdot)$ | Token 估算函数 | 2.2 |
| $\tau$ | 压缩触发时刻 | 2.2 |
| $\Gamma$ | 压缩算子 | 2.2 |
| $\beta$ | 压缩率参数 | 2.2 |
| $\rho$ | 信息保留率 | 2.2 |
| $U(\cdot)$ | 压缩效用函数 | 2.2 |
| $Q(\cdot)$ | 压缩质量函数 | 2.3 |
| $C(\cdot)$ | 压缩成本函数 | 2.3 |
| $s_t$ | 时刻 $t$ 的会话状态 | 2.4 |
| $e_i$ | 第 $i$ 个事件 | 2.4 |
| $\oplus$ | 状态合并算子 | 2.4 |
| $k$ | 基线后事件数量 | 2.4 |
| $\bar{c}$ | 单事件平均处理成本 | 2.4 |
| $T_{\text{total}}$ | 实时上下文总预算 | 2.5 |
| $\tau_{\text{mem}}$ | 记忆相关性阈值 | 2.5 |
| $T_{\text{mem}}$ | 记忆时间窗口 | 2.5 |
| $I(\cdot; \cdot)$ | 互信息 | 2.6 |
| $H$ | 完整历史 | 2.6 |
| $Y$ | 用户意图 | 2.6 |
| $T$ | 任务变量 | 2.6 |