You don’t need long context 完全拆解:单动作压缩、选择性读取与语义状态空间模型

11657 字
58 分钟
You don’t need long context 完全拆解:单动作压缩、选择性读取与语义状态空间模型

长任务不一定要求模型在每一步重新看到全部历史。更关键的问题是:下一步决策究竟依赖哪些信息,这些信息能否被持续维护为一个更小、可核验的状态?

先区分三件事:长输入、长过程与长上下文

2026 年 11 月 3 日,Peter Belcak 等 NVIDIA 研究者发布技术报告 《You don’t need long context》。报告提出的挑战不是“长文档是否存在”,而是“完成长任务,是否必须让模型持续持有很长的活动上下文”。它主要改变 Agent 的运行框架与信息呈现方式,没有要求更换注意力算子。

这一区分决定了如何理解标题中的“不需要”。一个代码仓库可以有数百万行,一个调查可以经历上百次检索,但任意一次模型调用需要直接处理的信息,可能只是任务要求、当前进展和刚读到的一段证据。任务规模、任务持续时间与单次调用的输入长度,是三个不同维度。

概念长度来自哪里压缩方法要解决什么
长输入任务原始材料本身很大,例如一组报告或一个仓库材料放在哪里,当前应读哪一部分
长程任务多轮行动、反馈、修正不断积累哪些过去的事实会影响下一步
长活动上下文一次调用同时放入很多 token这些 token 是否都需要同时参与计算

论文把约 16K–50K token 的工作区间称为短上下文,把允许历史向约 256K 及以上增长的策略归入长上下文。这是相对实验所用模型窗口的操作性定义;16K token 已经能容纳相当多内容,不能把这里的“短”理解成只剩几句提示。

一个具体例子是修复配置解析错误。最初的十次命令可能依次列目录、找到入口、阅读解析器、运行测试、排除两个猜想。到第十一步,模型不一定仍需要所有目录清单、完整失败日志和已经推翻的推理,但必须知道错误触发条件、相关文件、已验证事实、失败方案及尚未完成的检查。如果后者能被可靠保存,前者就不必反复进入注意力计算。

这与本站介绍过的 Multi-Agent Memory 有共同的系统视角:信息可以存放在不同层级。本文进一步讨论一个更具体的问题:单个 Agent 是否能依靠持续更新的语义状态,在很短的活动上下文里完成长程任务。

长上下文的成本为什么延伸到每一个输出 token

KV 缓存省掉重算,却没有省掉对历史的访问

自回归推理一般分为 Prefill 和 Decode。Prefill 把输入变成各层的 Key、Value;Decode 每生成一个新 token,就让新的 Query 与历史 Key 计算匹配关系,再对 Value 加权求和。KV 缓存避免每一步重新投影所有历史 token,但在全注意力层里,历史越长,解码仍然要处理越多 KV。

对一个采用常规 GQA 的模型,单条序列的逻辑 KV 数据量可以近似写成:

MKV(L)=2NlayerLHKVdhb.M_{\mathrm{KV}}(L)=2N_{\mathrm{layer}}LH_{\mathrm{KV}}d_hb.

这里 LL 是已缓存的 token 数,NlayerN_{\mathrm{layer}} 是缓存 KV 的层数,HKVH_{\mathrm{KV}} 是每层 KV 头数,dhd_h 是头维度,bb 是每个元素的字节数;系数 2 对应 Key 和 Value。这一式子暂不包含页表、量化尺度和内存对齐;MLA 和循环状态模型需要使用各自的存储公式。

作为量级示例,假设一个模型有 32 个全注意力层、8 个 KV 头、128 维头,KV 使用 BF16,即每元素 2 字节。每个 token 的 KV 是 131,072 字节,也就是 128 KiB;16,384 token 对应约 2 GiB,262,144 token 对应约 32 GiB。这里只是说明线性关系的假想模型,不是论文某个模型的配置或测量。

KV 缓存的容量和读取成本会同时影响单请求与并发服务。 这份容量会同时作用于两个方向。单请求每一步的注意力负担变大;多请求服务中,每条请求占用更多显存,系统能并行容纳的序列也可能变少。历史不必重新生成,但它仍然占空间,并可能在后续每一步被访问。

近似地,可把单步成本拆成:

tstep(L)≈tother+αL.t_{\mathrm{step}}(L)\approx t_{\mathrm{other}}+\alpha L.

tothert_{\mathrm{other}} 表示权重读取、其他算子和调度等部分,αL\alpha L 表示全注意力随历史长度增加的部分。这是用于解释趋势的模型,不是严格性能预测器;批大小、缓存命中、并行度和内核调度都会改变它。也正因为存在 tothert_{\mathrm{other}},上下文缩短 16 倍,并不意味着端到端速度必然提高 16 倍。

论文的云端曲线到底测了什么

论文图一:三个开放权重模型的输出 token 成本随上下文窗口增大而上升

图源:原论文图 1。横轴是配置的窗口大小,纵轴是根据实测峰值解码吞吐折算的每百万输出 token GPU 成本;三条曲线分别属于 GLM 5.2、Kimi K2.6 和 Qwen 3 Coder Next。它展示的是特定服务实验中的资源成本,不是三款模型的公开 API 报价。

