Hermes Wiki

RTK vs Headroom — Compression Layer Comparison

Short answer: RTK and Headroom are not competing tools. They operate at different layers, and Headroom actually bundles RTK as a dependency. Understanding where each one compresses tells you exactly when to use one, the other, or both.


1. The One-Line Mental Model for Each

Tool Mental model
RTK A transparent shell proxy — intercepts git, pytest, docker etc. and compresses their stdout before it enters the agent context
Headroom A context compression pipeline — compresses everything an agent reads: RAG chunks, JSON tool outputs, prose docs, chat history, and shell output via bundled RTK

RTK is a surgical tool. Headroom is the operating table.


2. Where Each One Compresses

Agent task
│
├── git log --stat -2         ← RTK intercepts here (shell output layer)
│     Raw: 8,388 tokens
│     RTK: 108 tokens  → 98.7% savings
│
├── git status                ← RTK intercepts here
│     Raw: 66 tokens
│     RTK: 22 tokens  → 66.7% savings
│
├── RAG retrieval (pgvector)  ← RTK does nothing here. Headroom owns this.
│     user records JSON       → SmartCrusher (deterministic, -9–40%)
│     code search results     → CodeCompressor (AST-aware, -15–50%)
│     prose doc chunks        → Kompress ML model (extractive, -40–85%)
│
├── Chat history (long sessions) ← Headroom owns this. RTK does nothing.
│
└── LLM call

RTK has zero coverage on RAG, chat history, or prose content. Headroom has zero native coverage on shell commands — it delegates those to RTK.


3. RTK's Real Strengths

3.1 Developer loop — where it matters most

RTK is purpose-built for the dev loop commands that dominate every Claude Code / Cursor / Hermes session. These are numbers from a real run against this repo:

Command Raw tokens RTK tokens Savings
git log --stat -2 8,388 108 98.7%
git branch -v 88 6 93.2%
git status 66 22 66.7%
ls -la 376 113 69.9%
git log --oneline -20 138 101 26.8%
Total 9,413 638 93.2%

When the LangGraph agent ran both modes on the same task:

  • Raw mode: 8,592 tool-output tokens fed into LLM context
  • RTK mode: 231 tool-output tokens fed into LLM context
  • 97.3% fewer context tokens. Same quality response from Qwen2.5:7b.

3.2 Zero configuration transparency

RTK's hook-based integration (rtk init -g for Claude Code) means the agent never knows RTK exists. Every git status the agent issues becomes rtk git status at the shell level — no prompt changes, no tool schema changes, no model changes.

This is the correct architecture: optimization at the harness boundary, invisible to the reasoning layer above.

3.3 Deterministic, auditable, lossless

RTK filters are hand-written per command family — not ML, not probabilistic. git log --stat output is structurally compressed; the commit hash, author, and file stats are preserved. Nothing is inferred or summarized. The full output is tee-logged locally (~/.local/share/rtk/tee/) on failure so the agent can always retrieve the raw original.

This matters for compliance contexts: deterministic output is auditable output.

3.4 Speed

RTK adds <10ms to any command. There is no ML inference overhead, no network call, no ONNX runtime. It runs in Rust and exits.


4. Where Headroom Wins

4.1 RAG and structured data (SmartCrusher)

Headroom's SmartCrusher compresses repeated-schema JSON — the kind that dominates RAG payloads (user records, search results, API responses). From the Headroom experiment in this project:

  • 10 user records × 12 fields each → shared header + compact per-record diffs
  • 343 tokens removed, 9.2% prompt reduction, zero semantic loss
  • Fully deterministic, zero semantic risk

RTK would not touch this payload at all. It only fires on Bash tool calls.

4.2 Prose content (Kompress)

Headroom ships chopratejas/kompress-v2-base — a small HuggingFace model (~180 MB, Apache 2.0) that compresses natural language via extractive sentence scoring. This is the only compressor that works on documentation chunks, chat history, and verbose log narratives.

RTK has no prose compressor. If your context is 40–60% prose, RTK leaves that entirely untouched.

The tradeoff the experiment revealed: Kompress adds ~35% inference time overhead on CPU. At <5,000 tokens, the overhead exceeds the savings. At >15,000 tokens, context pressure savings dominate. Keep kompress_model="disabled" until context pressure actually forces you to enable it.

4.3 Reversibility (CCR)

Headroom stores originals in a local CCR (Content Compression Repository) with configurable TTL. The agent can call headroom_retrieve(content_id) to pull full original content when it decides it needs more detail. This is the escape hatch that makes lossy compression safe: compress aggressively by default, retrieve only when needed.

RTK has no reversibility mechanism (beyond its tee log). It's lossless-by-design for shell output, so it doesn't need one.

4.4 CacheAligner — preserving prompt cache hits

This is an underappreciated insight in Headroom's design. Naive compression changes the prompt prefix, which breaks the provider's KV cache. Headroom's CacheAligner stabilizes compressed prefixes so Anthropic/OpenAI prompt caching still hits after compression. You save tokens and keep your cache discount.


5. RTK vs Headroom — Decision Matrix

Dimension RTK Headroom
Shell command output ✅ Native (98%+ savings on git log --stat) ✅ Via bundled RTK
JSON tool outputs / RAG chunks ❌ No coverage ✅ SmartCrusher
Source code blobs ❌ No coverage ✅ CodeCompressor (AST-aware)
Prose / chat history ❌ No coverage ✅ Kompress (ML, optional)
Compression type Deterministic, lossless Mixed — deterministic (JSON/code) + lossy ML (prose)
Reversibility ❌ (tee log for debugging only) ✅ CCR cache + headroom_retrieve
Agent integration Hook / plugin / rules file Proxy / library / MCP / agent wrapper
Overhead <10ms (Rust binary) Low (rule-based) to moderate (with ONNX Kompress)
Local-first
Install complexity brew install rtk + rtk init -g pip install headroom-ai[all]
Audit-safe ✅ (deterministic, tee log) ✅ rule-based only; ⚠️ with Kompress (non-deterministic)

