Home

/

Keep PII Out of Your LLM

/

Plausibility hazard

Plausibility hazard

Chapter 10
Part III
5
min read

Plausibility hazard

Surrogates preserve utility better than tokens, and they introduce a risk that tokens do not.

<PERSON_1> is obviously not a person. Megan Alvarez is obviously a person, and is not the person. If a surrogate escapes the boundary where values are restored, a human downstream has no way to tell, and will act on it as real. The failure is not that someone is careless. It is that a well-chosen surrogate is designed to be indistinguishable, and you have removed the signal a reader would need in order to doubt it.

If you use surrogates, three rules.

The restore boundary must be explicit and total. One place in the code restores values, and nothing renders model output that has not passed through it.

Anything that escapes must be labelled. If a surrogate can reach a log, an export, a webhook, or a downstream system, it must carry a marker saying so.

Never use surrogates where the output feeds an action. Summaries for humans, yes. Arguments to a tool that sends an email, no. Chapter 15 has more on why model-composed values reaching actions is its own category of problem.

Deciding, per task

Work through four questions for each LLM feature. They take ten minutes and they prevent the silent-wrong-answer class entirely.

What does the task actually operate on? Write the sentence. "Classify the urgency of this ticket from its text." Urgency comes from the complaint, not the complainant. The name can go.

Which entities are load-bearing? For each entity type your detector catches, ask whether removing it changes the answer. Most of the time, for most entity types, it does not. When it does, you have found the ones that need a reversible safeguard rather than removal.

Can a generalisation carry the signal? Usually yes, and this is the most under-used answer in the book. The task rarely needs the exact date of birth, exact salary, exact ZIP code, or exact timestamp. It needs the decade, the band, the region, the month.

What happens if the model gets it wrong? If output goes to a human who can check it against the source, a degraded answer is an annoyance. If it triggers an action, a degraded answer is an incident, and you should be much more conservative about masking anything the decision depends on.

Measure the degradation

There is now measured evidence on how much this costs, and the headline is that it varies far more than you would guess. Deußer et al. (2026) ran five anonymisation strategies across eleven benchmarks and five models. Three findings are worth carrying into your own design.

The damage is task-specific, not uniform. On RGB, a retrieval-grounded benchmark, scores fell by between 0.22 and 0.47. On TruthfulQA, anonymisation improved results across every model tested, with Llama-3.1 gaining 8 percentage points, apparently because stripping named entities stopped the model reaching for incorrect memorised associations. The same safeguard helped one task and gutted another.

More capable models lose more. Qwen2.5-72B degraded by 6.9 percentage points on average against 2.3 for the much smaller Teuken-7B. The stronger model was relying on entity knowledge that anonymisation removed. Upgrading your model does not buy you headroom here, and may cost you some.

Telling the model does not help. Adding a prefix explaining that the text has been anonymised produced no significant or consistent improvement. If you were planning to solve this with prompt engineering, that is the experiment already run.

Which leads to the one thing you should actually do: evaluate your task with and without the safeguard applied.

Take fifty real examples. Run them through the model with the original text and with the de-identified text. Compare the outputs. Not with an automated metric, at least not at first; read them side by side. You will find out in an afternoon whether your safeguard costs you nothing, costs you a little, or has quietly broken the feature.

[Fact]
public async Task Deidentification_DoesNotDegradeSummaryQuality()
{
    foreach (var sample in EvalSet.Load(50))
    {
        var raw = await _model.SummariseAsync(sample.Text);
        var treated = await _model.SummariseAsync(Deidentify(sample.Text).Text);

        // Judged offline and recorded; this asserts the artefact exists,
        // the comparison itself is a human review.
        EvalReport.Record(sample.Id, raw, treated);
    }

    Assert.True(EvalReport.AgreementRate >= 0.90);
}

Teams run detector accuracy tests and almost never run task quality tests. The result is a privacy control that measurably works and a feature that quietly stopped working, and the second one is what users experience.

When the answer comes back that the task genuinely needs the real value, do not go looking for a cleverer mask. There is no mask that both hides a value and preserves it. What you need is a different design, where the sensitive value never needed to be in the prompt in the first place.

That is the rest of the book.

Sources for this chapter

  • Task-specific degradation (RGB −0.22 to −0.47), TruthfulQA improving under anonymisation (Llama-3.1 +8pp), larger models degrading more (Qwen2.5-72B −6.9pp against Teuken-7B −2.3pp), and anonymisation-awareness prompt prefixes producing no consistent improvement — Deußer et al., On the Impact of Anonymization on the Performance of Large Language Models, arXiv 2609.11335, 10 September 2026: https://arxiv.org/html/2609.11335
  • Numeric ambiguity in de-identified textUtility-Preserving De-Identification, arXiv 2602.16571: https://arxiv.org/pdf/2602.16571
  • Masking identifiers in resume screening to reduce bias, as a vendor-documented use case — https://learn.microsoft.com/en-us/azure/ai-services/language-service/personally-identifiable-information/overview

The plausibility hazard, the four per-task questions, and the rule against surrogates where output feeds an action are the author's argument. No incident data is cited for surrogates reaching end users, and the text does not assert that it has happened.

the-leak-you-cant-see
blast-radius
what-counts-as-pii
the-five-doors
the-accuracy-reckoning
the-hybrid-that-does-not-work
deterministic-detection
npi-in-c
the-three-way-choice
calling-the-analyzer-from-c
measuring-your-own-demo-gap
choosing-the-operating-point
the-ladder-of-safeguards
pseudonymisation
the-round-trip
restoring-safely
when-masking-breaks-the-task
plausibility-hazard
the-architecture-that-holds
the-reference-architecture
dont-send-it-at-all
structure-beats-prose
the-gateway
failure-is-a-policy-decision
the-sidecar-you-can-trust
egress-deny-it-at-the-network
rag-and-agents
de-identify-before-you-embed
dual-model-separation
the-boring-controls
evidence-and-the-first-thirty-days
week-two-the-chokepoint-and-the-fast-layer
entity-catalogue-and-c-validators
mbi-positional-rules
tooling-at-a-glance
azure-ai-language-pii-in-detail
container-trust-checklist
sources
azure-ai-language
provider-retention

Download the full PDF for free?

Free download — no account required

Get the PDF
Get the PDF
Related Chapters
Free Download
Get the full PDF
All pages, including all code examples, diagrams, and the appendix reference card.
No spam. Unsubscribe at any time.
Your email won't be shared.
Oops! There's a problem with your request. We're working on fixing it. Please try again later.