This guide explains a technical pattern. It is not legal advice; involve your data protection officer for your own case.
Why it matters
Every prompt you send copies its contents to the model provider, and often into your own logs and monitoring. The GDPR's data minimisation principle in Article 5(1)(c) requires personal data to be
"adequate, relevant and limited to what is necessary in relation to the purposes for which they are processed ('data minimisation')"
For most LLM tasks (summarising a ticket, drafting a reply, classifying a complaint) the model does not need to know the customer's name, account number or national ID number. It needs to know that there is a customer and an account.
Pseudonymisation, not anonymisation
Replacing personal data with placeholders and keeping a map to restore it is pseudonymisation. Article 4(5) defines it as
"the processing of personal data in such a manner that the personal data can no longer be attributed to a specific data subject without the use of additional information, provided that such additional information is kept separately and is subject to technical and organisational measures to ensure that the personal data are not attributed to an identified or identifiable natural person"
Recital 26 is clear that pseudonymised data is still personal data for whoever can re-identify it:
"Personal data which have undergone pseudonymisation, which could be attributed to a natural person by the use of additional information should be considered to be information on an identifiable natural person."
So redacting does not take your processing out of the GDPR. What it does is reduce what you hand to the model provider, and keep the key to re-identification, the placeholder map, on your side.
The pattern: redact, prompt, restore
- Replace personal data with placeholders such as
[PERSON_1]and[IBAN_1]. Keep the same placeholder for every mention of the same person, so the model can still follow the text. - Send only the redacted text to the model.
- Put the real values back into the model's answer, on your side.
"""Redact a support ticket, let an LLM work on it, put the real values back.
pip install requests
RAPIDAPI_KEY=... python examples/llm_roundtrip.py
"""
import os
import requests
HOST = "eu-pii-redaction.p.rapidapi.com"
HEADERS = {
"X-RapidAPI-Key": os.environ["RAPIDAPI_KEY"],
"X-RapidAPI-Host": HOST,
}
def redact(text: str) -> tuple[str, dict[str, str]]:
"""Return the redacted text and a placeholder -> original value mapping."""
r = requests.post(f"https://{HOST}/redact", json={"text": text}, headers=HEADERS, timeout=10)
r.raise_for_status()
body = r.json()
originals: dict[str, str] = {}
for e in body["entities"]:
# The first mention is the fullest one ("Karina Dahl" before "Karina").
originals.setdefault(e["placeholder"], text[e["start"]:e["end"]])
return body["redacted"], originals
def restore(text: str, originals: dict[str, str]) -> str:
for placeholder, value in originals.items():
text = text.replace(placeholder, value)
return text
def ask_llm(prompt: str) -> str:
# Replace with your LLM client. For the demo, a canned reply that uses the placeholders.
return ("Hi [PERSON_1], thanks for reaching out. We have refunded your order to [IBAN_1]; "
"it should arrive within 3 working days.")
ticket = """Hi, my name is Karina Dahl. I was charged twice for order 88412.
Please refund to DK50 0040 0440 1162 43 or call me on +45 32 12 34 56.
Karina"""
redacted, originals = redact(ticket)
print("Sent to the LLM:\n" + redacted + "\n")
reply = ask_llm(f"Draft a short reply to this support ticket:\n\n{redacted}")
print("LLM reply, restored:\n" + restore(reply, originals))
The model sees Hi, my name is [PERSON_1]. … refund to [IBAN_1], and your customer reads a reply with their real name
and account. You can try this on your own text without signing up.
What to watch out for
- Names in free text are the hardest part. Rule-based detection needs evidence (titles, greetings, sign-offs, known first names) and misses some names on purpose to avoid redacting ordinary words.
- Logs. Redact before logging prompts, not just before sending them.
- Attachments and quoted email history often contain more personal data than the message itself.
- Keep the placeholder map only as long as you need it to restore the answer.
- Test on a sample of your real data and review what is missed before relying on it.