hello 我是逆境不可逃
一段 Agent 会话可能包含很多轮工具调用:读取文件、输出日志、执行测试,再根据结果继续修改。历史可以保存在磁盘上,但每次请求模型时,能携带的内容有长度上限。
Pi 的压缩机制会整理较早的内容,同时保留一部分原始记录,让模型有空间继续任务。理解这个过程,需要分别看压缩何时触发、从哪里切分,以及压缩后的上下文怎样组成。
为什么不能把全部历史一直带着
模型的上下文容量通常以 token 衡量。token 是模型处理文本的计量单位,不能简单等同于汉字数或消息条数。一条很长的日志可能比几十条简短问答更占空间。
Pi 的一个自动压缩判断,会在启用压缩时比较当前上下文用量与"模型窗口减去预留空间"。用简化规则表示就是:
text
当前用量 > 模型上下文容量 − 预留空间
→ 达到压缩阈值
这里提前留出余量,而不是一直等待输入完全塞满。这个判断也说明,压缩并非简单地每聊固定轮数就触发一次。
是否触发压缩,与近期原文保留多少,是两个不同问题。Pi 还会根据近期内容的 token 预算,选择保留记录的起点。
摘要应该保留继续任务的依据
如果任务是修复登录问题,把几十轮讨论压缩成"讨论了鉴权方案",虽然短,却无法帮助下一轮继续工作。
更有用的摘要应该像这样。以下是说明用途的示例,并非模型实测输出:
text
目标:修复过期 token 仍能访问接口的问题
限制:不要修改公开接口
已完成:调整 token 过期时间判断
当前状态:测试仍失败,原因尚未查清
下一步:检查实际返回状态码和鉴权入口
Pi 的摘要提示词要求保留目标、约束与偏好、任务进度、关键决定、下一步和必要背景。进度还区分了已完成、进行中与受阻事项,并要求保留准确的路径、函数名和错误信息。
这些要求能引导摘要关注任务,但不能保证生成结果绝不遗漏。原文是"修改完成,尚未测试",摘要若变成"问题已修复",就改变了结论的确定程度,后续模型可能因此跳过验证。
信息是否值得保留,也不能只看新旧。很早提出的"不要修改公开接口",只要仍然有效,就比一段重复日志更重要;而日志中唯一的错误原因,又可能是继续定位问题所必需的依据。
摘要之外,为什么还要保留原始消息
摘要适合概括较早的工作,但最近的报错、参数和工具输出,往往需要保留细节。
例如,最新测试结果是:
text
失败测试:过期 token 仍可访问接口
预期状态码:401
实际状态码:200
压缩成"鉴权测试失败",就丢掉了具体差异。因此,Pi 会记录一个原始内容的保留起点。构造上下文时,组合三部分:
text
压缩摘要
→ 从保留起点开始的原始记录
→ 压缩之后新增的消息
例如,旧记录为 A、B、C、D,压缩记录 S 指定从 C 开始保留,之后又新增 E、F。模型得到的上下文就是:
text
S 的摘要 → C → D → E → F
A、B 不再以原文出现在这次上下文里,但仍保存在会话历史中。压缩改变的是模型本次接收的内容,并不通过这一步删除整份原始历史。
切分位置要考虑工具调用关系
只按"最后 N 条消息"截取,可能刚好把工具请求和结果切开:
text
模型:读取 app.log,从第 1000 行开始
工具:返回日志内容
模型:分析日志
如果从工具结果开始保留,就丢失了读取范围,模型可能误解这份日志的来源。
Pi 的默认切分逻辑不会把工具结果选作切分起点。它从较新的记录向前估算大小,再寻找可用边界;保留模型工具请求时,后面的对应结果也随之保留。
不过,这不意味着一次很长的交互必须全部原样留下。Pi 允许在交互中间的模型消息处切分,并为前半段额外生成摘要,说明最初请求、早期进展,以及理解保留部分所需的背景。
text
较早历史摘要
+ 本次长交互前半段的摘要
+ 保留下来的近期原文
这里的"长交互"可以从一条用户请求延续到多个工具循环,不要把它理解成第一篇里仅包含一次模型响应的 Agent Turn。
这种安排在保留细节与控制长度之间取舍:相关请求和结果要保持结构完整,较早的背景则可以用摘要承接。上下文预算是近似目标,还需要服从可用的消息边界。
再次压缩时,旧摘要怎样处理
任务继续推进后,之前保留的近期消息也会变老,需要再次压缩。
Pi 的准备逻辑会取出上一份摘要,并收集本次需要归纳的消息。上次原样保留的内容,如果已经移出新的保留范围,也会进入本次摘要材料。
构造上下文时,使用当前路径上的最新压缩记录。旧摘要不会一份接一份全部堆在模型输入前面。
更新摘要仍然存在信息损失风险。如果某条约束在上次摘要中就被漏掉,仅凭那份摘要继续更新,并不能自动找回它。需要时应回查原始记录,确认所属分支和适用条件,再补进上下文。
原始记录留在磁盘上,也不代表模型能自动看到。回查需要用户或程序明确取出相关内容。至于文件当前状态,则应重新读取,不能把旧工具结果当作实时事实。
怎样验证压缩行为
本地运行了仓库中的上下文构造测试,并额外选择了 9 个压缩阈值、切分点与压缩准备测试,均通过。这里用的是预设消息和摘要,没有调用真实模型评估摘要质量。
其中一个上下文构造用例明确检查:
text
旧消息:1、2、3、4
压缩摘要:5,指定从 3 开始保留
新消息:6、7
构造结果:摘要 5 → 消息 3、4 → 消息 6、7
其他用例还检查了多次压缩使用最新摘要、旧的保留消息在窗口移动后重新进入摘要材料,以及无需再次压缩时不重复准备。
这些断言能验证程序选中了哪些记录、结果按什么顺序组成。要判断模型生成的摘要是否保留约束、准确区分已完成与未验证事项,还需要另做内容质量评估。
Pi 的压缩机制把完整历史与当前上下文分开管理。摘要帮助保留任务进度,近期原文保留操作细节,原始历史则留下回查依据。理解这些不同用途,才能判断一份压缩结果是否足以支撑后续工作。
