在这里插入图片描述

你用 AI 编程时有没有发现,工具输出、日志、搜索结果占了大量 token,但真正有用的信息只需要一两条?Headroom 专门解决这个问题。
读完本文你将了解:操作步骤 | 技术原理 | 架构设计 | 适用场景


🎯 这个项目解决什么问题?

上个月我在排查一个线上事故,用 Claude Code 查了一堆日志和监控数据。半天下来,问题倒是定位到了,但看看用量报告:光那次调试就烧了 65,694 个 token。不是代码对话,是把整个日志 dump 喂进了上下文。

这事儿不只发生在我身上。AI 编程助手在做代码搜索、日志排查、GitHub Issue 分析时,真正需要 LLM 理解的信息可能不到 5%,但你得把完整上下文送进去,token 费跟着一起涨。

现有方案无非两个:要么截断上下文(可能丢失关键信息),要么多花钱买更长的上下文窗口。两个都不理想。Headroom 走了第三条路:把上下文先压缩再送进 LLM,需要的时候再按需取回原文——既省了 token,又不丢信息。

具体多省?在代码搜索结果上省 92%,事故排查省 92%,Issue 分析省 73%,代码库探索省 47%。关键后续的 benchmark 测试显示准确率没有任何下降。


🔧 快速上手

安装

Python 3.10+,一条命令:

pip install "headroom-ai[all]"

最简使用:三行代码体验压缩

from headroom import compress

# 假设这是你 Agent 收到的 100 条代码搜索结果
messages = [{"role": "user", "content": "search results: ..."}]  # 实际数据可能 10000+ tokens

result = compress(messages)
print(f"压缩前: {result.original_tokens} tokens")
print(f"压缩后: {result.compressed_tokens} tokens")
print(f"节省: {result.savings_pct:.0f}%")

直接包一个 Claude Code 体验

不用改任何代码,直接包装现有的 Agent:

headroom wrap claude

这时候你的 Claude Code 就自动走 Headroom 的压缩管道了。等对话结束后查看用量:

headroom stats

启动独立代理(零代码接入)

如果你不想依赖 Python SDK,Headroom 还提供了一个 HTTP 代理模式:

headroom proxy --port 8787

然后设置 OPENAI_BASE_URL=http://localhost:8787/v1 或者配到你的 Agent 里。所有请求自动走压缩管道,不需要改任何代码。

⚠️ 注意:代理模式默认基于 /tmp/headroom/ccr 存储原文索引,重启后原文映射会清空。生产环境建议配 SQLite 或 Redis 后端(参见下文架构部分)。

作为 MCP 工具集成

如果你是 MCP 客户端用户(比如 OpenClaw、Cursor MCP),直接配:

{
  "mcpServers": {
    "headroom": {
      "command": "headroom",
      "args": ["mcp"]
    }
  }
}

之后你的 Agent 就能用 headroom_compressheadroom_retrieveheadroom_stats 三个工具,非常方便。


⚙️ 技术原理

核心机制:不是压缩,是"缓存+检索"

Headroom 的核心思路跟你想象的"压缩"可能不太一样。它不是像 gzip 那样把文本做无损压缩后再解压——那样 LLM 根本看不懂。它的策略是:把大部分内容移出上下文窗口,仅保留信息密度最高的部分,然后在 LLM 需要的时候把完整内容按需取回。

具体实现上,Headroom 分为三步流水线:

第一步,内容检测器判断输入是什么类型:日志、JSON、代码、搜索摘要、自然语言、diff。不同类型用不同策略,能更精准地识别什么该删、什么该留。

第二步,三级压缩器各司其职

  • SmartCrusher(JSON 压缩):自动识别字段的可压缩性。比如一条 JSON 日志有 30 个字段,它只保留最关键的那几个,其余用统计摘要替代(“其他字段共 27 个,值范围…”)。对错误日志特别敏感——错误关键词附近的字段自动保留,不会误删关键信息。
  • CodeCompressor(代码压缩):基于 AST 分析,删掉重复的函数签名、注释、import 语句。不碰逻辑代码。

第三步,可恢复压缩(CCR):压缩后的内容塞进本地 SQLite/Redis,LLM 注意到"这里可能不完整"时调用 headroom_retrieve 取回完整原文。这个设计是整个系统的关键假设:LLM 不需要看到所有细节,但它需要知道"哪些细节我可能缺少"并有权主动取回。

为什么选这个方案而不是更激进的方案?

如果说 Headroom 选了分层缓存架构,那是因为更激进的方案——比如直接用一个小模型做摘要——有两个致命问题:

  1. 信息保真度不可控。 用 7B 模型做摘要,50% 的案例会把警告信息压缩成"正常",这在事故排查场景中等于灾难。
  2. 延迟叠加。 摘要模型的推理时间又叠在原有 LLM 调用之上,对用户体验不友好。

Headroom 的方案更像 CDN 的缓存策略:不改变原始内容,只是在最前面的"压缩缓存层"留下索引。需要的时候,原文触手可及。这个设计的代价是存储空间(需要本地存原文),但在磁盘价格面前几乎可以忽略不计。

