来源:互联网 更新时间:2026-06-20 07:41
AI 帮手修前端代码的时候,不会光靠嘴说完成。它会反复调用真实工具:git status 看文件状态、rg Button src 搜组件、pnpm test 跑测试、tsc 和 eslint 做静态检查、next build 验证构建——一轮又一轮,执行完根据输出再接着改。
这些命令本身是为人类终端设计的。程序员瞟一眼就能跳过进度条、忽略通过的用例、跳过样板提示,直接定位到错误发生的地方。LLM 没有这个眼睛。AI 助手里的 Bash / shell 执行工具,会把完整的 stdout / stderr 当作 tool result 一股脑塞回上下文。模型被迫同时接收有用信号和大量噪声。
RTK(Rust Token Killer)就是来管这段工具调用开销的。它是一个 CLI / 袋里层工具,卡在 AI 助手和真实开发命令之间。通过 hook 或者 plugin,把 AI 助手准备执行的 Bash 命令改写成 RTK 袋里命令。真实工具照常运行,文件系统副作用和退出码不能变,但返回给模型的是压缩后的输出。
README 里有个数据很说明问题:一次 30 分钟的 Claude Code 会话,原始命令输出大约占了 118,000 token,经过 RTK 压缩后降到约 23,900 token,省了差不多 80%。当然,这个数字不是死承诺,它揭示的是高频命令输出在典型 AI 编程会话里的真实成本。
AI 助手修一个问题时,会连续跑好几类命令:先看工作区状态,再搜相关代码,然后跑测试或构建。每一条命令的输出都会回到模型上下文里,跟任务描述、已读代码、错误线索挤在一起。
终端输出本来就是按人的阅读方式设计的。git status 带着 Git 的说明文本;vitest 或 jest 会打印通过的用例、进度条和失败栈;tsc、eslint、next build 把编译信息、规则提示、构建摘要和错误全混在一起;搜索命令可能带回几十个无关命中。
这些东西一股脑儿进入上下文,消耗的是同一块空间。噪声多一行,模型能保留的代码、约束和推理就少一行。上下文接近上限时,模型可能丢掉刚读过的关键文件,也可能忘了上一轮定位到的失败原因。
模型真正需要的信息其实很窄:
| 命令类型 | 模型需要的信息 | 容易吃掉上下文的内容 |
|---|---|---|
| Git | 当前分支、变更文件、diff 摘要 | 模板说明、长 diff 头、重复元信息 |
| 测试 | 失败用例、断言差异、错误栈 | 通过用例、进度条、重复日志 |
| TypeScript / Lint / 构建 | 错误文件、行号、规则、失败原因 | banner、构建进度、长 warning 列表 |
| 搜索 / 文件读取 | 命中文件、关键行、必要上下文 | 无关命中、过长文件内容 |
RTK 就是来解决这个浪费的。它不等模型读完完整的终端日志再自己总结,而是抢在命令输出进入上下文之前,先把适合机器消费的部分提炼出来。
RTK 不修 bug,也不替模型判断代码对不对。它只处理命令输出进入模型之前的那一段。
AI 助手跑 vitest 时,RTK 仍然调用测试框架;助手跑 next build 时,RTK 仍然调用 Next.js;助手跑 git diff 时,RTK 仍然调用 Git。RTK 只压缩真实工具的输出。
它有三大职责:
传话:接住 AI 助手要运行的命令,把它交给真实工具。
整理:过滤真实工具返回的 stdout / stderr,保留模型下一步需要的信息。
记账:记录原始输出和压缩输出的差异,让用户看到省了多少 token。
一句话,RTK 的目标就是减少 LLM 上下文里的无效 token。
用户不用每次手写袋里命令。装好 hook 或 plugin 后,AI 助手仍然发起普通 Bash 命令,改写发生在命令执行之前。
hook 接在 AI 助手调用 Bash 工具之前。助手提交原始命令后,hook 可以把这段命令文本替换成另一条命令,再交给执行器去跑。
在 Claude Code 里,RTK 把自己注册成 PreToolUse hook,settings.json 配置大致是这样的:
{"hooks": {"PreToolUse": [{"matcher": "Bash","hooks": [{"type": "command","command": "rtk hook claude"}]}]}}}
模型不需要记住“我应该主动用 RTK”。用户也不用改变和 AI 助手协作的方式。可优化命令在执行前被路由到 RTK,模型收到的是过滤后的结果。
注意,只有 Bash / terminal tool call 会触发这种透明改写。Claude Code 内置的读文件、搜索、Glob 能力不一定经过 Bash hook;这些场景要么显式用 shell 命令,要么直接调用 rtk read、rtk grep、rtk find。
RTK 也保留了直接调用方式。用户可以显式跑 rtk grep、rtk read、rtk find,或者用 rtk proxy 跑暂不支持的命令并记录用量。
命令被改写后,RTK 进入袋里执行阶段。这个“袋里”不要求模型换写法,也不依赖用户的 shell alias。
先看 PreToolUse 这类 hook 的通用原理。AI 助手准备调用 Bash 工具时,宿主先启动配置好的 hook 命令,并把这次工具调用的信息通过 stdin 传给 hook。输入里包含工具名和工具参数,比如工具名是 Bash,参数里有 command: "git status"。
hook 如果不想介入,可以什么都不返回,让宿主按原样执行。如果要改写 Bash 命令,就往 stdout 返回一段结构化结果,告诉宿主替换这次工具输入。在 Claude Code 这类格式里,关键字段是 hookSpecificOutput.updatedInput.command,它会覆盖原来的 command 字段:
{"hookSpecificOutput": {"hookEventName": "PreToolUse","permissionDecision": "ask","permissionDecisionReason": "rewrite command before Bash runs","updatedInput": {"command": "rtk git status"}}}}
宿主收到这段返回后,把 updatedInput.command 里的新命令交给 Bash。袋里发生在工具调用参数提交给 Bash 之前。
RTK 用这层机制改写命令文本。改写后的 rtk ... 命令启动后,RTK 进程调用真实的 Git、测试框架、构建工具,捕获 stdout / stderr,过滤后把结果打印回 Bash tool result。
RTK 先保证真实命令照常运行,再处理输出。

