PIIMiddleware(
self,
pii_type: Literal['email', 'credit_card', 'ip', 'mac_address', 'url'] | str,| Name | Type | Description |
|---|---|---|
pii_type* | Literal['email', 'credit_card', 'ip', 'mac_address', 'url'] | str | Type of PII to detect. Can be a built-in type ( |
strategy | Literal['block', 'redact', 'mask', 'hash'] | Default: 'redact'How to handle detected PII. Options:
|
detector | Callable[[str], list[PIIMatch]] | str | None | Default: None |
apply_to_input | bool | Default: True |
apply_to_output | bool | Default: False |
apply_to_tool_results | bool | Default: False |
Detect and handle Personally Identifiable Information (PII) in conversations.
This middleware detects common PII types and applies configurable strategies to handle them. It can detect emails, credit cards, IP addresses, MAC addresses, and URLs in both user input and agent output.
Built-in PII types:
email: Email addressescredit_card: Credit card numbers (validated with Luhn algorithm)ip: IP addresses (validated with stdlib)mac_address: MAC addressesurl: URLs (both http/https and bare URLs)Strategies:
block: Raise an exception when PII is detectedredact: Replace PII with [REDACTED_TYPE] placeholdersmask: Partially mask PII (e.g., ****-****-****-1234 for credit card)hash: Replace PII with deterministic hash (e.g., <email_hash:a1b2c3d4>)Strategy Selection Guide:
| Strategy | Preserves Identity? | Best For |
|---|---|---|
block |
N/A | Avoid PII completely |
redact |
No | General compliance, log sanitization |
mask |
No | Human readability, customer service UIs |
hash |
Yes (pseudonymous) | Analytics, debugging |
Example:
from langchain.agents.middleware import PIIMiddleware
from langchain.agents import create_agent
# Redact all emails in user input
agent = create_agent(
"openai:gpt-5.5",
middleware=[
PIIMiddleware("email", strategy="redact"),
],
)
# Use different strategies for different PII types
agent = create_agent(
"openai:gpt-5.5",
middleware=[
PIIMiddleware("credit_card", strategy="mask"),
PIIMiddleware("url", strategy="redact"),
PIIMiddleware("ip", strategy="hash"),
],
)
# Custom PII type with regex
agent = create_agent(
"openai:gpt-5.5",
middleware=[
PIIMiddleware("api_key", detector=r"sk-[a-zA-Z0-9]{32}", strategy="block"),
],
)Custom detector function or regex pattern.
Callable: Function that takes content string and returns
list of PIIMatch objectsstr: Regex pattern to match PIINone: Uses built-in detector for the pii_typeWhether to check user messages before model call.
Whether to check AI messages after model call.
When True, a stream transformer is also installed so
that every wire surface of an agent run is redacted in
flight:
content-block-delta of type
text-delta)content-block-delta
with tool_call_chunk / server_tool_call_chunk
fields, plus the finalized tool_call content block
on content-block-finish)tools channel
(tool-started.input, tool-output-delta,
tool-finished.output, tool-error.message)values channel — message
lists are walked and each message's .content is
redacted on a fresh copy (state itself stays intact
for before_model / after_model to act on
independently)State-level redaction via after_model (and
before_model with apply_to_tool_results) remains the
canonical enforcer; the streaming transformer ensures
consumers reading astream_events(version="v3") or
run.messages / run.tool_calls / run.values never
see PII on the wire.
Whether to check tool result messages after tool execution.