如何用 5 个工具 + 自定义 Hooks 把 Claude Code Token 消耗砍掉 90%+
我们在实际开发过程中经常会发现Claude Pro套餐几个来回额度就见底,活还没干完;随手发一句 test,背后可能已经滚掉几百 token;一次代码检索直接冲到 400K token,会话二十分钟就烧完
我们在实际开发过程中经常会发现Claude Pro套餐几个来回额度就见底,活还没干完;随手发一句 test,背后可能已经滚掉几百 token;一次代码检索直接冲到 400K token,会话二十分钟就烧完。你以为是在写代码,实际上token都消耗在看不见的地方了。
所以省 token 不能只靠“少说两句”或者“换个便宜模型”。真正要做的是把整条链路拆开:代码检索先走 CBM,长输出先进 context-mode,Shell 原始结果先交给 RTK 压缩,再由 Headroom 做全量压缩,最后用 Caveman 限制 Claude 废话输出。
这套方案的核心很简单:不要指望模型自觉,要把省 token 变成默认执行。
处理路径
你的 Prompt
│
▼
Layer 1: CBM(知识图谱查代码) ← cbm-code-discovery-gate 封 Read/Grep
│
▼
Layer 2: context-mode(大输出沙箱) ← PreToolUse hook 导流到 ctx_batch_execute
│
▼
Layer 3: RTK(Shell 输出原地压缩) ← bash-ban-raw-tools 封 cat/grep
│
▼
Layer 4: Headroom(出机器前全量压缩) ← shell wrapper 拦截 claude 二进制
│
▼
Layer 5: Caveman(Claude 自己少说话) ← 插件自动激活,无需额外 hook
│
▼
Anthropic API

可以把它理解成五道闸门。每一层只处理自己那一段的消耗,不指望一个工具包解决所有问题。

第一层:CBM + cbm-code-discovery-gate
工具:Codebase Memory MCP
仓库:github.com/DeusData/codebase-memory-mcp

CBM 用 tree-sitter AST 把代码库解析成持久化知识图谱,支持 66 种语言。查函数定义、调用链、模块关系时,Claude 可以直接问图,而不是把几十个文件塞进上下文。
原文里的数字很夸张,但也说明问题:5 次结构查询,CBM 大约用了 3,400 token;逐文件 grep 大约 412,000 token。差距是 99.2%。
门禁:cbm-code-discovery-gate
这里靠两个 Hook 搭一个很小的状态机。
PreToolUse hook(cbm-code-discovery-gate)做三件事:
第一次看到 Grep / Glob / Read / Search,直接 exit 2 拦掉,并提示先用 CBM。
同时写一个 /tmp/cbm-code-discovery-gate-$PPID 标记,说明已经提醒过。
后续再遇到文件搜索,先看 /tmp/cbm-mcp-used-$PPID 是否存在。存在就放行;不存在但已经拦过一次,也放行,避免死循环。
PostToolUse hook(cbm-mcp-marker)负责补第二个标记。只要调用过 mcp__codebase-memory-mcp__*,就 touch /tmp/cbm-mcp-used-$PPID。
SessionStart hook(cbm-session-reminder)在 startup / resume / clear / compact 时重新注入 CBM 使用规则。长会话跑着跑着,Claude 很容易忘掉前面的约束,这一步就是给它补一遍记忆。
这层的重点很简单:只写“建议使用 CBM”没用。Claude 总会滑回 Read 和 Grep。要省 token,就得把捷径堵上。

第二层:context-mode + PreToolUse 导流
工具:context-mode
仓库:github.com/mksglu/context-mode

context-mode 处理大输出。它让命令在沙箱子进程里跑,完整输出留在本地并建 BM25 索引,进对话窗口的只有摘要。之后需要细节,再用搜索把相关片段捞出来。
原文给的效果是:同样 200K 上下文窗口,会话从大约 30 分钟延到 3 小时以上。
常用工具:
门禁:PreToolUse Hook 导流
安装分两步:
claude plugin marketplace add mksglu/context-mode
npm install -g context-mode
插件和 npm 包都要有。插件让 Claude Code 认识它,npm 包给 Hook 调 CLI。
Hook 挂在 PreToolUse、PostToolUse、PreCompact、SessionStart 上,统一调用:
context-mode hook claude-code
测试命令值得单独管。npm test、pytest、go test ./… 这类命令一跑就是几千行输出。可以加一个非阻塞 PreToolUse hook:不强拦,只提醒 Claude 改用 ctx_batch_execute。测试日志不应该直接灌进上下文。
第三层:RTK + bash-ban-raw-tools
工具:RTK(Rust Token Killer)
仓库:github.com/rtk-ai/rtk