这条链路里有几个必须遵守的底线:
这些底线把 RTK 牢牢限定在开发工具链袋里的位置,而不是一个日志总结脚本。
RTK 分两层识别命令。
第一层发生在 hook 或 plugin 里。Claude Code 准备执行 Bash 命令时,RTK hook 会拿到原始命令文本。它先判断这条命令有没有已知改写规则:git status 可以改写到 rtk git status,rg Button src 可以改写到 RTK 的搜索过滤链路,vitest、tsc、eslint、next build 这类前端命令也会进入对应袋里路径。
比如 AI 助手想跑 rg Button src。hook 先判断它是搜索命令,再把它交给 RTK 的搜索链路;RTK 运行真实搜索工具后,按文件分组命中行,并截断过长上下文,最后把更短的搜索结果返回给模型。
第二层发生在 RTK 进程内部。命令已经带上 rtk 前缀后,RTK 会根据子命令和工具名路由到具体模块:
| 原始命令形态 | RTK 识别到的类型 | 后续过滤重点 |
|---|---|---|
git status / git diff | Git | 分支、变更文件、diff 摘要 |
rg ... / grep ... | 搜索 | 命中文件、关键行、截断上下文 |
vitest / jest | 前端测试 | 失败用例、断言差异、错误栈 |
tsc | TypeScript | 文件、行号、类型错误 |
eslint / biome | Lint | 文件、规则、错误数量 |
next build / vite build | 构建 | 构建错误、关键 warning、摘要 |
hook 找不到可靠规则时,不改写命令。RTK 内部没有对应过滤器时,走原样透传或通用处理。识别类型只服务于一件事:在有把握压缩时介入。
统一的截断解决不了命令输出问题。
测试失败的关键内容可能在末尾;Git diff 的关键内容在变更行;eslint 输出要按规则和文件聚合;tsc 输出要按文件和错误位置整理;搜索输出要按文件分组并截断长行。RTK 因此必须按命令类型选择过滤器。
不同命令的噪声长得完全不一样,过滤器不能只做统一截断。
以 git status 为例。普通输出适合人看,有分支说明、未跟踪文件提示和 git add 建议。模型需要更短的状态信号:当前分支、文件状态,以及仓库是否处在 rebase、merge、cherry-pick、detached HEAD 这类危险状态里。
RTK 默认用更适合机器解析的状态输出生成短结果,同时从普通 git status 头部补回危险状态。这样既能删掉 Git 的提示语,也不会因为压缩把关键仓库状态藏起来。

