Headroom:给 Coding Agent 装个“省 Token 阀门”
你有没有遇过这种场面:
让 Agent 跑一次测试,它把几千行日志原封不动塞回上下文;让它查个接口,返回一大坨 JSON;让它读构建输出,满屏都是重复进度条和无关警告。
模型还没开始思考,钱包已经先冒烟了。更烦的是,上下文被垃圾信息挤满后,真正关键的报错反而容易被忽略。
Headroom 干的事很直接:在工具输出进入 LLM 之前,先压缩一遍。
它面向命令行输出、日志、文件内容、JSON,以及 RAG 检索出的文本块。项目提供了库、代理和 MCP Server 等接入方式,适合放进 Coding Agent 的工具链里。
先搞懂:它压缩的不是“信息”,是噪声
很多人一听“压缩”,会担心模型拿不到细节,修 Bug 时瞎猜。
Headroom 的思路不是粗暴截断,而是尽量保留对任务有用的结构:
- 报错类型、报错位置、调用栈重点
- 文件路径、行号、命令执行状态
- JSON 里的字段名、关键值和异常字段
- 重复日志中的变化部分
- RAG 文本里的核心事实和关联上下文
被优先清理的,通常是这些东西:
- 一模一样地重复几百次的日志
- 无意义的空行、颜色控制符、进度条
- 冗长的依赖安装过程
- JSON 里大量重复的对象结构
- 对当前问题毫无帮助的成功信息
GitHub 项目给出的数据很诱人:用于 Coding Agent 时,Token 消耗可减少约 20%;面对 JSON,压缩幅度可达到 60%~95%,同时尽量维持回答质量。
别把这个数字当成固定收益。你的项目日志越脏、接口返回越肥,省下来的越多。
最适合接入的 4 个场景
1. Agent 反复跑测试
比如你让 Agent 修一个单测:
npm test -- --runInBand
测试框架可能输出几百行内容。其中真正有价值的,往往只有:
FAIL src/utils/date.test.ts
Expected: 2025-01-01
Received: 2024-12-31
at src/utils/date.ts:42
剩下那些通过的用例、耗时统计、彩色符号、重复堆栈,对模型帮助很小。
把测试输出经 Headroom 处理后再交给 Agent,它更容易盯住失败点,不会在日志海里游到缺氧。
2. 工具调用返回巨型 JSON
这类情况太常见了:
- GitHub API 返回几百条 issue
- 数据库查询吐出几十列、上千行记录
- OpenAPI 接口带着层层嵌套的响应
- 浏览器自动化工具返回整页 DOM 或网络请求
假设你的工具返回:
{
"status": 200,
"data": [
{ "id": 1, "name": "...", "metadata": { "...": "..." } }
]
}
Agent 真正要找的也许只是:哪个 id 状态异常、哪条记录缺字段、某个接口为何返回空数组。
这时候把完整响应直接喂进去,属于拿 Token 做慈善。压缩层能保留结构和异常值,减少重复对象带来的浪费。
3. MCP 工具太“能说”
MCP 让 Agent 能调用数据库、浏览器、代码仓库、内部 API。问题也很明显:每个工具都可能是 Token 吞金兽。
尤其是查询类工具。一句“帮我列出最近 100 个 PR”,可能换来几十 KB 的字段和评论。
Headroom 提供 MCP Server 形态,适合放在工具与模型之间。你的 Agent 还是照常调用工具,只是收到的内容更干净。
4. RAG 检索片段塞得太满
RAG 最经典的坏味道是:检索召回了 20 段文档,全塞进 Prompt,结果模型看到了很多相似定义,却没看到真正的操作步骤。
可以把链路改成:
检索文档 → Headroom 压缩与去重 → LLM 回答
目标不是把文档压成一句废话,而是减少重复段落、样板声明和无关上下文,把模型的注意力留给答案本身。
怎么接入:按你的工具链选路
Headroom 提供三种常见形态。别一上来就大改架构,挑最顺手的一种试。
| 你的情况 | 建议方式 | 适合谁 | | --- | --- | --- | | 正在写 Python / TypeScript Agent | 用 Library | 能控制工具调用代码的人 | | 已有一堆 API 或 Agent,不想逐个修改 | 用 Proxy | 想低成本接入旧系统的人 | | Agent 基于 MCP 协议 | 用 MCP Server | Claude Code、Cursor 或自建 MCP 工具链用户 |
方案 A:在代码里包住工具输出
核心动作就一句:工具结果返回给模型前,先走压缩函数。
伪代码长这样:
raw_output = run_command("pytest -q")
compressed_output = compress(raw_output)
agent.send_tool_result(compressed_output)
真实项目里,建议优先包这几类工具:
shell:执行命令、跑测试、构建项目read_file:读取大文件、锁文件、配置文件http_request:请求第三方 APIdatabase_query:查询记录或执行分析 SQLsearch_docs:返回 RAG 文档片段
安装命令、环境变量和具体 API 以 Headroom 官方仓库说明为准。项目迭代快,照着旧博客复制命令,踩坑概率很高。
方案 B:把它放到代理层
如果你手里已经有一个成熟 Agent,工具调用散落在几十个模块里,挨个改很痛苦。
代理模式更省事:
Agent → Headroom Proxy → 原来的工具 / API → Headroom Proxy → Agent
你要重点确认两件事:
- 代理只压缩“回传给模型”的内容,别误伤业务系统原始数据。
- 敏感数据的脱敏规则要在压缩前处理。压缩不是安全产品,别指望它替你遮住密钥和用户隐私。
方案 C:给 MCP 工具链加压缩层
MCP 场景里,最实用的策略是按工具类型分级:
- 高压缩:日志、搜索结果、列表查询、构建输出
- 中压缩:JSON API 返回、目录树、数据库结果
- 低压缩或不压缩:代码补丁、SQL 写操作确认、密钥配置、精确配置文件
原因很简单。日志允许折叠,补丁内容却需要字符级准确。你把 diff 压得面目全非,Agent 很可能给你一份“看起来能用、实际编译不过”的修改方案。那就尴尬了。
一套能直接照抄的落地顺序
别把所有输出一股脑压缩。用下面这套小步试跑的方式,比较稳。
1. 找出最烧 Token 的工具
连续记录几天工具输出,重点看:
- 单次输出超过 5,000 字符的工具
- 同类输出频繁重复的工具
- Agent 调用后很少引用具体内容的工具
- 一跑就带来上下文暴涨的命令
通常,git diff、测试日志、构建日志、搜索结果和 API 响应会排在前面。
2. 只压缩一个场景
建议从测试日志开刀。
原因很朴素:测试日志噪声多,失败信息又相对集中。就算压缩效果不理想,也容易人工核对。
记录压缩前后的三项数据:
- 原始 Token 数
- 压缩后 Token 数
- Agent 是否仍能定位并修复问题
别只盯着省了多少 Token。模型答错了,省下来的钱可能还不够你排查半小时。
3. 给关键任务保留“查看原文”通道
压缩结果应该是默认入口,不是唯一入口。
给 Agent 留一个明确工具,比如:
get_raw_output(task_id)
当压缩内容不足以判断时,Agent 可以主动拉取原始片段或指定范围的内容。
这个兜底很关键。尤其在排查复杂构建错误、解析嵌套 JSON、处理安全告警时,原始上下文有时就是证据链。
4. 给不同内容配置不同规则
别拿同一把尺子量日志、代码和 JSON。
可以按下面的逻辑配置:
| 内容类型 | 压缩重点 | 风险点 | | --- | --- | --- | | 测试日志 | 去重、聚焦失败用例 | 丢掉关键堆栈 | | 构建日志 | 保留 error、warning、文件位置 | 忽略前置依赖错误 | | JSON | 合并重复结构、突出异常值 | 丢失关联字段 | | RAG 片段 | 去重、提取操作信息 | 断开上下文关系 | | 代码 Diff | 谨慎处理 | 改坏精确内容 |
避坑清单:别为了省 Token 把 Agent 省傻了
不要压缩写操作的确认信息
像删除数据库、发布生产环境、修改权限这类动作,确认信息要完整、明确、可审计。
这点 Token,别省。
不要把压缩结果当成原始事实
压缩输出适合帮助模型理解和决策。涉及审计、合规、故障复盘时,原始日志和原始响应仍要保存。
不要忽略压缩失败
任何中间层都可能报错。给系统设好降级逻辑:压缩服务不可用时,原样返回内容,别让整个 Agent 卡死。
压缩成功 → 返回压缩内容
压缩失败 → 标记异常并返回原始内容
不要一开始就追求极限压缩率
把 10 万 Token 压到 1 万 Token 很爽。可如果模型因此漏掉一行关键参数,后面多跑十轮工具调用,账单照样涨。
你要盯的是完成任务所需的总 Token,不是单次输出看起来有多瘦。
什么时候值得上 Headroom?
符合下面任意两条,就值得试:
- 你每天都在用 Claude Code、Cursor 或自建 Agent 跑项目
- 工具输出经常占满上下文窗口
- API 返回和数据库查询很大
- RAG 文档重复率高,模型回答却不稳定
- 团队开始关心 Agent 的调用成本
- 你经常看到 Agent 对着几千行日志“沉思”,然后给出一句没用的建议
Headroom 不会替你写好 Agent,也不会自动让模型变聪明。
它做的是一件基础但很值钱的事:别把模型的注意力和预算,浪费在重复、冗长、无关的工具输出上。
把最吵的那条日志链路接进去,跑一周,拿真实数据说话。省下来的 Token,往往比你精修半天提示词更实在。