论文使用 H100 集群和 vLLM。Qwen 部署使用 8 张 H100,另两个模型使用 16 张。GLM 与 Kimi 使用 INT4 专家权重、BF16 激活,Kimi 还使用 FP8 KV 缓存;Qwen 使用 BF16。每个窗口设置下,从同一 token 序列的嵌套前缀中均匀抽取请求长度,每条请求输出 1,024 token。

尤其关键的是,作者先预填最长前缀并启用前缀缓存,再扫描并发数,选择没有 KV 抢占的最高持续解码吞吐。因此实验有意聚焦已有输入 KV 上的解码阶段,并尽量排除反复 Prefill 的开销。窗口从 256K 降到 16K 时,作者报告三款模型的峰值聚合解码吞吐分别提高约 3.6、5.6、7 倍。

在 GPU 数与单位时间价格固定时,吞吐和单位输出成本互为倒数:

C1M=106Gp3600T.C_{1\mathrm{M}}=\frac{10^6G p}{3600T}.

GG 是 GPU 张数,pp 是每张 GPU 的小时价格,TT 是聚合输出 token/s,C1MC_{1\mathrm{M}} 是每百万输出 token 的美元成本。论文按 2026 年 9 月 Nebius H100 按需价格 3.85 美元/GPU·小时折算。这个价格是原实验的换算参数,不代表其他部署环境的当前报价。

这也限定了“7 倍”的含义:它是特定模型、窗口、请求长度分布、并发搜索与缓存条件下的解码吞吐比值。实际 Agent 还要付出工具执行、状态压缩、新上下文 Prefill、队列等待等成本,不能把这个比值直接标成整项任务的加速。

本地推理受影响的方式并不完全相同

论文图二:DGX Spark 上输入长度与逐 token 延迟、单请求吞吐及内存占用的关系

图源:原论文图 2。左、中、右三个面板分别表示逐 token 延迟、单请求解码吞吐和内存占用,横轴均为输入长度。不同颜色属于不同模型,不能把某一模型的斜率当作所有架构的通用规律。

这组实验在 DGX Spark 上一次运行一个模型和一个请求,对不同长度的输入前缀继续生成 1,024 token。中间面板的吞吐就是平均逐 token 延迟的倒数,与云端饱和并发的聚合吞吐不同。论文观察到部分模型较深位置 token 的生成延迟接近早期的两倍,但含滑窗、线性注意力、全注意力的模型曲线各异。

因而缩短上下文有三类可能收益:减少历史 KV 容量、降低部分注意力层的解码负担、为并发释放空间。实际能得到多少,要看是哪类层占主导、权重本身有多大、GPU 是否已被其他算子限制。

三种运行方式:全历史、临界压缩与单动作压缩

论文的实验沿用一个简单的 ReAct 循环:模型根据任务和上下文选择一条 Bash 动作,环境执行并返回结果,再由模型决定下一步。软件与终端任务采用 mini-swe-agent,其他任务使用把相同循环推广到检索、问答和工具交互的 mini-agent。

在 mini-swe-agent 官方介绍 中,Bash 工具和线性消息历史正是简化运行框架的关键。这里的上下文管理改变的是每轮送入哪些消息,以及什么时候启动新会话;模型的底层推理内核可以保持相同。

论文图三:全历史积累、达到阈值后压缩和每次动作后压缩的消息结构

图源:原论文图 3。左侧只有一段持续增长的对话;中间在阈值附近插入压缩提示,再把压缩结果送入新会话;右侧将一次动作、工具返回和语义状态更新组成一个周期。图中的箭头表示会话交接,不表示旧文件或真实环境被清空。

FHA:每一步都携带越来越长的过去

Full-History Accumulation,即全历史积累,保留任务开始后的所有模型动作和工具观测。假设初始提示长度为 BB,每一步平均增加 uu token,执行 nn 步后,输入长度约为 B+nuB+nu。

这很容易实现,也保留了全部原始细节。问题是,一份过时目录清单、一段重复报错、一个已排除的猜想,都与真正重要的约束一起不断进入后续调用。前缀缓存可以避免重算某些输入,却不能让活动 KV 的体积和注意力负担消失。

从消息长度看,把每轮提示长度相加,会出现:

∑i=0n−1(B+iu)=nB+un(n−1)2.\sum_{i=0}^{n-1}(B+iu)=nB+\frac{u n(n-1)}{2}.

这是全部提示暴露量的简化计算,并不是 GPU FLOPs 或实际收费公式,因为前缀缓存会改变哪些输入需要重新处理。它说明的是:如果没有状态管理,旧内容会被越来越多次地放进决策环境。

EoCC:达到阈值才交接

End-of-Conversation Compaction 在一段会话中仍按 FHA 工作;当历史跨过预设压缩阈值,就要求模型停止执行工具,产出一份受预算约束的状态交接。运行框架随后新建会话,重新放入系统提示、原任务和交接内容,再继续执行。

论文用“总上下文限额 / 压缩阈值”描述设置,例如 16K / 12K。12K 是启动压缩的时机,16K 是更高的会话总预算;二者之间必须为压缩请求和输出留出空间。它不是“正文 16K 加摘要 12K”,也不是等到 16K 窗口完全塞满再开始总结。

