0Pricing
AI Agents · Lektion

Unveränderliche Aktionsprotokollierung für Agenten

Nur-Erweitern-Protokolle, kryptografische Signaturen und manipulationssichere Prüfpfade.

Unveränderliche Aktionsprotokollierung für Agenten ist eine kostenlose AI Agents-Lektion auf CoddyKit. Dies ist Lektion 1 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des AI Agents-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.

Warum Agenten unveränderliche Protokolle benötigen

Agenten führen Aktionen autonom aus – häufig ohne dass ein Mensch jeden Schritt überprüft. Wenn etwas schiefläuft, müssen Sie beantworten können: Was hat der Agent wann, im Auftrag welcher Person und warum getan?

Ein unveränderliches, manipulationsnachweisendes Protokoll verhindert, dass die Prüfspur nachträglich verändert wird.

Schema eines Protokolleintrags

Jeder Protokolleintrag enthält: Zeitstempel, Agentenidentität, Benutzeridentität, Aktionstyp, Parameter, Ergebnis und einen Hash, der ihn mit dem vorherigen Eintrag verknüpft. Diese Struktur unterstützt sowohl die Suche als auch die Erkennung von Manipulationen.

from dataclasses import dataclass
from typing import Any

@dataclass
class AuditEntry:
    timestamp:   float       # Unix time (UTC)
    agent_id:    str
    user_id:     str
    action_type: str
    parameters:  dict
    result:      dict
    session_id:  str
    prev_hash:   str         # hash of previous entry
    entry_hash:  str = ''    # computed after construction

if __name__ == '__main__':
    entry = AuditEntry(
        timestamp=1717000000.0, agent_id='agent-1', user_id='user-42',
        action_type='send_email', parameters={'to': 'a@b.com'},
        result={'status': 'sent'}, session_id='sess-1', prev_hash='0' * 64
    )
    print('Audit entry created:')
    print(' agent_id:', entry.agent_id)
    print(' action_type:', entry.action_type)
    print(' prev_hash:', entry.prev_hash)

Hash-Verkettung zur Manipulationserkennung

Der Hash jedes Eintrags wird aus seinem Inhalt plus dem Hash des vorherigen Eintrags berechnet. Wird ein Eintrag nachträglich geändert, ändert sich sein Hash, wodurch alle nachfolgenden Hashes ungültig werden. So lassen sich Manipulationen erkennen.

import hashlib, json, time

def compute_entry_hash(entry: dict, prev_hash: str) -> str:
    content = json.dumps(entry, sort_keys=True, default=str)
    payload = f'{prev_hash}:{content}'
    return hashlib.sha256(payload.encode()).hexdigest()

def create_log_entry(agent_id: str, user_id: str, action_type: str,
                     parameters: dict, result: dict,
                     session_id: str, prev_hash: str) -> dict:
    entry = {
        'timestamp':   time.time(),
        'agent_id':    agent_id,
        'user_id':     user_id,
        'action_type': action_type,
        'parameters':  parameters,
        'result':      result,
        'session_id':  session_id,
        'prev_hash':   prev_hash
    }
    entry['entry_hash'] = compute_entry_hash(
        {k: v for k, v in entry.items() if k != 'entry_hash'},
        prev_hash
    )
    return entry

if __name__ == '__main__':
    entry = create_log_entry('agent-1', 'user-42', 'send_email',
                              {'to': 'a@b.com'}, {'status': 'sent'},
                              'sess-1', prev_hash='0' * 64)
    print('New log entry hash:', entry['entry_hash'])
    print('Chained from prev_hash:', entry['prev_hash'])

Append-only-Protokoll innerhalb des Prozesses

Die einfachste Implementierung ist eine Liste im Arbeitsspeicher mit einer Methode, die nur das Anhängen neuer Einträge erlaubt. Es werden keine Methoden zum Löschen oder Aktualisieren bereitgestellt. In Produktionsumgebungen wird dies durch eine Datenbank oder einen Objektspeicher unterstützt.

class AppendOnlyLog:
    def __init__(self):
        self._entries: list[dict] = []
        self._last_hash = 'GENESIS'

    def append(self, agent_id: str, user_id: str, action_type: str,
               parameters: dict, result: dict, session_id: str) -> dict:
        entry = create_log_entry(
            agent_id, user_id, action_type,
            parameters, result, session_id,
            self._last_hash
        )
        self._entries.append(entry)
        self._last_hash = entry['entry_hash']
        return entry

    def verify_integrity(self) -> bool:
        running_hash = 'GENESIS'
        for e in self._entries:
            expected = compute_entry_hash(
                {k: v for k, v in e.items() if k != 'entry_hash'},
                running_hash
            )
            if expected != e['entry_hash']:
                return False
            running_hash = e['entry_hash']
        return True

    @property
    def entries(self):
        return list(self._entries)  # return copy, not reference

In PostgreSQL mit Append-Semantik schreiben

Schreiben Sie Protokolle in der Produktion in eine Datenbanktabelle, für die dem Anwendungsbenutzer keine UPDATE- oder DELETE-Berechtigungen erteilt wurden. Entziehen Sie diese Berechtigungen auf Datenbankebene, um echtes Append-only-Verhalten sicherzustellen.

