RTK

Rust Token Killer — 高性能 CLI 代理,最小化 LLM token 消耗

架构概览

01 / 04

问题

一个普通的 git log 命令会输出大量信息 —— commit hash、完整作者信息、日期、merge commit、Signed-off-by trailer。当这些内容作为上下文发送给 LLM 时,可能消耗数千 token,其中大部分是噪声。

02 / 04

RTK 的位置

RTK 作为 CLI 代理插入在用户(或 AI agent)和系统命令之间。它拦截命令输出,在内容到达 LLM 上下文之前进行过滤和精简。整个过程对上层透明 —— 只需把 git 替换成 rtk git。

03 / 04

两层过滤

RTK 的过滤能力分两层:第一层是 Rust 硬编码的专用 filter,为 40+ 个常用命令(git、cargo、npm 等)编写了精确的解析和优化逻辑。第二层是 TOML 声明式 filter,通过配置文件覆盖另外 60+ 个命令。两层通过 fallback 机制串联。

04 / 04

效果

同一个 git log 命令,经过 RTK 过滤后从 ~4,231 token 压缩到 ~1,384 token,缩减 67%。额外延迟 <10ms,零 LLM 调用成本。信噪比大幅提升 —— 每个 commit 只保留核心信息。

$ git log
commit a1b2c3d
Author: Alice <alice@example.com>
Date: Mon Apr 14 10:23:45 2026 +0800

    feat: add user authentication module

    Implements JWT-based auth with refresh tokens.
    Closes #142

    Signed-off-by: Alice <alice@example.com>
    Co-authored-by: Bob <bob@example.com>
commit e4f5g6h(Merge branch 'main')
Author: CI Bot <ci@example.com>
Date: Mon Apr 14 09:00:00 2026 +0800

    Merge pull request #141 from feature/logging
... 还有 48 条 commit ...
~4,231 tokens
User / Agent
RTK (CLI 代理)
系统命令 (git, ls, cargo...)
↓ 原始输出
RTK Filter Pipeline
↓ 精简输出
LLM Context
第一层
Rust 硬编码 Filter

40+ 命令的专用过滤器,每个命令有独立的解析和优化逻辑。

git loggit diffgit statuslscargo buildnpm test...
↓ fallback(未匹配到硬编码 filter 时)
第二层
TOML 声明式 Filter

60+ 命令通过 TOML 配置文件定义过滤规则,无需写 Rust 代码。

makegradlemvnkubectlterraformdocker...
$ rtk git log -10
a1b2c3d feat: add user authentication module (2 hours ago) <Alice>
Closes #142
f7g8h9i fix: resolve race condition in session handler (5 hours ago) <Bob>
j0k1l2m refactor: extract token validation logic (yesterday) <Alice>
~1,384 tokens
-67%
Token 缩减
<10ms
额外延迟
$0
LLM 成本

代码走读

以一次 rtk git log -10 调用为线索, 从入口到输出,走读 4 个关键函数。

01 / 04

入口:main() → run_cli()

程序从 main() 启动,核心逻辑在 run_cli() 中。Clap 库自动解析命令行参数为 Rust 枚举,然后通过 match 进行命令路由。

? 操作符在错误发生时立即 return,将错误沿调用链向上传播。match 穷举所有命令变体,确保每个命令都有处理逻辑。

02 / 04

核心流程:run_log()

当用户执行 rtk git log -10 时,路由到此函数。它构建 git 命令、注入 RTK 优化参数(自定义 format、limit、排除 merge)、执行命令,最后对输出进行后处理。

TimedExecution 计时器从头到尾记录执行耗时,用于 token 追踪分析。

03 / 04

过滤引擎:filter_log_output()

实际的过滤逻辑。按 ---END--- 标记分割 commit 块,每个 commit 只保留标题行和最多 3 行有意义的 body,去掉 trailer,截断长行。

迭代器链(.iter().take().map().collect())是 Rust 函数式风格的核心模式,零额外内存分配。

04 / 04

闭环:Token 追踪

过滤完成后,track() 记录原始输出和精简输出的 token 估算值到 SQLite。估算方式简单粗暴:每 4 字符约 1 个 token(len / 4)。不精确但 overhead 为零,适合高频命令的实时追踪。

