# Datenminimierung bei KI-Agenten für sicherere Tool-Aufrufe

Ein KI-Agent sollte keinen Kundendatensatz erhalten, nur weil er irgendwann vielleicht eine Information daraus braucht. Jeder Tool-Aufruf braucht einen kleineren Vertrag: die Aktion, die dafür notwendigen Mindestfelder und eine Ausgabe, die dem Agenten mitteilt, was passiert ist, ohne ihm einen neuen Stapel Kundendaten zu übergeben.

Daten gehen meist an der Schnittstelle zwischen einem leistungsfähigen Agenten und einer praktischen internen API verloren. Teams geben dem Agenten eine allgemeine Kundensuche, liefern die vollständige Antwort zurück und nennen das nützlichen Kontext. Dadurch werden jeder spätere Prompt, jedes Transkript, jeder Wiederholungsversuch, jede Debug-Spur und jedes Tool-Ergebnis zu einem Ort, an dem sich der Datensatz weiterverbreiten kann.

Die Lösung ist kein cleverer Schwärzungs-Prompt. Sie ist eine Design-Disziplin: Jede Aktion wird vor ihrer Freigabe abgebildet, eine begrenzte Anfrage wird an der Ausführungsgrenze erzwungen und unveränderte Antworten vorgelagerter Systeme bleiben für den Agenten nicht verfügbar.

## Eine Tool-Berechtigung berechtigt den Agenten nicht zum gesamten Datensatz

Die Berechtigung, eine API aufzurufen, und die Berechtigung, jedes von dieser API lieferbare Feld zu sehen, sind zwei verschiedene Entscheidungen. Teams vermischen sie, weil ein Servicekonto oft ein umfangreiches Objekt lesen kann, während ein Agenten-Tool nur einen kleinen Teil davon braucht.

Stell dir einen Agenten vor, der entscheiden muss, ob eine Zahlungserinnerung verschickt werden soll. Der Zustelldienst benötigt möglicherweise eine Empfängeradresse, eine Vorlagenkennung und eine Rechnungsreferenz. Der Agent selbst braucht vielleicht nur `eligible: true`, einen sicheren Anzeigenamen und eine Aktionsreferenz. Zahlungshistorie, Kundennotizen, Steuerinformationen und die Adresse, die der Absender intern verwendet, braucht er nicht.

Ein umfangreiches `get_customer`-Tool ist eine verführerische Fehlkonstruktion. Sobald es existiert, wird es für fremde Aufgaben verwendet, weil das scheinbar günstiger ist als ein passendes Aktions-Tool. Danach versuchen Teams, das Problem mit Anweisungen wie «sensible Felder nicht offenlegen» zu lösen. Anweisungen entfernen keine Felder aus einer JSON-Antwort.

Halte diese drei Fragen getrennt:

- Darf dieser Agentenprozess die Aktion anstoßen?
- Welche Felder muss der Ausführer erhalten, um sie durchzuführen?
- Welche Fakten muss der Agent nach Abschluss erhalten?

Jede Frage sollte zu einer eigenen Einschränkung führen. Die Zugriffskontrolle beantwortet die erste. Die Anfragevalidierung beantwortet die zweite. Die Antwortgestaltung beantwortet die dritte. Ein einziges allgemeines API-Token und ein flexibler JSON-Endpunkt beantworten keine davon zuverlässig.

Diese Unterscheidung ist besonders wichtig, wenn ein Agent ein Tool wiederholt verwendet. Eine einmalige umfangreiche Suche wirkt in einer Demo noch vertretbar. In einem echten Lauf kann der Agent sie nach einem Wiederholungsversuch erneut aufrufen, ihre Ausgabe in einer späteren Anfrage zitieren oder sie an ein anderes Tool weitergeben. Aus einem ersten unnötigen Feld werden viele unnötige Kopien.

## Erstelle die Datenübersicht rund um eine Aktion, nicht um eine Datenbanktabelle

Eine brauchbare Datenübersicht beginnt mit einem Verb und einer externen Wirkung. «Kunde lesen» ist für diesen Zweck keine Aktion. «Prüfen, ob eine Rechnung überfällig ist» und «Versandetikett erstellen» sind Aktionen, weil jede davon einen konkreten Empfänger, Zweck und erwartetes Ergebnis hat.

