Skip to content

Prompt Whitespace Normaliser

Inventory the invisible characters in a prompt — code point by code point — and clean the ones you choose to.

Invisible characters found
2

5 characters and 9 bytes removed.

Characters
152 → 147
UTF-8 bytes
162 → 153
Estimated tokens
≈ 52 → ≈ 50
CRLF line endings
0
Lines with trailing whitespace
1
Runs of 3+ newlines
1
Tab characters
0
Already in NFC
Yes

Every suspect code point in your text

  • U+200B ZERO WIDTH SPACEInvisible. Common in HTML-sourced text.1×
  • U+2019 RIGHT SINGLE QUOTATION MARKSmart quote — also used as an apostrophe.2×
  • U+2014 EM DASHAutocorrected from two hyphens.1×
  • U+FEFF ZERO WIDTH NO-BREAK SPACE (BOM)A byte-order mark that survived a file read.1×
Cleaned prompt
What this assumes: this page inspects characters. It cannot see your cache. What it can tell you is the mechanism: prompt caching matches an exact prefix, so two prompts that look identical but differ by one no-break space are different prefixes and cannot share a cache entry. Whether that is why your hit rate is low is a question for your provider’s usage fields, not for this tool. Note also that cleaning a prompt changes it, so the first request after a clean-up misses by definition. NFC is safe for Latin text and is not always a no-op elsewhere — some scripts have composition rules that alter more than the encoding. Token counts are estimates. Estimated, not tokenized. A real count needs the model's vocabulary; the authoritative number is usage.prompt_tokens on the response.

Where these characters come from, and what they cost

Almost nothing on the list above is typed. A no-break space arrives from a word processor, a zero-width space from HTML, a byte-order mark from a file read with the wrong encoding, smart quotes from an editor’s autocorrect, CRLF from a Windows checkout of a prompt file. Each is invisible in the place you would look for it, and each is a different byte sequence from the thing it resembles.

The concrete costs are three. First, tokens: a no-break space is not the space token, so it does not merge with the following word, and a prompt full of them tokenizes measurably worse. Second, caching: an exact-prefix match is unforgiving, and a single stray character anywhere in the supposedly stable prefix moves the whole boundary. Third, comparison — the string equality in your test, your dedupe and your cache key all fail on characters no reviewer can see, which is why a prompt that “did not change” behaves differently after a round trip through a document.

One caution: the quote-straightening toggle is off by default because it is the only option here that changes meaning rather than encoding. In a system prompt that is usually fine. In user content, in a legal quotation or in a language where the apostrophe is a letter, it is not — normalise the frame you control and leave what the user wrote alone.

Prompt Whitespace Normaliser · Multigrid