章节导航 第 15 章 / 共 21 章
上下文管理与 Compaction
为什么需要 Compaction、三层架构、内置策略、训练一致性、自定义策略开发
问题
Agent 的多轮对话会不断增长。当对话超过 LLM 的上下文窗口(如 128K tokens),推理会失败。
简单的截断会丢失关键信息。Nexus 的 Compaction 系统提供了更智能的方案。
这里需要先分清一件事:压缩的代价至少有三种。
- 信息损失——丢掉的内容让 Agent 答错;
- 重获取成本——丢掉的内容让 Agent 再调一次工具去取回来,省下的 token 被重新花掉;
- 前缀缓存失效——压缩改写的是提示词前缀,而 agent 流量里绝大部分 prompt token 是重读;前缀一改,原本命中缓存的重读部分要按全价重新 prefill。
第二种代价容易被忽略,却在最坏情况下能抵消甚至超过压缩本身省下的量。对工具密集的 Agent(Nexus 的 ToolExecutor 每轮可能产生多个大体积 tool message)尤其如此。本章后面「第四个维度:压缩的下游代价」一节会给出它的量化形式。第三种代价不是纸面推论:Claude Code 在 v2.1.275(2026-09-17)修的正是这一条——官方原文是「a restored memory file’s age note changing between requests after a compaction or resume, which caused prompt cache misses」。这是生产环境里真实发生过的 cache miss,不是论文模拟。
还要先限定一句,它会影响全章的论证走向:避免上下文溢出只是压缩的一部分理由。AutoCompact(arXiv:2610.02163,2026-10-01)在 256K 窗口下取得 +9.2 个绝对百分点的增益,而论文明确写这个窗口 never overflows——压不压都不是为了装得下。它的解释是:过期的探索历史本身会伤害后续决策,哪怕它装得下。换句话说,压缩同时是思维工具,不只是内存管理。本章后文凡是出现「为避免溢出而压缩」的表述,都应在这个更宽的口径下读。
三层架构
CompactionManager(编排层)
│ "什么时候做 compaction"
▼
CompactionTrigger(触发层)
│ "当前对话是否需要 compaction"
▼
CompactionStrategy(策略层)
│ "怎么压缩对话"
▼
压缩后的 messages
CompactionTrigger
监控 token 用量,决定是否触发:
class CompactionTrigger:
def should_compact(self, messages, tools, token_count) -> bool:
# 当前 token 数 > 阈值 → 触发
return token_count > self.threshold
这一行是全章最容易被读轻的地方:它把「要不要压缩」压成了一个标量与一个常量的比较。生产级实现里,触发至少有四个判据,而且每个判据都有自己独立的失效模式:
| 判据 | 平台侧实证 | 失效模式 |
|---|---|---|
| token 数 > 阈值 | 通用 | 阈值必须是 per-model 参数而非全局常量(v2.1.288,2026-10-02:/autocompact 改为按模型保存自动压缩窗口);token 估算误差会被直接放大到触发时机(v2.1.273,2026-09-15:context meter 与 auto-compact 把 advisor-tool turns 按约 2 倍计,导致在真实窗口约一半处就触发) |
| 还能不能被客户端安全分类器审查 | v2.1.288(2026-10-02) | 分类器的容量上限是独立于上下文窗口的第二条触发线:auto mode 下对话长到分类器无法审查时改为压缩,而不是每个工具调用都去问一遍或直接失败 |
| 最近一次回复上报的 token usage | v2.1.288(2026-10-02) | 上报为 0 会静默关掉触发,长对话直接报 Prompt is too long 而不是自动压缩 |
| 是否存在可完整摘要的 exchange | v2.1.269(2026-09-11) | 没有可完整摘要的前序 exchange 时,会话永久卡在 Prompt is too long |
还有一条边界情况:新环境的首次请求、或换模型之后的那一次请求,用的是内置窗口与输出上限而不是服务端下发的(v2.1.288,2026-10-02),该请求最多等待 1.5 秒——窗口未知时的引导问题也要算进触发器的健壮性。
把这些列出来的意义不在照抄,而在指出一个方向:触发失败不是「那就先不压」,而是直接变成硬错误。上表四条里有三条的失效结局都是 Prompt is too long。触发器的健壮性与压缩策略本身同等重要,而 §CompactionStrategy 那 968 行里没有一行是为它写的。
CompactionStrategy
实际的压缩逻辑。compaction_strategy.py 有 968 行——这是整个 compaction 目录里最大的文件。
内置策略:
| 策略 | 注册名 | 方法 | 适合场景 |
|---|---|---|---|
| Keep Recent | keep_recent | 保留 system + 最近 N 条消息 | 简单快速,信息损失大 |
| Summary | summary | 用 LLM 总结历史,替换为摘要 | 信息保留好,但增加 LLM 调用 |
| Rolling Summary | rolling_summary | 增量式 LLM 总结 | 在 summary 基础上避免重复总结 |
| RL-learned | (实验性) | 通过 RL 训练 compaction 策略模型 | 高保真压缩,但训练成本高 |
这张表有一个空格:keep_recent / summary / rolling_summary 三条手写策略都不做因果判断,而 RL-learned 那一条要求训练。对 Nexus 这种「不重新训练策略模型」的框架,中间那一格——不训练也能超过手写策略——此前是空的。FOCUS(arXiv:2609.37590,2026-09-29,Microsoft)填的就是这一格:它不问「压缩到多少比例」,而是问「下一步决策因果依赖于哪些过去的交互单元」,保留那些、丢掉其余;完全在测试时进行,无需离线数据采集或微调,架构无关,可以作为模块化压缩层挂在闭源 API 前面。官方摘要报的口径是峰值上下文削减最多 48%、依赖削减 73%,相对不压缩的完整执行任务成功率提升最多 8.9 个百分点。注意最后这个分母:对照是「不做压缩」,不是「别的压缩器」。训练无关是它在工程上最重要的属性——本节其余方案要么靠手写规则、要么靠训练,FOCUS 是唯一可以直接接进闭源链路的一条。
RL-learned 策略是新兴的研究方向,不再由人工设计压缩规则和 prompt,而是通过 RL 训练一个策略模型来决定何时压缩、保留什么:
- FoldAct:分离损失计算(summary token 和 action token 分别计算 PPO surrogate loss)+ 全上下文一致性损失,解决梯度稀释和自条件崩溃问题。量化数据:无一致性损失版本 49.6× 加速 + 80.7% 内存削减;完整版 5.19× 加速;长轨迹(10+ 轮)压缩至约 25% 初始长度
- SUPO(ICLR 2026 提交):推导出支持端到端优化 tool-use 行为和 summarization 策略的策略梯度公式,通过 advantage broadcasting 实现长程信用分配
- ActiveContext:解耦式架构——轻量 ContextCurator(7B)通过 RL 学习主动信息熵减,为冻结的 TaskExecutor 策展工作记忆
- CompactionRL(Yujiang Li、Zhenyu Hou、Yi Jing、Jie Tang、Yuxiao Dong;清华大学,前三位作者在 Z.AI 实习期间完成,2026-07-06,arXiv:2607.05378):把 context compaction 纳入 RL 训练,联合优化任务执行与摘要生成,用 token-level loss normalization(解决 summary token 梯度稀释)+ cross-trajectory GAE(跨压缩边界的信用分配)。GLM-4.5-Air(106B-A30B)达 SWE-bench Verified 66.8%(+7.0)、Terminal-Bench 2.0 24.5%(+3.1);GLM-4.7-Flash(30B-A3B)达 56.0%(+5.5)、20.2%(+6.8)。已部署到 GLM-5.2(750B-A40B)的 RL pipeline。
- ContextPilot(Zhuoshi Pan、Qizhi Pei 等 7 位作者;脚注区一级证据
Affiliation: 1 Tsinghua University 2 Tencent Youtu Lab 3 Shanghai AI Lab,2026-08-28,arXiv:2608.28476;代码github.com/Tencent/ContextPilot,权重huggingface.co/collections/panzs19/contextpilot):把上下文管理做成模型习得的行为,而不是框架里的固定策略。三件事——① 扩展工具集(论文工具语义含readChunk/searchChunk/writeMemory,覆盖 global planning、structured long-term memory、soft context offloading);② Context-Aware Partial Rollout:用 context 与 entropy 的变化定位高影响的上下文编辑决策,把探索预算集中到这些分支上采样;③ Snapshot-level Credit Assignment:把所有下游分支轨迹的结果并入动作级 advantage。基座为 Qwen3-8B / Qwen3-14B / Gemma4-E4B-it(长上下文 QA)与 WebSailor-7B / WebExplorer-8B(深度搜索)。主表与 5.2 节数字:仅用 32K 上下文窗口就超过 128K 窗口的基座;ContextPilot-8B-RL 在四个长上下文 QA 基准上平均超过 StateLM-8B-RL 3.55 分,比自身 SFT 版本再涨 3.62 分,在最难的 BrowseComp+ 上 RL 增益达 5.34 分(该基准平均输入约 552K token,NovelQA 约 119K——论文据此指出 RL 收益随任务难度增大);深度搜索上在两个基座上平均超过 SUPO 1.51 分。token 效率:取 ≥15 轮的轨迹看每轮输入,WebExplorer-8B 在 BrowseComp 上近线性增长到约 30K,ContextPilot-8B 稳定在约 8K–10K
- AutoCompact(arXiv:2610.02163,2026-10-01):把
compact()做成 agent 动作空间里的一个动作,训练它决定何时压、保留什么工作态、压完之后怎么继续。训练数据的构造方式值得单独记一笔——先跑基座 agent,用一个 judge 在线审阅它的压缩决策、摘要与压缩后的动作,把有问题的替换成修正版再放进环境里执行,于是每条轨迹都从被修正过的决策继续;这些轨迹先做 SFT,再用二元任务成功奖励做 RL,奖励里没有任何 compaction-specific 项。基座 Qwen3-Coder-30B-A3B-Instruct:SWE-bench Verified 绝对 +9.2 个百分点、SWE-PolyBench Verified 绝对 +5.0。行为侧的读数更能说明问题:SFT 后 agent 已在 44.3% 的任务上主动调用compact(),RL 后升到 58.5%,同时摘要遗漏关键状态的比率从 3.1% 降到 0.2%、遗漏下一步动作的比率从 8.2% 降到 2.2%。两个方向同时改善——用得更多,错得更少。
需要把一处可能的误读挡在前面。AutoCompact 的 Introduction 把 CompactionRL 明确归为 length-triggered 一类并点名批评,原文是:这类方法只在剩余上下文预算跌破固定阈值时压缩,“ties compaction to context length rather than task progress: stale exploration accumulates until the threshold is reached, and compaction may then occur in the middle of an unresolved stage whose evidence is still needed”。本章上一条刚把 CompactionRL 作为工业部署案例写入,两处看似打架,其实是触发时机归谁决定这一件事的两种答案:归框架(阈值,与任务进度无关)还是归策略(学出来的,随任务进度走)。CompactionRL 的价值在于它把压缩接进了 RL 的目标函数并已落地到 GLM-5.2;AutoCompact 的价值在于它把「何时压」本身也交给了策略。两者不是谁推翻谁,而是同一个坐标轴上的两个位置。顺着这条轴,本章后文「手写规则是框架决定何时压,ACM 是 Agent 决定何时压」那条二方对照可以升级成三方:框架阈值 / 可学习策略 / 固定 rubric。
RL-learned 策略已开始进入工业部署(CompactionRL 已集成到 GLM-5.2 的 RL pipeline),但尚未成为通用可配置的 compaction strategy。但其对训练一致性的影响深远——FoldAct 的分离损失计算直接解决了 policy-dependent compression 的 RL 训练不稳定问题(详见下文训练一致性扩充)。
RL-learned compaction 的应用场景也正从”对话历史压缩”扩展到更广的维度:
- 检索观察压缩:RECON(arXiv:2510.10448)在 RL-trained search agent 的每次检索后插入 learned summarizer,压缩器在 RL 训练期间保持冻结以维持策略稳定。集成进 Search-R1 流水线后,总上下文长度减少 35%,训练速度提升 5.4%,推理延迟降低 30.9%,平均 exact-match 在 3B agent 上 +14.5%、7B agent 上 +3.0%
- 记忆构建:LazyMem(arXiv:2607.22690)提出 query-time memory construction——写时存原始消息,查询时才用 4B 小模型做 KEEP/DROP + 压缩决策。在 LongMemEval 上以 213 个 answer-context memory token 达到 0.85 的 LLM-judge 准确率,相比 retrieval-only 少 68.7×、相比最强非 oracle 基线少 21.0×
- 记忆管理 RL 化的两条同期线索(📌 仅登记,未抓全文核数字):Hindsight Memory-PRM(arXiv:2608.29605,2026-08-30,17 位作者)用可审计的 hindsight credit 监督记忆管理;Selective Forgetting(arXiv:2608.28978,2026-08-29,3 位作者)用图基遗忘做长期 Agent 记忆修剪。两者与 RECON / LazyMem 同属”把记忆的留弃交给学习”这一方向
summary 策略的 prompt:
Please summarize the above history concisely.
Target length: approximately {ratio}% of original length.
Preserve key facts, decisions, tool call results, and context
needed for continuing the conversation.
Focus on tool call and tool response.
训练一致性
Compaction 对训练数据有重大影响——压缩后的对话和原始对话不同。如果训练时的 compaction 行为和推理时不一致,模型会学到错误的分布。
基础保障
- HyTuner 集成:CompactionManager 在 compaction 发生时产生新的 segment。HyTuner Processor 记录 compaction 前后的 token 序列,确保训练时能精确复现
- 确定性:相同输入 + 相同 compaction 配置 → 相同输出。Cache 系统也包括 compaction 步骤的缓存
Policy-Dependent Compression 的深层挑战
基础保障解决了”可复现性”问题,但未触及更根本的 RL 训练不稳定性问题——compaction 本身是 policy-dependent 的(摘要内容由当前策略决定),这引入了三个系统性挑战:
1. 分布偏移(自条件崩溃)
Compaction 后的摘要成为下一步推理的输入,而摘要内容取决于当前策略。策略更新 → 摘要变化 → 输入分布偏移 → 策略进一步更新,形成自条件循环。FoldAct 将其形式化为”自条件崩溃”——策略的微小变化通过 compaction 放大为输入分布的巨大偏移。
2. 梯度稀释
在 PPO 训练中,summary token 在整条轨迹中占比很小(通常 < 5%),但其质量直接影响后续所有 action token 的输出。标准 PPO 的 surrogate loss 对所有 token 一视同仁,导致 summary token 的梯度信号被 action token 稀释。FoldAct 的解法是分离损失——summary token 和 action token 分别计算 surrogate loss。
3. 信用分配
多轮 compaction 后,最终结果的奖励如何分配给早期 compaction 决策?这是长程信用分配问题。SUPO 通过端到端策略梯度 + advantage broadcasting 解决:compaction 决策的 advantage 不仅来自当前轮的即时反馈,还传播后续轮次的累积奖励。
解耦方案:ContextCurator + TaskExecutor
ActiveContext 提出了一种架构解耦:轻量 ContextCurator(7B)通过 RL 学习主动信息熵减,为冻结的 TaskExecutor 策展工作记忆。这种解耦的优势是:
- TaskExecutor 的策略保持稳定(不受 compaction 干扰)
- ContextCurator 可以独立升级(不影响主策略)
- 7B ContextCurator 即可匹配 GPT-4o 的上下文管理性能
与 Nexus 的关系:Nexus 的 CompactionManager + Agent 分离与此思路类似,但 CompactionManager 使用手写规则而非 RL 训练。理论上,CompactionManager 可以被替换为一个 RL-learned 的 ContextCurator,通过 register_compaction_strategy 注册为自定义策略。
Agent 自主管理压缩时机(ACM)
与”RL-learned ContextCurator”(训练策略模型)不同的另一条路线是 ACM(Agent-managed Context)——把压缩时机与内容纳入 agent 的 action space,通过 manage_context + query_memory 两个工具让 Agent 自己决定”何时压缩、保留什么”。压缩摘要携带唯一标识关联外部存储的原始消息,可随时回查,声称”无损上下文管理”——原始消息不被永久丢弃。
与 Nexus 的关系:这是比 RL-learned 更轻的落地路径——无需训练策略模型,只需给 Agent 增加两个管理工具,通过 register_compaction_strategy 即可接入。它与 CompactionManager 手写规则形成对照:手写规则是”框架决定何时压”,ACM 是”Agent 决定何时压”。
需要补一句:轻不等于终态。ContextPilot(见上文 RL-learned 策略)表明工具接口可以先定下来,之后要不要用 RL 训练模型来使用这些工具,是独立的第二步——先有 manage_context 式的动作空间,才谈得上训练;工具集设计得越完整(规划 / 长期记忆 / 软卸载),后续训练的上限越高。在 Nexus 里先把工具接口开出来,与日后的 RL 路线并不冲突,反倒是其前置条件。
📌 同期线索登记(2026-10-06,未回源,不作断言):Context Language Models(CLM,2026-10-01)让模型把上下文当文件来编辑,而不只是压缩,并配套 Suffix Cache Reuse 处理「编辑破坏前缀缓存」的问题。它是「agent 自主管理上下文」这一方向更强的形态,与本节 ACM 同源但走得更远。此处只登记方向与来源,不写具体数字,ACM 本身的待验证状态不因这条线索而改变。
自定义策略
from nexus.extensions.compaction.compaction_strategy import (
CompactionStrategy, register_compaction_strategy,
)
@register_compaction_strategy('my_custom')
class MyCustomCompaction(CompactionStrategy):
def compact(self, messages, tools, target_tokens, token_count_fn):
# 你的压缩逻辑
# 返回压缩后的 messages 列表
...
然后在配置中使用:
agent_config:
compaction_strategy: "my_custom"
压缩提示优化
summary 策略的 prompt 是固定的,但压缩质量高度依赖 prompt 的表达。ACON(Agent Context Optimization)提供了一种不修改框架代码、仅优化压缩提示的方法:
ACON 迭代优化流程
- 收集失败案例:找到全上下文成功但压缩上下文失败的案例
- 分析丢失内容:LLM 分析压缩过程中丢失了什么关键信息
- 更新压缩提示:修改 summary prompt,要求保留该类信息
- 迭代直到收敛:重复 1-3,直到压缩准确率达标
- 可选蒸馏:将优化后的提示策略蒸馏到小模型
ACON 实验结果:26-54% 峰值 token 减少,95%+ 任务准确率保留。值得注意的是,ACON 蒸馏到小模型后仍保留 >95% 准确率,且显著增强小模型作为长程 agent 的能力——AppWorld +32%、OfficeBench +20%、Multi-objective QA +46%。这意味着 ACON 蒸馏后的小模型可作为 Nexus ContextCurator 的轻量实现路径:用 7B 级蒸馏模型替代 GPT-4o 级摘要模型,在不牺牲压缩质量的前提下大幅降低成本。
Factory Anchored Iterative Summarization
Factory 的 anchored iterative summarization 在评估中最优(4.04 分 vs Anthropic compact API 3.74 vs OpenAI 3.43)。核心差异:增量合并到持久锚定状态而非每次全量重建摘要。
与 Nexus 的 rolling_summary 对比:
rolling_summary是增量式的,但每次重新生成完整摘要(非锚定)- Anchored 方法维护一个持久状态,每次只追加增量变更,减少信息损失
实践建议:直接在 summary 策略的 prompt 基础上应用 ACON 优化,是最小成本提升压缩质量的方式。无需修改 Nexus 框架代码。
压缩比量化对比
| 策略 | 预期压缩比 | 信息保真度 | 适用场景 |
|---|---|---|---|
| keep_recent | ~10× | 低(丢弃历史) | 短任务、对历史不敏感 |
| summary | ~3-5× | 中等 | 通用场景 |
| rolling_summary | ~3-5× | 中等偏上 | 长对话、需要历史连贯性 |
| RL-learned | ~16× | 高(98%+ QA 保真) | 实验性,Near-Lossless 论文报告 |
注:RL-learned 的 16× 压缩比来自 Near-Lossless Context Compression via RL 论文(ACL ARR 2026 提交),7B/32B 模型在 120k-token 上下文上匹配全上下文性能。手写策略的数据基于经验估计。
第四个维度:压缩的下游代价
上表比较的是”压缩掉多少”与”保真度如何”,隐含假设是省下的 token 就是净收益。TRACER(arXiv:2608.29363,2026-08-29)指出这个假设不成立,并把缺口命名为 compression–consequence gap:分配保留预算时不考虑”删掉某个工具输出”的下游后果,而激进压缩可能触发该工具被重新调用,重调用的开销反过来抵消、甚至超过省下的 token。论文给的量级感很直接——单次 SQL 结果就可以超过一万 token,而一个典型任务要调五到十次工具。
它的做法是把压缩重定义为逐工具的序列决策:轻量 REINFORCE 策略输出 query-conditioned 的保留比例(Beta 分布参数化),奖励一并计入任务成功、总 token 消耗与压缩后的工具重调用次数;再用一个学到的 outcome model 做单工具反事实(“如果全部保留这个工具输出会怎样”)来稠密化信用分配。
| 策略 | 是否计入下游代价 |
|---|---|
| keep_recent | ❌ 只按新旧丢弃 |
| summary / rolling_summary | ❌ 只看压缩比与信息保真 |
| RL-learned(FoldAct · SUPO · CompactionRL) | 部分——奖励计入任务成功,但不含重调用惩罚 |
| TRACER | ✅ 奖励显式含”压缩后的工具重调用次数” |
但「下游代价」这个词在本章里只开了一格,而它其实至少有三格。上表问的是「谁在计重调用」,下面这张表问的是「代价有几种类型」:
| 代价类型 | 谁在计 | 实证 |
|---|---|---|
| 工具重调用 | TRACER ✅;其余 ❌ | TRACER 论文(见上) |
| 前缀缓存失效 | 全部 ❌ | v2.1.275(2026-09-17)生产环境 cache miss;agent 流量里重读占比高,压缩改写前缀后这部分要全价重算 |
| 副作用被重复触发 | 全部 ❌ | v2.1.271(2026-09-14):压缩后仍在运行的后台命令(watch 任务、dev server)被启动了第二份 |
第三行尤其值得单独说。TRACER 的代价模型是「被删掉的工具输出会不会被重新取回」,它长在工具调用的账本上;而 v2.1.271 的代价是「压完之后某个还活着的进程被复制了一份」——这件事根本不在工具调用的账本上,用再好的工具级信用分配也看不见。同理第一行与第二行也不共用账本:一个是「重跑一次工具」的显式开销,一个是「缓存不命中」的隐式开销。把三格摆在一起的含义是:「是否计入下游代价」不是一个是非题,而是一张清单,任何只填了一格的压缩器都还可以被继续追问。
数字(均回 arxiv.org/html/2608.29363v1 正文与表 3 核对):在真实生产查询、三种压缩器后端上,相对”全保留”省下 29–46% token 且任务成功率持平或更高——摘要式压缩收益最高(46%),截断 31%、AGORA 式后端 34%、Self-Info 29%;相对”按工具类型固定比例”的静态策略再省 15–18%(原文是 token 节省的百分比,不是百分点);跨 agent backbone 与压缩器架构迁移仍为正收益;5 个 held-out LOCA-bench 环境上省 18–25%。学到的 per-tool 信用分与实测的单工具后果相关:Spearman ρ = 0.66、top-3 命中 82%、方向符号正确率 84%。另有一个容易与前者串台的数——outcome model 自身在留出 episode 上的 Spearman ρ = 0.72(Brier 0.07),那是模型精度,不是反事实验证的相关性。
限制必须随数字一起读:验证集只有 120 条生产查询,按难度分三档——25 条简单查询、55 条”schema 检索 + SQL”多步查询、40 条多表权限查询;训练/留出划分为 80/40,留出集按 7/19/14 分层。查询来自单一企业的单一 Agent 栈。补充材料明确不含生产 agent、数仓与知识库内容、原始 prompt 与工具输出、事件日志与轨迹、训练 checkpoint,也不含 LOCA-bench 与商业模型端点,外部无法复现。部署门槛同样实在:训练前需先录一份”全保留”的重放基线,即每查询 5 次参考运行——对 Nexus 用户来说,这条是可操作性上的硬门槛,不是论文里的脚注。
对 Nexus 的含义:ToolExecutor 天然知道每次工具调用的来源与体量,Ch17 的 tool_output_truncation: 10000 已经是逐工具的粗粒度版本(按字符截断),TRACER 给的是”按工具输出的后验价值决定保留比例”的升级版。最小落地可以很轻——在 post_iteration_hook 或自定义 CompactionStrategy 里给 tool message 打上”该工具后续是否被重调用过”的标签,先把这个特征攒下来,再谈策略。
平台级 Compaction 与自建 Compaction 的关系
OpenAI 于 2026.02 在 Responses API 中发布 server-side compaction,配合 GPT-5.4 的 1M token 上下文窗口。这标志着压缩从”框架级策略”升级为”平台级能力”。对 Nexus 的影响需分短期和长期分析:
短期影响:使用 OpenAI 模型的 Nexus Agent 可受益于平台 compaction,减少触发自建 CompactionManager 的频率。1M 上下文窗口改变了压缩触发阈值——许多当前需要主动压缩的场景可能被更大窗口直接容纳。
机制层事实:平台侧的 compaction 已经是一等可观测事件,而不只是一个内部动作。以 Claude Code 的 OTel 事件为例,claude_code.compaction 带 trigger(auto / manual)、success、duration_ms、pre_tokens、post_tokens、error,以及 precompute_reuse——自动 compaction 会在上下文窗口填满之前于后台预先生成一份摘要,手动触发时记录是否复用:命中为 hit;未命中给出三种理由 miss_custom_instructions(自定义指令变了)、miss_hook(hook 干预)、miss_not_ready(还没算完)。该属性要求 v2.1.153+。
这条记录揭示平台还做了第三件事:预计算 + 可失效复用。于是 §Factory Anchored Iterative Summarization 之后那条”两条路”的对比可以扩成三条:
| 方案 | 何时算 | 失效模式 |
|---|---|---|
rolling_summary | 每次触发时全量重算 | 重复消耗 + 信息损失累积 |
| Factory Anchored | 增量合并到持久锚定状态 | 锚定状态污染 |
| 平台 precompute | 窗口填满前于后台先算好,用不上就作废 | 三种 miss(自定义指令 / hook 干预 / 尚未就绪) |
| 迭代式再压缩 | 压完仍超长就再压一次,每次保留更少的最近对话 | 抖动:压了没用、再压还没用,直到把上下文压到不可用 |
第四条路来自 v2.1.284(2026-09-28):官方原文是「Fixed “Prompt is too long” errors that persisted after compacting: when the compacted request is still too long, Claude Code now compacts once more, keeping less of the recent conversation」。它和前三条不在同一个维度上——前三条是「一次压缩怎么算」,第四条是「一次不够怎么办」,因此它可以和前三条任意一条叠加。
它的失效模式在生产里已经有名字了。v2.1.286(2026-09-30)的官方条目里出现了 autocompact-thrashing 这个错误名,并说明模型 fallback 会把上下文窗口从 1M 掉到 200K——窗口骤降会诱发抖动,抖动又会把上下文压到不可用,两者互为因果。对 Nexus 的直接含义是:CompactionManager 需要一个重试上限 + 抖动检测,判据可以很轻——连续 N 次压缩后 token 数下降比例低于某个阈值时,报 COMPACTION_THRASHING 而不是继续压。没有这个分支的话,“再压一次”这条恢复路径本身就会变成新的死循环。
三条路各有各的失效模式,选哪条取决于你更怕哪一种。
压缩的第三种角色:窗口强制
前面把压缩定位成两件事:溢出前的补救,以及训练数据的采集口径。平台侧还有第三个定位——它是执行窗口策略的手段,压缩不是窗口快满了才来救火,而是被拿去主动把会话压回某个目标窗口。
两条官方事实可以钉住这件事。CLAUDE_CODE_DISABLE_1M_CONTEXT 在 v2.1.223(2026-08-05)被改成:对所有原生 1M 窗口的 Claude 模型,通过 auto-compaction 把它们压回 200K,而不只是作用于一份固定名单;启动时若发现 auto-compaction 没能把会话压在 200K,会给出警告。更早的 v2.1.172(2026-06-10)是同一套逻辑的雏形:使用 1M 上下文但没有额度的会话会永久卡住,修法是让会话自动压回标准上下文限制以内。同一版本还加了另一条:auto-compact 会把使用未知 model ID 的会话维持在假定窗口之内,而不是任其膨胀。
这也解释了为什么窗口一变,压缩触发点就整体跟着动:v2.1.287(2026-10-02)把 Opus 4.7+ 与 Fable 在 Bedrock / Vertex / Foundry / Claude apps gateway 上默认切成 1M 窗口后,v2.1.247(2026-08-26)已经先把 Sonnet 5 的默认自动压缩窗口从约 934K 提到约 967K——窗口上限与压缩策略在平台侧是同一个旋钮的两面。
对 Nexus 的含义是一条具体的设计要求:CompactionManager 应当支持目标窗口而不只是触发阈值。两者的差别是方向性的——阈值只能被动响应(超了才压),目标窗口可以主动下压(为了把会话维持在某个尺寸而压)。只有阈值这一个旋钮时,「给这个 agent 限定 200K 工作集」这类需求是表达不出来的。
第三个平台:Gemini CLI 把压缩触发开放成配置项。 前面两家各有各的形态——OpenAI 是服务端 compaction 加 1M 窗口,Claude Code 是 OTel 一等事件加后台预计算。Gemini CLI 补上的是第三种形态:它把压缩触发阈值直接开放成一个可写进配置的数。model.compressionThreshold 的官方定义是「触发上下文压缩的上下文使用占比(例如 0.2、0.3)」,默认 0.5;配套的 model.maxSessionTurns 限制单会话轮数,默认 -1(不限)。
要点不在那个默认值,而在参数化方式:它用的是占比,不是绝对 token 数。这个差别在窗口会变的年代是实的——占比口径天然随窗口缩放,绝对 token 口径在窗口从 200K 变成 1M 时必须手工改一次。本章已经有现成的例子:Sonnet 5 的自动压缩点从约 934K 被提到约 967K(v2.1.247),正是绝对口径下的手工维护。建议 Nexus 自建路径采用占比口径,把阈值写成窗口的分数而不是 token 常数。
长期影响:自建 compaction 的核心价值仍在于训练数据采集。HyTuner Processor 需要精确的压缩前后 token 序列来构建训练数据,平台 compaction 对客户端透明,无法提供此能力。此外,token 成本仍随长度线性增长——即使 1M 窗口不触发截断,长上下文的推理成本也随 token 数增加,压缩的经济价值不减。
结论:平台 compaction 是 Nexus compaction 的补充而非替代——平台处理”能容纳多少”,Nexus 处理”应该保留什么”以及”训练数据怎么采”。再补一层:平台还不只是”能容纳多少”,它在用预测性预计算掩盖压缩延迟。Nexus 若要在自建路径上对齐,最小成本是给 CompactionManager 增加”预算 + 复用”分支——token 接近阈值时先生成摘要,真正触发时直接复用,并把命中率记成一个可观测指标(对应上表的 hit 与三种 miss)。
本轮未采纳与待核实(2026-10-06 编辑)
- KV-streams(vLLM 0.19 fork,作者自述 agentic RL 中压缩后重新 prefill 改为从 live cache 驱逐 16-token block、训练快近 2×):无正式论文,本轮未取到一手源。它本可作为「前缀缓存失效」那一行代价的量级证据,但正文只用 v2.1.275 的一手 changelog 支撑该行,不引用此数字。
- Galahad(2026-10-02,测得 prompt token 中 98.7% 是重读):同样未回源。本章开篇已经用「agent 流量里绝大部分 prompt token 是重读」的非数字表述保留了这一论点,等拿到一手源再补百分比。
- CLM 的具体数字(BrowseComp-Plus +11.4%、21.5% 更少 FLOPs、Suffix Cache Reuse 服务端算力 −35%):按低置信度纪律只登记方向不写数字,见 §ACM。
- Claude Code 版本锚点:本轮全部版本事实回
code.claude.com/docs/en/changelog.md一手核对,版本日期取 npm registry 的time字段,最新为 2.1.289(2026-10-03)。其中 v2.1.223 的提案标注日期为 08-06,npm 实际为 2026-08-05T22:51Z,本章按 npm 写。