Skip to main content

Prompt privacy

Refuse prompts that contain personal information before they ever reach the AI agent's model.

Why Use Prompt Privacy

A user pastes a customer record into your support agent and asks it to summarize the complaint. That prompt now travels to your model provider, lands in the conversation history, and is replayed on every following turn. Nothing in the agent's own instructions can undo that: by the time the model could decline, it has already read the data.

Prompt privacy stops the turn at the door. The prompt is screened before the agent's model sees it, and a prompt carrying PII is refused outright:

Backend code
await this.squid.ai().agent('support-agent').updatePii({
onDetect: 'reject',
});

Overview

When prompt privacy is enabled, every incoming prompt is screened by a small, fast classifier model before the agent runs. If the prompt contains any of the information you selected, the turn is refused:

  • The prompt is never sent to the agent's model.
  • No answer is generated and no quota is consumed.
  • Nothing is written to the conversation history, so the next turn starts from the previous state.
  • The caller receives an error beginning with PII_DETECTED_IN_PROMPT.

How this differs from the PII guardrail

Prompt privacy is the inbound counterpart to the disablePii guardrail, and the two solve different problems:

pii (this page)guardrails.disablePii
DirectionInbound: what the user sendsOutbound: what the agent answers
MechanismA classifier screens the prompt before the agent runsAn instruction in the agent's system prompt
On a matchThe turn is refusedThe model is asked to omit the information
Reaches the agent's model?NoYes

Use pii when the requirement is that the data must not reach the model at all. Use disablePii when you want the agent to answer while keeping personal data out of its reply. They can be enabled together.

Quick Start

Enabling screening takes one call. Configuration lives on the stored agent, so it applies to every caller.

Backend code
// Refuse any prompt containing an email address or a national identity number
await this.squid
.ai()
.agent('support-agent')
.updatePii({
onDetect: 'reject',
entities: ['email', 'ssn'],
});

A refused prompt surfaces as a thrown error, so handle it where you call the agent:

Backend code
try {
const answer = await this.squid.ai().agent('support-agent').ask(userPrompt);
return answer;
} catch (error) {
const message = error instanceof Error ? error.message : String(error);
if (message.includes('PII_DETECTED_IN_PROMPT')) {
return 'Please remove any personal details from your question and try again.';
}
throw error;
}

Configuration

All settings live under the agent's pii option.

FieldTypeDefaultDescription
onDetect'off' or 'reject''off''reject' refuses a prompt carrying PII. 'off' disables screening entirely.
entitiesarray of entity kindsevery kindWhich kinds of information to screen for.
customRulesarray of stringsnoneInformation specific to your business, described in plain language.
allowListarray of stringsnoneExact values that must never be treated as PII.
classifierModelmodel namegpt-5.6-lunaThe model that performs the screening.

updatePii merges with the agent's existing settings rather than replacing them, the same way updateGuardrails does.

Entity kinds

KindMatches
emailEmail addresses
phoneNumberPhone numbers
creditCardPayment card numbers
ssnNational identity numbers, such as a US Social Security Number
ibanBank account numbers, such as an IBAN
passportPassport and other travel document numbers

Leaving entities unset screens for every kind. Set it to an empty array to rely on customRules alone.

Custom rules

Because a model reads the prompt, custom rules are written as descriptions rather than as patterns. Anything a careful reader could recognize from a sentence will work:

Backend code
await this.squid.ai().agent('support-agent').updatePii({
onDetect: 'reject',
customRules: [
'internal case numbers like CASE-12345',
'employee IDs, which are always six digits prefixed with E',
'any reference to a customer contract number',
],
});

Allow list

Shared, non-personal values that would otherwise be flagged belong in the allow list:

Backend code
await this.squid
.ai()
.agent('support-agent')
.updatePii({
onDetect: 'reject',
allowList: ['support@example.com', '+1-800-555-0100'],
});

Core Concepts

Screening is judged in context

A model reads the prompt, so a value is classified by what the prompt says it is rather than by the shape it happens to fit. A number written as SSN 113-772-1098 is grouped like a phone number, but it is reported as an ssn because the surrounding text says so.

The policy cannot be overridden per request

pii is read from the stored agent. A pii value passed in the options of an individual ask or chat call is ignored, so a caller cannot switch off the screening the agent's owner turned on.

Rejections are audited with the prompt redacted

When the agent has audit logging enabled, a refused turn is still recorded, but the stored prompt has every matching value replaced with [REDACTED]. The entry is tagged with the kinds that matched and never with the values themselves, so the audit trail shows that a request was refused and why without restating the data that caused it.

Screening is fail-closed

If the classifier cannot be reached, the turn is refused with PII_SCREENING_UNAVAILABLE rather than allowed through unscreened. An agent configured to reject PII does not quietly stop rejecting it.

Error Handling

ErrorMeaningWhat to do
PII_DETECTED_IN_PROMPTThe prompt contained PII and was refused. The message lists the kinds that matched.Ask the user to resubmit without the personal details.
PII_SCREENING_UNAVAILABLEThe classifier could not be reached, so the prompt was refused.Retry. If it persists, check that the configured classifierModel is available.

Both are thrown from the ask and chat calls, before any answer is produced.

Best Practices

  • Screen only what you need. Every enabled agent pays one classifier call per prompt, ahead of its own model, which adds latency and tokens to each turn. Narrowing entities does not remove that call, so treat screening as something you switch on deliberately rather than by default.
  • Tell the user what to do next. PII_DETECTED_IN_PROMPT names the kinds that matched. Turning that into a specific message ("remove the credit card number") is far more useful than a generic failure.
  • Remember the boundary. Prompt privacy covers the prompt. Data reaching the model through connector results or knowledge base content is not screened, so do not describe it to users as an end-to-end guarantee.
  • Keep an allow list for shared values. Support addresses and public phone numbers otherwise trip the screen on ordinary questions.
  • Pair it with the outbound guardrail when both directions matter. Enable pii to keep personal data out of the model and guardrails.disablePii to keep it out of the answer.

Configuring Prompt Privacy in the Studio

To configure prompt privacy for an agent via the Squid Console:

  1. Navigate to the Agent Studio tab in the left sidebar
  2. Select the agent you want to configure
  3. Click on the Guardrails tab
  4. Scroll to the Prompt Privacy section
  5. Toggle Reject prompts containing PII on
  6. Under Information to reject, clear any kinds you do not want screened. All are selected when you switch the feature on
  7. (Optional) Add one custom rule per line in the Custom PII rules field