cd /news/developer-tools/show-hn-turo-an-aggressive-token-sav… · home topics developer-tools article
[ARTICLE · art-71199] src=github.com ↗ pub= topic=developer-tools verified=true sentiment=· neutral

Show HN: Turo – An Aggressive Token-Saving Proxy for CLI AI Agents

A developer released Turo, an open-source token-saving proxy for CLI AI agents that reduces prompt token counts by up to 70% by stripping articles, prepositions, and repeated words while preserving code and identifiers. The tool, installable via Homebrew, Go, or shell script, supports multiple compression levels and works with agents like Claude Code, Codex, and Gemini.

read11 min views1 publishedJul 24, 2026
Show HN: Turo – An Aggressive Token-Saving Proxy for CLI AI Agents
Image: source

Point more. Token less.

A real instruction block — 138 tokens (cl100k):

When you are reviewing a pull request, please make sure that you carefully
examine each of the changed files and verify that the new code does not
introduce any regressions in the existing behavior. It is really important that
you check whether the author has added appropriate tests for the new
functionality, because untested code is very likely to break in subtle ways that
are difficult to debug later. You should also confirm that the documentation has
been updated to reflect the changes, and that the commit messages clearly
explain what was changed and why. If you notice any potential security
vulnerabilities, such as unsanitized user input or hardcoded credentials, you
must flag them immediately and request changes before the pull request can be
merged.

becomes 54 tokens — 61% fewer (turo

, meaning intact):

Reviewing pull request make examine changed files verify new code introduce
regressions existing behavior important check author added appropriate tests
functionality untested break subtle ways difficult debug later also confirm
documentation updated reflect changes commit messages explain notice potential
security vulnerabilities unsanitized user input hardcoded credentials must flag
merged

or 41 tokens — 70% fewer at --level ultra

(deduped by lemma):

Review pull request make examine change file verify code introduce regression
exist behavior important check author add test untested break debug later
confirm documentation updated reflect commit message notice security
vulnerability unsanitized user input hardcoded must flag merge

Or 69 characters with --level wenyan

, which additionally swaps each word for a single Classical Chinese character (for CJK-tokenizer models — see wenyan):

閱引請作察變檔驗碼引退存為要查者增試 untested 破診後證文更映交訊覺安隙 unsanitized 戶入 hardcoded 須標併

766 -> 69 characters (35 Han chars). Token counts for that output:

tokenizer tokens
Qwen / DeepSeek / GLM (~1 per Han char) ~42
OpenAI cl100k (2-3 per Han char) 67