工程上,阈值和硬上限之间的余量也要覆盖一次工具返回可能带来的突增。一个读取命令若一次吐出数万 token,仍可能在压缩前越界。因此受限读取与输出截断是预算控制的一部分,不能只依赖一个 token 计数器。

EoCC 的优势是压缩发生得较少,一段会话内还能自然复用消息前缀。它的风险是压缩时历史已经比较长,模型需要从大量内容中找出仍有用的部分;阈值过小又可能使任务刚推进几步就进入下一次交接。

SAC:每执行一次动作,就重新形成状态

Single-Action Compaction 把这一过程推进到极端。每一段新会话只执行一次环境动作,观察返回后,更新语义状态,随后再重置会话。跨动作传递的是当前语义状态,而不是一条无限延长的消息列表。

一次周期可以表示为:

固定系统指令 + 原始任务 + 当前语义状态
→ 模型选择一个环境动作
→ 工具执行,返回观测
→ 运行框架发出状态更新提示
→ 模型写出下一份语义状态
→ 新会话接收它,开始下一周期

这里的“单动作”限制的是每段会话中的环境动作数,不是只能生成一个 token,也不是整个周期只有一次推理调用。图 3 明确画出了工具结果后的 compaction nudge:实验机制要为状态更新再生成文本。忽略这一步,就会低估 SAC 的调用次数和输出成本。

重置的也只是模型会话。已经写入仓库的修改、磁盘文件和工具环境中的实际状态继续存在;否则下一轮连刚刚完成的编辑都看不到。对一个正在编写补丁的 Agent 来说,短语义状态和持久仓库共同承担记忆职责。

论文在 SAC 实验中保留基础任务循环、模型和环境,主要替换上下文管理方式。这个控制有助于观察压缩频率的影响,但并不意味着 SAC 对任意运行框架都能直接套用,尤其是那些一次并行发出多项工具动作的系统。

摘要怎样成为能继续执行的状态

好交接保留的是未来依赖

论文附录 A 的一个重要发现是,把压缩当作普通摘要并不理想。论文附录 A 指出,普通摘要容易着重概括整段对话讲过什么,还容易给多次出现的内容更高权重;但一段重复十次的失败日志,未必比只出现一次的约束更重要。

压缩应保留未来行动的依赖。 因此,压缩的目标应当是:让下一次调用知道现在处于什么状态、哪些事实已得到证实、下一步还缺什么。它需要对未来工作有用,不能仅仅在叙事上忠实。

原论文描述的内容可归纳为三组:原任务或近乎原样的任务要求;当前工作、意图和下一步计划;直接影响后续执行的事实、完成条件、产物以及指向产物的位置。附录 G 又把交接提示细化为目标、已知事实、已应用修改、验证、失败路线和剩余计划。

这些项目并非互相替代。例如“已修改解析器”只描述动作,不描述修改是否通过验证;“发现可能是空值问题”只是猜想,也不能改写成已确认原因。

下面是一份用于解释结构的示例,文件名和命令都是假想工程中的占位名称,并非论文运行记录:

目标与约束:
修复空配置项导致的解析错误;保留既有合法输入行为。
已确认事实:
parser.py 的 parse_value 会在空字符串上抛出 IndexError。
tests/test_parser.py 中的合法数字测试当前通过。
当前修改:
parser.py 已加空值分支;修改尚未完成全部回归验证。
验证记录:
空字符串最小复现通过;完整解析器测试尚未运行。
已排除路线:
调整文件编码不能消除错误,不再重复这条路线。
下一步:
运行解析器回归测试,检查空白字符和缺失字段两类边界。
完成条件:
最小复现与回归测试通过;确认没有改变合法数字解析。

这比“已经深入研究了解析问题,并做了一些修改”更长,却更节省下一轮恢复工作的成本。压缩率最大,不等于信息质量最高。

哪些东西应该原样,哪些可以只保留指针

原始目标、严格限制、验收条件和尚未兑现的承诺,适合由运行框架作为固定输入重新提供。这样可以避免多次摘要后,“必须保留兼容性”逐渐变成“尽量兼容”。

对大文件、长日志和证据表,语义状态可以只保存路径、行号、关键值和读取命令。需要细节时,模型重新打开源材料。这里有一个前提:那个指针必须在下一周期仍然有效。临时输出没有保存,或者文件已被覆盖,短摘要中的“见刚才日志”就不是可恢复的记忆。

路径也不是永远充分。代码编辑后行号可能变化,网页可能更新,日志可能追加。工程上可为证据补充符号名、版本、内容哈希或稳定记录编号,使“去哪里查”同时说明“查的是哪个版本”。这是由论文方法推导出的实现要求,论文没有给出一套通用证据数据库。

连续压缩为什么会累积错误

设某个事实最初只是推测。第一次压缩删掉“可能”,第二次压缩把它与其他事实合并,第三次压缩又删除反证所在的位置,最终就可能把一个猜想固化成后续决策的前提。

同样危险的是删除负面证据:如果只留下“正在检查缓存问题”,却没有留下“关闭缓存后仍复现”,新会话可能再次走同一条失败路线。活动上下文变短了,整个任务却变长了。

