长任务如何省上下文成本:SoL-Pi 在线上下文压缩机制全解读
【免费下载链接】SoL-PiSoL-Pi: Scaling Auto-Research Loops for Efficient Agent Harnesses项目地址: https://gitcode.com/gh_mirrors/so/SoL-Pi
做长任务 AI 编码时,你是不是也遇到这种糟心事:上下文越滚越长,每一轮请求都要为大量"早该忘掉"的旧内容付费?SoL-Pi 的在线上下文压缩(Online Context Compact)机制专门解决这个痛点——它让 AI 编码助手 Pi 在长任务中自动判断"现在压缩是否划算",只在该省的时候才触发原生压缩,既省钱又不丢证据。
为什么长任务特别"烧钱"?
理解这个机制之前,先搞清楚长任务的上下文成本是怎么膨胀的:
| 成本来源 | 发生了什么 |
|---|---|
| 上下文重放 | 已完成的子任务、旧工具结果一直留在上下文里,每次请求都要重发 |
| 缓存写入溢价 | 上下文一变,缓存失效,新内容按"写价"计费,通常是"读价"的十几倍 |
| 窗口压力 | 上下文逼近模型窗口上限时,要么被截断,要么被迫提前压缩 |
关键矛盾在于:压缩不是免费的。压缩会生成一段摘要,之后每轮请求都要为摘要后的新前缀重新付"缓存写入"的钱。如果任务只剩一两个请求就结束,压缩纯属倒贴。
SoL-Pi 的答案是:别按时间压缩,按经济学压缩。这就是它的核心设计思想——把上下文压缩变成一个"划算才动手"的投资决策。
机制总览:四个模块各司其职
在线上下文压缩由 4 个文件组成,全部位于 src/sol-pi/extensions/online-context-compact/ 目录:
- 触发器extension.ts:监听回合结束事件,收集数据并调用决策函数
- 决策引擎economics.ts:核心"算账"逻辑,判断该不该压缩
- 计划解析plan.ts:识别哪些计划步骤刚完成,作为"安全压缩点"
- 状态账本state.ts:把请求数、上下文增长、压缩负债等数据持久化到会话日志
关键设计:用"完成计划步骤"当安全压缩点
很多人会问:压缩会不会把任务压断在关键步骤中间?SoL-Pi 的答案很巧妙——只在你刚完成一个计划步骤时才考虑压缩。
机制会向 AI 注册一个叫update_plan的工具(见 tools.ts),AI 每次汇报计划时都要提交完整的步骤列表。analyzePlanTransition 函数对比前后两次计划,一旦发现某个步骤从"进行中"变为"已完成",就标记一个进度边界(boundary)。
边界之所以"安全",是因为它同时满足了两个条件:
- 语义上安全:一个子任务已完成,接下来压缩旧上下文不会打断任何进行中的操作
- 证据上有保障:完成步骤时附带的
progress参数会记录改了哪些文件、做了什么验证、有哪些决策,这些摘要信息随压缩保留下来
决策引擎:这套"算账逻辑"才是精华
真正的亮点在 decideCompaction 函数。它回答一个问题:"压缩省下的钱,够不够覆盖压缩付出的缓存重建成本?"
第一步:估算"还剩多少请求"
决策引擎用 estimateRemainingRequests 预测任务还差几轮请求:
- 统计历史上每个已完成边界之间花了多少请求,算出平均值和下界
- 再乘以剩余未完成的步骤数,得到"无窗口上限的预估剩余请求数"
- 同时用"上下文窗口剩余空间 ÷ 平均每轮增长量"算出一个窗口硬上限,两者取较小值
第二步:计算"回本点"
压缩的收益是归档 token 数 − 摘要 token 数;压缩的成本是当前上下文 ×缓存写读比 − 1(缓存写入相对读取的溢价部分)。两者的比值就是回本请求数:
简单说:压缩一次要花 X 钱,每轮能省 Y 钱,X÷Y 就是"做几轮请求才能回本"。
第三步:双重闸门——经济账 + 窗口保护
只有满足以下任一条件才真正压缩:
- 经济闸门:回本请求数 ≤ 预估剩余请求数,即"压缩这笔投资能赚回来"
- 窗口保护闸门:上下文已逼近窗口上限(默认预留 16384 token,见 economics.ts),此时不管划不划算都必须压缩
而且对"第一次压缩"和"后续压缩"采用了不同的谨慎度:第一次压缩要求回本点落在收紧后的预估范围内;后续压缩还要额外满足1.5 倍安全边际,并且必须把上次压缩留下的"缓存负债"一并算进回本账——防止连续压缩越压越亏。
缓存负债:一个容易被忽略的细节
每次成功压缩后,recordCompaction 会把这次的"重建成本"记为负债,之后每轮请求通过 recordProviderRequest 逐步"偿还"。这让决策引擎不会天真地以为压缩是零成本,是整套经济模型能站住脚的关键一环。
压缩之后任务不会"断片"
最后一个新手最关心的问题:压缩完 AI 会不会忘了自己该干嘛?
流程是这样的(见 extension.ts):
- 决策触发后,先让当前回合正常结束
- 调用 Pi 的原生压缩,并附上专门指令:
保留已完成的工作、验证结果、重要决策和剩余工作(extension.ts) - 压缩成功后,自动发一条隐藏消息并开启新回合,提醒 AI先重建剩余工作的计划再干活(extension.ts)
全程无需人工干预,也不会产生额外的压缩文件——所有状态都作为版本化条目存在 Pi 的会话日志里。用户取消或退出 Pi 时不会触发自动续跑,行为完全可预期。
如何启用:两行配置搞定
SoL-Pi 所有机制默认关闭,需显式开启。在项目下创建.pi/sol-pi.json(项目已受信任时)或~/.pi/agent/sol-pi.json:
{ "version": 1, "onlineContextCompact": true, "cacheWriteReadRatio": 12.5 }| 配置项 | 说明 | 默认值 |
|---|---|---|
onlineContextCompact | 启用在线上下文压缩,注册update_plan工具 | false |
cacheWriteReadRatio | 缓存写/读价格比,经济决策的唯一输入 | 12.5 |
安装方式:先装 Pi(npm install --global @earendil-works/pi-coding-agent@0.85.1),再执行pi install git:github.com/NVlabs/SoL-Pi。完整的配置模式与查找顺序见 docs/configuration.md。
⚠️ 一个务实建议:cacheWriteReadRatio直接决定压缩激进度。如果你用的模型缓存写入很便宜(甚至免费),把比值调低,压缩会更积极;反之调高则更保守。它只在会话加载时生效一次,改完需重启 Pi。
小结:把"压缩上下文"从玄学变成数学
SoL-Pi 的在线上下文压缩机制,本质是把三个朴素直觉工程化了:
- 只在该压缩的时候压缩:用"完成计划步骤"定义安全边界,不中断进行中的工作
- 压缩前先算账:回本请求数 vs 剩余请求数,算不清就不动手
- 记住历史教训:缓存负债和首次/后续压缩的差异化门槛,避免连续压缩亏损
对跑长任务的开发者来说,这套机制的意义在于:你不需要盯着 token 账单手动喊"压缩",也不用担心压缩把任务压崩——决策引擎替你做了最划算的那个决定。
【免费下载链接】SoL-PiSoL-Pi: Scaling Auto-Research Loops for Efficient Agent Harnesses项目地址: https://gitcode.com/gh_mirrors/so/SoL-Pi
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考