RTK alone is the right choice when:

  • Your agent primarily runs shell commands (git, pytest, cargo, docker)
  • You want zero configuration, zero latency overhead, deterministic output
  • The compression layer must be auditable (compliance, regulated environments)
  • You're in a Claude Code / Cursor / Hermes session doing dev-loop work

Add Headroom when:

  • Your agent also processes RAG retrievals, JSON API outputs, or large prose chunks
  • Context window pressure is coming from content other than shell output
  • You need reversible compression (the model may need to pull back the original)
  • Session history is growing long enough to cause context pressure

Never need to choose — use both: Because Headroom bundles RTK, running headroom wrap claude gives you Headroom's full pipeline plus RTK's shell compression transparently. You're not stacking two competing tools; you're getting the complete two-layer stack.


6. RTK's Hermes Agent Plugin

Hermes is a plugin-based local agent framework. Unlike Claude Code (which uses hooks) or Cursor (which uses rules files), Hermes exposes a native plugin API. RTK ships a dedicated Hermes plugin that integrates at the plugin layer rather than at the shell hook layer.

How to install

rtk init --agent hermes

This places:

  • Plugin manifest and runtime files under ~/.hermes/plugins/rtk-rewrite/
  • Source in RTK's own hooks/hermes/ directory

How it works

When Hermes issues a terminal command, the rtk-rewrite plugin intercepts it via Hermes's plugin API and calls rtk rewrite before the command executes. The agent sees the compressed output as if it were the native response — same as the Claude Code hook path, just via the plugin API instead of a PreToolUse hook.

Hermes agent → issues terminal command
                     ↓
          rtk-rewrite plugin intercepts
                     ↓
          rtk rewrite <command> runs
                     ↓
     compressed output returned to Hermes
                     ↓
     Hermes sees 231 tokens instead of 8,592

Why the plugin path matters vs the hook path

For Claude Code, RTK sits at the PreToolUse hook level — it rewrites the command string before execution. For Hermes, there's no equivalent hook; the plugin API is the right integration point and gives full parity.

The practical difference: if Hermes evolves its plugin API (as it likely will), RTK's plugin will evolve with it. The Claude Code hook path is static — it just rewrites a command string.

Practical value for a Hermes-based ambient agent

If Hermes becomes your always-on ambient layer (running on a VPS, issuing git/docker/kubectl commands as part of background workflows), the RTK plugin pays off more than it does in interactive sessions — because background agents issue commands without the human in the loop to notice runaway context consumption. RTK becomes a cost control mechanism, not just a UX optimization.

From the experiment: running git log --stat -2 raw consumed 8,388 tokens. In a background agent that checks repo state hourly, that's 200K tokens/day from one command alone. With RTK: 2,592 tokens/day. At Sonnet 4.6 input pricing, that difference compounds quickly over weeks.

Current limitation

The Hermes plugin fires on terminal commands issued through Hermes's plugin API. Commands issued via Hermes's Read, Glob, or native file-read tools bypass it — same constraint as the Claude Code hook (Bash-only interception). Design Hermes workflows to route dev-loop commands through the terminal tool rather than native file tools to maximize coverage.


7. The Stack Recommendation

For a Claude Code / Cursor session (dev loop work):
  RTK alone — install in 2 minutes, zero friction, 93%+ savings on shell output.

For a RAG-heavy agent or long-session agent:
  RTK + Headroom — run headroom wrap, which brings RTK with it.
  SmartCrusher handles JSON, RTK handles shell, Kompress handles prose when you need it.

For a Hermes ambient agent on a VPS:
  RTK Hermes plugin — install with rtk init --agent hermes.
  Add Headroom proxy if the agent also reads documents or long context.

For compliance / audit environments:
  RTK (deterministic) + Headroom rule-based only (kompress_model="disabled").
  Both layers together, neither introduces non-determinism.

8. Real Numbers from This Project

RTK benchmark (this repo, LangGraph + Qwen2.5:7b):

git log --stat -2    8,388 raw → 108 RTK   (98.7% savings)
git branch -v           88 raw →   6 RTK   (93.2% savings)
git status              66 raw →  22 RTK   (66.7% savings)
ls -la                 376 raw → 113 RTK   (69.9% savings)
──────────────────────────────────────────────────────────
Agent session:       8,592 raw → 231 RTK   (97.3% savings)

Headroom experiment (local_first_compression_layer project):

Rule-based only (SmartCrusher):
  3,496 tokens → 3,174 tokens  (9.2% reduction, -4.4% inference time)
  Transforms: router:tool_result:smart_crusher

With Kompress ML model:
  3,496 tokens → 2,600 tokens  (25.6% reduction, +35% inference time on CPU)
  Break-even: ~5,000–15,000 tokens depending on hardware

The numbers sit in different categories because RTK compresses a fundamentally more compressible content type (structured shell output with known schemas) while Headroom's SmartCrusher ran on a more modestly-redundant JSON payload. Neither benchmark is inflated — they reflect different real workloads.


Filed under: Dev Tools · Context Engineering · Harness Layer · Hermes Plugin

Hermes Wiki