因此状态更新至少要保持三个界限:观测与假设分开,已完成动作与已验证结果分开,尚未完成与明确失败分开。摘要还应保留否定、单位、时间范围和例外条件;这些内容字符数很少,丢失后的语义影响却很大。

Anthropic 的上下文工程文章 也把上下文管理视为持续选择下一轮信息的过程。这里更具体的执行原则是:一份好的语义状态要能支持继续行动,并允许回到证据,而不只是读起来流畅。

长输入变成可选择性读取的外部资源

先把“必须同时看到”改成“需要时能访问”

长输入实验没有先把全部文档压成一次摘要,再让模型回答。作者把原始文档保存在文件系统中,在初始消息里提供问题、文件信息和工具说明。模型通过 Bash 搜索与读取局部内容,把长输入问答转化成多步行动。

这个区别很重要。如果先读完百万 token 再压缩,第一轮仍然要支付完整读取成本;选择性读取则允许模型从一开始只读少量信息。真正的大材料由外部存储持有,模型活动上下文只持有本轮有关的片段。

论文实现提供 docs-list、doc-stats、doc-read 和 doc-syn 等辅助命令,也使用普通 grep、sed、head、tail。其中 doc-read 默认读取 6,000 字符,硬上限是 8,000 字符;这里是字符预算,不是 tokenizer 意义上的 token 数,两者不能直接等同。

搜索可以扫描整个文件,只有返回的命中片段进入模型上下文。因此“模型没有看到整份文件”不意味着“整个系统没有遍历整份文件”。成本由高昂的模型计算部分转移到文件 I/O、字符串匹配及可能的索引操作,后者也需要计入工程账本。

搜索命中只是定位,不是证据核验结束

附录 E 给出的轨迹体现了一个稳定模式:先找实体或概念,再读取附近语境,最后核对限制条件。

一个 LongBench v2 例子需要利用约百万字符的 Kalamang 语法材料翻译句子。Agent 先搜索句子中的词,定位到语法章节,再读取周围几十行,确认语法规则和例句。这不是仅从命中行复制一个词义。

一个 LOONG 例子要求判断几篇论文之间的引用关系。Agent 先跨文件搜索论文名,再读取命中文件的开头核对标题,把“某文本中出现了目标名称”和“究竟是哪篇论文引用了它”区分开。

AA-LCR 的例子还包含行业排除条件。只找到消费者侵权次数并不够,必须读出统计时间范围、行业分类,以及问题明确排除的广播行业。选择性读取如果忽略周围限定语,完全可能更快地产出错误答案。

可用下列四步概括这一机制:

  1. 根据问题列出必须判断的实体、关系和条件。
  2. 搜索名称、同义词和相关表达,形成候选位置。
  3. 有界读取周边段落,确认单位、时间、否定和例外。
  4. 记录证据位置与中间结论;仍缺证据时继续扩大范围。

这套流程不要求一定使用向量检索。论文的关键是可选择、可迭代地访问原文,而不是某一种检索器。若语义线索难以匹配,可以换用索引、结构化查询或分层阅读;这些是扩展设计,不能算作论文已经验证的每一条路径。

输入长度不再直接等于模型读入长度

论文图七:LongBench v2 中原始文档长度与各段会话长度总和的散点关系

图源:原论文图 7。横轴是按 cl100k 统计的原文 token 数,使用对数刻度;纵轴是各段会话最终长度之和,使用线性刻度。每个点是一道题,颜色区分数据集的长度分组,虚线表示二者相等。由于横轴是对数坐标,虚线在图上弯曲不意味着复杂度本身是指数级。

作者在 Claude Opus 4.5、16K / 12K 设置下发现,多数点的纵坐标没有随文档长度同比例上升。这支持一个受限结论:在这些问题里,需要进入会话的信息通常只占源材料的一部分。

纵坐标既不是总存储量,也不是全部 API 调用的输入 token 求和,而是论文定义的分段会话最终长度之和。更不能从一张散点图推出任意文档任务都具有常数读取复杂度。

例如,要精确比较十万条记录中的全部例外,或证明某条件在整份文档中从未出现,系统可能必须扫描大量甚至全部材料。选择性读取可以把工作切成小块,却不能消除任务本身的信息需求。

SSSM:把文本记忆看成递归状态

一个动作周期对应一次状态转移

SAC 的结果启发作者提出 Semantic State Space Model,即语义状态空间模型,简称 SSSM。这里的状态是可读的自然语言描述:模型读取任务与当前状态,决定动作,接收环境结果,再更新那份描述,让另一轮推理能够继续工作。

为了把信息流写清楚,可以用下面这组解释性公式表达;这不是论文给出的一套新神经层公式:

at∼πθ(⋅∣q,st),ot=E(at),st+1=Uθ(q,st,at,ot).\begin{aligned} a_t &\sim \pi_\theta(\cdot\mid q,s_t),\\ o_t &= \mathcal{E}(a_t),\\ s_{t+1} &= U_\theta(q,s_t,a_t,o_t). \end{aligned}

qq 是固定任务,sts_t 是第 tt 步之前的语义状态,ata_t 是模型选择的动作,oto_t 是环境执行后返回的观测。πθ\pi_\theta 表示动作决策过程,UθU_\theta 表示状态更新过程,θ\theta 表示所用模型参数,E\mathcal{E} 表示工具环境。公式把决策、环境执行、状态更新分开,是因为它们的正确性条件和成本来源不同。

