Prompts sind Vorschläge. Hooks sind harte Stopps.
Monatelang behandelte ich Claude Code wie einen Junior-Entwickler, der einfach nur klare Grundregeln brauchte. Meine Projektanweisungen waren explizit: niemals force-pushen, niemals Branches löschen, niemals destruktive Befehle ausführen. Die meisten Abende funktionierte das. Der Agent schrieb Tests, refaktorisierte Funktionen und ließ die Finger von der Git-Historie. Dann geriet ein Rebase aus dem Ruder.
Das Kontextfenster füllte sich mit Git-Fehlermeldungen. Konfliktmarker, „detached HEAD“-Meldungen und Warnungen über Branch-Divergenzen stapelten sich, Token für Token. Unter diesem Rauschen vergrub sich meine höfliche Anweisung, Force-Pushes zu vermeiden. Für das Modell war der aktuellste und auffälligste Text im Thread der Error-Stream. Die statistische Aufmerksamkeit siegte über die Richtlinie. Der Agent führte einen Befehl aus, der zwei Stunden uncommitted lokale Änderungen löschte. Es war nicht böswillig; es war abgelenkt. Diese Unterscheidung ist wichtig. Ein LLM bricht Regeln nicht aus Bosheit. Es bricht sie, weil ein lauteres Muster im Kontextfenster vorübergehend eine frühere Anweisung überschreibt.
Dieser Vorfall änderte meine Sichtweise auf die Sicherheit von Agenten. Eine Leitplanke, die zu neunundneunzig Prozent funktioniert, ist ein Risiko. Wenn der Fehlerfall Zeit, Geld oder Produktionsdaten kostet, darf man ihn nicht innerhalb des Prompts belassen. Man benötigt eine Durchsetzung außerhalb der Denklogik des Modells.
Claude Code Hooks lösen genau dieses Problem. Es sind kleine Skripte, die Tool-Aufrufe in drei spezifischen Momenten abfangen: bevor ein Tool ausgeführt wird (PreToolUse), nachdem ein Tool fertig ist (PostToolUse) und wenn der Agent entscheidet, dass er fertig ist (Stop). Da sie als externer Code laufen, hängen sie nicht vom Gedächtnis, der Stimmung oder dem Kontextdruck des Modells ab. Das Modell kann jede Anweisung vergessen, die man ihm je gegeben hat; der Hook wird trotzdem „Nein“ sagen.
Hier ist das Gerüst, das ich nach diesem verlorenen Abend gebaut habe.
Der Guard-Hook: Abfangen vor dem Schaden
Mein PreToolUse-Hook überprüft jeden Bash-Befehl, bevor die Shell ihn berührt. Ich führe eine strikte Denylist für destruktive Muster. Wenn die Befehlszeichenfolge mit etwas Gefährlichem übereinstimmt, bricht der Hook die Ausführung ab und gibt den Fehler direkt an den Agenten zurück.
Die Muster, die ich blockiere, sind einfach und eindeutig:
git push --forceoder jedeforce-with-lease-Variante, der ich noch nicht vertrauegit reset --hardrm -rf
Das ist keine anspruchsvolle Sicherheitsforschung. Es ist ein Sicherheitsgurt. Aber das entscheidende Detail ist, was nach der Blockierung passiert.
Ich gebe niemals ein schlichtes „Blockiert“ zurück. Eine flache Ablehnung verwirrt den Agenten und kann ihn in einer Schleife gefangen halten, in der er Variationen desselben destruktiven Befehls ausprobiert. Stattdessen enthält die Fehlermeldung einen Fluchtweg. Wenn der Hook einen Hard Reset abfängt, sagt er dem Agenten: „Dieser Befehl ist zum Schutz uncommitted Arbeit blockiert. Erstelle zuerst einen Checkpoint und bewerte die Situation dann neu.“ Dieser zusätzliche Satz ändert das Verhalten des Agenten komplett. Er wechselt von dem Versuch der Schadensbegrenzung hin zur Erstellung von Sicherheit. Der Hook ist nicht nur eine Mauer; er ist Verkehrsleitung.
Ich habe mich bei Shell-Befehlen auch für eine Denylist statt einer Allowlist entschieden. Zuerst hatte ich in Erwägung gezogen, nur einen expliziten Satz sicherer Git-Subbefehle zuzulassen. Das scheiterte schnell. Agenten sind kreativ wörtlich. Sie führen legitime, aber unerwartete Befehle wie git stash push -m "wip" oder git branch --show-current aus, um den Status zu prüfen. Eine Allowlist unterbricht den normalen Workflow in dem Moment, in dem das Modell einen gültigen, aber nicht gelisteten Befehl erfindet. Eine kurze, kuratierte Denylist mit wirklich destruktiven Mustern gibt dem Agenten Spielraum, während die Grenzen geschützt bleiben.
Der Formatter-Hook: Routineaufgaben automatisieren
Früher habe ich Prompt-Token verschwendet, indem ich dem Agenten sagte: „Führe nach dem Bearbeiten einer Datei immer den Formatter aus.“ Er hat es die Hälfte der Zeit vergessen. Die andere Hälfte hielt er inne und fragte, ob er formatieren solle, wodurch ein Tool-Aufruf für eine Entscheidung verbraucht wurde, die nur eine richtige Antwort hatte.
Jetzt erledige ich das mit einem PostToolUse-Hook. Nachdem der Agent eine Datei bearbeitet hat, prüft der Hook die Dateiendung. Wenn es Python ist, führt er Ruff aus. Wenn es JavaScript oder TypeScript ist, führt er Prettier aus. Wenn es Go ist, führt er gofmt aus. Der Agent weiß nicht einmal, dass der Formatter existiert. Er muss es auch nicht wissen.
Das Auslagern aus dem Prompt hatte zwei Auswirkungen. Erstens ist der Code konsistent sauber, ohne die kognitive Last für das Modell zu erhöhen. Zweitens wurden meine Projektanweisungen kürzer. Jedes „immer“ und „niemals“, das man aus einem Prompt entfernt, ist ein Token, das das Modell für die eigentliche Problemlösung verwenden kann. Der Hook übernimmt die Invariante; der Prompt übernimmt die Intention.
Das Quality Gate: „Fertig“ neu definieren
Der Stop-Hook wird ausgeführt, wenn der Agent entscheidet, dass er die Aufgabe abgeschlossen hat, und versucht, die Sitzung zu beenden. Das lasse ich nicht zu. Stattdessen führt der Hook die vollständige Testsuite aus. Wenn ein Test fehlschlägt, blockiert der Hook den Stop-Befehl und gibt die Fehlermeldung an den Agenten zurück.
Dies verändert die Definition von „Abgeschlossen“. „Fertig“ ist nicht länger ein Gefühl, das das Modell hat. Es ist ein messbares Gate. Der Agent kann erst abschließen, wenn das Harness bestätigt, dass der Code funktioniert. In der Praxis erzeugt dies eine enge Feedbackschleife. Der Agent schreibt Code, glaubt, er sei fertig, drückt den Stop-Button und sieht sofort einen pytest-Traceback. Er korrigiert sich dann selbst, behebt den Import-Fehler oder die fehlerhafte Assertion und versucht erneut, zu stoppen. Ich habe beobachtet, wie Agenten innerhalb dieser Schleife drei- oder viermal ohne menschliches Eingreifen iterieren. Das Harness erzwingt Qualität; das Modell liefert die Patches.
Was dies über Agent Engineering lehrt
Der Aufbau zuverlässiger autonomer Systeme erfordert einen Mentalitätswechsel. Man bewegt sich weg vom Schreiben längerer Prompts hin zum Bauen engerer Harnesses.
Nutzen Sie Hooks für die Durchsetzung und Prompts für die Richtlinien. Wenn eine Regel zu einhundert Prozent gelten muss, gehört sie in den Code, nicht in die natürliche Sprache. Prompts glänzen bei Mehrdeutigkeit, Geschmack und Architektur. Bei Invarianten sind sie jedoch miserabel. Wenn ein Fehler Sie einen Nachmittag an Wiederherstellungszeit oder, schlimmer noch, Produktionsverfügbarkeit kosten würde, schreiben Sie einen Hook.
Kürzere Prompts liefern bessere Ergebnisse. Wenn Sie mechanische Regeln in Skripte auslagern, muss sich das Modell weniger merken und weniger widersprechen. Das Kontextfenster des Agenten ist eine knappe Ressource. Füllen Sie es nicht mit Formatierungshinweisen.
Akzeptieren Sie schließlich, dass sich Ihre Rolle verändert. Da Agenten an Autonomie gewinnen, verschiebt sich die Aufgabe des Menschen vom Generieren von Inhalten hin zum Entwerfen von Guardrails. Sie bauen das Harness, das entscheidet, was das Modell anfassen darf, wann es fertig sein kann und wie es sich verhalten muss, wenn etwas schiefgeht. Das ist Engineering, nicht Prompting.
Die Quelle, die diesen Ansatz inspiriert hat, sowie zusätzliche Implementierungsdetails finden Sie hier.
Wenn Sie mit KI-Agenten arbeiten und sich mit anderen Praktikern austauschen möchten, finden Sie die GyaanSetu-Lerncommunity hier.