Schreibe für jedes geplante Tool einen kurzen Eintrag, bevor du das Schema erstellst:

| Punkt | Beispiel: Zahlungserinnerung senden |
|---|---|
| Auslöser | Ein Agentenprozess für Abrechnungssupport |
| Wirkung | Sendet eine genehmigte Vorlage an einen berechtigten Empfänger |
| Mindesteingabe | `invoice_ref`, `template_code` |
| Vertrauenswürdige Abfrage | Empfängeradresse, Spracheinstellung, Berechtigungsregeln |
| Für den Agenten sichtbares Ergebnis | `sent`, `suppressed` oder `needs_human_review` |
| Verbotene Eingabe | E-Mail-Adresse, Zahlungshistorie, Kontonotizen, vollständiges Kundenobjekt |
| Verbotene Ausgabe | Zustelladresse, unveränderte Antwort des Anbieters, Zahlungsdaten |

Die Spalte zur vertrauenswürdigen Abfrage übernimmt die schwierige Arbeit. Sie benennt Informationen, die der Ausführer benötigt, der Agent aber nicht. Verschiebe diese Abfrage hinter die Grenze. Der Agent sendet eine Rechnungsreferenz, und ein von dir kontrollierter Dienst ermittelt den Empfänger erst, nachdem er die Aktion geprüft hat.

Mache `invoice_ref` nicht zu einer verkappten Kopie einer E-Mail-Adresse oder zu einer zusammengesetzten Kennung, die einen Kundennamen enthält. Undurchsichtige Referenzen verringern die unbeabsichtigte Offenlegung, machen ein System aber nicht automatisch privat. Wenn eine Referenz beliebige Abfragen eines Kundenobjekts erlaubt, braucht sie weiterhin Autorisierung, Ablaufzeit und eine Einschränkung auf die vorgesehene Zielgruppe.

Die Datenschutz-Grundverordnung der Europäischen Union nennt das relevante Prinzip in Artikel 5 Absatz 1 Buchstabe c klar: Personenbezogene Daten müssen dem Zweck angemessen und erheblich sein sowie auf das für die Zwecke der Verarbeitung notwendige Maß beschränkt werden. Der Ausdruck «für die Zwecke» wird in Entwicklungsteams oft nicht ernst genommen. Der Zweck lautet nicht «dem Agenten bei seiner Arbeit helfen». Es geht um die konkrete Operation an der Grenze, etwa eine Erinnerung zu senden oder einen Supportfall zu eröffnen.

Eine Übersicht macht auch Felder sichtbar, die in keine Richtung die Grenze überschreiten sollten. Freitextnotizen verdienen eine eigene Zeile. Sie enthalten regelmäßig eingefügte E-Mails, Ausweisdokumente, Zugangsdaten, Gesundheitsinformationen und ungefilterte Beschwerden von Kunden. Ein allgemeines Feld `notes` hat keine begrenzte Bedeutung und gehört deshalb nicht in eine routinemäßige Tool-Anfrage.

## Strenge Schemata stoppen Komfortfelder vor der Ausführung

Ein Schema sollte Felder ablehnen, die die Aktion nicht benötigt. Zusätzliche Eigenschaften stillschweigend zu ignorieren klingt entgegenkommend, verbirgt aber während des Tests ein Datenleck und lässt Entwickler glauben, das Feld sei übertragen worden.

Angenommen, ein Agent muss eine Erstattungsprüfung anfordern. Dieser Anfragevertrag erlaubt nur eine Fallreferenz und einen ausgewählten Grund. Kundenkontrollierte Beträge, Adressen und beliebige Notizen werden abgelehnt.

```json
{
  "name": "request_refund_review",
  "description": "Create a review task for an existing support case.",
  "input_schema": {
    "type": "object",
    "additionalProperties": false,
    "required": ["case_ref", "reason_code"],
    "properties": {
      "case_ref": {
        "type": "string",
        "pattern": "^case_[A-Za-z0-9]{16}$"
      },
      "reason_code": {
        "type": "string",
        "enum": ["duplicate_charge", "service_not_received", "other"]
      }
    }
  }
}
```

