PII Detection and Data Privacy for LLM Systems
How to detect, transform, retain, and delete personal data in LLM request and storage paths.
Personal data can pass through retrieval, model providers, traces, analytics, caches, and long-term memory during one request. Detection and transformation must happen before each disclosure boundary, while retention and deletion controls must cover every stored derivative.
Detect PII in stages
The production-grade detector is not a single component. It is a cascade; three layers, each with different precision/recall/latency characteristics, run in series with early exit on confident hits.
Layer 1: regex on every byte. The first pass catches the structured patterns: email addresses, US/UK/EU phone formats, SSNs and national IDs, credit card numbers (with Luhn validation to suppress false positives), IBANs, IPv4/IPv6 addresses, MAC addresses, URLs containing personal subdomains, AWS access keys, Stripe customer IDs. Regex catches roughly 80% of the structured PII at sub-millisecond latency per kilobyte and zero memory cost. The failure mode is unstructured personal data; names, addresses spelled out in prose, identifiers that don’t match a known format. Regex alone is what most teams ship as v1 and what every auditor flags as insufficient by v2.
Layer 2: Named-entity recognition. The second pass is a small NER model; typically spaCy under Microsoft Presidio, occasionally a fine-tuned BERT-class model; that tags spans of text with entity types: PERSON, ORG, LOCATION, GPE, DATE. NER catches the unstructured cases regex misses, at the cost of single-digit-millisecond per kilobyte and a few hundred MB of model weights. The failure mode is contextual; a name that’s also a common noun (“Ms. Booker”), an organization name that’s a person’s name, a date that’s incidental rather than tied to a person. NER alone has higher recall but lower precision than regex; the false-positive rate runs 5–15% in production traffic.
Layer 3: LLM-based classification. The third pass; used sparingly, only on flagged samples or on the highest-risk surfaces; runs a guard model (Llama Guard 4 S7: Privacy category, OpenAI’s Privacy Filter released as open-weight in 2026, or a small dedicated classifier) to disambiguate the cases NER couldn’t. LLM-based classification handles context the previous layers can’t (“this is a fictional name in a story” vs “this is a real person’s name in a customer support ticket”), at the cost of 50–200ms of additional latency and the dollar cost of an extra inference call.
The cascade pattern is the same shape as the reranking cascade; a cheap, high-recall first pass narrows the candidate set; a more expensive, higher-precision later pass refines the verdict. The production calibration: regex on every byte; NER on every byte that regex didn’t already cover with high confidence; LLM-based classification only on flagged samples in eval pipelines or on the highest-risk inputs (uploaded documents, retrieved chunks crossing tenant boundaries). Prediction Guard’s PII pipeline writeup lays out the same three-tier architecture from a regulated-industries angle; the cascade is by now consensus.
Choose a transformation
Once detected, the personal data has to be transformed before it crosses whatever boundary the policy guards. Four modes, in increasing order of how much utility they preserve:
Mode 1: Redaction. Replace the span with a placeholder: [EMAIL], [REDACTED], █████. Loses all information including type. Cheap, deterministic, irreversible. Appropriate for telemetry exports and eval samples where the personal data was never load-bearing.
Mode 2: Masking. Preserve type, lose specifics: [EMAIL_1], [PHONE_2]. Adds an index so the model can distinguish multiple PII spans in the same prompt (“Send the report to [EMAIL_1] and CC [EMAIL_2]”). Cheap, deterministic, reversible if you store the mapping. The reversible variant; store [EMAIL_1] → [email protected] in a tenant-scoped vault, un-mask in the response; is the dominant pattern for production LLM pipelines because it preserves utility without exposing the cleartext to the model or to downstream telemetry.
Mode 3: Synthetic substitution. Replace [email protected] with [email protected]. Preserves type and locale (a UK postcode stays a UK postcode); the model sees realistic-looking text and produces coherent output; the original lives in the vault and substitutes back on rendering. This is the Presidio anonymizer engine’s default operation. Higher utility than masking (the model handles plausible names better than placeholder tokens), at the cost of having to be careful that the substitution doesn’t accidentally introduce a real person’s identity; a synthetic name generator that pulls from a finite pool can collide with a real customer’s name in the next request.
Mode 4: Tokenization with a hardened vault. The full PCI pattern: the personal data lives in a separate system with its own access controls, audit log, and encryption-at-rest with a customer-managed key; the LLM pipeline sees opaque tokens; un-tokenization happens at the rendering boundary by a service that re-authenticates the user. Highest utility (the model’s output can include the original values, indirectly, via the rendering layer un-tokenizing) and highest engineering cost. Appropriate when the data is high-sensitivity (healthcare, financial) or the regulatory regime demands segregated storage.
The choice between modes is policy, not engineering. The engineering question is: does the operation need to be reversible, and which boundary does the cleartext live behind? Once those are answered, the mode follows.
Place privacy checks in the request path
The cascade adds latency in the obvious place; between the user request and the model call; and again on the response side. A realistic budget on a typical pipeline:
| Stage | Median latency | Cost adder | Notes |
|---|---|---|---|
| Regex pass | 0.5–2ms/KB | $0 | Pure CPU, easy to parallelize |
| NER pass (Presidio + spaCy) | 5–20ms/KB | $0 (self-hosted) | Single-threaded per request; batch where you can |
| LLM-based classifier (input) | 50–200ms | $0.0001–0.001 | Only on flagged samples or high-risk paths |
| Vault token mint/lookup | 1–5ms | $0 | Local with a Redis-class store |
| Output cascade (mirror of above) | 7–25ms | $0 + classifier sample | Run in parallel with output guard where possible |
| Total typical overhead | ~15–50ms | <$0.001 typical | Dominated by NER; LLM tier is sampled |
The latency budget interacts with the rest of the production stack. Run the cascade before the prompt-cache prefix; if you tokenize after the cache hits, the cache stores cleartext and the deletion pipeline can’t reach it. Run the cascade before the observability tracer sees the prompt; span attributes are personal data when they contain personal data, and the trace store is a separate retention tier the deletion API has to invalidate. Run the cascade after the user’s authentication is verified; pre-auth requests don’t deserve the latency budget, and unauthenticated traffic that contains personal data is its own incident.
The structural alternative; and the one the on-device-inference camp argues is the only honest answer; is to avoid the latency entirely by avoiding the network call. On-device inference shipping in 2026 (Apple Foundation Models, executorch on Android, MLC Chat) means the personal data never leaves the device, the PII detection cascade becomes optional rather than mandatory, the residency question is trivially answered, and the deletion is what the OS already does when the user uninstalls the app. The trade-off is model quality; the 3B-parameter on-device class is materially weaker than frontier cloud models, and the model-routing layer becomes the natural place to send only privacy-sensitive workloads on-device while keeping the rest in the cloud. We return to this in trade-offs.
Code: a detect-redact-deidentify pipeline in Python
The example is the v1 production cut: Presidio’s analyzer for detection, a vault for reversible mapping, redaction modes per entity, and a clean interface that the rest of the harness can call. Install: pip install presidio-analyzer presidio-anonymizer openai anthropic. The analyzer needs python -m spacy download en_core_web_lg once.
| |
The shape worth internalizing: detection is symmetric (input and output), tokenization is asymmetric (only the tokens this request minted are eligible to be reversed on the response), and the deletion API (vault.purge) is the artifact a GDPR auditor asks for. The naive failure mode; un-tokenize every token in the output; is exactly how a multi-tenant system leaks across tenants when the model regurgitates a token from a different tenant’s prompt cache.
Further reading from the field
- Microsoft Presidio; official documentation; the canonical reference for the open-source detector and anonymizer. Read the analyzer recognizers list and the anonymizer operators before designing your detect-redact pipeline; both are the cleanest description of what a production-grade PII stack actually contains, and the PII Shield blog post shows how Microsoft itself wraps Presidio as a privacy proxy in front of LLM calls.
- OpenAI; Introducing the OpenAI Privacy Filter; the May 2026 release of an open-weight model purpose-built for detecting and redacting PII in text, designed to run locally. This is the highest-quality drop-in alternative to NER-based detectors for the LLM-based third tier of the cascade, and the open-weight release means it can run inside your own infrastructure with no data egress.
- EDPB; Opinion 28/2024 on AI models and personal data processing; the European Data Protection Board’s December 2024 opinion on when AI models can be considered anonymized, the legitimate-interests basis for training and deployment, and the deletion-and-erasure expectations. This is the most authoritative single source on how EU regulators expect LLM systems to be governed in 2026.
- Simon Willison; Prompt injection and AI agents; the running tag index Willison maintains; every post in the tag is relevant to the PII-via-injection failure mode, and his lethal trifecta framing is the cleanest formal statement of when an agent can exfiltrate personal data via injection.