Show HN: Lowfat – pluggable CLI filter that saved 91.8% of my LLM tokens
摘要
Lowfat 是一个轻量级 CLI 工具,通过对 CLI 输出和文件内容进行过滤来降低 AI 代理的 token 成本。核心是小型单二进制可扩展组件、本地优先(无遥测)、UNIX 管道风格的可组合性以及用户可自有历史记录。提供了 git、docker、ls 等命令的 before/after 对比示例以及嵌入式样本中命令输出削减比例(例如 git log ultra 级别可达 91% 削减)。支持预构建二进制、Claude Code 钩子(PreToolUse 和 PostToolUse)、Shell 集成、OpenCode 插件、Pi agent 以及直接命令前缀使用。包含 post-read 文件压缩功能(源码、Markdown、JSON、锁文件等按 lite/full/ultra 级别处理)、架构图、配置文件和插件文档。另有与 rtk 等工具的对比,以及单次运行在同一仓库的 token 节省数据(使用 tiktoken 计数)。
荐读理由
提供 .lf DSL 插件方式与 PostToolUse 后读压缩钩子,能直接迁移到 AI 工程项目中过滤命令输出和文件内容,减少 agent 上下文;代码过滤压缩、锁文件摘要和 git 差异等具体实现提供真实 token 节省技术变化。
原文
lowfat is a lightweight CLI tool that reduces AI token costs by filtering CLI output and file content before it reaches your agent.
Core focus
Lightweight — Small single binary, small core; but extensible.
Local-first — No telemetry; you own your data.
Composable — UNIX-style pipes, mix built-ins and your own filters; not magic.
User-owned —
lowfat historyshows what you run most; allow you to customize for your usecase.
Before / after
git status at the full level — same signal, less noise.
Before — raw git status:
On branch main
Your branch is up to date with 'origin/main'.
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: crates/lowfat-cli/src/commands/plugin.rs
modified: crates/lowfat-cli/src/main.rs
Untracked files:
(use "git add <file>..." to include in what will be committed)
plugins/git/git-compact/samples/
no changes added to commit (use "git add" and/or "git commit -a")
After — lowfat git status:
On branch main
Changes not staged for commit:
modified: crates/lowfat-cli/src/commands/plugin.rs
modified: crates/lowfat-cli/src/main.rs
Untracked files:
plugins/git/git-compact/samples/
Reduction of raw command output, measured on the bundled samples (crates/lowfat-plugin/embedded/*/samples/). Reproduce with cat <sample> | lowfat filter <plugin>/filter.lf --sub=<sub> --level=<level>:
| command | lite |
full |
ultra |
|---|---|---|---|
git diff |
-16% | -38% | -96% |
git log |
-53% | -80% | -91% |
git status |
-62% | -62% | -74% |
docker ps |
-38% | -38% | -85% |
docker images |
-48% | -58% | -86% |
ls -la |
-2% | -75% | -87% |
These percentages are the reduction of a single command's output, not your end-to-end agent token usage. savings depend on how much of your context is command output and how lossy a level you pick — higher levels drop more, so verify your agent still has what it needs. treat the table as a ceiling on the output slice, not a promise on the total.
Install
cargo install lowfat
# or
brew install zdk/tools/lowfat
Pre-built binaries on GitHub Releases.
Setup
Pick one of:
Claude Code hook — add to .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [{ "type": "command", "command": "lowfat hook" }]
}
],
"PostToolUse": [
{
"matcher": "Read",
"hooks": [{ "type": "command", "command": "lowfat post-read" }]
}
]
}
}
PreToolUse rewrites Bash commands through lowfat filters. PostToolUse compresses file content after Read — strips comments, collapses function bodies, summarizes lock files.
The filtering pattern Anthropic recommends, but via lowfat.
Shell integration — auto-activates inside agent environments (CLAUDECODE=1, CODEX_ENV), or set LOWFAT_ENABLE=1 to force it on any shell:
echo 'eval "$(lowfat shell-init zsh)"' >> ~/.zshrc # or ~/.bashrc
OpenCode plugin — one command, no config editing:
lowfat opencode install # writes ~/.config/opencode/plugins/lowfat.ts
Restart OpenCode; commands are rewritten transparently before they run. Uninstall with lowfat opencode uninstall.
Direct usage — prefix any command:
lowfat git status
lowfat docker ps
lowfat ls -la
Pi agent — in ~/.pi/agent/settings.json:
{ "shellCommandPrefix": "eval \"$(lowfat shell-init zsh)\"; " }
Usage highlights
# See what's configured and how loud each filter is being
lowfat info # status badge + active filters
lowfat info git # pipeline for `git`
lowfat info --config # full resolved config
# See what lowfat has saved you
lowfat stats # lifetime token savings
lowfat stats --audit # recent plugin executions
lowfat history # rank commands by potential savings
# Dial the aggressiveness
lowfat level ultra # max compression
LOWFAT_LEVEL=lite lowfat git log # one-off override
# Write a plugin
lowfat plugin new terraform # scaffold ~/.lowfat/plugins/terraform/
lowfat plugin doctor # check plugins (and pre-install any Python deps)
# Test a plugin against a sample without installing it
cat samples/git-diff-full.txt | lowfat filter --explain ./filter.lf --sub=diff --level=ultra
File content compression (post-read)
When Claude reads files, lowfat post-read compresses the content before it enters the context:
| Content type | What it does |
|---|---|
| Source code (Rust, Python, Go, Elixir, JS/TS, Java, Ruby, C/C++, Shell) | Strip comments, normalize blanks; at ultra: collapse function bodies to signatures |
| Markdown | Strip badges, HTML comments; truncate code blocks and tables |
| HTML / Vue / Svelte | Strip <style>, <script>, class attributes; at ultra: text extraction only |
| JSON / JSONC | Truncate large arrays, collapse deep nesting |
| Lock files (Cargo.lock, package-lock.json, yarn.lock, ...) | Replace with summary: package count + top deps |
| Unknown | Head + tail with line count |
Compression level follows LOWFAT_LEVEL (lite/full/ultra). Files with <10% savings pass through unchanged.
Learn more
docs/ARCHITECTURE.md — high-level diagram: CLI, Runner, Plugins, Builtins
docs/CONFIG.md —
.lowfatfile, env vars, pipeline DSL, built-in processors, thehistoryrankingdocs/PLUGINS.md — lf-filter (the
.lfplugin DSL), shell escape hatches, PEP 723 + uv, AI agent prompt
Alternatives
vs rtk
rtk is the closest tool but differ in philosophy: rtk is batteries-included; lowfat is a minimal core you extend yourself.
| lowfat | rtk | |
|---|---|---|
| Built-in commands | 6 curated (git, docker, grep, find, ls, tree) |
100+ across many ecosystems |
| Custom filters | .lf DSL + shell + Python (PEP 723/uv) |
TOML DSL |
| Levels | lite / full / ultra |
-l aggressive, --ultra-compact |
| File-content filtering | post-read hook (code, markdown, HTML, data, lock files) |
rtk read / smart (signatures, summaries) |
| Agent integrations | Claude Code, OpenCode, shell, Pi | 14 tools (Claude Code, Copilot, Gemini, Codex, …) |
| Telemetry | None — local-only | Opt-in, off by default (anonymous aggregate) |
| Savings analytics | lowfat stats / history (local) |
rtk gain / discover (local) |
Token savings, head-to-head
Same commands, same repo, same cwd, run through both tools. Output tokens counted with tiktoken (cl100k_base); savings are vs the raw command output:
| command | raw tokens | lowfat full |
lowfat ultra |
rtk |
|---|---|---|---|---|
git status |
81 | -91% | -91% | -79% |
git diff |
1241 | -15% | -97% | -9% |
git log |
3350 | -93% | -97% | -56% |
ls -la |
153 | -77% | -89% | -86% |
find |
535 | -0% | -58% | -66% |
Honest read: lowfat compresses git harder; rtk edges out find; ls is close. find only engages at lowfat's ultra level. rtk's --ultra-compact gave near-identical numbers to its default here, so the default is shown. This is a single small run on one repo — directional, not a benchmark; measure on your own workload before trusting any of it.
License
Apache-2.0
AI notice
Multiple AI tools were used for this project
Star History
这条对你有帮助吗?