动作完成和状态更新是两个独立步骤。 若只写出一个好动作而没有记录其结果,下一轮不知道这个动作成功还是失败;若只记录结果而没有保留目标和剩余计划,下一轮可能不知道如何使用它。状态更新的责任是把当前观测变成后续可用的事实与计划。

与 Mamba 等神经状态模型的区别

SSSM 这个名字容易让人联想到 Mamba,但二者位于不同层次。常规神经状态空间模型在网络内部维护数值状态,按 token 或序列位置更新;这里的语义状态则跨 Agent 动作或会话传递,以文本为主要载体。

比较项神经状态空间模型论文讨论的 SSSM
状态内容网络内部的数值张量任务进展、事实、计划与证据位置等文本
典型更新粒度token 或序列位置一次动作及其返回之后
可读性不能直接按自然语言解释可以阅读、核对和修订
与底层架构的关系属于模型内部计算结构本文实验先由运行框架组织已有模型实现
可能的瓶颈状态算子、数值精度和内核效率遗漏信息、更新开销、检索与状态一致性

本站的 Mamba 状态空间模型推理解析 讨论的是前者。一个普通 Transformer 也能在外部框架中执行 SAC;它仍然在每次调用内部使用自己的注意力与 KV 缓存。不能因跨会话只传一份文本,就断言底层模型已经变成无 KV 的线性时间架构。

SSSM 在论文中属于概念与未来能力目标,SAC 才是用已有模型实际执行的上下文管理方案。报告没有展示一个独立 SSSM 检查点,也没有证明新架构已在所有任务上胜过全历史模型。

有限工作区不等于有限的全部记忆

更准确的系统状态还应包含环境中的持久对象:代码仓库、文档、日志和结构化记录。可以把系统看成一个二元组 (st,mt)(s_t,m_t),其中 sts_t 是短活动状态,mtm_t 是可读取的外部记忆。

假设任务要求记住一串随机抛硬币结果,未来可能查询其中任意位置。固定长度的有损摘要无法永远精确保留任意长的独立结果。论文也明确给出类似反例;解决方法是把原始历史留在外部记录中,需要时按位置读取。

由此可见,短上下文的主张不是信息可以无代价消失,而是信息未必都要同时参与一次模型推理。原始信息仍需某种可靠存储,而模型还必须知道什么时候要找回它。

可以用“决策相关性”理解压缩目标:若历史 hth_t 被映射为状态 sts_t 后,对下一步最合适动作的判断基本不变,这份状态才足够好。实践中很难事先证明这一点,因为后续问题可能改变,工具也可能返回意料之外的信息。因此外部历史与原始任务的可恢复性,比一个看起来完美的摘要更可靠。

实验告诉了什么,又没有证明什么

三个问题使用的证据并不相同

论文围绕三个问题组织实验:长程任务能否只保留短上下文;长输入能否通过选择性读取处理;每段上下文是否甚至只需执行一次动作。前两组主要采用 EoCC,第三组才使用 SAC,不能把所有结果都归因于逐动作压缩。

长程组包含六类基准:500 题的 SWE-bench Verified、300 题的 SWE-bench Multilingual、89 题的 Terminal-Bench 2.1、824 题的 FRAMES、184 题的 τ²-bench,以及 BFCLv3 中 200 个长上下文多轮任务。它们分别覆盖代码修复、终端操作、多跳检索和带状态变化的工具交互。

长输入组包含 LongBench v2、LOONG、AA-LCR,以及 NIAH、RULER、Counting-Stars、BABILong。前三个提供真实长文档与多文档推理,后四个更多检查信息定位、变量追踪、计数和事实组合。真实文档问题与人工构造的检索任务,不能只看一个平均值就认为难度相同。

主要任务准确率实验使用 Claude Opus 4.5 与 GPT 5.6 Sol;开放模型的 H100 吞吐实验和 DGX Spark 补充实验是另外的证据组。把开放模型测得的硬件吞吐曲线直接视为闭源模型实际部署曲线,会跨越论文没有直接测量的部分。

EoCC:小窗口常能维持质量,但不是单调变好

论文图五:六种长程任务上不同上下文限额的准确率变化与估算成本节省

图源:原论文图 5。六个小图对应六组任务。每个小图上半部分是相对全历史基线的准确率百分点变化,下半部分是附录 B 成本模型计算的节省倍数。星形标记是基线,不是额外的实验模式;橙色和蓝色分别对应两款模型。

以 SWE-bench Verified 为例,Claude 的全历史基线是 70.0%,24K / 18K 时为 74.8%,而 16K / 12K 时为 68.8%。GPT 的基线为 84.4%,48K / 36K 时为 88.8%,16K / 12K 时为 84.6%。这些结果表明,小于原始最大窗口的设置仍能完成大量任务;它们没有显示“压得越短就越好”。

FRAMES 更能暴露压缩对跨文档证据整合的影响。两款模型在论文列出的 EoCC 设置下都低于各自全历史基线:Claude 下降约 1.3–3.7 个百分点,GPT 下降约 1.5–3.3 个百分点。不能只引用代码任务中提升的点,而忽略这一组退化。

