Kimi CLI Context Compaction Mechanism: Summarizing History in `src/kimi_cli/soul/compaction.py`
The Kimi CLI context compaction mechanism monitors conversation token usage and automatically summarizes older messages into a concise summary when the history approaches the model's context limit, preserving the most recent exchanges in the new shortened history.
The MoonshotAI/kimi-cli repository relies on an automated context compaction system to keep long-running agent conversations within strict LLM token budgets. The Kimi CLI context compaction mechanism is implemented primarily in src/kimi_cli/soul/compaction.py, where a combination of heuristic estimation, configurable triggers, and LLM-driven summarization replaces aging dialogue with a compact summary.
Core Steps of the Kimi CLI Context Compaction Mechanism
Before any summarization occurs, the runtime approximates token consumption with functions defined in src/kimi_cli/soul/compaction.py. According to the MoonshotAI/kimi-cli source code, the system uses a cheap heuristic for sizing and a dual-condition guard for triggering.
Estimating usage with estimate_text_tokens
The estimate_text_tokens function iterates over every Message in the conversation, inspects its TextPart elements, and divides the total character count by four to derive a fast token estimate. This avoids expensive tokenizer calls during the decision phase.
token_count = estimate_text_tokens(context.messages)
Deciding when to compact via should_auto_compact
The should_auto_compact function returns True when either:
token_count >= max_context * trigger_ratio(default ratio0.9), ortoken_count + reserved_context_size >= max_context(default reserved buffer200).
These two guards ensure the model never exceeds its window while leaving a safety margin for the next reply.
if should_auto_compact(token_count, max_context, trigger_ratio=0.9,
reserved_context_size=200):
# perform compaction
The SimpleCompaction Implementation in compaction.py
The default implementation of the Compaction protocol is SimpleCompaction, located in src/kimi_cli/soul/compaction.py. It handles message selection, prompt construction, LLM invocation, and result packaging.
Selecting messages with SimpleCompaction.prepare
SimpleCompaction.prepare walks the history backwards, counting user and assistant messages until it reaches max_preserved_messages (default 2). Everything older than that becomes the to_compact slice; the remainder is to_preserve. For each message in the compaction slice, a TextPart is added that records the role and content. The method then appends the static COMPACT template from kimi_cli.prompts and any custom instruction supplied by the caller.
Summarizing with the LLM and building the result
The compact method sends the prepared compaction prompt to the LLM via kosong.step with:
- system prompt =
"You are a helpful assistant that compacts conversation context." - empty toolset (no tool calls allowed during summarization)
- a single-message history consisting of the generated compact-message
The LLM response is filtered to drop any ThinkPart artifacts. A new user message is built with the fixed prefix COMPACTION_OUTPUT_PREFIX followed by the summary text. The preserved messages are appended unchanged, and the method returns a CompactionResult that stores the new message list, exact token usage reported by the provider, and an optional trace ID for debugging.
CompactionResult(messages=compacted_messages, usage=result.usage, ...)
Practical Usage Example
Developers can invoke the Kimi CLI context compaction mechanism directly when testing custom policies or building alternative runtimes. The following pattern estimates tokens, evaluates the trigger, and runs SimpleCompaction:
from kimi_cli.soul.compaction import SimpleCompaction, should_auto_compact
from kimi_cli.llm import LLM
from kimi_cli.soul.message import Message
async def maybe_compact(messages: list[Message], llm: LLM, max_ctx: int) -> list[Message]:
# Quick token estimate
token_count = sum(len(p.text) for m in messages for p in m.content if isinstance(p, TextPart))
if should_auto_compact(token_count, max_ctx, trigger_ratio=0.85, reserved_context_size=250):
compactor = SimpleCompaction(max_preserved_messages=2)
result = await compactor.compact(messages, llm)
return list(result.messages)
return messages
In the main runtime located at src/kimi_cli/soul/kimisoul.py, this step is invoked automatically when the token budget is exceeded.
Summary
src/kimi_cli/soul/compaction.pyhosts the Kimi CLI context compaction mechanism, combining estimation, trigger logic, and LLM summarization.estimate_text_tokensprovides a fast heuristic by dividing character counts by four.should_auto_compactuses a ratio-based threshold and a reserved buffer to decide when compaction is necessary.SimpleCompaction.preparepreserves the most recent two user-assistant exchanges by default and bundles older messages for summarization.- The compaction prompt is drawn from the
COMPACTtemplate inkimi_cli.prompts, and the resulting summary becomes the opening message of the shortened history.
Frequently Asked Questions
What triggers the Kimi CLI context compaction mechanism?
The mechanism triggers when should_auto_compact detects that the estimated token count has reached at least 0.9 of the model's maximum context window, or when the current count plus a 200-token reserved buffer would exceed the limit. These thresholds are configurable via the trigger_ratio and reserved_context_size parameters.
How does SimpleCompaction decide which messages to keep?
SimpleCompaction.prepare traverses the conversation history from newest to oldest and retains up to max_preserved_messages user and assistant exchanges, which defaults to two. Every older message is moved into the compaction slice and replaced by a single LLM-generated summary.
Where is the compaction system prompt defined?
The compaction call uses the static system prompt "You are a helpful assistant that compacts conversation context." inside src/kimi_cli/soul/compaction.py. The instruction template appended to the compaction payload is imported as COMPACT from kimi_cli.prompts, which guides how the LLM should format the summary.
Can developers customize the compaction behavior?
Yes. Developers can instantiate SimpleCompaction with a different max_preserved_messages value or call should_auto_compact with custom trigger_ratio and reserved_context_size arguments. For deeper changes, the Compaction protocol can be implemented with an alternative class that replaces the default summarization strategy.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →