第2节 上下文经济学与记忆管理

技术报告§2.1–2.6
本节阐述上下文窗口的预算分配模型、双层压缩架构的博弈均衡、事件溯源机制,以及三层记忆系统的设计原理。

2.1 上下文窗口的预算分配

在长程智能体系统中,上下文窗口 $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章)。

2.2 压缩决策的形式化

压缩触发可建模为最优停点问题。给定历史序列 $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$ 为延迟权重。

2.3 双层压缩架构的博弈

本地压缩与远程压缩构成双层架构,可建模为成本-质量博弈。设两种压缩算子的质量函数分别为 $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}}$ 的特点:

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}}$ 由客户端模型上下文窗口和网络条件决定。

2.4 事件溯源与可重放

会话状态基于事件溯源模式,定义为事件序列的折叠:

$$ 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$ 为检查点对应的序号。崩溃恢复的正确性依赖于事件日志的确定性和幂等性。

2.5 记忆的三个时间尺度

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 系统实现:

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}}$ 为时间窗口。

2.6 设计原理剖析

"上下文是预算而非容器"的设计理念贯穿整个系统。传统视图将上下文视为固定容器,填满后溢出;Codex 将其视为有限预算,通过经济分配实现效用最大化。这体现为:

  1. 边际效用递减:早期对话轮次的边际信息贡献随时间递减,压缩决策基于此原理
  2. 机会成本:保留旧信息的机会成本是牺牲新信息空间,压缩阈值 $\theta$ 平衡二者
  3. 资源配置:通过线性规划将窗口分配给不同组分,最大化总体效用

从信息瓶颈视角看,给定有限窗口 $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
← 上一节下一节 →