Headroom 实测:给 AI Agent 的上下文做压缩,Token 省了 90%
用 Claude Code 跑一个中型项目的代码搜索,100 条结果塞进去,17765 个 token。换成 Headroom 压一下,1408 个。同样找到了目标函数,同样给出了正确修改建议。
省了 92% 的 token,账单直接砍到零头。
问题出在哪
AI coding agent 这两年进步很快,但有个问题一直没解决好:上下文太肥了。
一次 grep 搜索返回 100 个文件片段,大部分是噪音。一次 git log 输出几千行,真正相关的就那几条。一次数据库查询返回 50 行 JSON,有用的字段可能就 3 个。
这些东西全部原样塞进 prompt,模型照单全收,按 token 计费。Claude 3.5 Sonnet 的输入价格是 3/百万token,GPT−4o是2.5/百万 token。一个 SRE 排障会话,光是日志就能吃掉 65000 个 token------还没算模型思考和回复的消耗。
之前的解决思路通常就三种:
- 截断------只取前 N 行,但关键信息可能在第 N+1 行
- 摘要------用另一个 LLM 先总结,但有 500ms 延迟,而且总结本身也是有损的
- 加大上下文窗口------Gemini 给了 100 万 token,但问题不是能不能装下,是账单受不受得了
Headroom 的思路不一样:压缩上下文,保留原件,模型觉得不够再取。
Headroom 是什么
一个开源的上下文压缩层,跑在本地,插在 agent 和 LLM 之间。GitHub 上 10k+ star,本周涨了 6000 多。
核心流程:
scss
你的 Agent(Claude Code / Cursor / Codex / 自研代码)
│
│ 工具输出、日志、文件内容、RAG 结果
▼
┌──────────────────────────────────────────┐
│ Headroom(本地运行,数据不出机器) │
│ │
│ CacheAligner → ContentRouter → 压缩器 │
│ ├─ SmartCrusher (JSON) │
│ ├─ CodeCompressor (AST) │
│ └─ Kompress-base (文本) │
│ │
│ CCR 存原件 · 跨 agent 记忆 · MCP │
└──────────────────────────────────────────┘
│
│ 压缩后的 prompt + retrieve 工具
▼
LLM 提供商(Anthropic / OpenAI / Bedrock)
三种使用方式:代理模式(headroom proxy --port 8787,零代码改动),库模式(compress(messages)),或者直接 wrap agent(headroom wrap claude)。
压缩原理拆解
Headroom 不是简单地砍字数。它有三个针对不同内容类型的压缩器,由 ContentRouter 自动分发。
SmartCrusher:处理 JSON
agent 调用工具拿到的返回通常是 JSON。一个 API 响应可能长这样:
json
[
{"id": 1, "name": "Alice", "email": "alice@example.com", "role": "admin", "created_at": "2026-01-15", "last_login": "2026-06-03", "status": "active", "department": "engineering"},
{"id": 2, "name": "Bob", "email": "bob@example.com", "role": "user", "created_at": "2026-02-20", "last_login": "2026-06-01", "status": "active", "department": "marketing"},
{"id": 3, "name": "Carol", "email": "carol@example.com", "role": "admin", "created_at": "2026-03-10", "last_login": "2026-05-28", "status": "inactive", "department": "engineering"}
]
50 条这种记录,key 名重复 50 次。SmartCrusher 检测到数组+字典结构后,把重复的 key 提出来做表头,值按行排列。类似从 JSON 转成 CSV,但更智能------嵌套对象会递归处理,混合类型也能兼容。
CodeCompressor:处理代码
用 tree-sitter 做 AST 解析,识别代码结构后,保留函数签名、类定义、关键注释,砍掉函数体里的具体实现。模型在做代码搜索时,大多数情况下只需要知道"这个函数接收什么参数、返回什么类型",不需要逐行读实现。
需要 tree-sitter 的二进制包,大概 50MB,支持 Python、JavaScript、Go、Rust、Java、C++ 六种语言。
Kompress-base:处理自然语言
这是 Headroom 自己训练的一个 HuggingFace 模型,专门针对 agent 交互场景的文本做压缩。训练数据来自大量真实的 agent trace(工具调用日志、对话历史、文档片段)。
跟通用摘要模型的区别:Kompress-base 知道哪些信息对 agent 后续决策有用。比如错误日志里的堆栈信息会保留,而重复的时间戳和进程 ID 会被压缩。
CCR:压缩可逆
这是 Headroom 最关键的设计。CCR(Compressed Context with Retrieval)不删除原始数据,而是存在本地 LRU 缓存里。压缩后的 prompt 里带着一个 headroom_retrieve 工具------如果模型发现压缩版信息不够用,可以调这个工具拿回原始内容。
作者在 Hacker News 上说过设计思路:
你没法事先知道哪些数据是模型需要的。如果模型需要更多数据,它会请求并在 1ms 内拿到。实际使用中模型几乎不需要检索,因为智能压缩已经保留了关键内容。
这个"先压后取"的策略很聪明。跟截断的区别是数据没丢,跟摘要的区别是不需要额外的 LLM 调用,跟加大上下文的区别是 token 确实省了。
实际跑一下
装起来很简单:
bash
pip install "headroom-ai[all]"
方式一:代理模式
最省事,不改现有代码。Headroom 启动一个 HTTP 代理,拦截发往 LLM 的请求,压缩 context,转发。
bash
headroom proxy --port 8787
然后把 agent 的 API endpoint 指向 http://localhost:8787。对 OpenAI 兼容的客户端都能用。
方式二:wrap 模式
一行命令包裹现有的 coding agent:
bash
headroom wrap claude # Claude Code
headroom wrap codex # Codex
headroom wrap cursor # Cursor(会打印一段配置,粘贴进去就行)
headroom wrap aider # 启动代理 + 启动 aider
方式三:库调用
Python 里直接用:
python
from headroom import compress
messages = [
{"role": "user", "content": "分析这段日志..."},
{"role": "assistant", "content": "...(长日志内容)..."}
]
compressed = compress(messages, model="claude-sonnet-4-20250514")
# compressed 可以直接传给 Anthropic SDK
TypeScript 也有对应的包:
typescript
import { compress } from 'headroom-ai';
const compressed = await compress(messages, { model: 'claude-sonnet-4-20250514' });
方式四:框架集成
跟主流框架都有现成适配:
python
# Anthropic SDK
from headroom import withHeadroom
client = withHeadroom(Anthropic())
# LangChain
from headroom.integrations import HeadroomChatModel
model = HeadroomChatModel(your_llm)
# LiteLLM
import litellm
from headroom.integrations import HeadroomCallback
litellm.callbacks = [HeadroomCallback()]
CacheAligner:被忽视的细节
除了压缩,Headroom 还做了一件事:稳定 prompt 前缀。
Anthropic 和 OpenAI 的 API 有 KV cache 机制------如果两次请求的 prompt 前缀相同,第二次可以复用缓存,速度更快、成本更低(Anthropic 的 cache hit 价格是普通输入的 10%)。
但实际使用中,agent 每次调用工具后返回的内容略有变化(时间戳不同、顺序不同),导致前缀频繁变化,cache 命中率很低。
CacheAligner 会把 prompt 中不变的部分(系统提示、历史对话)和变化的部分(工具输出)分开处理,确保不变部分的 token 序列稳定。这样 KV cache 的命中率会高很多。
这个优化是免费的,压缩的时候顺带就做了。
Benchmark 数据
官方给的测试数据(可复现,python -m headroom.evals suite --tier 1):
压缩率:
| 场景 | 原始 token | 压缩后 | 节省 |
|---|---|---|---|
| 代码搜索(100 条结果) | 17,765 | 1,408 | 92% |
| SRE 事故排查 | 65,694 | 5,118 | 92% |
| GitHub Issue 分类 | 54,174 | 14,761 | 73% |
| 代码库浏览 | 78,502 | 41,254 | 47% |
准确率影响:
| 基准测试 | 类型 | 无压缩 | 有压缩 | 差异 |
|---|---|---|---|---|
| GSM8K | 数学 | 0.870 | 0.870 | 0 |
| TruthfulQA | 事实 | 0.530 | 0.560 | +0.03 |
| SQuAD v2 | 问答 | --- | 97% | 压缩 19% |
| BFCL | 工具调用 | --- | 97% | 压缩 32% |
代码搜索和 SRE 排障的场景压缩率最高,因为这两类输出冗余特别严重------大量重复的文件路径、相似的日志格式。代码库浏览压缩率相对低,因为代码本身信息密度就比较高。
TruthfulQA 的分数反而提高了 0.03。一个可能的原因:压缩去掉了无关信息后,模型注意力分配更集中。
踩坑和局限
试用下来碰到几个问题:
1. tree-sitter 依赖比较重
CodeCompressor 依赖 tree-sitter,安装时需要编译原生模块。在 M1 Mac 上没问题,但在一些 CI 环境里可能需要手动装编译工具链。用 [ml] extra 安装 Kompress-base 模型也需要下载,首次启动会慢一些。
如果只需要 JSON 压缩和代理功能,可以用最小安装:pip install headroom-ai[proxy],跳过 tree-sitter 和模型下载。
2. CCR 缓存占内存
原始数据存在内存的 LRU 缓存里。长时间运行的 agent 会话,缓存可能会涨到几百 MB。可以通过配置限制缓存大小,但设太小了模型检索时可能找不到原文。
作者建议的做法是设置合理的 TTL(生存时间),让过期的工具输出自动清理。
3. 代码库浏览的压缩率偏低
47% 的压缩率对比其他场景差了不少。代码的信息密度高,AST 压缩只能去掉函数体,如果 agent 需要的恰好是函数实现细节,压缩反而会触发额外的 retrieve 调用。
对于需要深度阅读代码的场景(review、重构),建议关闭 CodeCompressor 或者调低压缩强度。
4. 图片压缩是新功能
官方说支持 40-90% 的图片 token 缩减,但这个功能比较新,文档还不完善。我没深入测,如果你的 agent 大量使用视觉能力,建议先在非生产环境试。
跟其他方案对比
市面上做类似事情的工具不多:
- RTK :只压缩 CLI 命令输出(
git show、ls这类),范围窄。Headroom 内部实际集成了 RTK 作为 shell 输出的预处理。 - lean-ctx:CLI + MCP 工具的上下文精简,跟 RTK 类似但覆盖面更广一点。
- Compresr / Token Co.:云端压缩 API。数据要传到第三方服务器,隐私敏感场景不适合。
- OpenAI Compaction:OpenAI 内置的对话历史压缩,只对自家 API 有效,不可逆。
Headroom 的优势在两点:全品类(JSON、代码、文本、图片都能压),可逆(原件还在)。劣势是本地部署,依赖相对重。
适合谁用
值得试的场景:
- 每天大量使用 AI coding agent,token 账单是个问题
- 同时用多个 agent(Claude Code + Cursor + Codex),需要跨 agent 共享记忆
- SRE/DevOps 场景,agent 需要处理大量日志
- RAG 应用,检索结果冗余度高
不适合的场景:
- 只用一家 provider,上下文窗口够大,不在乎成本
- 沙盒环境跑不了本地进程
- agent 调用频率低,压缩带来的收益不明显
小结
Headroom 解决的问题很实际:AI agent 的上下文太肥,浪费 token、浪费钱。三个压缩器分工处理 JSON、代码、文本,CCR 保证压缩可逆,CacheAligner 顺带优化 KV cache 命中。
从 benchmark 看,代码搜索和日志分析场景能省 90% 以上的 token,准确率几乎没损失。实际使用中,代理模式最省事,一行命令就能套到现有 agent 上。
项目地址:github.com/chopratejas/headroom,Apache 2.0 协议,PyPI 和 npm 都有包。