DEV Community

ZGI | AI Agent Platform
ZGI | AI Agent Platform

Posted on

Reversible Context Compaction: How to Compress Agent History Without Losing the Evidence

#ai

Context compaction is often explained as a summarization problem: when the prompt becomes too large, summarize the old messages and continue in a fresh window.

That description is adequate for a conversation. It is incomplete for an agent.

An agent trace is not only prose. It contains tool calls, tool results, approvals, files, database records, identifiers, checkpoints, and evidence that may later become important. If all of that is flattened into a paragraph, the runtime may save tokens while losing the ability to prove, inspect, or safely resume what happened.

For long-running agents, useful compaction should be reversible.

A summary is not a source of truth

Imagine an agent reviewing a large contract. A parsing tool returns 40,000 tokens of clauses, page coordinates, metadata, and extraction diagnostics. The model initially needs only the liability section, so a compactor later reduces the result to:

The contract contains a limitation-of-liability clause with several exceptions.

That sentence may be enough for the next planning step. It is not enough when the agent later needs the exact cap, the governing subsection, or the original page reference. It is also dangerous if a later model treats the summary as primary evidence.

The original tool result and the compact model view have different roles:

  • the original result is durable evidence;
  • the preview is a navigation aid;
  • the summary carries task-relevant conclusions;
  • the reference allows the agent to recover the source.

Compaction should change how information is loaded, not silently delete the only copy.

Store the original, send a bounded view

ZGI handles oversized tool results by moving the full result into an Artifact store and sending a smaller projection to the model. A conceptual receipt looks like this:

ArtifactReceipt
  reference: artifact://task/7f3a...
  media_type: application/json
  original_size: 40,812 tokens
  preview: selected high-signal fields and excerpts
  content_hash: sha256:...
  source_tool: contract_parser
Enter fullscreen mode Exit fullscreen mode

The receipt is deliberately not a replacement for the source. It tells the model what exists, where it came from, and how to request the complete content.

The content hash serves two purposes. It verifies that the recovered artifact is the same result the model saw earlier, and it allows the runtime to reuse an existing reference instead of creating a new artifact every time the source is opened.

That second property matters. Without reference reuse, an agent can accidentally create a recursive storage loop:

large result
  -> artifact A
  -> agent reloads artifact A
  -> reloaded content becomes artifact B
  -> agent reloads artifact B
  -> artifact C ...
Enter fullscreen mode Exit fullscreen mode

A stable reference turns the same flow into:

large result
  -> artifact A
  -> agent reloads artifact A
  -> runtime recognizes the content hash
  -> context returns to the same artifact A reference
Enter fullscreen mode Exit fullscreen mode

The model can inspect the full source when necessary without causing context and storage to grow recursively.

Preserve complete API rounds

Reversible evidence is only one invariant. Tool protocol integrity is another.

Most model APIs represent an agent step as a response containing one or more tool calls, followed by the corresponding tool results. These messages are structurally linked. Compaction must not select arbitrary message boundaries.

Treat the following as one complete API round:

model response
  -> tool call A
  -> tool call B
tool result A
tool result B
Enter fullscreen mode Exit fullscreen mode

The runtime may retain, summarize, or archive that round, but it should not produce an intermediate context such as:

model response
  -> tool call A
  -> tool call B
tool result A
Enter fullscreen mode Exit fullscreen mode

The missing result is not merely incomplete information. It creates an invalid execution history and may cause the next model call to fail or reason from a tool action that never appears to have completed.

The same rule applies to persistence and recovery. If an interruption leaves an incomplete tail, the runtime should restore the last complete round and represent the interrupted work as explicit task state rather than pretending the partial trace is valid history.

Compress in a controlled order

A robust compaction pipeline can be represented as a sequence of increasingly expensive interventions:

protect stable instructions and active task state

if request > working budget:
    project oversized tool results into artifact receipts

if request still > working budget:
    shrink old, already-consumed tool results

if request still > working budget:
    summarize the oldest complete API rounds

rebuild the request
validate tool-call pairing, task state, and token budget

if request > hard limit:
    run controlled recovery compaction
    validate again

if validation fails:
    checkpoint and stop with an explicit failure state
Enter fullscreen mode Exit fullscreen mode

This order avoids unnecessary semantic summarization. Raw output can often be reduced through deterministic projection alone. Semantic compaction is reserved for history whose meaning, rather than exact payload, must be carried forward.

Summaries should be written for continuation

A generic meeting-style summary is a poor handoff for an agent. The compaction prompt should produce a continuation record that preserves operational information:

  • the current objective and success criteria;
  • decisions already made and why;
  • completed actions and their outcomes;
  • unresolved questions and failed attempts;
  • pending approvals or external events;
  • references to source artifacts;
  • constraints that must remain active;
  • the most likely next step.

This is closer to a checkpoint manifest than a recap.

Anthropic’s guidance on long-horizon context similarly emphasizes preserving architectural decisions, unresolved bugs, and implementation details while removing redundant tool output. OpenAI’s native compaction retains high-value prior state for subsequent windows. The implementation details differ, but the shared goal is continuity, not merely brevity.

References:

Revalidate after compaction

Compaction output should never be accepted solely because a summarizer returned successfully. The reconstructed request needs a second validation pass.

At minimum, the runtime should verify:

  • the next request is within the working and hard budgets;
  • every visible tool call has the required result;
  • active instructions and the current user goal remain present;
  • pending approvals and workflow state are still represented;
  • artifact references resolve and match their expected hashes;
  • private runtime data has not leaked into the client-visible transcript.

If any invariant fails, the runtime needs a known recovery path. “Try the same oversized request again” is not a recovery strategy.

Keep model context separate from frontend history

One subtle design mistake is using the same message object for model input, persistence, debugging, and frontend rendering. These consumers need different views.

The model may require private tool metadata, internal references, or compressed execution state. The frontend should usually receive only user-safe messages and approved execution details. Debugging may require another privileged trace containing the final model request and the reason each compaction decision was made.

Separating these views improves both security and observability:

  • private context does not need to be exposed to the browser;
  • developers can inspect what the model actually received;
  • users can see a clean interaction history;
  • the runtime can evolve its internal representation without breaking the UI contract.

The real metric is recoverable progress

Token reduction is useful, but it is not the success condition. A successful compaction system should allow the agent to continue making correct, inspectable progress.

That means testing whether the agent can reload original evidence, preserve paired parallel tool calls, recover after summary failure, resume from checkpoints, and stop safely when valid reconstruction is impossible.

Reversible compaction turns context from a disposable prompt into a managed runtime layer. The model sees a small, relevant working set. The system keeps the complete evidence and execution state. When detail becomes important again, the agent can retrieve it rather than guess.

That is the foundation long-running agents need if they are expected to complete work rather than merely continue a conversation.

ZGI’s source is available on GitHub: github.com/zgiai/zgi

Top comments (0)