Reduce AI token costs by filtering CLI output
Lightweight CLI that filters verbose command output and file content before it reaches your AI agent, cutting token usage.
Why it matters
Lowfat helps developers reduce AI agent token consumption and costs by intelligently filtering unnecessary CLI output before it reaches the agent, making agent-assisted coding more efficient and affordable.
Outcomes
What it gets done
Filter verbose command output (git diff, docker ps, ls) to remove noise before sending to AI agents
Track and analyze which commands consume the most tokens with history ranking and stats
Integrate with Claude Code, OpenCode, Pi agent, or any shell via hooks and auto-activation
Create custom filters using the plugin DSL to handle domain-specific CLI tools like terraform
Install
Add it to your toolbox
Run in your project directory:
curl -fsSL https://spark.entire.vc/get/zdk-lowfat | bash Overview
Lowfat
Lightweight CLI that filters verbose command output (git, docker, grep, find, ls, tree) and compresses file content on Read before it reaches an AI agent's context, at a chosen lite/full/ultra aggressiveness level, cutting per-command output tokens by up to 96% in the project's own measurements. Use it whenever an agent's context is being filled with noisy CLI output or large file reads it doesn't fully need - wired in as a Claude Code hook, a shell integration, or an OpenCode plugin. Not needed if command output and file reads are already a small share of context usage.
What it does
Lowfat is a lightweight, local-first CLI tool that reduces AI agent token costs by filtering verbose command output and file content before it ever reaches the agent's context. It ships with 6 curated built-in filters (git, docker, grep, find, ls, tree) plus a post-read hook that compresses file content by type - stripping comments and collapsing function bodies in source code, stripping badges/HTML comments and truncating tables in Markdown, stripping style/script tags in HTML/Vue/Svelte, truncating large JSON arrays, and replacing lock files (Cargo.lock, package-lock.json, yarn.lock) with a package-count-and-top-deps summary.
When to use - and when NOT to
Use it whenever an agent's context is getting filled with noisy raw CLI output (a git status with instructional comments, a verbose git log, a wide docker ps) or large file reads it doesn't need in full. On the project's own bundled samples, filtering reduces single-command output by 16-96% depending on the command and the chosen level (lite, full, ultra) - the project is explicit that these are ceiling numbers on that command's output slice, not a promise about total end-to-end agent token savings, and that higher levels drop more content, so it's worth verifying the agent still has what it needs after enabling ultra. It only engages meaningfully where CLI output or file reads make up a real share of context usage; files with under 10% measured savings pass through unchanged.
Inputs and outputs
Install via cargo install lowfat or brew install zdk/tools/lowfat, or a prebuilt binary from GitHub Releases. Wiring options include a Claude Code hook (PreToolUse rewrites Bash commands through lowfat filters via lowfat hook; PostToolUse compresses Read output via lowfat post-read, following the offload pattern Anthropic recommends), shell integration that auto-activates inside agent environments (CLAUDECODE=1, CODEX_ENV) or via LOWFAT_ENABLE=1, a one-command OpenCode plugin install (lowfat opencode install), a Pi agent shellCommandPrefix setting, or direct prefixing of any command (lowfat git status). lowfat info, lowfat stats, and lowfat history show active filters, lifetime token savings, and which commands would save the most if filtered. lowfat level ultra (or a one-off LOWFAT_LEVEL=lite override) adjusts aggressiveness, and lowfat plugin new <name> scaffolds a custom filter using the .lf plugin DSL.
Integrations
Compared to the closest alternative, rtk (which the README benchmarks head-to-head with real token counts via tiktoken), lowfat positions itself as a minimal, extensible core rather than a batteries-included tool: 6 curated built-ins versus 100+ in rtk, custom filters via a .lf DSL plus shell/Python (PEP 723/uv) versus rtk's TOML DSL, and integrations with Claude Code, OpenCode, shell, and Pi versus rtk's 14 supported tools. Both are local-only or opt-in on telemetry; the head-to-head numbers show lowfat compressing git output harder while rtk edges out find.
Who it's for
Developers running AI coding agents who want to cut context/token spend from noisy shell output and file reads - especially heavy git/docker users - and who'd rather extend a small, transparent filtering core themselves than adopt a larger all-in-one tool.
Source README
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 withcat <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, thehistoryranking - docs/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.
AI notice
Multiple AI tools were used for this project
Star History
FAQ
Common questions
Discussion
Questions & comments ยท 0
Sign In Sign in to leave a comment.