01 触发条件与额度估算 本节摘要:第 7、8 章讲了会话核心与上下文管理,这一章讲当上下文「快爆了」时怎么办——上下文压缩(compaction)。本节讲压缩的触发条件:每一回合前如何估算请求 token,何时判定需要压缩。核心是一个额度估算公式,它决定「还剩多少空间」「什么时候该压缩」。理解了这个公式,你就知道 Agent 在马拉松式长对话里「什么时候会自动瘦身」。 一、为什么必须压缩 再大的模型窗口也会被长对话塞满。考虑一次长会话: 系统上下文(第 8 章):几千到几万 token 历史对话:每回合递增 工具输出:可能很大 工具描述:几千 token 这些累加,几十个回合后很容易逼近甚至超过模型窗口。超过会怎样?模型拒绝处理(报错)或截断(行为异常)。
本节摘要:第 7、8 章讲了会话核心与上下文管理,这一章讲当上下文「快爆了」时怎么办——上下文压缩(compaction)。本节讲压缩的触发条件:每一回合前如何估算请求 token,何时判定需要压缩。核心是一个额度估算公式,它决定「还剩多少空间」「什么时候该压缩」。理解了这个公式,你就知道 Agent 在马拉松式长对话里「什么时候会自动瘦身」。
再大的模型窗口也会被长对话塞满。考虑一次长会话:
这些累加,几十个回合后很容易逼近甚至超过模型窗口。超过会怎样?模型拒绝处理(报错)或截断(行为异常)。所以必须在「快超」之前主动压缩——把旧的替换成摘要,腾出空间。
压缩判断发生在每一回合前。系统会估算「这一回合的请求大概多少 token」,公式大致是:
估算 token = 系统上下文 + 历史 + 工具描述 + 用户输入 (或更精确地:输入 + 输出 + 缓存读 + 缓存写)
估算是为了判断「还剩多少空间」。如果估算值已经接近窗口上限,就该压缩了。
核心是「可用额度(usable)」的计算——它决定「这个会话最多能用多少 token 而不爆」。公式大致是:
usable = 模型输入上限 - 预留(reserved)
其中 reserved(预留)是关键:
reserved = 配置的预留值 ?? min(默认缓冲 20000, 模型最大输出)
也就是说,预留默认取「20000」和「模型最大输出」中的较小者。这个预留是给「输出和后续周转」留的空间——不能把窗口全占满,得给模型输出留地方。
💡 为什么要预留:如果占满整个窗口,模型连「回复」的空间都没了。预留就是「给输出和后续周转留的余地」。预留大小是个权衡:留多了,可用空间小,压缩频繁;留少了,可能输出不够用。默认 min(20000, maxOutput) 是个经验值。
有了估算和可用额度,触发条件就清楚了:
if 配置关闭了自动压缩 or 上下文为 0: 不压缩 else if 估算 token >= usable: 触发压缩 else: 不压缩
也就是说:估算的 token 超过可用额度,就触发压缩。简单直接。
假设某模型输入上限 200000,最大输出 8000:
reserved = min(20000, 8000) = 8000 usable = 200000 - 8000 = 192000
会话进行到第 30 回合,估算这一回合请求约 195000 token:
195000 >= 192000 ──► 触发压缩
压缩后,旧历史被摘要替换,估算降到比如 60000,远低于 192000,会话继续。这就是 Agent 长对话不爆的机制。
压缩不是死的——几个地方可配:
⚠️ 别关自动压缩:新手可能嫌压缩「让 Agent 忘事」而关掉它。但关了的后果是长对话直接爆窗口报错。正确做法是接受压缩的有损性(第 02 节),或者用记忆库(OpenWork 教程第 7 章)补长期记忆。
知道了何时压缩,下一节讲「压成什么」——隐藏检查点的结构。