Minify LLM prompts to save tokens — domain-aware, tiktoken-validated, zero regressions.
Project description
PromptMin
Minify LLM prompts to save tokens — without losing meaning.
LLM APIs charge per token, and non-English prompts (especially Spanish) can use 20–30% more tokens than their English equivalents. PromptMin rewrites your prompts into a denser form using curated, domain-aware substitutions, and reports real token savings measured with tiktoken.
Core guarantee. Every substitution rule is validated against
tiktokenat runtime. If a rule does not reduce token count, it is skipped. PromptMin never makes your prompt longer.
Why?
Most "token savers" are naive find-and-replace scripts that don't actually save tokens (because BPE tokenizers don't count characters). PromptMin is different:
- Mathematically validated. Rules are only applied when the tokenizer confirms they save tokens.
- Curated, not massive. ~400 high-signal rules beat 100,000 random ones.
- Domain-aware. Activate dictionaries by context (
web,backend,ai…) for aggressive but safe compression. - Multi-tokenizer. Optimize for the model you target: GPT-4o, GPT-4, Claude, Gemini.
- Bilingual. First-class Spanish + English, extensible to any language via YAML.
- Honest benchmarks. Run
promptmin benchmarkon your own corpus and see real numbers.
Real numbers
Measured on the included corpus examples/corpus_domains.txt (18 mixed EN/ES technical prompts):
Savings by configuration (tokenizer: gpt-4):
| Configuration | Tokens saved | Avg per prompt | Best |
|---|---|---|---|
| General rules only | 2.2% | 1.9% | 23.1% |
| + domain dictionaries | 23.9% | 23.2% | 38.5% |
| + domains + translate + aggressive | 25.3% | 24.5% | 42.3% |
Savings by tokenizer (config: lite + all domains):
| Tokenizer | Family | Total saved | Notes |
|---|---|---|---|
gpt-4 / cl100k |
OpenAI | 23.9% | Exact — used by GPT-4, GPT-3.5 |
claude |
Anthropic | 23.9% | Approximate (cl100k_base proxy) |
gemini |
23.9% | Approximate (cl100k_base proxy) | |
gpt-4o / o200k |
OpenAI | 21.7% | Exact — used by GPT-4o, o1, o3 |
The newer
gpt-4otokenizer (o200k_base) is already more efficient on raw text thancl100k_base, which is why PromptMin has slightly less margin to optimize on it. This is the honest reality — and exactly why benchmarking matters.
Zero regressions across all modes and all tokenizers. The validator guarantees it.
A note on Spanish prompts and modern tokenizers
If you write prompts in Spanish and target gpt-4o (or any modern o200k_base-family model), always use --translate. Without it, savings are modest (~10-15%). With it, savings jump to ~25-40%.
Why? Modern BPE tokenizers learn very efficient merges for common Spanish constructs like "una función", "la base de datos", "por favor". Substituting a single word ("función" → "func") inside Spanish text often produces zero token savings because the original Spanish merge was already compact. The only reliable way to save tokens on Spanish is to rewrite larger chunks into English at once, so BPE merges align on both sides.
This is why PromptMin v0.3+ uses phrase-level translation patterns (dicts/es_en_phrases.yaml) as the primary strategy for Spanish, applied BEFORE word-level rules. A simple prompt like:
"Por favor, desarrolla una función en Python que consulte la base de datos de usuarios y retorne un JSON con los activos"
goes from 24 → 15 tokens (37.5% saved) on gpt-4o with --translate, vs only 12.5% without.
Install
pip install promptminify
On PyPI the package is
promptminify(becausepromptminwas already taken), but the CLI command and Python import name are bothpromptmin:promptmin --helpfrom promptmin import minify
From source (development)
git clone https://github.com/DelvyG/promptmin.git
cd promptmin
pip install -e ".[dev]"
Usage
CLI
# Inline
promptmin run "Please, I would like you to build a function step by step"
# From file / clipboard / stdin
promptmin run --file prompt.txt
promptmin run --clipboard --out-clipboard
cat prompt.txt | promptmin run
# With domain dictionaries
promptmin run -d web,backend "Improve the user experience and add JWT authentication"
# Target a specific model's tokenizer
promptmin run -T claude "..."
promptmin run -T gpt-4o "..."
promptmin run -T gemini "..."
# List all available tokenizers
promptmin tokenizers
# Spanish with automatic EN technical translation
promptmin run -t "Por favor, desarrolla una función paso a paso para la base de datos"
# Aggressive mode (strips more filler)
promptmin run -m aggressive "..."
# List available domain dictionaries
promptmin domains
# Benchmark on a corpus
promptmin benchmark examples/corpus_domains.txt -d web,backend,devops,data,ai
# Just count tokens
promptmin count "hello world"
As a library
from promptmin import minify
from promptmin.tokens import savings
result = minify(
"Please improve the user experience on mobile responsive devices",
domains=["web"],
)
print(result["minified"])
print(savings(result["original"], result["minified"]))
# {'before': 11, 'after': 7, 'saved': 4, 'pct': 36.4}
How it works
┌─────────────┐
│ Your text │
└──────┬──────┘
▼
┌─────────────────────┐
│ 1. Detect language │ es / en (cheap heuristic)
└──────┬──────────────┘
▼
┌─────────────────────────────────────┐
│ 2. Domain dicts (highest priority) │ e.g. "user experience" -> "UX"
└──────┬──────────────────────────────┘
▼
┌─────────────────────────┐
│ 3. Language dict │ "please" -> "", "configuration" -> "config"
└──────┬──────────────────┘
▼
┌───────────────────────────────────┐
│ 4. ES→EN translation (optional) │ "desarrolla" -> "build"
└──────┬────────────────────────────┘
▼
┌─────────────────────┐
│ 5. Stopword strip │
└──────┬──────────────┘
▼
┌─────────────────────┐
│ 6. Whitespace clean │
└──────┬──────────────┘
▼
┌──────────────────────────────┐
│ Minified output + stats │
└──────────────────────────────┘
The validator. Every step applies rules one at a time. Before accepting a substitution, it calls tiktoken.encode() on before/after. If tokens didn't drop, the rule is discarded. This is why PromptMin can't make your prompt worse.
Dictionary architecture
src/promptmin/dicts/
├── en.yaml General English rules
├── es.yaml General Spanish rules
├── es_en.yaml Spanish → English technical translation
└── domains/
├── ai.yaml LLM / RAG / CoT / fine-tuning / embeddings
├── backend.yaml API / JWT / ORM / middleware / queues
├── data.yaml ETL / warehouses / KPIs / schemas
├── devops.yaml CI/CD / Kubernetes / SLO / observability
└── web.yaml UX / UI / SPA / PWA / responsive
Each file is plain YAML: "long phrase": "short version". No code required to contribute a new domain — drop a YAML file in dicts/domains/ and it's automatically picked up by promptmin domains.
Roadmap
- Phase 1 — MVP CLI (EN + ES dicts, tiktoken-validated)
- Phase 2 — Benchmark on real corpus,
lite/aggressive/translatemodes - Phase 2.5 — Domain dictionaries (
web,backend,devops,data,ai) - Phase 3 — Multi-tokenizer support: GPT-4o / GPT-4 / Claude / Gemini
- Phase 3.5 — Spanish phrase-level translation (
es_en_phrases.yaml) - Phase 3.6 — Official SDK integration for exact Claude/Gemini counts (optional extras)
- Phase 3.6 — More phrase patterns based on real-usage corpora
- Phase 4 — VSCode extension ("Minify Selection" + keybinding)
- Phase 4 — More domains:
mobile,security,gamedev,finance - Phase 4 — Domain auto-detection from prompt content
Contributing
Contributions are very welcome — especially new domain dictionaries and language support. See CONTRIBUTING.md.
The lowest-friction contribution is a new domain YAML: no Python, no tests, just curated phrases.
License
MIT © DelvyG
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file promptminify-0.3.0.tar.gz.
File metadata
- Download URL: promptminify-0.3.0.tar.gz
- Upload date:
- Size: 23.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a945c9711462080be5b8042c028668dd6cb1b5170699f307a5a9e8f797ba6b3f
|
|
| MD5 |
ccdfbe3c9731e4f0a728fb193ea252a7
|
|
| BLAKE2b-256 |
8f34452e8b918ecb5f41bd1d9cca32e524bc8850a51f41c16d01684d5f1c9df6
|
Provenance
The following attestation bundles were made for promptminify-0.3.0.tar.gz:
Publisher:
publish.yml on DelvyG/promptmin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
promptminify-0.3.0.tar.gz -
Subject digest:
a945c9711462080be5b8042c028668dd6cb1b5170699f307a5a9e8f797ba6b3f - Sigstore transparency entry: 1246147255
- Sigstore integration time:
-
Permalink:
DelvyG/promptmin@08201a20ff5e58a0fc8d053934034873a7e7382b -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/DelvyG
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@08201a20ff5e58a0fc8d053934034873a7e7382b -
Trigger Event:
push
-
Statement type:
File details
Details for the file promptminify-0.3.0-py3-none-any.whl.
File metadata
- Download URL: promptminify-0.3.0-py3-none-any.whl
- Upload date:
- Size: 22.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
985c4bfb0541e8a265b99e00c3d29cc70adcc3e54c034d20137905567fc795dc
|
|
| MD5 |
d22edfac681d2e2dafc09a7eb244cf18
|
|
| BLAKE2b-256 |
c3904d397ffb0395f9f1c20b0493b1e20756961419e324babe115d56420d1a6a
|
Provenance
The following attestation bundles were made for promptminify-0.3.0-py3-none-any.whl:
Publisher:
publish.yml on DelvyG/promptmin
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
promptminify-0.3.0-py3-none-any.whl -
Subject digest:
985c4bfb0541e8a265b99e00c3d29cc70adcc3e54c034d20137905567fc795dc - Sigstore transparency entry: 1246147270
- Sigstore integration time:
-
Permalink:
DelvyG/promptmin@08201a20ff5e58a0fc8d053934034873a7e7382b -
Branch / Tag:
refs/tags/v0.3.0 - Owner: https://github.com/DelvyG
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@08201a20ff5e58a0fc8d053934034873a7e7382b -
Trigger Event:
push
-
Statement type: