生成式压缩比筛选少 Θ(log n) 预算,Opus 端点成员查询近乎瞎猜

Context Compaction Theory

Hayder Tirmazi, Sam Markelon, Allison Bishop, Michael Mitzenmacher

cs.DS, cs.AI

2026-08-02

生成式压缩的最小预算等于单向通信复杂度,选择策略在一类查询上多花 Θ(log n) 位。Opus 4.8 压 1.5 万 URL 后成员查询错误率 0.50–0.56,同尺寸 Bloom 过滤器约三分之一。

这篇在解决什么

Agent 每调一次 LLM,都要把内部状态塞进有限的 context window。状态里有用户消息、模型回复、读文件和跑命令的结果。窗口装不下,系统就做一次 context compaction:把状态压成更短的输入,再用压过的版本继续往后走。

这件事每家都在做。Codex、Claude Code、Gemini CLI、OpenCode 都是用量超阈值就触发,常见阈值大约是窗口的 95%。但几乎没有形式化分析:压完还保得住什么,没有保证。经验论文只报下游任务准确率。

生产系统压完会把压缩结果当成新的内部状态继续用,不会每次都拿完整历史重压一遍。论文算过一笔账:80 万 token 的历史要产出 10 万 token 摘要,按 Claude Fable 5 的定价是输入 8 美元加输出 5 美元,合计 13 美元;按约 65 token/秒的生成速度,光写出摘要就要大约 26 分钟。压缩一旦发生,丢掉的信息在本轮会话里基本回不来。

方法

把压缩看成两玩家博弈。一方是压缩算法,另一方代表「未来还要用哪些信息」。状态被抽象成一组离散 item,一条错误信息、一个设计决策、一次工具输出都可以是一个 item,不跟 token 序列绑死。

两种策略对应两个博弈。

查询分两种体制。随机体制下,状态和查询一起从已知分布抽,关心期望误差。迟钝对手体制下,对手先定状态再定查询,但看不到压缩结果,关心最坏情况。自适应对手先看压缩结果再出题,这篇没覆盖。

核心定理:GEN 在目标误差 ε 下的最小预算,等于诱导出的单向通信问题的单向随机通信复杂度。压缩器扮演 Alice,之后读压缩结果的那次 LLM 调用扮演 Bob。通信复杂度里的已知上下界可以直接搬过来。

SELECT 是受限的单向协议:消息只能编码一个子集,解释器只能看这个子集。定理 3 给出分离。n 个大小各为 log₂ n 位的 item,查询是「把任意子集 X 原样交回来」。GEN 发 n 位指示向量即可零误差;SELECT 必须留下全部 item,预算至少 n log₂ n。差距是 Θ(log n)。

等价是信息论的,不保证某个具体摘要器算得出来。下界对任何解释器都成立,上界只说明存在某种 GEN 算法。

结果

理论结果是等价和分离。实验是拿这把尺子去量一个上线端点。

设置预算错误率
Opus 4.8 压缩,seed 4214.3 Kbits0.505(假阳性 0.04 / 假阴性 0.97)
seed 4313.6 Kbits0.535(0.28 / 0.79)
seed 4414.8 Kbits0.555(0.48 / 0.63)
同尺寸 Bloom 过滤器约 14 Kbits约 1/3
不压缩,全文留在上下文7280 Kbits0.02(0.00 / 0.04)

实验从 Malicious URLs 数据集均匀抽 15,000 条 URL 写进对话,约占 50 万 token,触发 Anthropic 服务端压缩(阈值 5 万 token),并事先告诉端点:压缩结果只用来做集合成员查询。之后用压缩后的摘要单独问 200 道是否在集合里,一半真成员、一半真非成员,三个随机种子。

三次错误率都贴着 0.5 的随机猜线。Bloom 过滤器在同样 bit 数下大约错三分之一;信息论下界是 (1/2)·2^{-B/N}。对照实验把 15,000 条全留在上下文、不做压缩,Opus 4.8 错误率掉到 0.02。误差来自压缩丢掉的信息,不是模型不会做成员查询。

摘要原文写得很直白:集合有上万条 URL,不可能无损塞进合理篇幅,于是改成描述集合的「气质」,钓鱼站、Mozi 僵尸网络、魁北克主题站点,再按像不像来猜。

讨论里还有一个设计含义。Agent 扫完仓库要回答「这些依赖有没有出现在 CVE 列表里」,这是集合不相交。要在所有输入上答对,压缩预算是 Ω(N m) 位,N 是依赖数、m 是包名位数,跟不压缩存清单一个量级。换成 Bloom 过滤器做近似成员查询,当查询集合可以大到整个包名宇宙时,仍然是 Ω(N m)。

为什么重要

给 Agent 作者一把尺子:给定未来可能问的那类问题,最小该留多少 bit,等于对应单向通信问题的复杂度。集合成员查询上,Bloom 过滤器已经是常数因子内最优的压缩算法,假阳性率 ε 大约用 1.44 N log₂(1/ε) 位,可以直接当基线。

也把现在的工程实践分了类。只做截断、只留最近 N 条,是 SELECT,在定理 3 那种查询上天生吃亏。LLM 摘要是 GEN,理论上可以更省,但附录实验说明:知道工作负载是成员查询、数据还是有结构的 URL,Opus 4.8 的摘要端点仍然没把信息压成 sketch,接近瞎猜。

对要做长会话 Agent 的人,这篇更接近一个警告。单次压缩已经是对 Agent 最有利的情况;多次压缩只会继续丢信息,而生产系统恰恰是把上次摘要当下次输入。论文把「重复压缩误差怎么涨」列为开放问题,没有给增长公式。

局限与存疑

作者自己列了四处缺口。定理不管自适应对手;SELECT 与 GEN 的差距只证了 Θ(log n) 这一例,一般查询上能差多大还不知道;模型只覆盖单次压缩;界是信息论的,不保证 LLM 摘要器能逼近最优,也不保证 LLM 能在上下文里执行 sketch 解码。

实验本身也窄。一个端点、一个模型 Opus 4.8、一种工作负载(恶意 URL 上的成员查询)、一种提示词。作者写明:这不是「上下文压缩一定不如 Bloom 过滤器」的通论,只是展示怎么用定理做测量。提示词要求「用任何最能减少成员查询错误的表示」,模型仍选择了自然语言气质描述,没有输出 bit 数组。这更像当前摘要器的行为快照,不是 GEN 类算法的能力上限。

item 粒度是建模选择,从整条消息到单个 token 都算 SELECT,但粒度一变,SELECT 和 GEN 的边界会跟着动。论文把无损压缩当成每个 item 内部的黑盒,不讨论跨 item 的联合编码,而联合编码恰恰是 GEN 比 SELECT 省预算的来源之一。

术语

原文与代码

社区讨论

相关论文

全部论文解读