PII-aware prompting: a pattern, not a tool

The market for PII-detection-and-redaction tools is growing fast. The right answer for most teams isn't a tool, it's a pattern that lives at the prompt-assembly layer and uses small, cheap models to do the work.

A close-up of a paper document on a wooden desk with several lines of text redacted by clean black bars and a fountain pen alongside

The market for PII-detection-and-redaction tools is growing fast. Multiple SaaS vendors have shipped offerings that wrap your AI calls and promise to scrub personal data before it reaches the model. They're well-engineered. They're not the right answer for most teams.

The right answer is a pattern that lives at the prompt-assembly layer, uses small cheap models to do the work, and doesn't require buying a SaaS. Let me walk through why, and what the pattern looks like.

Prompt assembly with local redaction User input raw text with names Redact locally names → placeholders LLM call sees placeholders only Restore placeholders → names Response back to user trust boundary The LLM never sees the names. Redaction sits at the boundary.
Redaction sits at the trust boundary.

Prompt assembly with local redactionUser inputraw text withnamesRedactlocallynames →placeholdersLLM callseesplaceholdersonlyRestoreplaceholders →namesResponseback to usertrust boundaryThe LLM never sees the names. Redaction sits at the boundary.Redaction sits at the trust boundary.

The problem the SaaS vendors are solving

The risk: your application sends user data to a hosted LLM. The user data contains PII, names, addresses, account numbers, medical identifiers, the long list of things that have legal definitions in various jurisdictions. The LLM provider's terms of service may or may not protect that data adequately for your compliance regime. Your vendors and partners may have requirements about what data leaves your perimeter. Your users may have privacy expectations the LLM call doesn't meet.

The naive answer is "don't send PII to LLMs." That's a non-starter for most use cases, the value of AI in many applications depends on the model seeing context that may include PII.

The better answer is "redact PII before sending, then re-insert in the response if needed." That's the workflow the SaaS PII vendors automate.

Why the SaaS approach is overkill for most teams

Three reasons the build-vs-buy calculation favors building.

The work is mostly pattern-matching. PII detection and redaction is, in most cases, a problem solvable by good regex plus a small named-entity-recognition model. The hard cases (context-dependent PII, indirect identifiers) are where the SaaS tools claim differentiation, and those cases are also the ones where automated redaction has uncertain value (because the indirect identifiers are often the data the model needs to do its job).

The latency tax is real. The SaaS PII vendors sit in your call path. Every request gets a network round trip to their service before the LLM call, and another round trip on the way back for re-insertion. For interactive applications this latency is felt. For agentic loops it compounds across turns.

The cost compounds. Per-call PII processing fees plus the LLM call cost adds up faster than expected at scale. For an application doing meaningful AI volume, the PII tool can become the largest line item in the AI budget after the model itself.

You're adding another vendor. Another contract, another security review, another integration. The org's vendor lock-in surface area gets larger. The PII vendor sees all your data; you've moved the trust boundary rather than tightened it.

What the pattern looks like instead

PII-aware prompting as a pattern, not a tool.

Detection runs locally. A small NER model (something in the few-hundred-MB range, runnable on CPU or on a small GPU on commodity hardware) handles the bulk of detection. Add regex for the well-formed cases (credit cards, SSNs, phone numbers, structured IDs). The detection runs at prompt-assembly time, before the call to the hosted LLM.

Redaction happens at the prompt-assembly layer. Once detected. PII gets replaced with placeholders the model can reason about without the actual identifier, [PERSON_1], [ACCOUNT_NUM_2], [ADDRESS_3]. The model sees the redacted version. The mapping from placeholder to real value lives in the application's session state, not in the model's context.

Re-insertion happens on the response. If the model's response contains placeholder tokens, the application re-inserts the real values before showing the response to the user. The model never sees the actual PII; the user sees the actual values.

The mapping is task-scoped. When the task ends, the placeholder-to-real mapping gets dropped. It doesn't accumulate in any persistent store. The PII never durably goes into the AI surface.

That's the whole pattern. Same shape as the secrets-isolation pattern I wrote about earlier, specialized for PII rather than credentials.

What you actually need to build it

Concrete pieces for a working build.

A local NER model. Several options work, a fine-tuned BERT-base for general NER, the Presidio-bundled NER model, a small distilled model from one of the major NER projects. Pick something with enough memory budget to run inline at prompt-assembly time without becoming a latency problem. Most options fit in 1-2 GB.

A regex bank for structured PII. Credit cards, SSNs, phone numbers, well-formed account IDs, common medical identifier formats. Open-source banks of these patterns exist; integrate one rather than writing from scratch.

A placeholder-token convention. Pick a syntax that's unlikely to collide with real model output. [PERSON_N], [EMAIL_N], [PHONE_N] works. Document it; use it consistently.

A session-scoped mapping store. A dictionary in application memory that holds the mapping for the current task. Goes away when the session ends. Not persistent, not indexed, not searchable.

A re-insertion pass on responses. When the model returns text with placeholder tokens, the application substitutes the real values before user-facing display. Trivial code.

The total build effort is on the order of a week of engineering for a competent platform team. The maintenance is low because the pieces are stable.

What this pattern doesn't catch

Worth being honest about the limits.

Indirect identifiers. "The CEO of the company in Chicago that just had layoffs" is identifying without containing any direct PII tokens. The pattern doesn't catch this; the SaaS vendors mostly don't either, because solving it requires understanding context the redaction step doesn't have.

Sensitive non-PII context. Medical history, financial details, legal exposure, these are sensitive but aren't PII per se. The pattern doesn't address them; if you want them redacted you need separate detection for those classes.

PII the user explicitly types into a query. The user types "what's the deal with John Smith at 123 Main St?", the pattern catches the name and address and replaces them. The model loses the specific context. Whether that's the right behavior depends on the use case; sometimes the user typed the PII on purpose because they wanted a question answered about the specific person.

Adversarial inputs. A user trying to exfiltrate PII from your system through prompt injection isn't stopped by output-side redaction; they need to be stopped by input validation and capability isolation. The PII pattern handles the inadvertent-leak case, not the deliberate-exfiltration case.

These limits matter. They're the same limits the SaaS tools have. Worth being clear-eyed about what redaction does and doesn't cover.

Where this fits in the broader discipline

PII-aware prompting is one specific use of the 70/30 rule for prompt vs context, it's a context-layer concern, handled at prompt-assembly time, not a model-layer concern handled by changing the prompt or the model. The work happens in the context preparation pipeline; the model sees clean redacted input; the application handles the un-redacted version.

It also fits the broader governance discipline: the right control is at the platform layer (PII handled automatically by the prompt-assembly middleware) rather than at the per-query review layer (engineer manually checks every prompt for PII). Automated, scoped, gettable from the engineering org's existing toolkit.

What I'd recommend

For teams thinking about PII handling in AI applications:

  • Build the pattern in your prompt-assembly layer. Don't buy a SaaS for the common case; the build cost is reasonable and the operational profile is better.
  • Use the pattern as the default for any user data flowing to a hosted LLM. Make it automatic, not opt-in.
  • Be clear about what the pattern doesn't cover. Document the limits. Have separate processes for the indirect-identifier and sensitive-context cases.
  • Consider the SaaS for the very-high-volume cases where the build-and-maintain cost beats the SaaS fees. That's a specific and small set of teams.

PII-aware prompting is one of those engineering disciplines I find easy to build, easy to run, and easy to skip. The teams that skip it eventually have an incident or a compliance scare that prompts the build. Better to do it once, on purpose, before something forces your hand.

Worth being a pattern engineers know rather than a vendor engineers buy.