So wenyan wins on CJK-tokenizer models (~42 vs plain ultra

's ~71) but loses on OpenAI (67 vs 41) — use it only with CJK models. See below.

No articles. No prepositions. No adverbs. No repeated words. Only the content words that carry meaning, deduplicated, in reading order. Every prompt, every turn — the savings compound. If a reduction is not smaller than the input, turo passes the original through unchanged.

Install turo once and any coding agent that can shell out to a binary — Claude Code, Codex, Gemini, Cursor, Windsurf, Cline, Copilot, and 20+ more — pipes its context through the same reducer. Code, paths, and identifiers pass through untouched.

Method Command
Homebrew
brew install kdeps/tap/turo
Go
go install github.com/kdeps/turo@latest
Shell
`curl -fsSL https://raw.githubusercontent.com/kdeps/turo/main/install.sh sh`
Manual
Download from
cat CLAUDE.md | turo              # text -> deduped content words
echo "fox jumps over dog" | turo  # pipe mode
turo --preamble                   # wrap for system prompt injection
turo -passes 1                    # single pass (default runs to convergence)
turo -filler=false                # skip filler deletion
turo -synonyms=false              # skip the synonym pass (keep words verbatim)
turo -gloss=false                 # skip the defining-word swap (less lossy)
turo -arrows                      # replace connective phrases with -> (opt-in)
turo --version                    # print version

-gloss

(on by default) replaces each word with the shortest same-part-of-speech word from its own dictionary definition (approach

-> come

). Definitions are prose, not synonyms, so it is the lossiest stage — disable it with -gloss=false

/ TURO_GLOSS=off

when you need words closer to the original.

-arrows

(off by default) replaces multi-word causal/sequential connectives (leads to

, results in

, gives rise to

, which produces

) with a single ->

token. Only multi-word phrases qualify, so the swap always saves at least one token; single-token connectives (then

, becomes

, thus

) are left alone because ->

costs the same. Enable with -arrows

/ TURO_ARROWS=on

.

A cache miss leads to a slow query which produces a timeout
                     |  -arrows
Cache miss -> slow query -> timeout

Every run is four stages, each on by default:

text -> [1] delete filler -> [2] swap cheaper synonyms -> [3] swap defining words -> [4] reduce to content words

Filler deletion removes pleasantries, hedges, and leaders that survive word-level stopword lists (please

,I think

,of course

,let me

), while protecting code, paths, URLs, and identifiers verbatim. Disable with-filler=false

/TURO_FILLER=off

.Synonym swap replaces words with a fewer-token synonym (see below). Disable with-synonyms=false

/TURO_SYNONYMS=off

.Gloss swap replaces words with the shortest defining word from their dictionary definition — the lossiest stage. Disable with-gloss=false

/TURO_GLOSS=off

.Reduction drops the remaining stopwords, keeps content words by part of speech, deduplicates, and (ultra) collapses inflections by lemma.

Arrows (opt-in, runs before reduction) rewrites multi-word connective phrases to ->

, which the reducer keeps verbatim between the surviving content words. Off by default; enable with -arrows

/ TURO_ARROWS=on

.

The whole pipeline repeats until the output stops changing (-passes 0

, the default; a positive -passes N

caps the count). The first pass keeps document structure (headings, per-section bodies); later passes flatten that and dedupe across it, so large structured docs keep shrinking before converging — this README goes 522 (1 pass) -> 376 tokens (converged, ~29 passes). Set -passes 1

to keep it single-shot.

turo never emits output larger than the input: if a stage does not save tokens, the text passes through unchanged.

turo runs a first pass that replaces each word with a fewer-token synonym before reducing (utilize

-> use

, demonstrate

-> show

). The table is built from WordNet synsets (real synonyms) and frequency-filtered so swaps land on common words, then gated to same-part-of-speech words and validated to cost strictly fewer tokens. turo still passes the original through if the result is not smaller.

Disable it with -synonyms=false

or TURO_SYNONYMS=off

when you need words verbatim. The gain is usually small — modern tokenizers already encode most words as a single token. WordNet polysemy also leaves some noise (leverage

-> purchase

), so keep it opt-in for prose, not code. The table is generated by tools/gensyn.py

(WordNet + wordfreq + the cl100k tokenizer), so token counts are measured for cl100k, not the target model's tokenizer.

Level What it keeps Reduction
lite
Adjectives, nouns, verbs, and leftover adverbs/prepositions ~65%
full
Adjectives, nouns, verbs ~70%
ultra (default)
Nouns and verbs only, deduplicated by lemma (base form) ~70%+
wenyan
ultra, then swap surviving words for a single 文言 (Classical Chinese) character CJK models only
echo "the quick brown fox jumps over the lazy dog" | turo --level lite   # quick brown fox jumps over lazy dog
echo "the quick brown fox jumps over the lazy dog" | turo --level full   # quick brown fox jumps lazy dog
echo "the quick brown fox jumps over the lazy dog" | turo --level ultra  # fox jump dog
echo "the wise king studies the old book" | turo --level wenyan    # 智王學舊書

wenyan

reduces at ultra, then swaps each surviving English content word for one Classical Chinese character (water

->

, king

->

, verify

->

) from a ~380-entry hand-curated lexicon. One char per concept, no spaces (Classical Chinese has none).

Two examples, measured:

input ultra wenyan chars cl100k CJK-model (~1/char)
The wise king uses water and fire... (80 ch)
Wise king use water fire person see mountain old tree
智王用水火人見山舊樹
10
15 ~10
the PR-review paragraph (766 ch) 283 ch / 41 tok 閱引請作察變檔驗碼引退存為要查者增試 untested 破診後證文更映交訊覺安隙 unsanitized 戶入 hardcoded 須標併
69
67 ~42

It collapses to the fewest characters (766 -> 69 on the paragraph). A CJK character is 2-3 tokens on OpenAI's cl100k, so wenyan

is larger there (67 > 41). It only wins on CJK-optimized tokenizers (Qwen, DeepSeek, GLM), where a common character is ~1 token — then those 69 chars are ~42 tokens vs plain ultra's 71. Don't use it with OpenAI models.

turo's own token estimator counts CJK as 1 rune = 1 token (matching those models), so it treats wenyan

as a reduction and never rejects it. Words outside the lexicon stay English (untested

, unsanitized

, hardcoded

above); code/paths/URLs are preserved verbatim. Extend wenyanMap

for more coverage.

In ultra, inflections of the same word collapse to one token by their dictionary base form: goes

, went

, going

-> go

; children

-> child

; servers

-> server

. A reduction is only applied when it lands on a real dictionary word, so no mangled non-words are ever emitted.

Set default via TURO_LEVEL

env var.

To compress all input for an agent that turo can't reach from the inside (Claude Code, Codex, ...), route the agent's requests through turo.

turo run claude          # every claude request reduced, base URL wired for you
turo run codex           # OPENAI_BASE_URL wired instead
turo run                 # list supported agents

turo run

starts an in-process proxy on a free port, points the agent's base-URL env var at it (ANTHROPIC_BASE_URL

for claude, OPENAI_BASE_URL

for OpenAI-compatible agents), execs the agent, and stops the proxy when it exits. One command, no exports, no /turo

