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. 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 wenyan-cjk-tokenizer-models-only : 閱引請作察變檔驗碼引退存為要查者增試 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 | php 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: php 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 dir Gemini CLI — gemini extensions install everything else — npx skills add kdeps/turo --skill turo -a