RTK rtk gain 深度指南:Token 节省度量、周期分解与数据导出实战
RTK(rtk)是一个用于降低 LLM token 消耗的 CLI 代理,而 rtk gain 是它内置的节省度量入口:它能告诉你 RTK 在历史命令中究竟压缩了多少 bash 输出,并提供日/周/月维度分解、配额估算与 JSON/CSV 导出能力。读完本文,你将掌握 rtk gain 全部参数的用法、bytes / 4 token 估算模型的确切含义、底层 SQLite 数据流的实现细节,以及如何把节省数据接入你自己的报表与看板。本文技术内容以 docs/guide/analytics/gain.md 为主体,并结合 src/analytics/gain.rs、src/core/tracking.rs 与 src/main.rs 的源码实现进行扩充。
一、rtk gain 到底度量什么
rtk gain 展示的是 RTK 在所有命令中移除的 bash 输出字节数,并换算为估算 token 数。这里有一个必须建立的正确心智模型:
- bash 输出只是输入 token 的一个贡献者,与你的提示词、系统提示词、对话历史并列;
- 输入 token 又只是账单的一部分,账单还包含输出 token;
- 因此
rtk gain里的百分比(Save%)是 bash 输出字节比率,不是你账单的节省占比。
原文档特别强调:示例数字只是说明性的单台机器数据,并非典型结果——你看到的数值完全取决于你运行了哪些命令。
二、快速参考
原文档给出的完整命令参考如下:
# 默认摘要
rtk gain
# 时间维度分解
rtk gain --daily # 自开始追踪以来的所有天
rtk gain --weekly # 按周聚合
rtk gain --monthly # 按月聚合
rtk gain --all # 一次性输出全部分解
# 经典标志
rtk gain --graph # ASCII 图表,最近 30 天
rtk gain --history # 最近 10 条命令
rtk gain --quota # 月度配额节省估算(默认档位: 20x)
rtk gain --quota -t pro # 使用 pro 档位的 token 预算做估算
# 导出
rtk gain --all --format json > savings.json
rtk gain --all --format csv > savings.csv
从 src/main.rs 的 clap 定义看,Gain 子命令实际接受的参数还包括 --project/-p(把统计限定到当前工作目录项目)、--failures/-F(查看解析失败日志)、--reset(清零统计,可配 --yes 跳过确认)。这些是文档未展开但源码中确实存在的选项,下文第六节单独说明。
三、默认摘要视图:KPI、命令排行与效率仪表
直接运行 rtk gain(不带分解标志)输出 KPI 风格摘要。对应源码 src/analytics/gain.rs 的默认分支会打印:
Total commands:RTK 命令总执行次数Input tokens/Output tokens:原始输出与过滤后输出的估算 token 总量Tokens saved (x.x%):节省量与平均节省率Total exec time (avg …):总执行时间与平均耗时Efficiency meter:一个 24 格进度条(█░),按节省率着色(≥70% 绿、≥40% 黄、否则红,见 print_efficiency_meter)
随后是 By Command 排行榜(src/analytics/gain.rs):每行含命令名、执行次数、节省量、平均节省率(颜色分级)、平均耗时和一条按比例渲染的 impact 迷你条形图,用于快速定位“哪条命令贡献了最多节省”。
默认视图还会做三类健康检查(输出到 stderr,不污染 stdout):
- Hook 状态检查:通过 hook_check::status() 检测 hook 缺失或过期,分别提示
rtk init -g; RTK_DISABLED旁路扫描:check_rtk_disabled_bypass() 轻量扫描最近 7 天的 Claude Code 会话,若RTK_DISABLED=1前缀命令占比超过 10%,会提示运行rtk discover查看详情;- 未信任过滤器提醒:若存在未
rtk trust的自定义过滤器,会提示其未被应用。
无数据时,命令会直接输出 No tracking data yet. 并提示先运行一些 rtk 命令(src/analytics/gain.rs)。
四、日/周/月分解:--daily / --weekly / --monthly / --all
rtk gain --daily
示例输出(说明性数字,来自单台机器,非典型结果):
📅 Daily Breakdown (3 days)
════════════════════════════════════════════════════════════════
Date Cmds Input Output Saved Save%
────────────────────────────────────────────────────────────────
2026-01-28 89 380.9K 26.7K 355.8K 93.4%
2026-01-29 102 894.5K 32.4K 863.7K 96.6%
2026-01-30 5 749 55 694 92.7%
────────────────────────────────────────────────────────────────
TOTAL 196 1.3M 59.2K 1.2M 95.6%
各列含义:
| 列 | 含义 |
|---|---|
| Cmds | 该周期内执行的 RTK 命令数 |
| Input | 原始命令输出的估算 token(bytes / 4) |
| Output | 过滤后输出的估算 token(bytes / 4) |
| Saved | Input - Output,估算 token |
| Save% | Saved / Input × 100 —— 是 bash 输出字节比率,不是账单占比 |
周视图与月视图列定义完全相同,只是聚合粒度不同:
rtk gain --weekly
rtk gain --monthly
- 周聚合按 周日至周六(源码注释明确说明 Weeks start on Sunday,与 SQLite 默认行为一致,见 DayStats/WeekStats 定义);
- 月聚合按 日历月(
YYYY-MM)。
三个视图最终都调用 print_period_table 渲染同一套表格结构,分别由 get_all_days_filtered / get_by_week_filtered / get_by_month_filtered 从 SQLite 聚合取得(src/analytics/gain.rs)。
五、经典展示选项:--graph 与 --history
--graph:在摘要视图后附加最近 30 天的 ASCII 条形图(print_ascii_graph),每天一行,条形按当日节省量相对最大值缩放至 40 列宽,附带日期缩写(MM-DD)与节省量。
--history:打印最近 10 条命令记录(tracker.get_recent_filtered(10, …)),每行格式为 时间 级别符号 命令 -节省率% (节省量),级别符号按节省率分档(src/analytics/gain.rs):
▲节省率 ≥ 70%■30% ≤ 节省率 < 70%•节省率 < 30%
六、源码中的扩展选项:--project、--failures、--reset
以下三个选项未在原指南中展开,但可从 src/main.rs 与 src/analytics/gain.rs 确认存在:
--project/-p:把统计限定到当前工作目录(canonical 路径),配合get_summary_filtered等过滤查询实现项目级口径;摘要标题会显示(Project Scope)与缩短后的项目路径(resolve_project_scope);--failures/-F:查看解析失败日志——即因解析失败而回退到原始执行的命令。输出总失败数、恢复率(recovery rate)、Top 失败命令与最近 10 条失败记录(show_failures),用于确认“哪些命令没被 RTK 真正处理”;--reset(可配--yes):将全部 token 统计清零。交互式终端下默认要求y/yes确认;管道等非交互环境下默认按 N 处理,避免脚本误删数据(confirm_reset)。
七、导出格式:text / json / csv
| 格式 | 标志 | 适用场景 |
|---|---|---|
text |
默认 | 终端展示 |
json |
--format json |
程序化分析、看板 |
csv |
--format csv |
Excel、Python/R、Google Sheets |
JSON 结构
文档给出的结构如下:
{
"summary": {
"total_commands": 196,
"total_input": 1276098,
"total_output": 59244,
"total_saved": 1220217,
"avg_savings_pct": 95.62
},
"daily": [...],
"weekly": [...],
"monthly": [...]
}
对照 export_json 的实现可以补充两点细节:
summary中实际还包含total_time_ms与avg_time_ms两个时间字段(ExportSummary);daily/weekly/monthly是Option,只有对应分解标志(或--all)被传入时才序列化输出,未请求的键会直接省略,便于按需消费。
CSV 结构
CSV 导出(export_csv)以注释行分节,每节自带表头,方便脚本按节切分:
# Daily Data
date,commands,input_tokens,output_tokens,saved_tokens,savings_pct,total_time_ms,avg_time_ms
...
# Weekly Data
week_start,week_end,commands,input_tokens,output_tokens,saved_tokens,savings_pct,total_time_ms,avg_time_ms
...
# Monthly Data
month,commands,input_tokens,output_tokens,saved_tokens,savings_pct,total_time_ms,avg_time_ms
...
这一分节设计正是下文 pandas 示例能定位 # Daily Data 的依据。
八、--quota:把节省量换算成月度订阅预算占比
--quota 将累计节省 token 表达为月度订阅预算的分数。和 rtk gain 的所有数字一样,它源自 bytes / 4 的 bash 输出估算,应视为数量级参考而非账单预测。
rtk gain --quota # 使用 20x 档预算(CLI 默认 tier 为 20x)
rtk gain --quota -t pro # Claude Pro 计划预算
rtk gain --quota -t 5x # 5× 使用计划预算
rtk gain --quota -t 20x # 20× 使用计划预算
档位与 Anthropic Claude API 订阅级别一一对应,各自的月度 token 分配不同,RTK 用该分配作为分母,把节省量表达为预算百分比。源码中的具体常量(src/analytics/gain.rs):
| 档位 | 预算常量 | 展示名 |
|---|---|---|
pro |
6,000,000 tokens | Pro ($20/mo) |
5x |
6,000,000 × 5 | Max 5x ($100/mo) |
20x |
6,000,000 × 20 | Max 20x ($200/mo) |
CLI 中 --tier 的默认值为 20x(见 src/main.rs),与文档“default tier: 20x”一致;无法识别的档位值会回落到 Pro 基准。输出末尾还会附注:该估算基于约 44K tokens/5h 的 Pro 基线,且 Claude 实际限额采用滚动 5 小时窗口而非月度上限——这解释了为什么它只能是数量级估算。
提示:
rtk gain展示的是 RTK 已节省的部分;若想知道哪些命令没有经过 RTK、错过了多少节省,见 rtk discover。
九、Token 估算原理:为什么是 bytes / 4
rtk gain 按 bytes / 4 估算 token,实现位于 estimate_tokens:
pub fn estimate_tokens(text: &str) -> usize {
// ~4 chars per token on average
(text.len() as f64 / 4.0).ceil() as usize
}
RTK 有意不内置真实分词器:嵌入 tokenizer 会增加启动耗时,而且不同模型需要不同的 tokenizer,或需要按会话做模型查询——后者 RTK 并未实现。关键保证是:原始输出与过滤后输出使用同一个估算器,所以百分比是可靠的;但绝对 token 数是近似的,不会与提供商的计费数字吻合。
估算公式:
Input Tokens = estimate_tokens(raw_command_output)
Output Tokens = estimate_tokens(rtk_filtered_output)
Saved Tokens = Input - Output
Savings % = (Saved / Input) × 100
十、各命令的典型节省率
| 命令 | Bash 输出压缩率 | 机制 |
|---|---|---|
git status |
77-93% | 紧凑 stat 格式 |
eslint |
84% | 按规则分组 |
jest |
94-99% | 只展示失败用例 |
vitest |
94-99% | 只展示失败用例 |
find |
75% | 树形格式 |
pnpm list |
70-90% | 紧凑依赖列表 |
grep |
70% | 截断 + 分组 |
再次强调:这些百分比度量的是 bash 输出字节被移除的比例,不是费用降幅。各过滤机制的具体实现散布在 src/filters/ 的 TOML 声明式过滤器与 src/cmds/ 的各语言/工具命令模块中,例如 vitest 过滤器 与 grep 处理 分别对应表中的“只展示失败”与“截断 + 分组”。
十一、数据存储:SQLite 与 90 天保留期
节省数据本地存储于 SQLite:
- 位置:
~/.local/share/rtk/history.db(Linux / macOS) - 保留期:90 天(写入时自动清理,见 Tracker 模块说明 与 90 天清理逻辑)
- 作用域:跨所有项目与所有 Claude 会话的全局数据
从源码看,数据库路径解析有明确的三级优先级(get_db_path):
- 环境变量
RTK_DB_PATH(最高优先,测试也验证了这一点); - 配置文件中
tracking.database_path项; - 平台默认数据目录下的
rtk/history.db。
这意味着在测试或隔离环境中可以用 RTK_DB_PATH 指向临时库,避免污染真实统计。另外,SQLite 的 WAL 旁路文件(-wal/-shm)与主库同目录同级存放,权限加固逻辑会同时覆盖它们(db_sidecars)。
常用数据库操作:
# 查看原始数据
sqlite3 ~/.local/share/rtk/history.db \
"SELECT timestamp, rtk_cmd, saved_tokens FROM commands
ORDER BY timestamp DESC LIMIT 10"
# 备份
cp ~/.local/share/rtk/history.db ~/backups/rtk-history-$(date +%Y%m%d).db
# 重置
rm ~/.local/share/rtk/history.db # 下次命令运行时自动重建
十二、分析工作流实战
每周/每月例行报表
# 每周进度:每周一生成 CSV 报告
rtk gain --weekly --format csv > reports/week-$(date +%Y-%W).csv
# 月度预算审查:JSON 导出后用 jq 换算配额占比
rtk gain --monthly --format json | jq '.monthly[] |
{month, saved_tokens, quota_pct: (.saved_tokens / 6000000 * 100)}'
# Cron:每日 JSON 快照供看板消费
0 0 * * * rtk gain --all --format json > /var/www/dashboard/rtk-stats.json
注意 jq 示例中的 6000000 正是源码里的 Pro 基准常量(ESTIMATED_PRO_MONTHLY),与 --quota -t pro 的口径一致。
Python / pandas 绘图
import pandas as pd
import subprocess
result = subprocess.run(['rtk', 'gain', '--all', '--format', 'csv'],
capture_output=True, text=True)
lines = result.stdout.split('\n')
daily_start = lines.index('# Daily Data') + 2
daily_end = lines.index('', daily_start)
daily_df = pd.read_csv(pd.StringIO('\n'.join(lines[daily_start:daily_end])))
daily_df['date'] = pd.to_datetime(daily_df['date'])
daily_df.plot(x='date', y='savings_pct', kind='line')
CI 中周期性归档
原文档给出了 GitHub Actions 的每周统计工作流示例;考虑到实际分发渠道可能不同,安装步骤请以 INSTALL.md 与 install.sh 给出的方式为准:
on:
schedule:
- cron: '0 0 * * 1'
jobs:
stats:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# 在此使用项目实际提供的安装方式(参见 INSTALL.md)
- run: rtk gain --weekly --format json > stats/week-$(date +%Y-%W).json
- run: git add stats/ && git commit -m "Weekly rtk stats" && git push
十三、故障排查
没有数据显示:
ls -lh ~/.local/share/rtk/history.db
sqlite3 ~/.local/share/rtk/history.db "SELECT COUNT(*) FROM commands"
git status # 运行任意被追踪的命令以生成数据
若 history.db 存在但计数为 0,说明尚无被追踪的命令执行记录;也可留意默认摘要视图中的 hook 缺失/过期警告——hook 未安装时命令不会经过 RTK,自然没有数据。
统计数字不准: token 估算只是启发式。若需精确计数,可用 tiktoken 交叉验证:
pip install tiktoken
git status > output.txt
python -c "
import tiktoken
enc = tiktoken.get_encoding('cl100k_base')
print(len(enc.encode(open('output.txt').read())), 'actual tokens')
"
预期结论:tiktoken 的精确计数与 bytes / 4 估算不会完全相等(估算按平均每 4 字符 1 token 向上取整),但两者的比值趋势应当一致——这正是把 rtk gain 的数字当数量级参考、而不是计费依据的原因。
小结与延伸阅读
rtk gain 的价值在于它把“RTK 省了多少”变成了可查询、可导出、可审计的数据:摘要视图看总览与命令排行,日/周/月分解看趋势,JSON/CSV 导出接入自建报表,--quota 把节省量对齐到订阅预算,而 SQLite + bytes/4 的极简数据链路保证了零依赖单二进制下依然可用的分析能力。想继续深挖,可阅读 docs/guide/analytics/discover.md(查找错过的节省机会)以及 src/analytics/ 与 src/core/tracking.rs 的完整实现。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0623
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00