import psycopg2, json

# Table DDL (run once):
# CREATE TABLE agent_audit_log (
#   id          BIGSERIAL PRIMARY KEY,
#   timestamp   DOUBLE PRECISION NOT NULL,
#   agent_id    TEXT NOT NULL,
#   user_id     TEXT NOT NULL,
#   action_type TEXT NOT NULL,
#   parameters  JSONB NOT NULL,
#   result      JSONB NOT NULL,
#   session_id  TEXT NOT NULL,
#   prev_hash   TEXT NOT NULL,
#   entry_hash  TEXT NOT NULL UNIQUE
# );
# REVOKE UPDATE, DELETE ON agent_audit_log FROM app_user;

def write_to_db(conn, entry: dict):
    with conn.cursor() as cur:
        cur.execute(
            'INSERT INTO agent_audit_log '
            '(timestamp,agent_id,user_id,action_type,parameters,result,session_id,prev_hash,entry_hash) '
            'VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s)',
            (entry['timestamp'], entry['agent_id'], entry['user_id'],
             entry['action_type'], json.dumps(entry['parameters']),
             json.dumps(entry['result']), entry['session_id'],
             entry['prev_hash'], entry['entry_hash'])
        )
    conn.commit()

Mit S3 Object Lock (WORM) schreiben

AWS S3 Object Lock im COMPLIANCE-Modus verhindert, dass irgendein Benutzer – einschließlich des Account-Root-Benutzers – Objekte während des Aufbewahrungszeitraums löscht oder überschreibt. Damit steht für Prüfprotokolle echter Write-once-Speicher zur Verfügung.

import boto3, json, time

s3 = boto3.client('s3', region_name='us-east-1')
BUCKET = 'your-audit-log-bucket-worm'

def write_to_s3_worm(entry: dict):
    key = f'audit/{entry["agent_id"]}/{int(entry["timestamp"])}/{entry["entry_hash"][:16]}.json'
    s3.put_object(
        Bucket=BUCKET,
        Key=key,
        Body=json.dumps(entry).encode(),
        ContentType='application/json',
        ObjectLockMode='COMPLIANCE',
        ObjectLockRetainUntilDate='2030-01-01T00:00:00Z'  # 4+ year retention
    )
    return key

Das Prüfprotokoll abfragen

Das Prüfprotokoll dient nicht nur der Compliance, sondern ist auch für den Betrieb nützlich. Fragen Sie es ab, um das Verhalten des Agenten zu debuggen, eine Sitzung zu rekonstruieren oder zu beantworten: „Warum hat der Agent X getan?“

def query_session(log: AppendOnlyLog, session_id: str) -> list[dict]:
    return [
        e for e in log.entries
        if e['session_id'] == session_id
    ]

def query_user_actions(log: AppendOnlyLog, user_id: str,
                       action_type: str = None) -> list[dict]:
    entries = [e for e in log.entries if e['user_id'] == user_id]
    if action_type:
        entries = [e for e in entries if e['action_type'] == action_type]
    return sorted(entries, key=lambda e: e['timestamp'])

def count_actions_by_type(log: AppendOnlyLog) -> dict:
    from collections import Counter
    return dict(Counter(e['action_type'] for e in log.entries))

Sensible Daten vor der Protokollierung bereinigen

Prüfprotokolle sollten festhalten, was der Agent getan hat, ohne sensible Daten offenzulegen. Entfernen Sie PII (Passwörter, API-Schlüssel, Kreditkartennummern) aus Parametern und Ergebnissen, bevor Sie diese schreiben.

import re

SENSITIVE_KEYS = {'password', 'api_key', 'secret', 'token', 'credit_card', 'ssn'}

def sanitize(obj, depth: int = 0) -> dict | list | str:
    if depth > 5:
        return '[MAX_DEPTH]'
    if isinstance(obj, dict):
        return {
            k: '[REDACTED]' if k.lower() in SENSITIVE_KEYS
               else sanitize(v, depth + 1)
            for k, v in obj.items()
        }
    elif isinstance(obj, list):
        return [sanitize(i, depth + 1) for i in obj]
    elif isinstance(obj, str):
        # Redact anything that looks like an API key
        return re.sub(r'(sk-|Bearer\s)[A-Za-z0-9_-]{16,}', '[REDACTED]', obj)
    return obj

if __name__ == '__main__':
    record = {'user': 'alice', 'password': 'hunter2', 'note': 'call me at sk-abcdefghijklmnopqrstuv'}
    print('Sanitized record:', sanitize(record))

Protokollrotation und Archivierung

Aktive Protokolle wachsen unbegrenzt. Rotieren Sie sie: Verschieben Sie Einträge, die älter als 90 Tage sind, in einen Cold Storage (z. B. S3 Glacier), und komprimieren Sie sie. Bewahren Sie die Verkettung, indem Sie den letzten Hash jedes rotierten Segments erhalten.

import time, json, gzip

