Schwärzen Sie personenbezogene Daten aus KI-Agentenprotokollen, bevor sie in Ihre Datenbank gelangen
Ihr Agent protokolliert jede Eingabeaufforderung und jeden Tool-Aufruf. Eine verpasste SSN in einem Transkript führt zu einer DSGVO-Offenlegung. Eine dreizeilige Middleware behebt das Problem, bevor die Zeile geschrieben wird.
Ihr KI-Agent protokolliert die Eingabeaufforderung. Die Eingabe des Werkzeugaufrufs. Das Werkzeugergebnis. Die letzte Antwort. Das war früher eine Goldgrube für Debugging-Daten. Heutzutage handelt es sich um eine DSGVO-Offenlegung, die darauf wartet, dass ein Support-Ticket eine SSN nach Ihrer Validierung enthält.
Sie können Benutzer nicht daran hindern, vertrauliche Daten einzufügen. Sie können verhindern, dass der Rohtext Ihren Protokollspeicher, Ihren Observability-Anbieter und Ihren wöchentlichen Auswertungsexport erreicht. Eine kleine Middleware erledigt dies in einem Hop.
Das Leck, das die meisten Agenten-Setups bereits haben
// before: every raw prompt, tool call, and tool result lands in the log row
logger.info({
event: 'agent.turn',
prompt: userInput,
tool_calls: toolCalls,
tool_results: toolResults,
});
// one support ticket later: "My SSN is 123-45-6789 and card 4111 1111 1111 1111"
// sits in the logs, the observability vendor, and the weekly eval export.
Jede Reihe trägt nun eine Kartennummer. Der Protokollspeicher speichert es 30 Tage lang. Das Observability SDK versendet es an einen Dritten. Der Auswertungsexport greift zwei Tage später dieselbe Zeichenfolge auf. Fünf Exemplare einer Karte; Sie alle liegen außerhalb des Geltungsbereichs Ihrer Richtlinie zur Verschlüsselung ruhender Daten.
Erkennen Sie personenbezogene Daten mit einem Anruf
Die Botoi /v1/pii/detect Der Endpunkt durchsucht Text nach E-Mails, Telefonnummern, SSNs, Kreditkarten (Luhn-validiert), IP-Adressen und Geburtsdaten. Es gibt jedes Ergebnis mit einem Start-Offset, einem End-Offset und einem maskierten Wert zurück, den Sie einfügen können.
Anfrage
curl -X POST https://api.botoi.com/v1/pii/detect \\
-H "Content-Type: application/json" \\
-d '{"text": "Reach me at alice@example.com or 555-123-4567. Card: 4111 1111 1111 1111."}'
Antwort
{
"found": true,
"count": 3,
"findings": [
{ "type": "email", "value": "alice@example.com", "start": 12, "end": 29, "masked": "al***@example.com" },
{ "type": "phone", "value": "555-123-4567", "start": 33, "end": 45, "masked": "***-***-4567" },
{ "type": "credit_card", "value": "4111 1111 1111 1111", "start": 53, "end": 72, "masked": "************1111" }
]
}
Drei Streichhölzer, drei maskierte Auswechslungen, Positionen, die man sauber verbinden kann. Keine Regex-Bibliothek, die gewartet werden muss, keine SSN-Präfixtabelle, die aktuell gehalten werden muss, kein Luhn-Pass, den man selbst schreiben muss.
Eine Protokoll-Middleware, die vor dem Schreiben redigiert
Der richtige Ort hierfür ist der letzte Hop, bevor die Zeile Ihren Prozess verlässt. Jede vorgelagerte Komponente sieht weiterhin den Rohtext, den sie benötigt; Die persistente Kopie wird bereinigt.
// log-redact.ts
import type { LogRecord } from './types';
const PII_FIELDS = ['prompt', 'tool_calls', 'tool_results', 'output'] as const;
export async function redactPii(record: LogRecord): Promise<LogRecord> {
const clone = structuredClone(record);
for (const field of PII_FIELDS) {
const value = clone[field];
if (!value) continue;
clone[field] = await scrub(JSON.stringify(value));
}
return clone;
}
async function scrub(text: string): Promise<string> {
const res = await fetch('https://api.botoi.com/v1/pii/detect', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
Authorization: \`Bearer \${process.env.BOTOI_API_KEY}\`,
},
body: JSON.stringify({ text }),
});
const data = await res.json();
if (!data.found) return text;
// Replace from the end of the string so offsets stay valid.
const sorted = [...data.findings].sort((a, b) => b.start - a.start);
let scrubbed = text;
for (const f of sorted) {
scrubbed = scrubbed.slice(0, f.start) + f.masked + scrubbed.slice(f.end);
}
return scrubbed;
}
In diesem Ausschnitt sind drei Details wichtig. Erstens durchläuft es bekannte PII-lastige Felder und nicht den gesamten Datensatz; Sie müssen die Anforderungs-ID nicht löschen. Zweitens wird jedes Feld vor dem Senden an die API in eine einzelne Zeichenfolge serialisiert, sodass ein Aufruf das gesamte Tool-Ergebnis abdeckt. Drittens werden Ersetzungen vom Ende der Zeichenfolge aus gespleißt, sodass sich die Offsets nicht darunter verschieben.
Verdrahten Sie es mit dem Logger
// logger.ts
import { redactPii } from './log-redact';
export async function logTurn(raw: LogRecord) {
const safe = await redactPii(raw);
await logStore.write(safe);
}
// anywhere in your agent loop:
await logTurn({
event: 'agent.turn',
prompt: userInput,
tool_calls: toolCalls,
tool_results: toolResults,
});
Anruf logTurn anstelle Ihres bestehenden logger.info an der Wendegrenze. Alles vorgelagert bleibt gleich.
Fail geschlossen, nicht Fail Silent
Der Erkennungsendpunkt antwortet normalerweise in weniger als 20 ms. Wenn das Zeitlimit überschritten wird, haben Sie immer noch die Wahl: Die Zeile roh protokollieren (Leckrisiko) oder die sensiblen Felder löschen und eine Markierung protokollieren. Das Löschen ist die sicherere Standardeinstellung für Compliance-empfindliche Workloads.
async function redactPiiSafe(record: LogRecord): Promise<LogRecord> {
try {
return await Promise.race([
redactPii(record),
new Promise<LogRecord>((_, reject) =>
setTimeout(() => reject(new Error('pii-detect timeout')), 250)
),
]);
} catch (err) {
// Fail closed: drop the sensitive fields rather than logging them raw.
return { ...record, prompt: '[REDACT_FAILED]', tool_calls: [], tool_results: [] };
}
}
Stellen Sie das Timeout auf einen kleinen Wert ein. 250 ms reichen aus, um eine regionale Verlangsamung aufzufangen, ohne einen fehlerfreien Anforderungspfad zu blockieren.
Python-Version
# log_redact.py
import os, json, httpx
PII_FIELDS = ('prompt', 'tool_calls', 'tool_results', 'output')
API = 'https://api.botoi.com/v1/pii/detect'
async def scrub(text: str) -> str:
async with httpx.AsyncClient(timeout=0.25) as client:
r = await client.post(
API,
headers={'Authorization': f"Bearer {os.environ['BOTOI_API_KEY']}"},
json={'text': text},
)
data = r.json()
if not data.get('found'):
return text
out = text
for f in sorted(data['findings'], key=lambda x: x['start'], reverse=True):
out = out[:f['start']] + f['masked'] + out[f['end']:]
return out
Fallen scrub in den Log-Hook Ihres Agent-Frameworks. FastAPI-Middleware, LangChain-Rückrufe und OpenInference-Span-Exporteure akzeptieren alle asynchrone Funktionen.
Was diese Middleware nicht kann
- Es werden keine Namen, Adressen oder Kontonummern erfasst, die keinem unterstützten Typ ähneln. Diese erfordern ein benanntes Entitätsmodell und eine politische Entscheidung (Maske? Weglassen? Den gesamten Zug redigieren?).
- Es schützt Ihren Modellanbieter nicht davor, die Roheingabeaufforderung zu sehen. Führen Sie dazu denselben Erkennungsaufruf auf dem Client aus, bevor Sie ihn an das Modell senden.
- Es ersetzt keine Richtlinie zur Datenaufbewahrung. Verkürzen Sie die Protokoll-TTL trotzdem.
Das gehört zu zwei Orten
| Schicht | Schützt | Anrufzeitpunkt |
|---|---|---|
| Vor Modellanfrage | Modellanbieter, Trainingsdaten, Evaluierungslecks | Blockierende, für den Benutzer sichtbare Latenz |
| Vor dem Protokoll schreiben | Protokolllager, Observability-Anbieter, Exporte | Out-of-Band, unsichtbar für den Benutzer |
Versenden Sie zuerst die Log-Write-Middleware. Es verläuft außerhalb des heißen Pfads und blockiert die häufigsten Leckmuster. Fügen Sie die Vormodellversion hinzu, sobald die Holzseite abgedeckt ist.
Holen Sie sich einen API-Schlüssel und starten Sie
Beim anonymen Zugriff erhalten Sie 5 Anfragen pro Minute, was ausreicht, um den Endpunkt anhand eines Beispielprotokolls zu testen. Für Produktions-Middleware erhalten Sie einen kostenlosen Schlüssel unter botoi.com/api/signup. Das kostenlose Kontingent umfasst 1.000 Scrub-Anrufe pro Tag ohne Kreditkarte.
Die vollständige Endpunktreferenz finden Sie unter PII-Erkennungs-API-Seite oder stöbern api.botoi.com/docs für die anderen 149 Endpunkte.
FAQ
- Warum verlieren AI-Agent-Protokolle mehr personenbezogene Daten als normale Serverprotokolle?
- Agenten protokollieren die gesamte Eingabeaufforderung, jede Werkzeugaufrufeingabe und jede Werkzeugausgabe. Ein Support-Transkript, das einst hinter einer „Nicht protokollieren“-Flagge verborgen war, erscheint jetzt an fünf Stellen: beim Orchestrator, beim Tool-Server, beim Observability-Anbieter, beim Modellanbieter und im Trainings-Evaluierungssatz.
- Wo soll der Schwärzungsschritt verlaufen?
- Führen Sie es an der Grenze des Protokollschreibers aus, unmittelbar bevor die Zeile an Ihren Protokollspeicher gesendet wird. Auf diese Weise sieht jede Upstream-Komponente (Orchestrator, Tool, Observability SDK) den Rohtext, den sie benötigt, und nur die persistente Kopie wird bereinigt.
- Fängt ein Regex-Redaktor alles ab?
- Nein. Beim Roll-your-own-Regex werden Kreditkartennummern mit ungewöhnlichen Abständen, SSNs, die wie andere 9-stellige Nummern aussehen, und Namen von Personen übersehen. Eine API wie /v1/pii/detect führt Luhn auf Karten aus, filtert SSN-Präfixe und gibt Positionen zurück, sodass Sie nur die Übereinstimmung löschen können, nicht die ganze Zeile.
- Welche Latenz fügt die Botoi PII Detect API hinzu?
- Der Endpunkt läuft am Rand und kehrt für eine Nutzlast von 500 Token in weniger als 20 ms zurück. Sie können es synchron in einer Protokoll-Middleware aufrufen, ohne die für den Benutzer sichtbaren Antwortzeiten zu beeinträchtigen. Die Protokollierung erfolgt nach dem Senden der Antwort.
- Kann ich den Client bearbeiten, bevor ich ihn an das Modell sende?
- Ja, und es ist eine gute zweite Schicht. Durch die Schwärzung in der Server-Middleware wird Ihr Protokollspeicher geschützt. Durch die Schwärzung im Client wird Ihr Modellanbieter davor geschützt, rohe personenbezogene Daten zu sehen. Beides zusammen ist das DSGVO-freundliche Setup.
Starte mit botoi zu entwickeln
150+ API-Endpunkte für Abfragen, Textverarbeitung, Bildgenerierung und Entwickler-Tools. Kostenloser Tarif, keine Kreditkarte nötig.