Wer hat den Assistenten dazu gebracht
Ein Audit-Eintrag sagt, wer wann was getan hat, ohne den privaten Text aufzubewahren. Das ist wichtig, weil man bei einem Problem rekonstruieren muss, was geschah, ohne die Nachrichten aller kopiert zu haben.
Ein Werkzeug lehnt am Dienstag eine seltsame Anfrage ab. Am Freitag fragt jemand, warum. Ein Eintrag mit Nutzer-ID, Werkzeugname, Ergebnis und Zeit beantwortet das. Eine Kopie des Chats würde es auch, und wäre ein Risiko.
Am Ende dieser Lektion
Notiz
Ich kann Audit-Einträge ohne privaten Inhalt schreiben und löschen, wenn ihre Aufbewahrungsfrist endet.
Schlüsselwörter
| Begriff | Was er bedeutet | Beispiel |
|---|---|---|
| Audit-Eintrag | eine Notiz, wer was wann mit welchem Ergebnis getan hat | |
| Aufbewahrungsfrist | wie lange ein Eintrag behalten wird | |
| Bereinigung | Einträge löschen, deren Zeit abgelaufen ist | |
| Testuhr | eine Zeit, die Ihr Code setzt, damit ein Test die Zeit steuert | |
| Kennung | ein Code, der eine Person vertritt, ohne sie zu nennen | u-17 |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Halten Sie fest, wer, was und wann
Schreiben Sie für jede Handlung der Funktion einen kleinen Eintrag. Bleiben Sie bei einer festen Liste von Feldern. Alles andere, etwa ein Prompt oder eine Antwort, wird vor dem Speichern verworfen.
Nehmen Sie für die Person eine Kennung statt eines Namens. Hängen Sie Einträge an und ändern Sie sie nie, damit das Protokoll vertrauenswürdig bleibt.
Beispiel: ein Audit-Eintrag
| Feld | Beispiel | Warum es da ist |
|---|---|---|
| zeit | eine Zeit | Wann es geschah |
| nutzer | u-17 | Wer gefragt hat, ohne Namen |
| aktion | notiz_lesen | Was die Funktion tat |
| ergebnis | erlaubt | Was die Prüfungen entschieden |
| tokens | 120 | Was es kostete, als Zahl |
| (nicht behalten) | der Prompt-Text | Er kann personenbezogene Daten enthalten |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Behalten Sie Einträge, solange sie nützen
Jeder Eintrag hat einen Grund, und der Grund endet. Wählen Sie je Art eine Aufbewahrungsfrist: kurz für Chattext, länger für Audit-Einträge. Löschen Sie dann, was älter ist.
Rechtliche Pflichten unterscheiden sich je nach Land und Bereich: Prüfen Sie die für Sie geltenden, bevor Sie eine Zahl wählen.
Das Audit-Skript schreiben, Teil 1
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'const TAG = 24 * 60 * 60 * 1000;' 'let jetzt = Date.UTC(2026, 0, 1);' 'const erlaubt = [\"nutzer\", \"aktion\", \"ergebnis\", \"tokens\"];' 'const protokoll = [];' '' '// Ein Audit-Eintrag hält fest, wer, was und wann. Nie den Text.' 'function aufzeichnen(felder) {' ' const sauber = { zeit: jetzt, id: protokoll.length + 1 };' ' for (const schluessel of erlaubt) {' ' if (schluessel in felder) sauber[schluessel] = felder[schluessel];' ' }' ' protokoll.push(sauber);' ' return sauber;' '}' > protokoll.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Das Audit-Skript schreiben, Teil 2
docker exec -w /home/node/project agent sh -c "printf '%s\n' 'aufzeichnen({ nutzer: \"u-17\", aktion: \"notiz_lesen\", ergebnis: \"erlaubt\", tokens: 120, prompt: \"Hallo, ich bin Anna\" });' 'jetzt = jetzt + 20 * TAG;' 'aufzeichnen({ nutzer: \"u-18\", aktion: \"shell_starten\", ergebnis: \"abgelehnt\", tokens: 0 });' 'jetzt = jetzt + 20 * TAG;' 'aufzeichnen({ nutzer: \"u-17\", aktion: \"addieren\", ergebnis: \"erlaubt\", tokens: 60 });' 'console.log(\"Behaltene Felder: \" + Object.keys(protokoll[0]).join(\", \"));' 'console.log(\"Prompt gespeichert: \" + (\"prompt\" in protokoll[0]));' >> protokoll.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Das Audit-Skript schreiben, Teil 3
docker exec -w /home/node/project agent sh -c "printf '%s\n' '// Aufbewahrung: einen Eintrag 30 Tage behalten, dann löschen.' 'const BEHALTEN = 30 * TAG;' 'function bereinigen(liste, zeitpunkt) {' ' return liste.filter(function (eintrag) { return zeitpunkt - eintrag.zeit <= BEHALTEN; });' '}' 'const uebrig = bereinigen(protokoll, jetzt);' 'console.log(\"Vorher: \" + protokoll.length + \", nachher: \" + uebrig.length);' 'console.log(\"Behaltene IDs: \" + uebrig.map(function (eintrag) { return eintrag.id; }).join(\", \"));' >> protokoll.js"Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Das Audit-Skript ausführen
docker exec -w /home/node/project agent node protokoll.jsHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Was das Skript ausgibt
| Zeile | Was sie zeigt |
|---|---|
| Behaltene Felder: zeit, id, nutzer, aktion, ergebnis, tokens | Das Feld prompt wurde verworfen |
| Prompt gespeichert: false | Nichts Privates gelangte ins Protokoll |
| Vorher: 3, nachher: 2 | Der erste Eintrag ist 40 Tage alt und die Grenze liegt bei 30 |
| Behaltene IDs: 2, 3 | Die zwei neuen Einträge bleiben |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Eine Liste ersetzt echten Speicher
Das Skript hält sein Protokoll in einem Array und stellt eine Testuhr von Hand. Ein echtes System nutzt eine Datenbank, mit Sicherungen und Zugriffskontrolle, und einen geplanten Job, der bereinigt.
Auch Sicherungen zählen. Ein aus der Datenbank gelöschter Eintrag steckt noch in der Sicherung vom Vormonat, außer sie läuft ebenfalls ab.
Ein häufiger Fehler
Warnung
Viele glauben, mehr zu protokollieren sei immer sicherer. Ein Protokoll, das jeden Prompt speichert, ist selbst ein Speicher personenbezogener Daten und muss wie einer geschützt und gelöscht werden. Protokollieren Sie die Felder, die Sie zum Beantworten einer Frage brauchen, und nicht mehr.