RTK 是一个 Rust 二进制文件,专门压 CLI 输出。它会删样板、合并重复内容、截断长输出、去重。开销小于 10ms,不联网。
它和 context-mode 的分工不一样:context-mode 管大输出,尤其是 20 行以上的测试和构建日志;RTK 负责中小型 shell 输出,比如 git status、npm install、短测试结果。
RTK 随 Headroom 捆绑安装,一般不用单独配。
门禁:bash-ban-raw-tools
这里要防的是 Bash 绕路。
Claude 可以不用 Read / Grep,直接跑:
cat file.py
grep "pattern" src/
| 命令 | 用途 |
|---|---|
/caveman:compress |
把 CLAUDE.md 和 memory 文件永久压成 caveman 格式 |
/caveman:caveman-commit |
压缩 commit message,标题不超过 50 字符 |
/caveman:caveman-review |
压缩 review 意见,每行只写位置、问题、修法 |
/caveman-help |
查看模式和命令 |
这样原始输出会绕过前面的压缩策略。bash-ban-raw-tools 就是专门堵这条路的 Bash PreToolUse hook。
它会拦:
cat、head、tail、find、grep、rg、wc 这类裸命令
没走 RTK wrapper 的命令
| head / | tail 这种看起来在截断、实际上已经把大量输出推到工具层的管道
也要留逃生门。真需要原始输出时,可以临时解锁:
touch /tmp/bash-raw-unlock-$PPID # 当前会话放行
touch /tmp/bash-raw-unlock # 全机放行
指标 |
原始状态 |
加工具 + Hook 后 |
怎么理解 |
|---|---|---|---|
会话时长(200K 窗口) |
~30 分钟 |
3+ 小时 |
约 6 倍以上,不是 token 降幅 |
单次代码探索 token |
~400K |
~3.4K |
约 99.2% 降幅,主要来自 CBM 替代逐文件读取 |
autocompact 触发时上下文占用 |
100% |
~70%(很少撞顶) |
说明窗口压力下降,但依赖任务类型 |
Shell 输出进入上下文的比例 |
100% |
10-40% |
剩余比例,不是总账单比例 |
API payload |
100% |
8-53% |
Headroom 报告的请求载荷压缩范围 |
Claude 回复冗长度 |
100% |
25-50% |
Caveman 压的是回复风格,不是推理成本本身 |
两个标记 10 分钟后过期。
第四层:Headroom + shell wrapper
工具:Headroom
仓库:github.com/chopratejas/headroom
前面三层都在控制“什么进入上下文”。Headroom 管的是另一件事:请求离开本机、发给 Anthropic API 之前,把整个 prompt 再压一遍。
它压的不只是工具输出,还包括对话历史、系统提示、CLAUDE.md、规则文件等。很多 token 就藏在这些地方,普通工具碰不到。
它主要由四块组成:
门禁:shell wrapper
Headroom 的 install.sh 会在 shell 配置里注入一个 claude 函数。
bash / zsh:
headroom wrap claude -- "$@"
fish:
headroom wrap claude -- $argv
这里的 – 不能省。后面的 –resume、-p “query” 等参数要靠它正确穿透。
这个 wrapper 会启动本地代理、设置 ANTHROPIC_BASE_URL,再拉起 Claude。RTK 也内嵌在 Headroom 二进制里,安装 Headroom 后会自动注册为内部 CLI 代理。
| 组件 | 作用 |
|---|---|
| CodeCompressor | AST 感知代码压缩,支持 Python / JS / Go / Rust / Java / C++ |
| SmartCrusher | 压 JSON 数组和对象 |
| Kompress-base | HuggingFace ML 模型,用 agentic traces 训练 |
| CacheAligner | 稳定 prompt 前缀,提高 KV cache 命中率 |
第五层:Caveman + 插件自激活
工具:Caveman
仓库:github.com/JuliusBrussee/caveman
还有一种浪费经常被忽略:Claude 自己太啰嗦。
Caveman 把 Claude 的回复压成“寄存器模式”。客套话、铺垫、重复解释都砍掉,技术信息保留。
压缩前:
“Sure! I’d be happy to help you with that. The issue you’re experiencing is likely caused by a race condition in the authentication middleware where the token expiry check uses a strict less-than comparison instead of less-than-or-equal.”
压缩后:
“Bug in auth middleware. Token expiry check use < not <=. Fix:”
常用命令:
强度有三档:lite、full、ultra。默认是 full。
门禁:插件自激活
Caveman 不需要手写 Hook。装成 Claude Code 插件后,它会在 SessionStart 和 UserPromptSubmit 上自动注册。
"enabledPlugins": {
"caveman@caveman": {},
"context-mode@context-mode": {}
}
| 变量 | 值 | 含义 |
|---|---|---|
CLAUDE_AUTOCOMPACT_PCT_OVERRIDE |
50 | 上下文窗口用到 50% 就触发压缩,别等默认 95% 才救火 |
CLAUDE_CODE_SUBAGENT_MODEL |
sonnet-4-6 | 子 agent 用 Sonnet 4.6,比 Opus 便宜 |
ENABLE_PROMPT_CACHING_1H |
1 | 把提示缓存 TTL 从 5 分钟拉到 1 小时 |
装好就生效。它自己就是门禁。
| Hook | 事件 | 用途 |
|---|---|---|
flutter-ctx-redirect |
PreToolUse Bash | Flutter / Dart 输出走 context-mode |
memory-repo-symlink |
SessionStart | 把 agent memory 限定到当前项目 |
sync-copilot-on-edit |
PostToolUse Edit | 把 slash command 镜像到 VS Code Copilot |
sync-runner-tools-on-edit |
PostToolUse Edit | 编辑后重写 e2e runner 工具白名单,顺手绕过子 agent MCP 继承 bug #30280 |
完整 settings.json 怎么看
五层工具最后会落到同一份配置里。
环境变量
"env": {
"CLAUDE_AUTOCOMPACT_PCT_OVERRIDE": "50",
"CLAUDE_CODE_SUBAGENT_MODEL": "claude-sonnet-4-6",
"ENABLE_PROMPT_CACHING_1H": "1"
}
模型与推理
"model": "claude-opus-4-7",
"effortLevel": "xhigh",
"advisorModel": "opus"
| 工具 | 用途 |
|---|---|
ctx_batch_execute |
一次跑多条命令,索引全部输出,并支持多查询搜索 |
ctx_search |
搜索当前会话已经索引的内容 |
ctx_execute / ctx_execute_file |
在沙箱里跑代码,只把摘要送进上下文 |
ctx_fetch_and_index |
抓 URL、建索引,返回约 3KB 预览 |
ctx_stats |
查看本轮会话省了多少 token |
effortLevel: xhigh 保留强推理;advisorModel: opus 让 advisor 走更强的模型。
插件
"enabledPlugins": {
"caveman@caveman": {}
}
Hook 路由表
PreToolUse:
Bash → context-mode + bash-ban-raw-tools + flutter-ctx-redirect + rtk
Grep|Glob|Read|Search → cbm-code-discovery-gate
PostToolUse:
所有工具 → context-mode
MCP 调用 → cbm-mcp-marker
Edit|Write|MultiEdit → sync-copilot-on-edit + sync-runner-tools-on-edit
PreCompact:
context-mode
SessionStart:
context-mode + memory-repo-symlink + cbm-session-reminder
CLAUDE.md 该写什么
CLAUDE.md 只写 Claude 在会话里能看到、能执行的规则。Headroom 和 RTK 在会话外运行,Claude 不知道它们存在,写进去也没意义。
建议保留这些内容:
基本原则:DRY / KISS / YAGNI / SSOT。先读代码再动手。破坏性操作先问。
实现流程:索引 → Skill gate → 澄清 → CBM 探索 → 方案 → 是否委派 → Ripple → TDD → 验证 → Advisor。
Ripple 检查:增删改前用 trace_path 查调用点,不要相信“只在这里用到”。
工具速查:查定义用 search_graph,查调用链用 trace_path,跑代码用 ctx_execute,抓网页用 ctx_fetch_and_index。
封禁列表:不要用 cat / head / tail / grep / find 读文件。走 Read / Grep / Glob,并接受门禁控制。
子 agent 策略:研究、多文件重构、审计、多文件影响分析时委派;并行上限 3。
回复风格:先给答案,少铺垫,少总结。
按语言拆规则文件
~/.claude/rules/ 可以按技术栈拆文件,再通过 @ import 加载。一个文件只管一个栈,维护起来更轻。
每个规则文件的结构可以固定成两段:先加载对应 skill,再列容易踩的坑。
Flutter 示例:
加载 building-flutter-apps skill
notifier 里每个 await 之后都检查 if (!ref.mounted) return;
不写 _buildXxx(),拆成独立 Widget
React / Next 示例:
加载 vercel-react-best-practices skill
Server Components 默认,只有交互处写 “use client”
重计算用 useMemo
不用 enum,改用 as const 对象
其他好用的 Hook
最后的效果展示
数字因统计口径的不同仅供参考。
这套方案的核心是分层堵漏——CBM 管代码探索,context-mode 管大输出,RTK 压 shell,Headroom 在 API 层再压,Caveman 少废话输出。工具和门禁一起上才省 token。
参考内容
https://github.com/sgaabdu4/claude-code-tips
https://github.com/DeusData/codebase-memory-mcp
https://github.com/mksglu/context-mode
https://github.com/chopratejas/headroom
https://github.com/JuliusBrussee/caveman
https://github.com/getagentseal/codeburn
https://github.com/vercel-labs/agent-browser
https://docs.flutter.dev/tools/mcp
https://code.claude.com/docs/en/claude-code/slash-commands
评论
加载评论…