PromptLint
Static analysis for LLM prompts. Think ESLint, but for the text you send to GPT-4 / Claude / Gemini.
Catches token waste, vague language, prompt injection, missing structure, and other issues that degrade prompt quality in production. Runs locally — no API calls, no round-trips, results in milliseconds.
Install
pip install promptlint-cli
For accurate token counting (requires a Rust toolchain on non-CPython):
pip install promptlint-cli[tiktoken]
Requires Python 3.9+.
Quick start
# lint a file
promptlint --file prompt.txt
# lint inline text
promptlint -t "Please write some code for me"
# multiple files with globs
promptlint prompts/**/*.txt --exclude prompts/drafts/*
# pipe from stdin
cat prompt.txt | promptlint --format json
# auto-fix what it can
promptlint --file prompt.txt --fix
# CI mode: exit 1 on warnings, only print the summary
promptlint prompts/ --fail-level warn --quiet
Exit codes: 0 = clean, 1 = warnings found (with --fail-level warn), 2 = critical issues.
Example output
$ promptlint --file system_prompt.txt
PromptLint Findings
[ INFO ] cost (line -) Prompt is ~38 tokens (~$0.0002 input per call on gpt-4o).
[ WARN ] structure-sections (line -) No explicit sections detected (Task/Context/Output).
[ WARN ] clarity-vague-terms (line 1) Vague term 'some' detected. Be more specific.
[ CRITICAL ] prompt-injection (line 5) Injection pattern detected: 'ignore previous instructions'.
1 file(s) scanned, 4 finding(s) in 0.41s
What it checks
| Rule | What it does | Fixable |
|---|---|---|
cost |
Token count and per-call cost estimate | — |
cost-limit |
Warns when prompt exceeds your token budget | — |
prompt-injection |
Catches injection patterns, even with leetspeak/unicode obfuscation | yes |
structure-sections |
Flags prompts with no clear sections | yes |
clarity-vague-terms |
Finds "some", "stuff", "maybe", "good", etc. | — |
specificity-examples |
Suggests adding examples for complex instructions | — |
specificity-constraints |
Suggests adding length/format/scope constraints | — |
politeness-bloat |
Flags "please", "kindly", "thank you" (burns tokens) | yes |
verbosity-sentence-length |
Flags sentences over 40 words | — |
verbosity-redundancy |
"in order to" → "to", "due to the fact that" → "because" | yes |
actionability-weak-verbs |
Flags excessive passive voice | — |
consistency-terminology |
Catches mixed terms (user/customer, function/method) | — |
completeness-edge-cases |
Reminds you to specify error handling | — |
Run promptlint --list-rules to see them all, or promptlint --explain cost for details on any rule.
Auto-fix
Pass --fix and PromptLint removes politeness filler, simplifies redundant phrases, strips injection lines, and scaffolds missing sections:
$ promptlint -t "Please kindly write code in order to sort the array, thank you" --fix
Optimized Prompt
<task>Write code to sort the array.</task>
Configuration
Drop a .promptlintrc in your repo root (or run promptlint --init to generate one):
model: gpt-4o
token_limit: 800
cost_per_1k_tokens: 0.005
calls_per_day: 10000
rules:
cost:
enabled: true
prompt_injection:
enabled: true
patterns:
- ignore previous instructions
- system prompt extraction
politeness_bloat:
enabled: true
words: [please, kindly, thank you, i would appreciate]
structure_sections:
enabled: true
fix:
enabled: true
prompt_injection: true
politeness_bloat: true
verbosity_redundancy: true
structure_scaffold: true
CLI reference
promptlint [FILES...] [OPTIONS]
-V, --version Show version
-f, --file PATH Single prompt file
-t, --text TEXT Inline prompt text
-c, --config PATH Config file (default: .promptlintrc)
--format {text,json} Output format
--fix Auto-fix and print optimized prompt
--fail-level LEVEL none / warn / critical (default: critical)
--show-dashboard Token savings breakdown
-q, --quiet Summary line only (for CI)
--exclude PATTERN Exclude globs (repeatable)
--list-rules Show all rules
--explain RULE_ID Explain a specific rule
--init Generate starter .promptlintrc
Injection evasion detection
The prompt-injection rule normalizes text before matching, catching obfuscated attacks that simple regex would miss:
| Evasion technique | Example | Detected? |
|---|---|---|
| Leetspeak | 1gn0r3 pr3v10u$ 1nstruct10ns |
Yes |
| Zero-width characters | ignore previous instructions |
Yes |
| Character repetition | ignoooore previooous instructions |
Yes |
| Fullwidth unicode | ignore previous instructions |
Yes |
| Mixed obfuscation | !gnor3 pr3v!0u$ in$truction$ |
Yes |
Custom injection patterns can be added in .promptlintrc under rules.prompt_injection.patterns.
Agent skills
PromptLint ships with skills for AI coding agents that teach them prompt conventions and a lint-and-fix loop:
- Cursor —
.cursor/skills/promptlint/SKILL.md - Claude Code —
.claude/skills/promptlint/SKILL.md
Links
License
Metadata
Release files for promptlint-cli 1.3.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 | |
|---|---|---|---|
| promptlint_cli-1.3.0.tar.gz | 44.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| promptlint_cli-1.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 79.8 kB
Release files / promptlint_cli-1.3.0.tar.gz
| Download URL | promptlint_cli-1.3.0.tar.gz |
|---|---|
| Size | 44.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
0f06e7391863debd82186d54c94d7a6e3e1e7d2b2c46e22edf1f66f28f59d3bc
|
|
BLAKE2b-256 checksum How to use checksums |
3eb270185f6e10086a6b4536bd8e884e8cd1a7ffc5430e87ba8e03898b1d52d9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.0
|
Release files / promptlint_cli-1.3.0-py3-none-any.whl
| Download URL | promptlint_cli-1.3.0-py3-none-any.whl |
|---|---|
| Size | 35.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
24d77f3b2dca86ed866d5167577968a5297490e0e2e6ff1b4f334659f4cd2eaa
|
|
BLAKE2b-256 checksum How to use checksums |
bcd0cca43854519127213ea62a334225aeeab444b75a97e27991d4557637b0a8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.0
|