Eine Anfrage mit `customer_email`, `shipping_address`, `amount` oder `conversation_text` sollte bei der Validierung mit einem eindeutigen Ergebnis wie diesem scheitern:

```json
{
  "error": "invalid_request",
  "message": "Unexpected property: customer_email"
}
```

Diese Fehlermeldung weist den Agenten auf den Vertrag hin und zeigt dem Entwickler, dass ein unerwünschtes Feld die Grenze erreicht hat. Gib den abgelehnten Wert nicht in der Fehlermeldung aus. Fehlerbehandlungen haben mehr Lecks verursacht als viele produktive Abläufe, weil sie die gesamte fehlgeschlagene Anfrage zu Debugging-Zwecken serialisieren.

Die Schema-Validierung schützt serverseitig verwaltete Felder allein nicht. Eine Anfrage kann eine gültig aussehende `case_ref` enthalten, die zu einem anderen Konto gehört, oder einen gültigen `reason_code` mit einer Aktionsreferenz kombinieren, die für einen anderen Agenten ausgestellt wurde. Der Ausführer muss die Referenz an Aussteller, vorgesehene Aktion und Gültigkeitsdauer binden. Betrachte eine Aktionsreferenz als Anspruchsschein, nicht als öffentlichen Primärschlüssel einer Datenbank.

Verwende einen Anfrage-Builder, wenn ein Agent mit nicht vertrauenswürdigem oder zu umfangreichem Kontext startet. Der Builder sollte die erlaubten Felder extrahieren und ein neues Objekt erstellen. Übernimm kein großes Objekt und lösche daraus einige bekannte gefährliche Schlüssel. Eine Schwärzung per Negativliste versagt, sobald ein neues Feld auftaucht, sich die Struktur eines verschachtelten Objekts ändert oder ein Entwickler das Tool mit einem anders benannten Alias aufruft.

```python
ALLOWED_REASONS = {"duplicate_charge", "service_not_received", "other"}

def build_refund_request(case_ref, reason_code):
    if not isinstance(case_ref, str) or not case_ref.startswith("case_"):
        raise ValueError("invalid case_ref")
    if reason_code not in ALLOWED_REASONS:
        raise ValueError("invalid reason_code")
    return {"case_ref": case_ref, "reason_code": reason_code}
```

Diese kleine Funktion verhindert einen häufigen Fehler: ein vollständiges `case`-Wörterbuch an eine Client-Bibliothek weiterzugeben, weil die Bibliothek beliebige Schlüsselwortargumente akzeptiert. Das explizite Rückgabeobjekt ist unspektakulär. An einer Grenze für Kundendaten ist das gut.

## Auch die Tool-Ausgabe braucht einen eigenen Vertrag

Eine unveränderte Tool-Ausgabe gehört zum Kontext des Agenten, selbst wenn das Tool bei der Eingabe keine Kundendaten erhält. Behandle jede Antwort als Material, das der Agent zitieren, aufbewahren, umformen oder an ein anderes System senden kann.

Die Antwort eines Anbieters nach der Erstellung eines Versands kann die vollständige Adresse des Empfängers, seine Telefonnummer, Informationen zum Spediteurskonto, Etikettendaten, Routingdetails und interne Diagnosefelder enthalten. Der Agent braucht meist nur eine Versandreferenz und die Information, ob er dem Kunden mitteilen darf, dass die Bestellung unterwegs ist.

Definiere die agentenseitige Antwort getrennt vom dienstseitigen Ergebnis:

```json
{
  "status": "created",
  "shipment_ref": "ship_Q7J4K2P8",
  "customer_message_allowed": true
}
```

Der Ausführungsdienst kann die detaillierte Antwort des Spediteurs dort speichern oder weitergeben, wo das Betriebspersonal sie benötigt. Er sollte sie nicht zurückgeben, nur weil das Debugging dadurch bequemer wird. Wenn ein Mitarbeiter einen Beleg braucht, gib ihm dafür eine geschützte Oberfläche. Verwende das Agenten-Transkript nicht als Fehlerdatenbank.