RTK 过滤器先判断哪些信息会影响模型下一步行动,再删掉解释性、重复性和过长的内容。
常见过滤策略包括:
vitest、jest、playwright test 的失败用例、断言差异和相关栈信息。tsc、eslint、biome 输出,让模型先看到错误分布。next build、vite build 里保留路由摘要、构建错误和关键 warning。不同命令的“有用信息”不同,RTK 的过滤器必须理解这些差异,而不是用一把尺子量所有输出。
RTK 支持很多开发常用命令:Git、GitHub CLI、pnpm、npm、vitest、jest、tsc、eslint、next build、playwright test、文件读取和搜索等。命令种类多,但袋里执行的骨架是相似的。
过滤器负责“某类输出怎样压缩”。runner 负责把真实命令运行、输出捕获、过滤调用、结果打印、统计记录这些通用步骤串起来。
runner 大致支持四类处理方式:
| 处理方式 | 适合场景 | 结果 |
|---|---|---|
| 一次性过滤 | 输出不长,结构清楚 | 收完整输出后再压缩 |
| 看退出码过滤 | 成功和失败需要不同摘要 | 成功极短,失败保留证据 |
| 流式过滤 | 输出较长 | 边读边处理 |
| 原样通过 | 没有可靠规则 | 保持原始输出 |
共享 runner 让命令模块可以复用执行逻辑,过滤器只关心一件事:“怎样把这个命令的输出压缩好”。
成功输出可以很短。vitest 通过、tsc 无类型错误、next build 完成、Git add 成功,模型往往只需要一个状态信号。
但失败输出不能压成一句“失败了”。模型下一步要修问题,至少需要知道:
RTK 必须在压缩率和证据保留之间做取舍。它默认给模型更短的结果,也保留了回看能力:需要时可以查看原始输出,用 verbose 模式拿到更多细节,或者用 tee 保存原始日志。一句话,压缩不能关掉后续排障入口。
专门模块适合复杂命令,小脚本不一定需要。
很多团队内部脚本只需要简单规则:删除进度行、保留错误行、去掉 ANSI 颜色码、限制最大行数、输出为空时返回默认摘要。
RTK 用 TOML 规则承载这类轻量扩展。它是一层声明式文本过滤,适合处理输出格式稳定、规则简单、团队经常运行的命令。
比如团队里有一个 api pull 命令,用来从接口平台拉取请求类型和发起请求的代码。原始输出可能长这样:
[auth] refreshing token[download] GET https://api.example.com/openapi.json[cache] schema unchanged: shared/common.json[type] UserProfile -> src/api/types/user.ts[type] OrderDetail -> src/api/types/order.ts[client] GET /api/users/:id -> src/api/user.ts fetchUser[client] POST /api/orders -> src/api/order.ts createOrder[progress] generated 2 type files, 2 client files[done] api pull completed in 4.8s
模型需要知道哪些类型文件变了、哪些请求函数变了、有没有失败或 warning。用 TOML 规则做轻量过滤后,返回可以压成:
[type] UserProfile -> src/api/types/user.ts[type] OrderDetail -> src/api/types/order.ts[client] GET /api/users/:id -> src/api/user.ts fetchUser[client] POST /api/orders -> src/api/order.ts createOrder[done] api pull completed in 4.8s
api pull 适合 TOML,因为输出按行稳定,保留 [type]、[client]、[warn]、[error]、[done] 这几类行就够了。如果团队以后要解析 OpenAPI JSON、按模块重新分组、合并重复类型、判断 breaking change,那就应该写专用过滤器。
对应的项目级 TOML 规则可以放在 .rtk/filters.toml:
[filters.api-pull]description = "Keep generated API types, client functions, and failures"match_command = "^apis+pull"strip_ansi = truekeep_lines_matching = ["^[type]","^[client]","^[warn]","^[error]","^[done]",]truncate_lines_at = 160max_lines = 80on_empty = "api pull: no changed API output"
这段配置不理解接口结构,只在稳定日志里保留关键行。仓库里的 .rtk/filters.toml 需要用户信任后才会生效,因为它会影响 AI 助手看到哪些命令输出。
TOML 规则降低了扩展成本。团队可以把常见噪声沉淀成配置,不必为了每个小脚本都改 Rust 代码。RTK 仍然保留了专用过滤器来处理 Git、前端测试、TypeScript、构建、Lint 这类复杂输出。
简单命令可以先用 TOML 规则试试。需要理解结构、分组错误、解析 JSON、处理失败路径或流式输出的命令,还是应该写专用过滤器。Git、tsc、vitest、next build、eslint 这些内置命令走对应的专用过滤器,而不是让项目 TOML 规则直接覆盖。
项目级规则还需要信任机制。仓库里的规则可能来自别人提交,它虽然不是 shell 脚本,但会影响 AI 助手看到什么。RTK 要求用户显式信任项目级规则后再启用。
RTK 会记录原始输出和过滤输出的 token 估算。用户可以通过 rtk gain 看累计节省,也可以用 rtk discover 找还没有接入 RTK 的高浪费命令。
AI 助手写代码时,命令输出很容易变成另一种上下文债务。一次 git status 不算多,几轮搜索、测试、构建叠在一起,模型要读的噪声就会超过真正的线索。
RTK 的做法很克制:命令还是原来的命令,Git、测试框架、构建工具照常运行;进入模型之前,输出先被整理成更适合下一步行动的信息。成功时给状态,失败时保留证据,不认识的命令就透传。
你可以把 RTK 当成 AI 编程会话里的输出闸门。它不替模型写代码,也不替工具做判断;它只让模型少读一些没用的终端文本,多保留一些代码、错误和上下文。
为何比特币BTC价格跌破7.3万美元?一文拆解影响近期比特币行情的五大原因
摩托车活塞环性能如何
ThinkBook系列最新价格全解析:2026年选购避坑与实时询价指南
文雅简易网名男生可爱(精选100个)
GPT5.6惨遭切脑,Fable 5回归要变弱鸡版?
Ondo将于今日上线股票永续合约
区块链存储板块是什么?有哪些?一文详解
暗黑4S14野蛮人终局BD攻略
免费网络收音机软件有哪些?高评分收音机APP推荐
《三角洲行动》S10赛季卡邮件技巧详解-三种方法及风险提示
电视剧《罗曼诺夫后裔》剧情介绍
如何在火狐浏览器中彻底禁用自动更新功能?
区块链OTC交易所有哪几家比较正规?
夸克浏览器AI画质增强功能在旧款手机上无法开启怎么办?
手机qq浏览器误删文件如何找回-手机qq浏览器误删除文件怎样恢复
360浏览器如何设置网页缩放比例
《三角洲行动》GTI超人成就解锁攻略-满辐射状态击杀技巧详解
全链网:戴蒙或继续担任摩根大通首席执行官三年
什么是山寨币?山寨币指数如何查看?全球前10大山寨币盘点
Binance新增15种bStocks代币化证券为杠杆抵押资产
手机号码测吉凶
本站所有软件,都由网友上传,如有侵犯你的版权,请发邮件haolingcc@hotmail.com 联系删除。 版权所有 Copyright@2012-2013 haoling.cc