inside the agent. Supported: claude

, codex

, opencode

, qwen

, aider

, crush

, goose

, amp

.

turo -proxy -upstream https://api.openai.com   # listens on 127.0.0.1:8787
export OPENAI_BASE_URL=http://127.0.0.1:8787/v1

Every /chat/completions

(and Anthropic /messages

) request has its message content reduced before it reaches the real endpoint; the response streams back untouched. By default only user

and tool

content is reduced (system and assistant history are left verbatim, since they are lossier to touch) — pass -proxy-all

to reduce every role. Auth headers pass through; non-chat paths are forwarded unchanged.

kdeps does not need this: in agent mode it already pipes the preamble, input, tool results, and history through turo before every call.

npx turo

installs the binary and registers the turo skill + /turo

command with every coding agent it finds on your machine — Claude Code, Gemini CLI, opencode, Codex, Cursor, Windsurf, Cline, Copilot, and 20+ more. Install once; every agent gets the same reducer.

npx turo                 # binary + register with detected agents
npx turo --list          # show every supported agent and its status
npx turo --only claude   # register with one agent
npx turo --all           # register with every supported agent
npx turo --no-binary     # register agents only (binary already installed)
npx turo --uninstall     # remove binary + registered skills

Under the hood each agent gets one of:

Claude Code / opencode— the skill and/turo

command are copied into the agent's config dirGemini CLIgemini extensions install

everything elsenpx skills add kdeps/turo --skill turo -a <profile>

Once turo is on PATH, any agent can also pipe context through it directly:

cat CLAUDE.md | turo --preamble    # compact system prompt
cat error.log | turo               # reduce log output

Set TURO_LEVEL=ultra

for maximum compression. KDEPS_TURO=off

or TURO_DISABLED=1

to disable.

  • Code blocks and inline code — passed through unchanged

  • URLs, file paths, version numbers — verbatim

  • Technical terms (API names, CLI commands, error strings) — exact

  • Embedded English dictionary (120k words, 14MB) classifies every word

  • Strips articles, prepositions, conjunctions, pronouns (~70 stop words)

  • Keeps the content words for the level (nouns, verbs, adjectives)

  • Deduplicates and emits them in reading order — then keeps the result only if it is actually smaller than the input

caveman is a sibling idea with the opposite dial. caveman deletes filler with regex (articles, pleasantries, hedges) and keeps readable prose. turo runs that same filler pass, then keeps going — POS-classifying, deduplicating, lemmatizing, and swapping words for shorter synonyms and glosses — trading readability for a much smaller token count.

Same input, measured with the cl100k tokenizer:

output tokens
input Please, I think you should really just utilize this approach to demonstrate the functionality of the component.
19
caveman You should utilize this approach to demonstrate functionality of component.
11
turo full Use come show functionality component
5
turo ultra Use come show component
4
caveman turo
method regex filler removal dict POS + dedup + lemma + synonyms + gloss
output readable prose keyword stream
dictionary / WordNet no yes
synonym / gloss swaps no yes (on by default)
best when you still need to read it you only feed it to an LLM

Use caveman when a human reads the result; use turo when only a model does.

System prompts are 50-200k tokens. Most of those words carry grammar, not meaning. Turo points at what matters and drops the rest.

Point more. Token less.

── more in #developer-tools 4 stories · sorted by recency
── more on @turo 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
Live at https://your-agent.zahid.host
Get free account → Pricing
from €0/mo · no card required
LIVE [news/show-hn-turo-an-aggr…] indexed:0 read:11min 2026-07-24 ·