Für Fehlermeldungen gilt dasselbe. Eine vorgelagerte API kann die abgelehnte Straßenadresse, eine Kontonummer oder einen zitierten Teil der Anfrage zurückgeben. Wandle das für den Agenten in einen begrenzten Fehlercode um, etwa `recipient_unavailable`, `reference_invalid` oder `provider_retryable`. Geschützte Diagnosedetails gehören in ein System für Mitarbeiter.

Die Spezifikation des Model Context Protocol definiert Tools als aufrufbare Funktionen mit strukturierten Eingaben und Ergebnissen. Diese Struktur bietet Entwicklern eine klare Stelle, um Antworttypen durchzusetzen. Ein Tool, das einen Prosatext oder beliebiges JSON zurückgibt, verzichtet auf diesen Vorteil. Ein enges Antwortschema erleichtert auch das Testen des Agentenverhaltens, weil die nächste Entscheidung nur von bekannten Feldern abhängen kann.

Vermeide ein Feld namens `details`, wenn du seine genaue Struktur und die Regeln für sensible Inhalte nicht beschreiben kannst. Eine vage Ausweichmöglichkeit bleibt dauerhaft bestehen. Irgendjemand wird während eines Vorfalls das unveränderte Ergebnis dort ablegen und anschließend vergessen, es wieder zu entfernen.

## Schwärzung, Pseudonyme und Geheimhaltung sind verschiedene Maßnahmen

Einen Namen durch ein Token zu ersetzen bedeutet nicht, dass die Daten sicher weitergegeben werden können. Ein stabiles Token, das sich mit einer Kundendatenbank verknüpfen lässt, bleibt in den meisten praktischen Bedrohungsmodellen ein personenbezogenes Datum. Eine einmalige Aktionsreferenz, die auf einen Aufrufer und eine kurze Gültigkeitsdauer beschränkt ist, hat ein deutlich kleineres Fehlerrisiko.

Schwärzung entfernt bekannte Werte aus einem Objekt. Das hilft, wenn ein internes System einem Mitarbeiter einen Datensatz anzeigen muss, ist als primäre Grenze für Agenten aber brüchig. Feldnamen ändern sich. Inhalte wandern in verschachtelte Strukturen. Freitext enthält Informationen, die keine feste Schwärzungsliste zuverlässig finden kann.

Pseudonymisierung ersetzt eine direkte Kennung durch einen anderen Bezeichner. Das verringert die Offenlegung, wenn der Empfänger die Zuordnung nicht auflösen kann. Sie versagt, wenn derselbe Agent mit dieser Kennung ein umfangreiches Such-Tool aufrufen kann, wenn das Token in verschiedenen, eigentlich unabhängigen Tools auftaucht oder wenn der Wert selbst Bedeutung trägt. `acme-health-urgent-001` ist nicht deshalb undurchsichtig, weil es kein @-Zeichen enthält.

Geheimhaltung entsteht dadurch, dass auflösende Daten und Zugangsdaten auf der vertrauenswürdigen Seite der Grenze bleiben. Der Agent sendet eine begrenzte Anweisung, und ein Dienst löst geschützte Informationen nur für diese erlaubte Aktion auf. Diese Unterscheidung verhindert den bekannten Fehler, ein «bereinigtes» Kundenobjekt an einen Agenten zu übergeben und die Aufgabe damit für erledigt zu halten.

Datenminimierung musst du außerdem von Autorisierung trennen. Ein ordnungsgemäß autorisierter Agent kann trotzdem zu viele Daten erhalten. Umgekehrt kann ein nicht autorisierter Aufrufer sehr wenige Daten erhalten, die dennoch Schaden anrichten können. Erzwinge beide Maßnahmen und teste sie unabhängig voneinander.

## Umfangreiche Zugangsdaten machen enge Schemata unglaubwürdig

Ein perfektes Anfrage-Schema kann einen Agenten nicht schützen, der eine Zugangsdaten besitzt, mit der er die zugrunde liegende API direkt aufrufen kann. Wenn der Agent das Geheimnis lesen oder aus seiner Laufzeit heraus verwenden kann, umgeht er das sorgfältig entwickelte Tool und fordert beim Anbieter eine umfangreichere Antwort an.

