How Compaction Works in Pi

160 points - yesterday at 5:57 PM

Source

Comments

kierangill yesterday at 10:56 PM
Instead of compaction, has anyone seen a successful implementation of pruning? That is, the agent looks at the conversation history and removes any low-value messages.

For example, sometimes context will be taken up by a side tangent, tool call outputs, or low-value codebase exploration.

Much of the time, I prefer to preserve the history of my conversation instead of summarizing it. I find summarized conversations lead to more frustrating future chats because the LLM misses intent and or context. (Or, the presence of paragraphs and paragraphs of LLM output makes the next token predictor dumber? Unsure.)

errantmind today at 3:27 AM
In my experience, the best approach to compaction is to never get to the point where you need compaction and to generally stay below about 30% context window utilization. Even for long agentic workflows this can be accomplished for quite a while, much longer than most people might think.

Here's what I do for each of my sessions:

1. For asides, off-topic work, or repetitive work that has already been done in the session, branch backwards (with /tree) and summarize.

2. If I've exceeded 30% or the 'price-doubling' multi-tier pricing, prune (my custom extension).

3. If I've already pruned and I'm still close to 30%, 'prune all' (more extensive prune).

Definition:

'/prune': Removes ~50% context on a fresh session (not previously pruned)

  - Keeps: User messages, normal assistant prose, commands/status markers, extension receipts, model settings, and a plain-text receipt for each tool call.
  - Removes: Thinking, signatures, actual tool calls/results, tool output, images, compaction summaries, and other extensions’ state.

'/prune-extended': Removes ~80% context on a fresh session

  - Keeps: User messages, normal assistant prose and conclusions, commands/status markers, extension receipts, and model settings.
  - Removes: Thinking, signatures, all tool calls/results and output, images, compaction summaries, other extensions’ state, and any tool-activity receipts created by /prune.

Both create a new session and delete the old one after a successful switch.

Using these I can keep a session going for weeks (or longer), even with extensive use and almost all the important context is preserved while dumping the less important context. Neither command requires an LLM summarization so they execute quickly.

novaRom yesterday at 9:42 PM
Compaction is painful if you run just one local LLM, the best way to avoid it is to keep context as small as possible.

One trick I find useful is to have one model with two KV caches running and while first cache has produced tokens, second cache immediately summarizes them during input tokens are being generated (tools time), then harness switches to the second KV cache which takes newly produced input tokens while KV in first cache is getting replaced with compacted summary tokens. This is a kind of ping pong, so we trade more space for less time. Still experimenting but it looks it works, and nice bonus it improves GPU utilization. Btw I have my own harness and model serving code, but it can be easily implemented in any other harness and model server.

skeledrew yesterday at 11:23 PM
I think the way prompt caching works really discourages more creative compaction techniques. Like perhaps some kind of heuristic progressive compaction that replaces tool results and thinking traces after use with pointers could potentially keep the model smart for much longer, but that'd mean breaking cache every turn, and possibly even within a turn, seriously driving up cost.
damsta yesterday at 10:08 PM
I don't like any of current solutions when it comes to compaction. I'd love to have a way to say what exactly should be summarized, because most of the time I just need to compact some noisy MCP tool calls, test runs and things like that. Just let me pick what should be summarized and keep the rest as is.
rcarmo today at 6:35 AM
I implemented a few additional strategies in https://github.com/rcarmo/piclaw/tree/main/runtime/src/exten... - including Codex-native server-side compaction. They all have slightly different trade-offs, but I run very long sessions quite successfully
jakswa yesterday at 10:56 PM
OMP changed the default compaction to images! Kinda nuts to read about. Saves the generation cost of the traditional compaction step and writes the context as tiny text to an image, if I was following correctly.
jedisct1 today at 8:57 AM
How context management works in Swival https://swival.dev/pages/context-management.html
zahrevsky yesterday at 10:12 PM
Was expecting the article to go more in-depth.

Say, what happens when chain of summaries grows so long, that it still overflows context window. Is summarization runned over the summaries in the context window?

storus yesterday at 9:34 PM
The advantage of running local stack is that you can do the compaction at the time of inference, i.e. some tool call runs out of context, you can just pause inference, purge/replace old tool calls with their summaries or just logs by operating directly over tokens on a GPU, rebuilding KV cache (one time prefill hit) and resuming the inference, easily being able to e.g. read 1000 markdowns, each 50k long, in a single LLM call. That's not possible with current agentic harnesses using LLM calls.
Aeolun today at 5:25 AM
My summarization creation functions over batches of 50 messages, and I don’t often lose important context any more. The loss comes from trying to stick a whole conversation in a single compaction request (at least in my case)
pornel yesterday at 11:40 PM
I don't like that it throws away the whole KV cache when compacting. It costs a cache miss of the whole conversation length, and that's a waste of time and money.

LLMs are perfectly capable of summarising the conversation without a new system prompt.

kennywinker yesterday at 9:16 PM
Compaction has been a pretty painful part of local llm usage. Scrapping the current context and parsing almosy 128k of context then generating something like 5-10k tokens - that can take quite a while when you’re working with 10t/s-45t/s (depending on the model).

I pretty much just start a new session whenever i fill the context.

navs today at 3:30 AM
Ampcode used a handoff feature for a while that I found genuinely useful [1] and then they removed it. Anecdotally, I felt it worked better than compaction.

[1] https://ampcode.com/news/handoff

deleted yesterday at 6:18 PM
Gecko4072 yesterday at 9:00 PM
Can someone recommend a Hermes alternative that is less token hungry? Pi did not work well for my use case.
brcmthrowaway today at 12:33 AM
Is pi a drop in replacement for OpenCode / Claude Code? I cannot be bothered installing 50 million plugins.
searealist yesterday at 9:59 PM
I expect Pi is mostly used with OpenAI plans, and OpenAI has a dedicated compaction endpoint you should probably be using with their models instead of a compaction prompt.
ka_de today at 9:19 AM
[flagged]
randomblock1 yesterday at 9:05 PM
TLDR: It keeps ~20k tokens of recent conversations, then hands the rest of the conversation to another model with a special system & user prompt. This then fills out a template with relevant information.

See: https://github.com/earendil-works/pi/blob/main/packages/codi...

tizerluo today at 1:32 AM
[flagged]
cyanydeez yesterday at 9:17 PM
Opencodes dynamic context pruning works by labeling tools and chat and the rest and the agent can collapse and expand summaries.

I get it into 1M+ routinely on local models with operations between 50k-85k

juleiie yesterday at 10:17 PM
[flagged]