5 分钟阅读

Pi Agent Compaction:长任务不爆上下文的关键机制


做 Coding Agent 最怕什么?

不是它不会写代码,而是一个长任务做到一半,前面的背景、约束、文件线索被上下文窗口挤掉。

Pi Agent 的 Compaction 就是为这个问题准备的:把旧对话压成结构化摘要,同时尽量保留最近正在推进的工作。

它不是简单“清空历史”,更像给长任务做一次可继续的工程交接。

先说结论


  • 压缩的目标是释放上下文空间,同时保留任务目标、约束、进度、关键决策和文件线索。
  • Pi 支持自动压缩,也支持手动执行 /compact [instructions],可以用说明词聚焦摘要重点。
  • 默认会预留 16384 tokens 给模型回复,并保留最近约 20000 tokens 不被摘要。
  • /tree 分支切换时还有 Branch Summarization,用来把离开的分支总结到新位置。
  • 扩展可以拦截压缩事件,取消压缩或提供自定义摘要。

背景:为什么长任务一定会遇到压缩

LLM 有上下文窗口限制。

当一次 Agent 会话越来越长,里面会堆很多内容:用户需求、模型回复、工具调用、命令输出、读过的文件、改过的文件。

如果不处理,后面的模型调用要么塞不进去,要么把很早但很重要的工程背景挤掉。

Pi 的做法不是把旧内容直接丢掉,而是把较早的消息总结成一个 CompactionEntry,后续模型看到的是:


1
system + summary + recent messages

也就是说,旧上下文被浓缩成摘要,最近的工作现场继续保留。

关键点 1:什么时候会触发 Compaction

自动压缩的触发条件可以记成这个公式:

1
contextTokens > contextWindow - reserveTokens

reserveTokens 默认是 16384,意思是给模型接下来的回复留出空间。

如果你不想等自动触发,也可以手动压缩:

1
/compact

还可以加说明,让摘要更偏向你关心的方向:

1
/compact focus on changed files, open risks, and next steps

这个适合在长重构、排障、代码审查中主动“收口”:先让 Agent 把已经发生的事整理清楚,再继续往下做。


关键点 2:它到底压缩了什么

Pi 会从最新消息往回看,累计 token 估算,直到达到 keepRecentTokens

默认 keepRecentTokens20000,也就是最近约 2 万 tokens 会尽量留下来,不进入摘要。

压缩流程大致是:

  1. 找到切分点:决定哪些旧消息要总结,哪些近期消息要保留。
  2. 抽取旧消息:从上一次保留边界或会话开头开始收集。

  1. 生成结构化摘要:必要时把上一次摘要也作为迭代上下文传入。
  2. 追加 CompactionEntry:记录摘要、firstKeptEntryId 和压缩前 token 数。
  3. 重新加载会话:后续上下文变成摘要加保留消息。

这里最重要的是 firstKeptEntryId

它告诉 Pi:从哪条消息开始仍然作为原始消息发送给模型。更早的内容则由摘要接管。


关键点 3:不是随便从中间切一刀

Pi 正常会按 turn 边界切。

一个 turn 从用户消息开始,包含后续 assistant 回复和工具调用,直到下一条用户消息。

这样做是为了避免把“工具调用”和“工具结果”拆散。

Pi 文档里明确提到:有效切分点包括 user message、assistant message、bash execution message、custom message 和 branch summary;不会切在 tool result 上。


如果单个 turn 自己就超过 keepRecentTokens,Pi 会进入 split turn 场景:在这个巨大 turn 的 assistant message 处切分,并分别总结历史上下文和这个 turn 的前半段,再合并摘要。

这对一次性超大任务很关键,例如:

1
用户给了一个巨大需求 -> Agent 连续读文件、跑命令、改代码 -> 单个 turn 已经很长

这种情况下,Pi 不是强行等待下一个用户消息,而是有专门的 split turn 处理。


关键点 4:摘要格式是工程交接单

Pi 的 compaction 和 branch summarization 使用同一套结构化摘要格式。

它不是随便写一段“前情提要”,而是会围绕这些信息组织:

  • Goal:用户要达成什么目标
  • Constraints & Preferences:约束和偏好
  • Progress:已完成、进行中、阻塞项
  • Key Decisions:关键决策和理由

  • Next Steps:下一步怎么做
  • Critical Context:继续任务必须知道的信息
  • read-files / modified-files:读过和改过的文件

这也是为什么 Compaction 对 Coding Agent 特别重要。

真正有价值的不是“聊天记录还在”,而是下一轮模型还能知道:任务目标是什么、哪些坑已经踩过、哪些文件不能乱动、接下来该做什么。


关键点 5:/tree 切分支时也会总结

Pi Sessions 是树状结构。

当你用 /tree 从一个分支切到另一个分支时,Pi 会询问是否总结你正在离开的分支。

这个机制叫 Branch Summarization。

它会找到旧位置和新位置的共同祖先,收集旧分支上被离开的那些 entries,生成摘要,并把这段上下文注入到切换后的分支语境里。


可以这样理解:

flowchart TD
  A[共同祖先] --> B[旧分支探索]
  B --> C[旧分支结果]
  A --> D[目标分支]
  C --> E[旧分支摘要]

如果你让 Agent 试了方案 A,后来切回去走方案 B,Branch Summarization 能把方案 A 的关键发现带过去,避免“换分支就失忆”。


可以直接照抄的配置清单

Compaction 可以配置在全局或项目级设置里:

1
2
~/.pi/agent/settings.json
<project-dir>/.pi/settings.json

最小配置示例:

1
2
3
4
5
6
7
{
  "compaction": {
    "enabled": true,
    "reserveTokens": 16384,
    "keepRecentTokens": 20000
  }
}

几个使用建议:

  1. 长任务默认保持自动压缩开启,不要等上下文快炸了再处理。
  2. 关键节点主动用 /compact <instructions>,让摘要偏向文件、风险和下一步。
  3. 探索分支时配合 /tree,切走前让 Pi 总结离开的分支。
  4. 如果团队有特殊摘要要求,可以通过扩展监听 session_before_compactsession_before_tree
  5. 如果关闭自动压缩,仍然可以手动执行 /compact

最后总结

Pi Agent 的 Compaction 可以理解成:给长会话做“可继续的上下文整理”。

它保留最近工作现场,把更早内容压成结构化摘要,并记录读过、改过的文件。

对短对话来说,你可能感受不明显;但对重构、排障、长时间代码审查这类任务,它直接决定 Agent 能不能稳定接着做。

如果你已经在用 Pi Agent,建议把 /compact/tree 分支摘要一起学,它们解决的是同一个核心问题:让复杂工程任务不要在上下文里断线。


参考资料

话题标签

#PiAgent #CodingAgent #AI编程 #上下文工程 #程序员效率