Platziere Zugangsdaten dort, wo die Aktion ausgeführt wird, nicht dort, wo das Modell schlussfolgert. Der Ausführer fügt den Autorisierungs-Header oder die SSH-Identität erst ein, nachdem er die begrenzte Anfrage validiert hat. Der Agent sieht weder das Geheimnis noch einen Platzhalter oder eine Kopie in einer Umgebungsvariable, sondern nur das Ergebnis.

OAuth 2.0, beschrieben in RFC 6749, verwendet Scopes, um den Zugriff eines Clients zu begrenzen. Scopes sind nützlich, aber viele Implementierungen behandeln einen Scope wie einen allgemeinen Zutritt für eine ganze Abteilung. Ein Scope `customers.read` kann weiterhin eine vollständige Kundensuche erlauben. Kombiniere den Berechtigungsumfang mit aktionsspezifischen Endpunkten und gefilterten Antworten. Andernfalls begrenzt der Scope nur, welche große Sammlung der Agent durchsuchen kann.

Teile Berechtigungen nach ihrer Wirkung auf. Ein Agent, der einen Entwurf erstellen darf, sollte nicht auch die Berechtigung zum Versenden erhalten. Ein Agent, der eine Erstattungsprüfung anfordern darf, sollte keine Erstattung auslösen können. Diese Trennung verringert den Druck, für einen einzigen Ablauf eine allgemeine administrative Zugangsdaten einzuführen.

Für macOS-Teams, die Sallyport verwenden, verwahrt die App API- und SSH-Zugangsdaten in ihrem verschlüsselten Tresor und führt die HTTP- oder SSH-Aktion aus, ohne die Zugangsdaten an den Agenten weiterzugeben. Das hilft nur, wenn der Aufruf selbst begrenzt bleibt. Auch ein geschütztes Token kann eine zu umfangreiche Anfrage autorisieren.

## Ein Support-Ablauf zeigt, wo sich Daten verbreiten

Ein häufiges Leck beginnt mit einer vernünftigen Anfrage: Ein Support-Agent soll eine Antwort auf eine fehlgeschlagene Zustellung vorbereiten. Die erste Implementierung stellt `get_order(order_id)` bereit. Dieses Tool gibt Bestellung, Kundenprofil, Lieferadresse, Zahlungsstatus, Supportverlauf und Speditionsereignisse zurück. Der Agent braucht aber nur das Ereignis des Spediteurs und die Berechtigung, eine genehmigte Aktualisierung zu senden.

Der Agent ruft die Suche auf und erhält den vollständigen Datensatz. Danach gibt er ausgewählte Details an ein Tool zur Nachrichtenerstellung weiter. Der Prompt enthält nun Adresse und Verlauf, obwohl beides für die Nachricht keine Rolle spielt. Ein fehlgeschlagener Tool-Aufruf schreibt den gesamten Prompt in ein Fehlerprotokoll. Ein Entwickler kopiert diesen Fehler zur Diagnose in ein Ticket. Aus der ersten umfangreichen Antwort sind vier getrennte Probleme bei der Aufbewahrung geworden.

Baue den Ablauf anders. Gib dem Agenten eine Aktion `assess_delivery_update`, die `order_ref` akzeptiert. Der Ausführungsdienst prüft die Berechtigung des Aufrufers, ruft die Bestellung intern ab, liest den Status des Spediteurs, wendet die Kontaktregel an und gibt nur Folgendes zurück:

```json
{
  "status": "contact_allowed",
  "event_code": "delivery_delayed",
  "approved_template": "delivery_delay_notice",
  "order_ref": "ord_9VJ3R6M1"
}
```

Der Agent kann entscheiden, ob die Situation eine genehmigte Nachricht rechtfertigt. Eine separate Aktion `send_approved_delivery_update` akzeptiert `order_ref` und `approved_template`. Sie akzeptiert weder eine E-Mail-Adresse noch einen Freitext. Der Dienst löst den Empfänger auf und rendert die Vorlage erst, nachdem er Einwilligung und Bestellstatus geprüft hat.