少量百分点变化也需要结合样本量判断。Terminal-Bench 只有 89 道题,单个任务就对应约 1.12 个百分点;一个点上的小幅提升不自动构成稳健优势。表中的最佳 EoCC 还是作者在多个阈值中列出的最好结果,部署时需要独立验证选中的预算,而不是把事后最优值当成默认表现。

SAC:证明极短工作上下文可行,而非全面替代 EoCC

论文表 2 的四组结果足以说明主要结论:

模型与任务FHA 准确率SAC 准确率SAC 峰值上下文,中位数 / 最大值
Claude Opus 4.5,SWE-bench Verified70.0%70.2%8K / 16K
Claude Opus 4.5,Terminal-Bench 2.147.2%51.8%9K / 19K
GPT 5.6 Sol,SWE-bench Verified84.4%82.4%7K / 15K
GPT 5.6 Sol,Terminal-Bench 2.187.6%84.3%8K / 37K

这里的“峰值上下文中位数”是先对每个任务取其最大单次调用长度,再对任务集合求中位数,不是平均摘要长度。最后一列的最大值还说明,即使每轮只有一次动作,工具返回和状态更新仍可能带来明显峰值。

SAC 让 Claude 在这两组任务中接近或超过基线,GPT 则分别损失 2.0 和 3.3 个百分点。更准确的表述是:逐动作压缩没有令这些任务的能力整体崩溃,并显著压低峰值工作上下文。它并没有在四组实验中全部达到最佳 EoCC 的准确率。

这组证据也没有提供完整的 SAC 端到端延迟结论。每步都更新状态是否划算,仍取决于模型写状态有多长、额外调用是否串行,以及原本每一步的上下文成本有多高。

长输入实验:先理解信息入口发生了变化

论文图六:长输入基准中选择性读取结合上下文压缩的准确率与估算成本变化

图源:原论文图 6。各面板上方是相对完整输入基线的指标变化,下方是估算成本节省。LOONG 报告平均分,RULER 报告召回率,Counting-Stars 此图报告完全匹配;这些指标不能混成一种统一准确率。

在 LongBench v2 上,16K / 12K 的选择性读取方案使 Claude 从 68.0% 变为 67.6%,GPT 从 70.8% 变为 72.6%。在 LOONG 上,各设置都提高了两款模型的平均分与完全正确比例。AA-LCR 的 16K / 12K 设置下,Claude 从 65.0% 提高到 84.0%,GPT 从 82.0% 提高到 83.0%。

从机制上推测,这些提升可能来自更集中的证据、更主动的检查和更多轮操作;对照的是“完整输入直接进入工作会话”与“可用工具逐段查找”的两种系统工作方式。因此它们支持选择性读取作为整体方案的价值,却不能独立证明模型在同一份输入、同一次前向里获得了更强的长距离理解能力。

NIAH 的两款模型都通过选择性读取达到 100%,而且没有发生一次压缩。Counting-Stars 也没有发生压缩;RULER 的压缩次数中位数为零。也就是说,很多长输入任务缩短工作上下文的主要原因,是从一开始就没有把无关材料读进来,而不是后来把它压掉。

开放模型的反例必须保留

附录 D 是理解适用边界的重要部分。作者在 DGX Spark 上使用量化开放模型补充测试:两个 Qwen 模型使用 NVFP4,Gemma、Step 和 MiniMax 使用 GGUF 的 3–4 bit 量化权重。

SWE-bench Verified 模型全历史基线EoCC 32K / 24KEoCC 16K / 12K
Qwen 3.6 27B68.6%68.2%65.0%
Qwen 3 Coder Next53.0%40.4%3.6%
Gemma 4 31B65.2%65.8%58.0%
Step 3.7 Flash70.0%64.6%56.6%
MiniMax M2.772.6%73.2%67.8%

这些是各自量化部署条件下的论文报告值,不能直接替代其他精度、其他服务框架的结果。最紧的预算下,五个模型的 SWE-bench Verified 都低于自身基线;Qwen 3 Coder Next 的下降尤其大。

作者将其主要归因于冗长轨迹挤占了有限预算,使有效推进与压缩之间剩余空间太少。这提示一个机制:模型能写代码,不一定同样擅长把工作状态压缩成可继续执行的文本。短上下文策略的稳定性依赖模型的状态维护能力,不能只凭原模型最大窗口或常规代码分数预测。

开放模型的 Terminal-Bench 结果也不完全相同:Qwen 3.6 27B 与 MiniMax 在 16K / 12K 下维持了各自基线分数。因此既不能说所有开放模型都不适合压缩,也不能说闭源模型中的稳定性已经普遍成立。

成本节省要拆成三本账

硬件吞吐、实际 API 账单与假设定价

论文同时使用了硬件实测、名义零售费用与 estimated optimized retail cost,即估算优化零售费用。三者回答不同问题。

硬件实测回答的是:在规定硬件、窗口、请求分布和并发条件下,能持续产生多少输出 token。名义零售费用把实验记录的新输入、缓存输入和输出数量,乘以当时 API 单价。估算优化零售费用则进一步假设:较短窗口带来的底层效率收益能反映到模型定价上。

