Creates a middleware that detects and redacts personally identifiable information (PII) from messages before they are sent to model providers, and restores original values in model responses for tool execution.
The middleware intercepts agent execution at two points:
wrapModelCall)generateRedactionId() → "abc123"[REDACTED_{RULE_NAME}_{ID}] → "[REDACTED_SSN_abc123]"{ "abc123": "123-45-6789" }afterModel)/\[REDACTED_[A-Z_]+_(\w+)\]/gstructuredResponse state fieldUser Input: "My SSN is 123-45-6789"
↓ [beforeModel]
Model Request: "My SSN is [REDACTED_SSN_abc123]"
↓ [model invocation]
Model Response: tool_call({ "ssn": "[REDACTED_SSN_abc123]" })
↓ [afterModel]
Tool Execution: tool({ "ssn": "123-45-6789" })
This middleware provides model provider isolation only. PII may still be present in:
For comprehensive PII protection, implement additional controls at the application, network, and storage layers.
piiRedactionMiddleware(options: __type = {}): AgentMiddleware<StateDefinitionInit | undefined>| Name | Type | Description |
|---|---|---|
options | __type | Default: {}Configuration options |
import { piiRedactionMiddleware } from "langchain";
import { createAgent } from "langchain";
import { tool } from "@langchain/core/tools";
import { z } from "zod/v3";
const PII_RULES = {
ssn: /\b\d{3}-?\d{2}-?\d{4}\b/g,
email: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
phone: /\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g,
};
const lookupUser = tool(async ({ ssn }) => {
// Receives original value: "123-45-6789"
return { name: "John Doe", account: "active" };
}, {
name: "lookup_user",
description: "Look up user by SSN",
schema: z.object({ ssn: z.string() })
});
const agent = createAgent({
model: new ChatOpenAI({ model: "gpt-4" }),
tools: [lookupUser],
middleware: [piiRedactionMiddleware({ rules: PII_RULES })]
});
const result = await agent.invoke({
messages: [new HumanMessage("Look up SSN 123-45-6789")]
});
// Model request: "Look up SSN [REDACTED_SSN_abc123]"
// Model response: tool_call({ "ssn": "[REDACTED_SSN_abc123]" })
// Tool receives: { "ssn": "123-45-6789" }const agent = createAgent({
model: new ChatOpenAI({ model: "gpt-4" }),
tools: [someTool],
middleware: [piiRedactionMiddleware()]
});
// Configure rules at runtime via middleware context
const result = await agent.invoke(
{ messages: [new HumanMessage("...")] },
{
configurable: {
PIIRedactionMiddleware: {
rules: {
ssn: /\b\d{3}-?\d{2}-?\d{4}\b/g,
email: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}\b/g,
}
}
}
}
);const customRules = {
employee_id: /EMP-\d{6}/g,
api_key: /sk-[a-zA-Z0-9]{32}/g,
credit_card: /\b\d{4}[- ]?\d{4}[- ]?\d{4}[- ]?\d{4}\b/g,
};
const middleware = piiRedactionMiddleware({ rules: customRules });
// Generates markers like: [REDACTED_EMPLOYEE_ID_xyz789]