另一个关键设计是 CacheAligner(KV Cache 对齐器)。LLM 服务商的 KV Cache 对前缀顺序极其敏感——如果你前一个请求的前缀和当前请求的前缀不同,cache 全部 miss。Headroom 会刻意把压缩后的输出排列成固定前缀格式,让服务端的 KV Cache 命中率大幅提升。这意味着不仅省了 token,还省了推理延迟。

竞品对比

不是所有"省 token"的方案都是竞品。真正的对比维度是:要不要改变 LLM 看到的原始信息?

方案 做法 信息保真度 额外推理 恢复能力
截断上下文 丢掉超出窗口的部分 ❌ 丢信息 无法恢复
小模型摘要 跑 7B 摘要→送 LLM ⚠️ 不可控 无法恢复
LLMLingua 类 删除低重要度 token ⚠️ 语法离散 不可逆
Headroom 缓存原文+压缩索引 ✅ LLM 按需取回 完全可逆

Headroom 不走摘要路线,走的是"索引缓存+按需取回"路线。这个取舍意味着它不适用那些"LLM 必须看到每一个标点"的高精度场景(比如法律合同审阅),但对 99% 的 Agent 工作流——代码搜索、日志排查、Issue 分析——正好命中。


🏗️ 架构分析

模块划分

Headroom 的核心架构由四个 Rust crate 构成,全部用 Rust 实现(Python/TypeScript SDK 是通过 FFI 和 WASM 分别暴露的薄封装层):

┌─────────────────────────────────────────┐
│           接入层(任意语言)               │
│  Python SDK │ TypeScript SDK │ HTTP Proxy │
├─────────────────────────────────────────┤
│              headroom-proxy               │
│        HTTP 代理 + MCP 工具端点           │
├─────────────────────────────────────────┤
│              headroom-core               │
│  ┌───────────────────────────────────┐   │
│  │  ContentDetector → Pipeline       │   │
│  │  ├─ SmartCrusher (JSON)           │   │
│  │  ├─ CodeCompressor (AST)          │   │
│  │  ├─ LogCompressor                 │   │
│  │  ├─ SearchCompressor              │   │
│  │  └─ DiffCompressor                │   │
│  ├───────────────────────────────────┤   │
│  │  Relevance (BM25 / Embedding)     │   │
│  ├───────────────────────────────────┤   │
│  │  CCR Store (In-Memory / SQLite)   │   │
│  └────────────────────────────────────┘  │
├─────────────────────────────────────────┤
│           headroom-py / headroom-parity  │
│      Python 扩展模块 + 兼容测试          │
└─────────────────────────────────────────┘

三个核心角色:

  • headroom-core:一切压缩逻辑的引擎(压缩器流水线、CCR 存储、相关性评分)
  • headroom-proxy:HTTP 代理层(支持 OpenAI 兼容 API、MCP 工具端点)
  • headroom-py / SDK:Python 扩展模块和 TypeScript SDK 的绑定层

设计亮点:压缩器的流水线编排

SmartCrusher 是整个架构中最精妙的部分。它不是简单的"压缩 JSON",而是一整套可插拔的分析+压缩管道

  1. Analyzer 先对 JSON 做 schema 推断,给每个字段打分(值域、变异系数、语义类型)
  2. Classifier 基于分数决定字段级别(保真/摘要/删除/占位符)
  3. Compactor 执行压缩,生成"紧凑 JSON"+ 元数据
  4. Observer 把压缩过程和原文映射一起写入 CCR Store

这种多阶段管道让压缩决策变得透明和可控。如果你想调压缩强度,改的是配置参数而不是代码。

不够好的地方

目前 Headroom 的压缩策略选择是硬编码的——根据内容类型预设算法,不能根据用户的使用模式动态调整。比如你在做安全审计时可能需要比做代码搜索更保守的压缩设置,但目前没有这个灵活性。另外,CCR 的取回依赖 LLM 主动调用工具,如果 LLM 没意识到"这里信息不全"就不会去取——这在新模型没适配的场景下可能漏信息。


✅ 优缺点 & 适用场景

优点

  1. 省钱效果明显。 实测代码搜索结果省 92% token,事故排查省 92%。按 Claude Sonnet 的定价算,每天用 Agent 8 小时的用户,一个月能省 30-50 美元。
  2. 信息可逆。 CCR 存储让 LLM 在需要时能取回原文。不像摘要或截断方案那样丢信息。
  3. 接入方式多样。 可以包装命令行工具、启动 HTTP 代理、集成 MCP 服务,对团队内不同技术栈都能覆盖。

缺点

  1. 压缩策略不可动态调整。 在安全审计和代码搜索之间,压缩激进程度应该不同,但目前是硬编码的。
  2. 严重依赖 LLM 自己判断"该取回原文"。 如果 LLM 漏判,压缩引入的信息损失就跟摘要方案一样了。

适合谁

  • 立刻试试:每天用 Claude Code / Codex / Cursor 的重度用户。如果你在排查 bug 时经常扔大量日志进上下文,Headroom 的回本速度以天计。
  • 再等等:如果你的工作场景以精细文本生成为主(文案、翻译、法律文档),上下文中有价值信息的密度天然很高,压缩的收益不大。

竞品一句话

跟 LLMLingua 等 token 级压缩工具比,Headroom 的差异化在于:它不是压缩后扔掉原文,而是缓存+按需取回。代价是需要本地存储空间和额外的取回调用——但磁盘便宜,取回调用也比直接送原文便宜。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