Pi Agent 学习笔记:对话太长以后,如何压缩上下文

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 的压缩机制把完整历史与当前上下文分开管理。摘要帮助保留任务进度,近期原文保留操作细节,原始历史则留下回查依据。理解这些不同用途,才能判断一份压缩结果是否足以支撑后续工作。


相关推荐
daidaidaiyu5 小时前
ThingsBoard 集群的核心逻辑源码分析
java
我可能是个假开发6 小时前
FTP Unicode 文件名导致 `550` 的问题分析与解决方案
java·开发语言·spring
caoerzhong6 小时前
中小企业上 WMS 该先上哪几块:JeeWMS 开源 Java 仓库管理系统的分批上线清单
java·python·开源
【JAVA】玩家7 小时前
Spring核心原理全解析:从零到生产实战
java·后端·spring
Wang's Blog7 小时前
Java框架 SpringCloud 快速入门: 实现 Feign 最佳实践(抽取方式)
java·spring cloud
MandalaO_O8 小时前
IDEA 开发(快捷键 + 调试 + 序列化)
java·ide·intellij-idea
xiaoqiMikko9 小时前
JVM 线上排查实战(七):jps 看不见它、jstack 连不上它,可它明明活得好好的
java·jvm
狼爷10 小时前
Rust/Go/Java/Python/PHP 大比拼:负载下后端框架到底差多少?
java·后端·编程语言
念何架构之路10 小时前
zap扩展生态与总结
java·前端·数据库
第七页独白11 小时前
汽车零件厂如何通过 QMS 真正落地 IATF 16949——QMS软件系统:品质检验-内审稽核-8d客诉管理:全星质量管理软件系统
java·前端·数据库