def rotate_log(log: AppendOnlyLog, max_age_days: int = 90) -> dict:
    cutoff = time.time() - max_age_days * 86400
    archive = [e for e in log.entries if e['timestamp'] < cutoff]
    remaining = [e for e in log.entries if e['timestamp'] >= cutoff]

    if not archive:
        return {'archived': 0, 'remaining': len(remaining)}

    # Compress archive
    archive_bytes = gzip.compress(json.dumps(archive).encode())
    archive_file  = f'/tmp/audit_archive_{int(time.time())}.json.gz'
    with open(archive_file, 'wb') as f:
        f.write(archive_bytes)

    # Update in-memory log
    log._entries = remaining

    return {'archived': len(archive), 'remaining': len(remaining), 'file': archive_file}

Bei verdächtigen Mustern Benachrichtigungen auslösen

Überwachen Sie das Prüfprotokoll in Echtzeit auf ungewöhnliche Muster: eine Häufung risikoreicher Aktionen, Aktionen außerhalb der Geschäftszeiten oder dieselbe Aktion, die innerhalb eines kurzen Zeitfensters mehr als N-mal wiederholt wird.

import time
from collections import defaultdict

HIGH_RISK_ACTIONS = {'delete_user', 'send_mass_email',
                     'transfer_funds', 'export_all_data'}
BURST_LIMIT = 5
BURST_WINDOW = 60  # seconds

action_timestamps: dict[str, list] = defaultdict(list)

def check_suspicious(entry: dict) -> list[str]:
    alerts = []
    action = entry['action_type']

    if action in HIGH_RISK_ACTIONS:
        alerts.append(f'HIGH_RISK_ACTION: {action} by {entry["agent_id"]}')

    now = time.time()
    action_timestamps[action].append(now)
    recent = [t for t in action_timestamps[action] if now - t < BURST_WINDOW]
    action_timestamps[action] = recent

    if len(recent) > BURST_LIMIT:
        alerts.append(f'ACTION_BURST: {action} called {len(recent)}x in {BURST_WINDOW}s')

    return alerts

if __name__ == '__main__':
    entry = {'action_type': 'delete_user', 'agent_id': 'agent-9'}
    for _ in range(6):
        alerts = check_suspicious(entry)
    print('Alerts on 6th call:', alerts)

Die Integrität des Protokolls bei Bedarf überprüfen

Führen Sie eine Integritätsprüfung als Teil Ihrer Monitoring-Pipeline aus. Lösen Sie sofort einen Alarm aus, wenn ein Verifikationsfehler erkannt wird – dies weist entweder auf einen Fehler im Protokollierungscode oder auf einen aktiven Manipulationsversuch hin.

def verify_and_alert(log: AppendOnlyLog) -> dict:
    is_valid = log.verify_integrity()
    total    = len(log.entries)
    result   = {
        'total_entries': total,
        'integrity_ok':  is_valid
    }
    if not is_valid:
        import logging
        alert_logger = logging.getLogger('agent.integrity_alert')
        alert_logger.critical(
            'AUDIT LOG INTEGRITY FAILURE: tampered or corrupted entries detected. '
            'Total entries: %d. Initiating incident response.', total
        )
        result['alert_sent'] = True
    return result

# Run periodically via cron or monitoring hook
# verify_and_alert(global_audit_log)

Was erkennt die Hash-Verkettung in einem Prüfprotokoll?

Die Hash-Verkettung ist der kryptografische Mechanismus, der dem Prüfprotokoll seine Eigenschaft der Manipulationsnachweisbarkeit verleiht. Zu verstehen, was sie erkennt, ist grundlegend für das Design von Prüfprotokollen.

Zusammenfassung: Unveränderliche Aktionsprotokollierung

Unveränderliche Agentenprotokolle verwenden: Hash-Verkettung zur Manipulationserkennung, Append-only-Speicher (UPDATE/DELETE auf Datenbankebene entziehen), WORM-Objektspeicher (S3 Object Lock) für die gesetzlich vorgeschriebene Aufbewahrung, PII-Bereinigung vor dem Schreiben und Echtzeit-Benachrichtigungen bei Anomalien aufgrund verdächtiger Aktionsmuster.

Häufig gestellte Fragen

Ist die Lektion „Unveränderliche Aktionsprotokollierung für Agenten“ kostenlos?

Ja — der vollständige Text von „Unveränderliche Aktionsprotokollierung für Agenten“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des AI Agents-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Unveränderliche Aktionsprotokollierung für Agenten“?

Nur-Erweitern-Protokolle, kryptografische Signaturen und manipulationssichere Prüfpfade. Du übst AI Agents mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um AI Agents zu starten?

Keine Vorkenntnisse erforderlich. AI Agents auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 1 von 4.

Wie lange dauert die Lektion „Unveränderliche Aktionsprotokollierung für Agenten“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser AI Agents-Lektion Code schreiben und ausführen?

Ja. Jede AI Agents-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Unveränderliche Aktionsprotokollierung für Agenten
  2. Richtliniendurchsetzung für Agentenaktionen
  3. Einhaltung gesetzlicher Vorgaben: GDPR und SOC2
  4. Freigabestufen mit Human-in-the-Loop
← Zurück zu AI Agents