AI笔记008. token优化, RTK安装, hook指向exe
知识点:
- 节省了token的同时, 也让上下文不那么容易爆, 以后不用频繁开新session了, 相当于长任务能力暴涨N倍
- cc 的 hook command 可以指向任何可执行文件(不一定是hook目录的脚本)
Why RTK,官方Readme描述:
rtk 在命令输出到达 LLM 上下文之前进行过滤和压缩。单一 Rust 二进制文件,零依赖,<10ms 开销。
Token 节省(30 分钟 Claude Code 会话)
| 操作 | 频率 | 标准 | rtk | 节省 |
|---|---|---|---|---|
ls / tree |
10x | 2,000 | 400 | -80% |
cat / read |
20x | 40,000 | 12,000 | -70% |
grep / rg |
8x | 16,000 | 3,200 | -80% |
git status |
10x | 3,000 | 600 | -80% |
git diff |
5x | 10,000 | 2,500 | -75% |
cargo test / npm test |
5x | 25,000 | 2,500 | -90% |
| 总计 | ~118,000 | ~23,900 | -80% |
测试环境:Windows 11 + Claude Code + Bash/PowerShell 双 shell
1. 安装 RTK
RTK 应已安装到 E:\__work\BaseTools\rtk\rtk.exe,加到path或在 C:\Users\yg\.local\bin\ 建立符号链接rtk.exe
验证:
rtk --version
# 期望输出:rtk 0.42.4
2. 初始化 RTK 配置
运行全局初始化:
rtk init -g --auto-patch
这会做三件事:
- 创建
C:\Users\yg\.claude\RTK.md - 在
C:\Users\yg\.claude\CLAUDE.md添加@RTK.md引用 - 在
C:\Users\yg\.claude\settings.json注入PreToolUsehook
3. 检查 settings.json
确认出现以下段落:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash|PowerShell",
"hooks": [
{
"type": "command",
"command": "rtk hook claude"
}
]
}
]
}
}
注意:
matcher必须包含你实际使用的工具类型(Bash|PowerShell)
4. 重启 Claude Code
必须重启。Hook 在 Claude Code 启动时加载,当前 session 不生效。
5. 验证是否生效
重启后发一个 Bash 命令:
git status
如果输出变成紧凑格式(类似 git status --short --branch),说明 hook 已生效:
* master...origin/master
?? __docs/debug_notes/
再验证 token 节省:
rtk gain -p -H
6. 常见问题
Q1: rtk init -g 后没生效
rtk init -g 在非交互模式下默认不 patch settings.json。改用:
rtk init -g --auto-patch
Q2: Bash 里提示 rtk: command not found
PowerShell 能找 rtk.cmd,但 Git Bash 的 PATH 可能不包含 C:\Users\yg\.local\bin。两种修复:
- 方案 A:settings.json 用完整路径
"command": "E:/__work/BaseTools/rtk/rtk.exe hook claude"
- 方案 B:把
C:\Users\yg\.local\bin加入 Windows 用户 PATH(需重启 Claude Code)
Q3: ~/.claude/hooks/ 下没有 RTK 脚本
正常现象。RTK 的 hook 不是独立脚本,而是 rtk hook claude 这个内置子命令。rtk 从 stdin 读取 Claude Code 传入的工具参数,把 git status 改写成 rtk git status 后通过 stdout 返回。
Q4: 哪些命令会被 rewrite
常见命令如 git、ls、rg、npm、pnpm、tsc、eslint、vitest、pytest、cargo、go test、docker ps 等。未知命令会透传不变。
7. 快速诊断
手动测试 hook 是否能正常 rewrite:
echo '{"session_id":"test","cwd":"/test","hook_event_name":"PreToolUse","tool_name":"Bash","tool_input":{"command":"git status","description":"test"}}' | rtk hook claude
期望输出包含 updatedInput.command": "rtk git status"。
8. 卸载
rtk init -g --uninstall
然后手动从 settings.json 删除 RTK 的 PreToolUse 段落。
探索过程记录:
👤 User
再用rtk 节省token的方式跑一遍cg 技能 ,看节省多少token
🤖 Assistant
用 RTK 重跑 cg 技能的 token 节省结果
Token 节省数据
rtk gain -p -H 当前项目统计:
| 指标 | 数值 |
|---|---|
| 命令数 | 11 |
| 原始输出 tokens | 10.3K |
| RTK 压缩后 tokens | 1.1K |
| 节省 tokens | 9.2K |
| 节省比例 | 89.0% |
按命令类型
| 命令 | 节省比例 | 典型节省 |
|---|---|---|
rtk read |
99% | 读文件时几乎只保留有效行 |
rtk rg |
86–88% | 去空白、截断、按文件分组 |
rtk cg ... |
0% | cg 不是 RTK 子命令,透传无过滤 |
最近命令明细
07-14 16:54 • rtk read -0% (0)
07-14 16:54 • rtk fallback: cg kb pi... -0% (0)
07-14 16:54 ▲ rtk rg -87% (525)
07-14 16:53 ▲ rtk read -99% (8.0K)
07-14 16:53 ▲ rtk rg -87% (225)
07-14 16:53 ▲ rtk rg -88% (112)
07-14 16:53 ▲ rtk rg -86% (56)
07-14 16:53 ▲ rtk rg -86% (75)
07-14 16:53 ▲ rtk rg -88% (112)
关键观察
- 最大收益来自
rtk read:读SCH-MM32F0140.md这种 60 行文件,原始输出约 8K tokens,RTK 过滤后接近 0.1K,省 99%。 rtk rg稳定在 86–88%:网表 grep 结果去掉了大量空白和上下文噪音。cg无节省:cg kb pinout被 RTK 标记为fallback: cg kb p...,输出 JSON 直接被透传,无压缩。
当前限制
手动加 rtk 前缀才能生效。rtk init -g 已注册全局 hook,但 尚未 patch settings.json 并重启 Claude Code,所以仍提示:
[rtk] /!\ No hook installed — run `rtk init -g` for automatic token savings
如需自动生效,需把以下内容加入 C:\Users\yg\.claude\settings.json 后重启:
{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "rtk hook claude" }]
}]
}
}
总结
本次 cg 技能用 RTK 手动跑,省 9.2K tokens(89%);如果 cg 也有 RTK 子命令或 hook 自动重写,节省还能更高。
👤 User
rtk read 为什么能节省token,如果read出来不是原文,那能用吗
🤖 Assistant
rtk read 为什么能省 token?读出来的还是原文吗?
省 token 的三层机制
rtk read 的节省来自 截断 + 过滤 + 格式压缩:
| 机制 | 选项 | 作用 | 风险 |
|---|---|---|---|
| 行数截断 | -m N |
只读前 N 行,其余显示 [X more lines] |
可能漏掉需要的中间内容 |
| 内容过滤 | -l minimal/aggressive |
去掉空行、注释、分隔线等 | aggressive 可能误删有效内容 |
| 格式压缩 | --ultra-compact |
行内紧凑显示 | 可读性下降 |
实测对比
1. 默认 none 级别 = 原文,只截断行数
rtk read -n -m 10 "SCH-MM32F0140.md"
输出:
1 │ # MM32F0140 (U2) 板上信号名 ...
2 │
3 │ > 网表: `FX-T268-V6-10米-5065.NET` ...
4 │
5 │
6 │ [52 more lines]
✅ 文字是原文,只是只读了前 10 行,剩下 52 行被折叠。
2. aggressive 级别可能过度过滤
rtk read -n -l aggressive -m 20 "FX-T268-V6-10米-5065.NET"
输出:
rtk: warning: filter produced empty output ..., showing raw content
⚠️ aggressive 过滤把网表内容当成"无意义文本"全删了,被迫回退到原文。
对 cg 技能来说能不能用?
✅ 适合用 rtk read 的场景
- 读 小文件全文(如
SCH-MM32F0140.md只有 57 行) - 读 配置文件开头 确认格式
- 配合
-m N快速预览,不需要精确中间行
❌ 不适合/有风险的场景
cg 技能的核心是精确网表定位,例如:
- R101 的定义在网表第 1514 行
- R101-1 的网络在第 2492 行
- U7 的器件定义在第 1634 行
rtk read 没有 --offset 参数,无法直接读第 1500 行附近。如果硬用 -m 1500 从头读到 1500 行:
- 虽然内容是原文
- 但 token 节省意义不大(读了大半文件)
- 不如直接用
Read工具的offset/limit精确读取
推荐组合
| 任务 | 推荐工具 | 原因 |
|---|---|---|
| 精确读文件中间段 | Read 原生工具 |
有 offset + limit,内容 100% 原文 |
| 快速 grep 定位 | rtk rg |
省 86%+,输出足够精确 |
| 读小文件/开头预览 | rtk read -m N |
省 99%,内容是原文 |
| 关键网表/配置文件 | 🚫 别用 aggressive |
可能过滤掉有效节点名 |
结论
rtk read默认读出来的是原文,token 主要靠少读行数来省;
但如果用-l aggressive或-l minimal,内容可能被改写,做 cg 技能这种依赖精确网表和引脚映射的工作时不建议用。
对于你的场景, safest 的做法是:
- 定位用
rtk rg(省 token 且精确) - 精确读取用
Read原生工具(带 offset,原文保证)
👤 User
我运行了rtk init -g, claude.md多了一个@RTK.md,但C:\Users\yg.claude\hooks没有发现hook,所以All other commands are automatically rewritten by the Claude Code hook.只是依据空话
👤 User
我运行了rtk init -g, claude.md多了一个@RTK.md,但C:\Users\yg.claude\hooks没有发现hook,所以All other commands are automatically rewritten by the Claude Code hook.只是一句空话
🤖 Assistant
你说得对。rtk init -g 目前只是空话,它并没有真正启用自动 rewrite。
现状核查
1. ~/.claude/hooks/ 下确实没有 RTK 文件
ls -la C:/Users/yg/.claude/hooks/
只有:
auto-approve-claude-filescbmm-auto-indexcbmm-code-discovery-gatecbmm-session-reminder
2. settings.json 里也没有 RTK hook
当前 PreToolUse 只配置了 cbmm:
"hooks": {
"PreToolUse": [
{
"hooks": [{ "command": "~/.claude/hooks/cbmm-code-discovery-gate", "type": "command" }],
"matcher": "Grep|Glob|Read|Search"
}
]
}
3. rtk init -g 实际做了什么
它只是:
- 创建了
C:\Users\yg\.claude\RTK.md - 在
CLAUDE.md里加了@RTK.md引用 - 在非交互模式下跳过了
settings.jsonpatch(默认 N)
所以 RTK.md 里 “All other commands are automatically rewritten by the Claude Code hook” 这句,前提条件没满足。
RTK hook 的真实形态
RTK 的 “hook” 不是 ~/.claude/hooks/ 目录里的独立文件,而是 rtk 二进制的一个子命令:
rtk hook claude
Claude Code 的 PreToolUse hook 可以调用任意命令。正确配置后,每次 Bash 工具调用前,Claude Code 会把工具参数通过 stdin 传给 rtk hook claude,由它决定是否把 git status 重写成 rtk git status。
修复方法
需要手动把 RTK hook 合并进 settings.json,并重启 Claude Code。
合并后的 hooks 段应该是:
"hooks": {
"PreToolUse": [
{
"hooks": [
{
"command": "~/.claude/hooks/cbmm-code-discovery-gate",
"type": "command"
}
],
"matcher": "Grep|Glob|Read|Search"
},
{
"hooks": [
{
"command": "rtk hook claude",
"type": "command"
}
],
"matcher": "Bash"
}
],
"SessionStart": [
{
"hooks": [
{
"command": "~/.claude/hooks/cbmm-auto-index",
"timeout": 300000,
"type": "command"
},
{
"command": "~/.claude/hooks/cbmm-session-reminder",
"type": "command"
}
],
"matcher": "startup"
},
{
"hooks": [
{
"command": "~/.claude/hooks/cbmm-session-reminder",
"type": "command"
}
],
"matcher": "resume|clear|compact"
}
]
}
关键新增部分:
{
"hooks": [
{
"command": "rtk hook claude",
"type": "command"
}
],
"matcher": "Bash"
}
要不要我现在帮你 patch?
我可以直接编辑 C:\Users\yg\.claude\settings.json 加上这段配置。加完后必须重启 Claude Code 才能生效。
另外,rtk init 其实有 --auto-patch 选项:
rtk init -g --auto-patch
你现在运行它,应该能自动完成同样的修改。需要我帮你运行/编辑吗?
👤 User
我已经运行了rtk init -g --auto-patch,看是不是有了
🤖 Assistant
有了。settings.json 第 43-51 行现在已经正确加入了 RTK hook:
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "rtk hook claude"
}
]
}
两个注意点
1. 必须重启 Claude Code 才生效
Hook 是在 Claude Code 启动时加载的。当前这个 session 还没重启,所以现在你运行 git status 仍然不会被自动改写成 rtk git status。
重启后,Bash 工具的命令会先经过 rtk hook claude 处理,然后才会执行。
2. 当前只 hook 了 Bash,没 hook PowerShell
你的环境主 shell 是 pwsh,Claude Code 有独立的 PowerShell 工具。当前 matcher 是 "Bash",所以:
| 工具 | 是否自动 rewrite |
|---|---|
| Bash | ✅ 重启后生效 |
| PowerShell | ❌ 不生效 |
如果你希望 PowerShell 也自动 rewrite,把 matcher 改成:
"matcher": "Bash|PowerShell"
需要我现在帮你改吗?
验证是否生效的方法
重启 Claude Code 后,你可以发一个简单命令测试:
git status
如果 hook 生效,实际执行的应该是 rtk git status,输出开头会带:
[rtk] /!\ No hook installed — run `rtk init -g` for automatic token savings
如果生效了,那个 “No hook installed” 的警告反而会消失(因为 hook 已经装好了)。
要我帮你把 PowerShell 也加进 matcher 吗?
👤 User
改"matcher": “Bash|PowerShell”
🤖 Assistant
已改。settings.json 里 RTK hook 的 matcher 现在是:
"matcher": "Bash|PowerShell"
下一步
重启 Claude Code 后生效。
验证方法
重启后随便发一个 Bash 或 PowerShell 命令,例如:
git status
如果 hook 工作正常,它会被自动改写成 rtk git status,你应该能看到 RTK 的紧凑输出,而不是普通的 git status 输出。
如果还是普通输出,说明 hook 没加载成功。
👤 User
已重启,你试一下
🤖 Assistant
找到原因了:Bash 里找不到 rtk。
rtk 只在 PowerShell PATH 里(C:\Users\yg\.local\bin\rtk.cmd),但 Claude Code 的 Bash 工具运行的是 Git Bash,PATH 不同。所以 rtk hook claude 这个 hook 命令在 Bash 里执行失败,导致命令没被 rewrite。
已修复
我把 settings.json 里的 hook command 改成了 rtk.exe 的完整路径:
{
"matcher": "Bash|PowerShell",
"hooks": [
{
"type": "command",
"command": "E:/__work/BaseTools/rtk/rtk.exe hook claude"
}
]
}
已验证这个路径在 Bash 和 PowerShell 都能运行:
"E:/__work/BaseTools/rtk/rtk.exe" --version
# rtk 0.42.4
还需要一次重启
settings.json 修改后,需要再重启一次 Claude Code 才能加载新的 hook 命令。
重启后再试 git status,如果输出变成 RTK 格式(紧凑、带 [rtk] 标记),就说明自动 rewrite 生效了。
👤 User
我改成了"hooks": [
{
“type”: “command”,
“command”: “rtk hook claude”
}
]
已重启,你试试
🤖 Assistant
生效了。Hook 已经工作。
测试证据
1. git status 被改写了
我发的命令是 git status,实际输出是 RTK 紧凑格式:
* master...origin/master
?? __docs/debug_notes/
普通 git status 应该是长格式带 On branch master... 那段,现在被压缩成短格式了。
2. ls -la 被改写了
输出变成:
755 .claude/
755 .codegraph/
755 .git/
...
普通 ls -la 会带权限串、所有者、大小、日期,现在只剩权限数字和文件名。
3. rtk gain -p -H 确认
Total commands: 22
Input tokens: 31.5K
Output tokens: 3.6K
Tokens saved: 27.9K (88.6%)
最近命令列表已经出现了自动 rewrite 的记录:
| 命令 | 节省 |
|---|---|
rtk git status |
-81% |
rtk ls -la ... |
-67% |
rtk git log --oneline -5 |
-0% |
为什么 "rtk hook claude" 现在能用了?
之前 Bash 找不到 rtk,重启后环境变量/PATH 刷新,现在 Claude Code 的 Bash 工具能解析到 rtk 了。可能是你加了 PATH,也可能是重启后 pyenv/shim 路径被正确继承。
总之:自动 rewrite 已生效,以后 Bash 和 PowerShell 的常用命令都会走 RTK 过滤。
👤 User
C:\Users\yg.claude\hooks 没有hook脚本,rtk 的hook是怎么实现的
🤖 Assistant
你说得对,C:\Users\yg\.claude\hooks 目录下确实没有 RTK 脚本。RTK 的 hook 不是放在那里的独立脚本,而是 rtk 可执行文件本身的一个子命令。
RTK hook 的实现机制
Claude Code 的 settings.json 支持 PreToolUse hook。每次工具调用前,Claude Code 会:
- 把工具参数打成 JSON,通过 stdin 传给 hook 命令
- hook 命令处理完后,通过 stdout 返回 JSON
- 如果返回的 JSON 里有
updatedInput,Claude Code 就用更新后的参数执行工具
实测:rtk hook claude 做了什么
我用正确的 Claude Code hook JSON 格式手动喂给它:
echo '{"session_id":"test","cwd":"/test","hook_event_name":"PreToolUse","tool_name":"Bash","tool_input":{"command":"git status","description":"test"}}' | rtk hook claude
输出:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecisionReason": "RTK auto-rewrite",
"updatedInput": {
"command": "rtk git status",
"description": "test"
}
}
}
看到了吗?它把 git status 改成了 rtk git status,通过 updatedInput.command 回传给 Claude Code。
同样,ls -la 会变成 rtk ls -la:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecisionReason": "RTK auto-rewrite",
"updatedInput": {
"command": "rtk ls -la"
}
}
}
为什么 ~/.claude/hooks/ 里没有 RTK 文件?
~/.claude/hooks/ 只是一个常见的脚本存放位置,不是唯一位置。Claude Code 的 hook command 可以指向任何可执行文件,包括:
~/.claude/hooks/cbmm-code-discovery-gate(cbmm 放的脚本)rtk hook claude(rtk 的子命令)- 任何路径的
.exe、.cmd、.sh
当前你的 settings.json 里 RTK hook 配置是:
{
"matcher": "Bash|PowerShell",
"hooks": [
{
"type": "command",
"command": "rtk hook claude"
}
]
}
rtk hook claude 直接调用 rtk 二进制内部的 hook 处理器,不需要额外的脚本文件。
总结
RTK hook 的实现方式:
| 项目 | 说明 |
|---|---|
| Hook 位置 | settings.json 的 hooks.PreToolUse |
| Hook 命令 | rtk hook claude(rtk 内置子命令) |
| 输入 | Claude Code 通过 stdin 传入工具参数 JSON |
| 输出 | rtk 通过 stdout 返回 updatedInput JSON |
| 效果 | git status → rtk git status |
~/.claude/hooks/ 文件 |
不需要,因为 hook 逻辑在 rtk 二进制里 |
所以 ~/.claude/hooks/ 里没有 RTK 文件是正常的,它不是靠脚本文件实现的,而是靠 rtk 自己的子命令。
Sources:
- Claude Code Docs – Hooks reference
- Claude Code Docs – Automate actions with hooks
- GitHub / luongnv89 – Claude howto hooks README
- dev.to / bfxavier – PreToolUse sandboxing hook
👤 User
写一个简洁的rtk安装指南.md
🤖 Assistant
已写好,保存在:
E:/__work/__longMem/rtk-install-guide-2026-07-14.md
内容覆盖了我们今天踩过的全部关键点:
- 安装验证 —
rtk --version - 正确初始化 — 必须用
--auto-patch,否则settings.json不会被改 - 配置检查 —
matcher要包含Bash|PowerShell - Bash 找不到 rtk 的修复 — 用完整路径
E:/__work/BaseTools/rtk/rtk.exe hook claude - 必须重启 Claude Code
- 验证方法 —
git status输出变紧凑、rtk gain -p -H - 手动诊断 hook — 用正确 JSON 喂给
rtk hook claude - 解释为什么
~/.claude/hooks/里没有 RTK 文件
可以直接当速查手册用。
更多推荐

所有评论(0)