Dieses Design wirkt restriktiver, weil es das tatsächlich ist. Genau darum geht es. Der Agent kann ein Kundenprofil nicht beiläufig für eine andere Aufgabe verwenden, und ein späteres Tool kann die Daten nicht versehentlich erhalten.

Setze dem nicht das allgemeine Argument entgegen, ein Tool müsse «flexibel» sein. Flexibilität gehört in vertrauenswürdigen Anwendungscode, den du testen, prüfen und auf seine Datenverarbeitung hin auditieren kannst. Wenn du einem Agenten über umfangreiche Anfrage- und Antwortobjekte Flexibilität gibst, verlagerst du die Kosten auf jeden Prompt und jedes nachgelagerte System.

## Genehmigungsfenster können nicht jedes versteckte Feld prüfen

Eine Genehmigung schützt vor nicht autorisierten Aktionen, kann aber übergroße Nutzlasten nicht zuverlässig kontrollieren. Eine Person sieht eine kurze Zusammenfassung, entscheidet unter Zeitdruck und genehmigt die Aktion. Wenn der Dienst eine unnötige Adresse oder Historie in einer Anfrage versteckt, hat die Genehmigung die Offenlegung nicht minimiert.

Eine Genehmigung wird außerdem zum schlechten Ersatz für gutes Tool-Design, wenn sie als solches verwendet wird. Entwickler fügen weiter Felder hinzu, weil «der Benutzer jeden Aufruf genehmigt». Bald enthält die Genehmigungskarte zu viele Details zum Lesen oder zu wenige für eine fundierte Entscheidung. Menschen genehmigen wiederholte, harmlos wirkende Aktionen, ohne zu bemerken, dass eine Anfrage ein neues Feld enthält.

Zeige die Aktion und ihre begrenzten Parameter in der Genehmigungsoberfläche, erzwinge die Positivliste aber schon vorher. Die genehmigende Person sollte wählen, ob sie «genehmigte Lieferaktualisierung für ord_9VJ3R6M1 senden» autorisiert, und nicht manuell einen serialisierten Kundendatensatz prüfen müssen.

Verwende eine Genehmigung pro Aufruf für Wirkungen, bei denen jede Ausführung menschliche Aufmerksamkeit verdient. Verwende sie nicht als Scanner für personenbezogene Daten. Die Person, die die Genehmigung sieht, hat weder die Zeit noch den Kontext, um zu entscheiden, ob jedes verschachtelte Feld notwendig war.

Ein guter Prüftest ist einfach: Entferne die genehmigende Person aus der Geschichte. Würde der Tool-Vertrag weiterhin verhindern, dass unnötige Daten den vertrauenswürdigen Dienst verlassen? Wenn nicht, leistet die Grenze zu wenig.

## Audit-Einträge sollten Aktionen belegen, ohne zu einer weiteren Datensammlung zu werden

Du brauchst Belege dafür, dass ein Agent im Namen eines Kunden gehandelt hat. Für diesen Beleg brauchst du kein dauerhaftes, für den Agenten lesbares Archiv vollständiger Nutzlasten.

Protokolliere den Aktionsnamen, den auslösenden Prozess oder die Sitzung, den Zeitstempel, das Ergebnis, die Autorisierungsentscheidung und eine Korrelationsreferenz. Wenn du einen Integritätsnachweis für die Nutzlast brauchst, speichere einen kryptografischen Digest einer kanonischen, geschützten Darstellung und nicht die Darstellung selbst. Speichere die akzeptierten Feldnamen, nicht deren sensiblen Werte.

Ein Audit-Ereignis kann beispielsweise diese Form haben:

```json
{
  "action": "send_approved_delivery_update",
  "session_ref": "sess_4KH8N2",
  "order_ref_digest": "sha256:8e4c...",
  "accepted_fields": ["order_ref", "approved_template"],
  "outcome": "sent",
  "authorized_by": "per_call"
}
```