附录 B 先从三款开放模型的 16K 与 256K 窗口输出成本比中取近似平均,得到 r=0.20r=0.20。随后以闭源模型的参考窗口和零售输出单价为锚点,将较短窗口的单价线性插值到这个比例。其核心缩放因子可写成:

f(W)=r+(1−r)max⁡(W,16K)−16KWref−16K.f(W)=r+(1-r)\frac{\max(W,16K)-16K}{W_{\mathrm{ref}}-16K}.

WW 是实验的总上下文限额,WrefW_{\mathrm{ref}} 是论文对该模型采用的参考窗口。在适用区间内,W=16KW=16K 时 f(W)=0.20f(W)=0.20,W=WrefW=W_{\mathrm{ref}} 时 f(W)=1f(W)=1;小于 16K 时用 16K 钳位,不继续降低。论文对 Claude 与 GPT 使用了不同参考窗口,不能把此式直接当作某个服务商的真实价格规则。

再按论文设定的输出与新输入、以及新输入与缓存输入的比例推导另外两类估算价格,最终用三类 token 数计算总估算费用:

Ctaskest=IcIest(W)+HcHest(W)+OcOest(W).C_{\mathrm{task}}^{\mathrm{est}} =I c_I^{\mathrm{est}}(W) +H c_H^{\mathrm{est}}(W) +O c_O^{\mathrm{est}}(W).

II、HH、OO 分别是以百万为单位的新输入、缓存输入、输出 token 量,cIestc_I^{\mathrm{est}}、cHestc_H^{\mathrm{est}}、cOestc_O^{\mathrm{est}} 是对应的估算单价。这个估算把硬件收益跨模型迁移到了零售价格层,是一种情景模型;论文没有直接测量两款闭源模型在所有窗口下的底层 GPU 成本。

一个不能省略的反向例子

在 SWE-bench Verified 的 GPT 实验中,附录 C 列出的全历史名义费用为 167.68 美元,16K / 12K 设置的名义费用为 203.12 美元,增加约 21%。同一设置的估算优化费用则是 40.62 美元,约为基线的四分之一。

两种数字都来自同一张表,却对应不同假设。较频繁压缩会生成额外输出、重建新输入,并减少某些长前缀缓存的复用;如果 API 单价不因工作窗口缩短而降低,实际账单就未必下降。

因此图 5、图 6 中的成本倍数可以说明潜在的系统效率与定价空间,但不能直接写成已经获得的 API 账单折扣。尤其在对外部服务发起很多状态更新请求时,应按实际 usage 重新计算。

短活动上下文、少 token、低延迟不是同一个指标

短活动上下文限制的是单次调用峰值;累计 token 量还取决于调用次数、重读次数和状态输出长度;墙钟延迟还受工具和队列影响。这三个目标可能一致,也可能冲突。

例如,FHA 中同一份 20K 前缀也许已在 GPU 上缓存,SAC 则每轮写出不同状态、重新预填。虽然 SAC 活动 KV 较小,却增加了一份串行输出。如果任务只需十几步且每步很短,额外更新可能吃掉收益;若每一步都背着很长历史、还要生成很多 token,缩短上下文的收益就更有机会显现。

对多租户服务还有资源生命周期问题:逻辑上开始新会话,并不保证旧前缀 KV 立刻归还全部物理页。引擎可能继续保留可复用缓存,直到容量压力触发驱逐。要验证集群内存收益,需要同时观察活跃请求占用和可驱逐前缀缓存,而不能只看提示长度。相关引擎机制可参考 vLLM BlockPool 的回收与引用计数。

从论文方法到推理服务的工程取舍

下面的实现原则是从论文信息流推导出的工程设计,不是报告已经发布的完整生产系统。

把不该遗忘的内容放在摘要之外

原始任务、硬性限制和最终完成条件由运行框架持有,每次重新注入;可变语义状态保存进展、证据、失败路线与下一步。原始文档和完整事件日志则放在可检索的持久存储中。

这样可以形成四个职责明确的部分:固定要求决定什么算正确,短状态决定现在做什么,证据存储支持细节恢复,真实环境记录已发生的变化。任何一部分缺失,都可能产生“摘要看起来完整,任务却无法继续”的情况。

在 LangChain 的 Context Management for Deep Agents 中,摘要与完整历史持久化也是配合使用的:摘要承担短工作记忆,文件系统保留可恢复的原记录。这能避免把短上下文优化变成不可逆删除信息。

动作与状态更新之间需要可恢复的提交顺序

SAC 的一个薄弱点位于工具动作已经执行、语义状态尚未更新的间隙。进程若此时崩溃,旧状态可能仍写着“准备执行”,但环境已经改变;恢复时盲目重做就可能重复提交、重复修改或重复发送。

工程实现可为每个动作分配记录编号,先持久化动作与结果,再生成下一份状态,校验通过后原子切换状态指针。恢复时先查动作记录和环境结果,而不是仅根据自然语言猜测上一步有没有发生。

下面仅表示控制顺序,不是可直接运行的完整框架:

