✂️ prompt-optimizer
Cut your LLM prompts down to size — automatically.
Whitespace cleanup · dedup · tool minification · history & RAG trimming — all local, zero-dependency.
prompt-flamegraph shows you where your prompt tokens go. prompt-optimizer cuts them. Same structured-prompt format, same zero-dependency philosophy — feed it a prompt, get a smaller prompt plus a report of every change.
📦 PyPI note: the name
prompt-optimizerwas already taken on PyPI, so this package ships aspromptflame-optimizer. The import name is stillprompt_optimizerand the CLI is stillprompt-optimizer.
Install
pip install promptflame-optimizer
| Extra | Why |
|---|---|
pip install promptflame-optimizer[flamegraph] |
accurate token counting + waste findings via prompt-flamegraph |
pip install promptflame-optimizer[dev] |
pytest, build, twine |
With no dependencies at all, a built-in word-count estimator is used; with prompt-flamegraph installed, its tokenizer pipeline (tiktoken/words/model encodings) is used automatically.
Quick start
from prompt_optimizer import optimize
prompt = {
"system_prompt": "You are a helpful assistant.",
"chat_history": [...], # OpenAI-style messages
"tools": [...], # tool schemas
"rag_context": {...}, # retrieved docs
}
report = optimize(prompt, token_budget=8000, keep_last_n=20)
print(report.original_tokens, "->", report.optimized_tokens)
print(report.savings_pct, "% saved, under budget:", report.under_budget)
use_this = report.optimized # your prompt is never mutated
OpenAI/Anthropic-style request bodies ({"messages": [...], "system": ...}) and bare message lists are auto-normalized, just like prompt-flamegraph's normalize() — except tool_calls/tool_call_id keys are preserved so history trimming never splits a tool-call pair.
Dry-run without applying:
from prompt_optimizer import suggest
for s in suggest(prompt, token_budget=8000):
print(f"[{s.kind}] {s.path}: {s.message} (~{s.tokens_saved} tokens)")
Strategies
Applied cheap-and-lossless first, aggressive last:
| Order | Strategy | What it does | CLI flag |
|---|---|---|---|
| 1 | whitespace |
Collapses 3+ newlines to 2, strips trailing spaces — fenced code blocks untouched | --no-whitespace |
| 2 | dedup |
Removes exact-duplicate leaves (NFC-aware), duplicate messages, repeated list items — keeps first occurrence | --no-dedup |
| 3 | minify_tools |
Drops decorative schema keys (title, examples, $schema, default), truncates descriptions to ~120 chars |
--no-minify-tools |
| 4 | trim_history |
Keeps the last N messages (keep_last_n), or trims oldest until the budget is met. Inserts a [... N earlier messages omitted] marker; an assistant tool_calls turn and its tool_call_id responses are an atomic group |
--no-trim-history, --keep-last N |
| 5 | trim_rag |
When over token_budget, drops RAG entries with the lowest keyword overlap vs the last user message |
--no-trim-rag, --budget |
Safety guards: input is deep-copied (never mutated), traversal is iterative with cycle detection and a 500-level depth cap, and user strings are never parsed as JSON. preserve=("system_prompt",) keeps named top-level sections verbatim.
CLI
prompt-optimizer prompt.json # report + optimized prompt on stdout
prompt-optimizer prompt.json -o slim.json # optimized prompt JSON to a file
prompt-optimizer prompt.json --format json # full report as JSON
prompt-optimizer prompt.json --budget 8000 # trim to fit (exit 3 if unmet)
prompt-optimizer prompt.json --keep-last 10 # keep last 10 history messages
prompt-optimizer prompt.json --no-dedup # disable a strategy
prompt-optimizer prompt.json --dry-run # suggestions only, no output
prompt-optimizer --demo # try it on a bloated sample
cat openai_request.json | prompt-optimizer - # stdin works too
Works great with prompt-flamegraph
from prompt_flamegraph import profile_prompt
from prompt_optimizer import optimize
# see where the tokens go...
profile_prompt(prompt, output="before.html")
# ...then cut them
report = optimize(prompt, token_budget=8000)
profile_prompt(report.optimized, output="after.html")
When prompt-flamegraph is importable, optimize() measures with its tokenizer and surfaces near_duplicate findings it cannot auto-fix as informational suggestions.
API
from prompt_optimizer import (
optimize, # prompt dict → OptimizeReport
suggest, # prompt dict → list[Suggestion] (no changes)
OptimizeConfig, # budgets, keep_last_n, per-strategy toggles, preserve
OptimizeReport, # .optimized .token_savings .savings_pct .under_budget
Suggestion, # .kind .path .message .tokens_saved .action
)
OptimizeConfig(
token_budget=None, keep_last_n=None,
dedup=True, whitespace=True, minify_tools=True,
trim_history=True, trim_rag=True,
preserve=("system_prompt",), model=None, tokenizer=None,
)
report.to_dict() # JSON-serializable report
report.to_markdown() # human-readable report
Source
https://github.com/fjjjuv/prompt-optimizer
License
LGPL-3.0-or-later — see LICENSE and LICENSE.GPL.
Metadata
Release files for promptflame-optimizer 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| promptflame_optimizer-0.1.0.tar.gz | 36.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| promptflame_optimizer-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 71.6 kB
Release files / promptflame_optimizer-0.1.0.tar.gz
| Download URL | promptflame_optimizer-0.1.0.tar.gz |
|---|---|
| Size | 36.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f9ea53a8d1eae501c374f485fd239893b83ffa537c3e13cd29be49ea54fb24c5
|
|
BLAKE2b-256 checksum How to use checksums |
c469e0c985b3d602b7a26e72ab1e414099af2ed81558f34564306080b56d7e24
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Release files / promptflame_optimizer-0.1.0-py3-none-any.whl
| Download URL | promptflame_optimizer-0.1.0-py3-none-any.whl |
|---|---|
| Size | 35.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b9e681217620ba354f682ed233555958b2de3c9ea8f3dbb84bdcaf14eba6fb23
|
|
BLAKE2b-256 checksum How to use checksums |
e48acfe8903b762439c419f123ee6cd711ec5485bfea234797d69be881e9b428
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.6
|
Security for promptflame-optimizer 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.