ZH

 


脑容量满了怎么办

Context 必须塞进 model.contextWindow。可是长会话里历史越堆越多,迟早撑爆。pi 的答案是Compaction(压缩):当 token 逼近上限,把早期对话摘要化,腾出空间,让会话能一直跑下去。

token 用量
  ▲
  │                      ┌─ 阈值(窗口的 X%)
  │            ╱╲       │
  │          ╱    ╲     │
  │        ╱        ╲   ▼  触发 compaction
  │      ╱            ╲────────┐
  │    ╱               压缩后  ╲___
  │  ╱                              ╲___
  └──────────────────────────────────▶ 轮次

压缩不是删除,是「摘要 + 边界」

压缩会在历史里立一道compact boundary:边界之前的内容被一段摘要替代,边界之后保持原样。之后每轮只取边界后的消息再拼 Context——既保留近期细节,又不丢早期脉络。

📄packages/coding-agent/src/core/compaction/compaction.ts(精简)typescript
3 个注解
1// 每轮 API 调用前:检查是否需要压缩
2const { compactionResult } = await autocompact(
3 messagesForQuery, ctx,
4 { systemPrompt, userContext },
5)
6
7// 只取「压缩边界」之后的消息参与本轮请求
8function getMessagesAfterCompactBoundary(messages) {
9 const idx = messages.findLastIndex(
10 (m) => m.type === "compact_boundary",
11 )
12 return idx === -1 ? messages : messages.slice(idx)
13}
14
15// 摘要:让模型把早期对话浓缩成一段
16const summary = await summarize(earlyMessages)
17messages.push({ type: "compact_boundary", summary })
注解(点击跳转)

这就是为什么 pi 能处理跨越成百上千轮的超长任务:它会主动「忘掉细节、记住要点」,像人一样管理自己有限的工作记忆。