读取固定任务、已提交状态与环境版本
构造受预算约束的提示
生成一个动作,分配动作编号
执行动作,持久化动作结果与证据位置
请求状态更新
校验:任务约束、证据指针、未完成事项、长度
原子提交新状态及对应动作编号
继续下一步,或进入完成验证

若状态更新失败,应重试更新或从记录重建状态;对于有副作用的动作,应先核实是否已执行。这个问题不会被更好的摘要提示自动解决,因为它来自模型会话与外部系统之间的事务边界。

读取上限必须与任务语义配合

工具结果过大时,简单保留前几千字符可能正好删掉关键报错或末尾结论。更好的方式是把完整结果保存下来,返回命中位置、总量、错误摘要和可继续读取的指针。

例如,运行测试可返回退出码、失败用例名称、日志路径和相关行号;统计任务则应返回表头、单位、处理记录数及未处理范围。输出预算约束的应是进入模型的片段,而不是原始证据的完整性。

若一个文档任务必须逐段处理全部输入,状态还应保存已扫描区间、重叠边界与未覆盖部分。否则模型可能把“没在当前片段找到”误当成“整份材料都没有”。

压缩频率应由收益与风险共同决定

论文提供 FHA、阈值压缩和逐动作压缩三个明确比较点,真实系统还可以在它们之间选择。这个扩展应以测量为依据,而不是直接把 SAC 设为所有模型的默认值。

一个用于分析端到端时间的分解是:

Ttask=∑t=1n(Tact,t+Ttool,t+Tstate,t+Tqueue,t).T_{\mathrm{task}}=\sum_{t=1}^{n} \left(T_{\mathrm{act},t}+T_{\mathrm{tool},t} +T_{\mathrm{state},t}+T_{\mathrm{queue},t}\right).

nn 是动作数,四项依次表示动作决策推理、工具执行、状态更新推理和等待时间。它是串行路径的简化账本,实际系统还可能存在重叠。使用 FHA 时显式状态更新项通常不存在;使用 SAC 时,这一项需要每步计入,而更短上下文可能降低其他推理项。

阈值压缩让一段局部连续操作保留在同一上下文中,减少交接;逐动作压缩最严格地控制历史增长,却可能付出更多状态写回。若状态文本不断变长,SAC 也不会自动保持固定工作量,仍需给状态规定预算并检查信息质量。

LangChain 的 Autonomous context compression 讨论了在适合的任务节点主动触发压缩的思路。这与论文逐动作实验形成一个有用的设计对照:频率越高,活动上下文越容易控制;压缩时机越贴近自然阶段边界,越可能减少对正在进行的局部推理的打断。哪一种更好,需要针对具体模型与负载实测。

用质量约束住优化,而不是只观察窗口变小

评估至少同时记录:任务成功率、单任务最大活动上下文、新输入与缓存输入量、输出量、状态更新时间、工具调用次数、重复读取次数和总墙钟时间。还应检查压缩后是否重走失败路线、遗漏否定条件或提前判定完成。

更有针对性的验证方法,是固定一个已完成动作后的环境快照,分别让完整历史和短状态继续执行,比较两者是否还能完成同一组剩余要求。若短状态版本总是重新探索目录、重复验证已确认事实,窗口虽然变小,恢复效率却有问题。

对人工持续介入的交互流程还要额外谨慎。论文附录 A 明确区分了自主执行与接收后续人工反馈:后者可能改变目标,使先前看似无关的信息重新变得重要。测试中的自主任务保持质量,并不足以保证任意后续追问都能只靠当前摘要回答。

《You don’t need long context》最有工程价值的命题,是把“整个任务拥有多少信息”与“模型此刻必须同时处理多少信息”分开。短活动状态、持久证据和受控读取共同组成方案;状态维护能力不足、检索漏证据或更新成本过高,都会让这个方案失效。长窗口因此仍是一种有价值的能力,但不必成为每一步执行都要用满的默认工作方式。

参考资料

  1. Peter Belcak 等:You don’t need long context,arXiv:2611.05306v1,2026 年 11 月
  2. 原论文 HTML 全文:方法、官方图表与附录 A–G
  3. mini-swe-agent 官方文档:Bash 工具、线性历史与简化 Agent 循环
  4. Anthropic:Effective context engineering for AI agents,2025 年 9 月
  5. LangChain:Context Management for Deep Agents,2026 年 1 月
  6. LangChain:Autonomous context compression,2026 年 3 月

文章分享

如果这篇文章对你有帮助,欢迎分享给更多人!

You don’t need long context 完全拆解:单动作压缩、选择性读取与语义状态空间模型
https://pinghaoyang.com.cn/articles/insights/posts/you-dont-need-long-context/
作者
平昊阳
发布于
2026-11-06
许可协议
CC BY-NC-SA 4.0

评论区

访客信息
--°天气加载中

正在获取所在地区…

💨 风力--
💧 湿度--

正在读取天气

Profile Image of the Author
平昊阳
乘长风,破巨浪, 展鸿图于未央!
公告
欢迎来到我的个人博客!欢迎关注交流吖!
更多相关公告,见
「社交-留言」。
音乐
封面

音乐

暂未播放

0:000:00
暂无歌词
站点统计
文章
448
分类
29
标签
451
总字数
6,178,652
运行时长
0 天
最后活动
0 天前

文章目录