Ein Digest beseitigt Datenschutzrisiken nicht automatisch. Wenn die Eingabe aus einer kleinen bekannten Menge stammt, kann ein Angreifer Werte erraten und Hashes vergleichen. Verwende eine geschützte interne Referenz, wenn Mitarbeiter Details abrufen müssen, und begrenze den Zugriff auf das System, das den Originaldatensatz verwahrt. Behandle einen einfachen Hash einer E-Mail-Adresse niemals als anonym.

Halte Betriebsdiagnosen vom eigenen Tool-Ergebnis des Agenten getrennt. Supportmitarbeiter benötigen möglicherweise für kurze Zeit geschützten Zugriff auf den Fehlertext eines vorgelagerten Dienstes. Der Agent nicht. Diese Trennung schafft außerdem eine klarere Grundlage für Löschung und Aufbewahrung, weil sich unveränderte Datensätze nicht in jedem Journal ansammeln.

Sallyport versieht Agentensitzungen und einzelne Aufrufe mit einem schreibgeschützten, verschlüsselten und hashverketteten Audit-Log. Der Befehl `sp audit verify` kann die Kette offline und ohne Tresorschlüssel prüfen. Die Integritätsprüfung beantwortet die Frage, ob ein aufgezeichnetes Ereignis verändert wurde. Dein Ereignisschema entscheidet weiterhin, ob dieser Eintrag von Anfang an zu viele Kundendaten enthält.

## Teste die Grenze mit absichtlicher Übertragung zu vieler Daten

Eine Datenschutzprüfung, die nur gültige Standardaufrufe testet, übersieht das Verhalten, das die meisten unbeabsichtigten Offenlegungen verursacht. Teste, was passiert, wenn ein Agent ein vollständiges Objekt sendet, ein vorgelagerter Dienst ein unerwartetes Feld zurückgibt und mitten in einer Anfrage eine Ausnahme auftritt.

Verwende ein Testobjekt mit erkennbaren, aber künstlichen sensiblen Werten und prüfe anschließend, dass diese die Agentengrenze nicht überschreiten. Das Objekt sollte verschachtelte Felder und Freitext enthalten, weil flache Beispiele Schwärzungscode zu leicht bestehen lassen.

```json
{
  "case_ref": "case_Ab92Kx71LmQ4Rt8P",
  "reason_code": "duplicate_charge",
  "customer": {
    "email": "test.person@example.invalid",
    "address": "17 Example Lane",
    "payment_note": "card ending 4242"
  },
  "conversation_text": "Customer says their medical appointment depends on delivery."
}
```

Das erwartete Ergebnis ist ein Validierungsfehler, der nur das unerwartete Feld nennt. Prüfe anschließend vier Stellen: die für den Agenten sichtbare Antwort, Anwendungsprotokolle, Fehleraufzeichnungen und Audit-Ereignisse. Entwickler validieren die Anfrage oft, vergessen aber, dass ihre Ausnahmebehandlung den ursprünglichen Inhalt protokolliert hat.

Füge auch Vertragstests für die Ausgabe hinzu. Simuliere eine Antwort des vorgelagerten Dienstes, die ein vollständiges Kundenobjekt enthält, und prüfe, dass das Tool nur seine dokumentierten Felder ausgibt. Wiederhole diesen Test bei jeder Änderung am Client des Anbieters. Ein SDK-Upgrade kann Antwortfelder hinzufügen, ohne dass jemand den Agenten-Prompt anfasst.

Führe schließlich einen Transkript-Test durch. Gib dem Agenten eine normale Aufgabe, erfasse alle Tool-Eingaben und -Ergebnisse, die er erhält, und suche nach den Testwerten. Dieser Test findet versehentliche Prompt-Interpolation und Debug-Text, die Schema-Tests möglicherweise übersehen.

Das erste neu zu gestaltende Tool ist meistens das allgemeine Such-Tool. Ersetze es durch eine Aktion, die eine echte externe Wirkung auslöst oder eine begrenzte Entscheidung zurückgibt. Wenn der neue Vertrag zu eng und unpraktisch wirkt, ist das oft ein Hinweis darauf, dass das System bisher darauf angewiesen war, dass der Agent Daten mit sich führt, die er nie gebraucht hat.
