
你给 agent 装了一个 token 压缩插件。跑完一个三十分钟的会话,敲 rtk gain,仪表盘显示省了 11.8 万 token 里的八成。月底打开 API 账单,降幅不到三成。
这个落差不是工具在骗人。它量的是 bash 输出的体积,你关心的是钱的数目,中间隔了三层折算。今天 GitHub 趋势榜上省钱类工具又一次挤进前面(rtk 已经 8.2 万 star,context-mode 单日涨 246),值得把这笔账拆开算一遍。
一、这类工具改的是哪一层
同样是"省 token",rtk 和 context-mode 动的不是同一个位置。
rtk 是命令出口的文本改写器。它挂 PreToolUse hook,把 git status 改写成 rtk git status,在 shell 和模型之间插一层过滤器。四种手法:滤掉注释与空白的噪音、把同类条目聚合(错误按类型分组、文件按目录分组)、截断冗余上下文、把重复日志行折叠成带计数的单行。具体到命令各有定制:cargo test 只留失败用例,通过的折成一个数字;git log 只留 hash、作者、标题;ruff check 按规则和文件分组。单 Rust 二进制,覆盖 100 多个命令,自身开销低于 10 毫秒。
context-mode 走另一条路:把原始输出整体挪出上下文。命令在沙箱子进程里跑,原始字节进本地 SQLite 的 FTS5 表,模型看到的是摘要,需要细节时靠 BM25 检索回查。它给的例子是 315KB 的原始输出最终只占 5.4KB。
这个区别决定了失效方式。rtk 折掉的信息永久留在上下文里,你没看见就是没了。context-mode 的信息还在本地,丢的是"模型有没有想起来去搜一下"。
二、三个稀释点,为什么 90% 不是 90%
第一层稀释,rtk 自己在 README 里写清楚了:它压的是 bash 输出,而 bash 输出只是输入 token 的一个来源,旁边还站着你的提示词、系统提示和对话历史。输入 token 又只是账单的一部分,账单里还有输出 token。体积的降幅每走一步就摊薄一次。
第二层是对数字的精度。rtk 不加 tokenizer,报告的 token 数按 bytes / 4 估算,所以它只说百分比可信,绝对数值是近似值。更值得留意的是 rtk gain 仪表盘里那个美元数字,官方说明写的是"由估算的已省 token 乘以一个固定内部常数得出"。那是内部常数换算出来的展示值,不是你账单上的任何一行。
第三层藏在单价结构里。命中缓存的输入 token 和未命中的输入 token,单价能差一个数量级。压掉一段每轮都要重发、且每轮都不同的大块输出,省下来的是全价的部分;压掉的如果是本来稳定复用、一直在缓存里的内容,省的就是折扣价,两者的钱包效果差很远。rtk 专门解释过它不破坏 prompt cache,理由是过滤只在命令执行那一次发生,结果进历史后照常被缓存,输出更小反而让缓存读写更便宜。这条辩解成立,也顺手说明了第三层稀释的存在:同样一兆字节,落在缓存里和落在缓存外,不是一个价钱。
三个稀释点合起来是一件事:能压缩的是输出体积,账单由单价结构决定,中间没有恒等关系。
三、供应商给的对照数据,要看哪一列
context-mode 的官网放了一组 168 对的对照实验:同一批任务分别直连 Anthropic 和走插件,Claude Opus 5.5,按 API 标价计算。挑几行看:
| 任务类型 | 直连 | 走插件 | 降幅 |
|---|---|---|---|
| 长 agentic 编码会话(1M 窗口) | $7.20 | $2.49 | 65.5% |
| minitest 修错循环 | $0.157 | $0.061 | 61% |
| 小改动 npm test 修错循环 | $0.087 | $0.068 | 22% |
| 一次性大日志处理 | $0.091 | $0.071 | 22% |
| 跨 150 文件 grep | $0.093 | $0.066 | 29% |
| 大文档交给脚本处理 | $0.223 | $0.201 | 10% |
总计 168 组里 155 组更便宜,任务成功率两边都是 168/168。厂商自己发布的数字当然要打折看。打折之后这张表依然有用,因为表里最有价值的一列是降幅的分布,而不是首页上那个 98%。
分布很规律:任务越大、会话越长、工具输出占比越高,降幅越大;小任务和一次性任务基本在 10% 到 30% 之间。这不是测试噪音,规律来自这类工具的收益机制。它省的是"每轮重新上传的重复字节",会话轮次越多、重复次数越多,杠杆越长。所以评估顺序应该反过来:先量自己一次任务里工具输出占输入 token 的比重,比重低于 15% 的话,装这类插件基本白忙。另外 context-mode 那张表底下写了一句"Codex 还没有数字",用户的工具链如果不是 Claude Code,参照系还得自己搭。
四、省钱的另一面,四个会翻车的地方
hook 覆盖率决定成败。 rtk 的 hook 只对 Bash 工具调用生效,Claude Code 内置的 Read、Grep、Glob 不经过它,agent 只要改用内置工具读文件,压缩就整条绕过去了。context-mode 把代价量化得更直白:没有 hooks 时只靠指令文件的遵循率大约 60%,装上 hooks 才到 98%,而一次没被接管的 Playwright 快照就是 56KB,足以把一整轮的节省抹平。这类工具的收益更像乘法,一个漏点就能把结果归零,所以覆盖率比百分比重要。
折叠规则比压缩率重要。 context-mode 的卖点之一是"错误保持完整,其余归档可回查",这条规则才是让折叠变安全的东西。反过来说,哪家工具的规则是"太长就截断",你会在最需要细节的那次调试里丢掉细节。挑工具先看这条规则怎么写。
数据挪出去以后,模型只能靠检索。 检索不到等于这件事没发生过,而 BM25 是词面匹配加词干还原,不是语义检索。上下文压缩得越狠,设计对"检索能不能命中"的依赖就越重。压缩本身没错,但压得越狠,检索质量就越关键。
沙箱会改变 agent 的行为边界。 context-mode 在 PreToolUse 直接拦掉 curl、wget、内联 HTTP 和 rm -rf,从子进程里剥掉 60 多个环境变量。出于安全这是对的,代价是 agent 能做的事变少了。上线前先跑一遍自己的流程,确认没有哪一步依赖被拦掉的命令。
五、自己算这笔账的四步
第一步,先量会话构成。 把 agent 的会话记录导出来,统计工具输出在输入 token 里占了多少。不用装插件,一段脚本就够:
import json, glob
total, tool_out = 0, 0
for path in glob.glob("~/.claude/projects/**/*.jsonl", recursive=True):
for line in open(path):
try:
rec = json.loads(line)
except ValueError:
continue
msg = rec.get("message") or {}
content = msg.get("content")
if not isinstance(content, list):
continue
for block in content:
if not isinstance(block, dict):
continue
text = block.get("text") or ""
chars = len(str(block.get("content", ""))) + len(text)
if block.get("type") == "tool_result":
tool_out += chars
total += chars
print(path, "tool output share:", round(tool_out / max(total, 1), 3))
数字在 15% 以下,先别装工具,去优化提示词和历史管理。数字在 40% 以上,这类工具能立刻见效。
第二步,用账单做 A/B,别用仪表盘。 同一批任务跑两遍,一次直连一次走工具,然后打开 API 用量页,看输入、输出、缓存读、缓存写四项各自的量。只有这四项乘上单价才是钱。
第三步,按性价比排优化点。 收益最大的是每轮都重发、每轮都不一样的那些大块:完整测试日志、全量 diff、页面快照、成批的 JSON。这几类的压缩回报是两位数百分比起。命令级的微调(git push 输出从十行变成一行)属于锦上添花,单轮省几百 token,靠会话长度堆量。
第四步,往上再走一层:让模型少读。 要统计 47 个文件的行数,读 47 次是 700KB 进上下文,写一个脚本循环一遍只回 3.6KB,差两个数量级。这一步不需要任何插件,只需要把"让模型当数据处理机"改成"让模型写代码"。context-mode 把它写成了硬规则,这是它文档里我觉得最值得抄的一条。
结语
仪表盘上的百分比是制造商的指标,账单才是你的指标。省 token 的工具值得用,但顺序不能颠倒:先量清楚自己的会话贵在哪一层,再决定拦截的粒度,百分比放在最后看。
从 90% 的宣称落到 10% 到 65% 的真实降幅,中间那部分差额不是骗局,是三层折算加上任务形态的差异。看懂折算关系,就不会在月底对着账单怀疑自己装错了东西。
参考来源
- rtk-ai/rtk — 命令输出压缩,含 How Savings Work、prompt cache 说明与许可边界
- rtk-ai/rtk: How RTK Savings Work
—
rtk gain仪表盘与美元估算口径 - mksglu/context-mode — MCP 沙箱折叠方案、FTS5 索引与 hook 覆盖率数据
- Context Mode: Context Saving — 168 组成本对照实验与分任务类型降幅