数据写入 ~/.local/share/rtk/tracking.db,支持 90 天自动清理和日/周/月聚合查询。

// src/main.rs
fn main() {
let code = match run_cli() {
Ok(code) => code,
Err(e) => {
eprintln!("rtk: {:#}", e);
1
}
};
std::process::exit(code);
}
fn run_cli() -> Result<i32> {
let cli = Cli::try_parse()?;
// 命令路由:match 穷举所有子命令
let code = match cli.command {
Commands::Ls { args } => ls::run(&args, cli.verbose)?,
Commands::Git { command, .. } => {
git::run(command, &args, cli.verbose)?
}
// ... 40+ 命令
};
Ok(code)
}
// src/cmds/git/git.rs
fn run_log(args: &[String], verbose: u8, global_args: &[String]) -> Result<i32> {
let timer = tracking::TimedExecution::start();
let mut cmd = git_cmd(global_args);
cmd.arg("log");
// 智能默认值:仅在用户未指定时注入
if !has_format_flag {
cmd.args(["--pretty=format:%h %s (%ar) <%an>%n%b%n---END---"]);
}
if !has_limit_flag {
cmd.arg("-10");
}
cmd.arg("--no-merges");
// 执行真实 git 命令
let output = cmd.output().context("Failed to run git log")?;
let stdout = String::from_utf8_lossy(&output.stdout);
// 过滤输出 + 记录 token 节省量
let filtered = filter_log_output(&stdout, limit, user_set_limit, has_format_flag);
println!("{}", filtered);
timer.track("git log", "rtk git log", &stdout, &filtered);
Ok(0)
}
// src/cmds/git/git.rs
fn filter_log_output(output: &str, limit: usize, user_set_limit: bool, user_format: bool) -> String {
// 按 commit 块分割
let commits: Vec<&str> = output.split("---END---").collect();
let max_commits = if user_set_limit { commits.len() } else { limit };
let mut result = Vec::new();
for block in commits.iter().take(max_commits) {
let block = block.trim();
if block.is_empty() { continue; }
let mut lines = block.lines();
let header = truncate_line(lines.next().unwrap_or("").trim(), 80);
// 过滤 body:去 trailer,限 3 行
let body_lines: Vec<&str> = lines
.map(|l| l.trim())
.filter(|l| {
!l.is_empty()
&& !l.starts_with("Signed-off-by:")
&& !l.starts_with("Co-authored-by:")
})
.take(3)
.collect();
result.push(format_entry(&header, &body_lines));
}
result.join("\n")
}
// src/core/tracking.rs
pub fn estimate_tokens(text: &str) -> usize {
// ~4 chars per token(近似值,零开销)
(text.len() as f64 / 4.0).ceil() as usize
}
impl TimedExecution {
pub fn track(&self, original_cmd: &str, rtk_cmd: &str, input: &str, output: &str) {
let elapsed_ms = self.start.elapsed().as_millis() as u64;
let input_tokens = estimate_tokens(input);
let output_tokens = estimate_tokens(output);
if let Ok(tracker) = Tracker::new() {
// 写入 SQLite,失败不阻断命令执行
let _ = tracker.record(
original_cmd, rtk_cmd,
input_tokens, output_tokens, elapsed_ms,
);
}
}
}
Rust 概念速查对照表
Rust 概念你可能熟悉的对应物RTK 中的例子
enum 带数据TypeScript tagged union / Kotlin sealed classCommands::Git { command, ... }
matchswitch + 解构 + 穷举检查命令路由、错误处理
Result<T, E>Java checked exception / Go (val, err)几乎每个函数的返回值
Option<T>Java Optional<T> / Kotlin T?max_lines: Option<usize>
? 操作符throw / raise / return errcmd.output()?
&str vs Stringstring_view vs std::string (C++)参数用 &str,存储用 String
&T(借用)传引用 / 传指针&args, &self
mut默认 const,显式 mutablelet mut cmd = ...
迭代器链Java Stream / JS array 链式调用.iter().filter().map().collect()
Vec<T>ArrayList<T> / list[T]Vec<String>
#[derive(...)]Java @Lombok / Python @dataclass#[derive(Parser)]
lazy_static!Java static final + 延迟初始化所有正则表达式