Compaction 上下文压缩
概述
LLM 的上下文窗口是有限的。当对话变长时,Pi 使用 Compaction(压缩) 来总结旧内容,同时保留最近的工作。
Pi 有两种总结机制:
| 机制 | 触发条件 | 目的 |
|---|---|---|
| Compaction | 上下文超限或 /compact | 总结旧消息释放上下文 |
| Branch Summarization | /tree 导航 | 切换分支时保留上下文 |
Compaction 何时触发
当:
contextTokens > contextWindow - reserveTokens
默认 reserveTokens 为 16384(可在 settings.json 中配置)。
也可以手动触发:/compact [instructions]
工作原理
- 找到分割点:从最新消息向前累积,直到达到
keepRecentTokens - 提取消息:收集要总结的消息
- 生成摘要:调用 LLM 生成结构化摘要
- 追加条目:保存
CompactionEntry - 重新加载:使用摘要 + 保留的消息继续
压缩前:
entry: 0 1 2 3 4 5 6 7 8 9
┌─────┬─────┬─────┬─────┬──────┬─────┬─────┬──────┬──────┬─────┐
│ hdr │ usr │ ass │ tool │ usr │ ass │ tool │ tool │ ass │ tool│
└─────┴─────┴─────┴──────┴─────┴─────┴──────┴──────┴─────┴─────┘
└────────┬───────┘ └──────────────┬──────────────┘
要总结的消息 保留的消息
↑
firstKeptEntryId (entry 4)
压缩后:
entry: ... 9 10
┌─────┬─────┐
│ ... │ cmp │
└─────┴─────┘
↑
新增的压缩条目
自定义压缩
可以通过扩展自定义压缩逻辑:
pi.on("compact", async (event, ctx) => {
// 自定义总结方式
const summary = await myCustomSummary(event.messages);
return { summary };
});