Entwurf des Agent-Harnesses: Richtlinien, Sandbox-Technologie, Speicher und Überprüfung
Erfahren Sie, welche Laufzeit-Ebenen eine LLM, die Tools aufruft, in einen zuverlässigen Agenten verwandeln: Ausführungspolitik, OS-Sandboxing, persistenter Zustand, Überprüfung, Kontrollmechanismen für den Kontext sowie Kosten.
Quellen: Agent Harness Engineering: The Missing Layer Between an LLM and a Real AI Agent
Teams, die einen KI-Agenten entwickeln wollen, beginnen in der Regel damit, Modelle miteinander zu vergleichen: Größe des Kontextfensters, Benchmark-Werte, Qualität der Argumentation, Preis pro Token. Sobald ein Modell ausgewählt wurde, werden einige Tools integriert, und das Ergebnis wird als Agent bezeichnet. Tatsächlich handelt es sich zu diesem Zeitpunkt um ein Modell, das Funktionen aufrufen kann; die Lücke zwischen diesem Modell und einem echten Produktionsagenten wird durch eine Laufzeitschicht überbrückt, die heute üblicherweise als Agent-Harness bezeichnet wird. Diese Anleitung erläutert die einzelnen Schichten dieses Harness, vor welchen Gefahren jede davon schützt und wie man ihn schrittweise erweitern kann, ohne in den Abstraktionen des Frameworks unterzugehen.
Ein modellbasiertes Funktionsaufrufsystem ist noch kein Agent
Das typische Ausgangspaket besteht aus einer kurzen Liste der Funktionen, die dem Modell zur Verfügung gestellt werden.
search()
read_file()
write_file()
run_command()
Mit diesen vier Funktionen kann das Modell suchen, lesen, schreiben und Befehle ausführen. Das wirkt wie Autonomie, doch in dieser Konfiguration wird nicht entschieden, was das Modell berühren darf, welche Operationen eine menschliche Genehmigung benötigen, welche Informationen nach einem Absturz oder Neustart erhalten bleiben, wie die Ausgabe überprüft wird oder wie viel vom Ergebnis jedes Tools in die Eingabe zurückgegeben wird. All diese Verantwortlichkeiten liegen beim „Harness“.
Der „Harness“ erweist sich außerdem als messbare Variable. Zum Zeitpunkt der Niederschrift berichtete eine Studie aus dem Jahr 2026, die Coding-Agent-Harnesses verglich, von Unterschieden von bis zu 40-fach in den für jede gelöste Aufgabe verbrauchten Tokens, während die Unterschiede in der Bestehensrate zwischen denselben Harnesses deutlich geringer waren. Die Schlussfolgerung ist nicht, dass ein cleverer Laufzeitumgebung ein schwaches Modell zum Brillanten macht. Vielmehr prägt die Laufzeitumgebung stark, wie effizient, sicher und vorhersehbar ein leistungsstarkes Modell seine Arbeit erledigt.
Die Schleife in der Mitte und die damit verbundenen Fragen
Im Kern ist ein Agent eine Schleife: Man fragt das Modell, was zu tun ist, führt das angeforderte Tool aus, fügt das Ergebnis zum Kontext hinzu und wiederholt diesen Vorgang, bis das Modell angibt, dass es fertig ist.
while True:
response = model(context)
if response.is_final:
break
result = execute_tool(response.tool_call)
context.append(result)
Viele reale Agenten haben im Grunde genommen etwas sehr Ähnliches in ihrer Struktur. Das Modell trifft eine Entscheidung, die Ausführungsumgebung setzt sie um, die Beobachtungen fließen zurück, und das Modell wählt den nächsten Schritt aus. Die Schleife an sich ist einfach; die ingenieurtechnische Herausforderung liegt in allem, was sie umgibt. Ein nutzbares Framework muss bei jedem Schritt eine lange Liste von betrieblichen Fragen beantworten können.
Can the agent execute this command?
Can it access this directory?
Does it need human approval?
What happens if the command fails?
What information should return to the model?
What should survive the session?
Should another agent review the result?
How much context should we send?
How much will this turn cost?
What happens if the model loops forever?
Insgesamt bilden diese Antworten das „Harness“. Ein kürzlich veröffentlichter konzeptioneller Artikel beschreibt es als den Laufzeitumfeld, das ein Sprachmodell über Tools, Kontextverwaltung, Sicherheitskontrollen, Orchestrierung und Erweiterungspunkte mit der Außenwelt verbindet. Ein praktisches Bild teilt den Agenten in zwei Hälften auf.
AI Agent
│
┌────────┴────────┐
│ │
Model Harness
│ │
reasoning ┌──────┼───────┐
planning │ │ │
generation Tools Memory Safety
│ │ │
Sandbox Context Verification
Auf der einen Seite liefert das Modell Reasoning, Planung und Generierung. Auf der anderen Seite stellt das „Harness“ Tools, Speicher und Sicherheitsmechanismen bereit, unterstützt durch einen Sandbox, Kontextverwaltung und Überprüfung. Das Modell trägt zur Intelligenz bei; das „Harness“ bestimmt, wie diese Intelligenz reale Systeme beeinflusst.
Warum ein Prompt kein Sicherheitsmechanismus sein kann
Nehmen wir an, der Systemprompt enthält eine klare Regel:
Löschen Sie niemals eine Produktionsdatei, ohne mich zuerst zu fragen.
An diesem Satz gibt es nichts Zweideutiges, dennoch handelt es sich weiterhin um eine Anfrage. Das Modell könnte ihn falsch interpretieren, im Laufe einer langen Sitzung den Überblick verlieren, ihn mit widersprüchlichen Anweisungen im Kontext abwägen, sich davon überzeugen, dass der aktuelle Fall eine Ausnahme ist, oder durch ein anderes Werkzeug das gleiche zerstörerische Ergebnis erzielen, das von der Regel nicht offensichtlich abgedeckt wird. Einen Agenten darum zu bitten, etwas zu vermeiden, unterscheidet sich grundlegend davon, diese Handlung ohne Autorisierung unmöglich zu machen. Ein Prompt drückt einen Wunsch aus:
Please don't do X.
Ein Harness kann eine in Code ausgewertete Regel darstellen:
if dangerous_action and not approved:
deny()
Die zweite Version funktioniert unabhängig davon, ob das Modell sich an die Anweisung erinnert. Das entspricht dem ersten Prinzip der Harness-Engineerung: Wenn eine Regel deterministisch ist, muss sie in deterministischem Code umgesetzt werden. Claude Code verfolgt bei seiner Gestaltung denselben Ansatz. Hooks laufen bei Lebenszyklusereignissen und Toolaufrufen ab und können beispielsweise einen Toolaufruf vor seiner Ausführung ablehnen, während Dateien wie CLAUDE.md Anleitungen liefern, die das Modell als Kontext liest. Wenn Sie eine solche Datei schreiben, nutzen Sie sie zur Orientierung und verlagern die Durchsetzung in Hooks; unser Playbook für eine effektive CLAUDE.md-Datei erklärt, was dort hineingehört.
Schicht 1: eine Ausführungsgrenze zwischen Anfrage und Aktion
Die erste Frage, die das Harness klären muss, ist, welche Aktionen der Agent überhaupt ausführen darf. Betrachten wir ein Tool, das eine Datei löscht.
def delete_file(path):
os.remove(path)
Das Modell kann es mit jedem beliebigen Argument aufrufen.
delete_file("important.md")
Falls dieser Aufruf sofort ausgeführt wird, hat das Modell uneingeschränkte Befugnisse über alles, was die Funktion erreichen kann. Die Lösung besteht darin, jeden Aufruf über einen Gatekeeper zu leiten, der vor der Ausführung die Richtlinien überprüft.
def execute(call):
if call.name == "delete_file":
if not call.args.get("human_approved"):
return "DENIED: human approval required"
return dispatch(call)
Nun kann das Modell zwar weiterhin eine Löschung anfordern, doch eine Anfrage bedeutet nicht mehr automatisch die Ausführung. Der Ablauf wird zu einer Entscheidung nach Richtlinien mit zwei möglichen Ergebnissen.
Model decision
↓
Policy check
↓
Permission?
↙ ↘
No Yes
↓ ↓
Deny Execute
Das spiegelt ein konventionelles Sicherheitsdesign wider: Das Modell schlägt vor, die Laufzeit kümmert sich um die Umsetzung. Ein Detail, das im echten Code verbessert werden sollte, ist die Herkunft der Genehmigung. Im obigen Entwurf wird das Genehmigungsflag aus den eigenen Argumenten der Aufrufstelle gelesen, die vom Modell erzeugt werden. Ein Produktionsumfeld sollte die Genehmigung extern einholen – durch eine menschliche Bestätigung oder einen signierten Token, den das Modell nicht selbst erstellen kann – andernfalls könnte das Modell das Flag einfach selbst setzen.
Warum Tool-Ebene-Prüfungen versagen
Tool-Policies sind notwendig, aber nicht ausreichend. Stellen Sie sich vor, das Tool lehnt diesen Aufruf ab:
delete_file("secrets/api_key")
Das sieht wie Schutz aus – bis der Agent stattdessen den entsprechenden Shell-Befehl ausführt:
rm secrets/api_key
Die delete_file-Policy sieht diese Operation niemals. Oder das Tool blockiert den Zugriff auf den geheimen Pfad:
read("secrets/api_key")
Aber ein relativer Pfad kommt durch, weil ihn niemand normalisiert hat:
read("../secrets/api_key")
Symbolverknüpfungen, Hilfsprogramme, die im Auftrag des Agents Dateien öffnen, sowie Interpreter, die beliebigen Code akzeptieren, erzeugen alle ähnliche Seitentüren. Eine Richtlinie, die in Begriffen von Tool-Names und Zeichenkettenargumenten ausgedrückt wird, kann nicht alle Wege zu einer Ressource auflisten, weshalb sie keine vollständige Sicherheitsgrenze darstellt. OpenAI’s Anleitung zur Verwaltung von Programmier-Agenten empfiehlt stattdessen die Kombination aus Sandboxing, Genehmigungsrichtlinien, eingeschränkter Ausführung, Netzwerkkontrollen und Telemetrie anstelle des Vertrauens auf Prompts. Das zu befolgende Prinzip lautet: Die Steuerungssoftware durchsetzt die Richtlinien, während das Betriebssystem die endgültige Sicherheitsgrenze bildet.
Schicht 2: Sandboxing dessen, was der Agent physisch erreichen kann
Die Richtlinie fragt, was dem Agenten erlaubt ist; ein Sandbox-Modell fragt zunächst, wohin er überhaupt zugreifen kann. Der schwache Ansatz besteht aus einer Ablehnungsliste, die versucht, jeden sensiblen Ort aufzuzählen.
Don't access:
- /etc
- ~/.ssh
- secrets/
- production/
- credentials/
- ...
Derartige Listen sind niemals vollständig. Der stärkere Ansatz kehrt die Standardpraxis um: Man gewährt fast nichts und fügt anschließend genau das hinzu, was die Aufgabe benötigt – beispielsweise einen einzelnen Projektarbeitsbereich.
Agent workspace:
/workspace
├── src/
├── tests/
├── pyproject.toml
└── README.md
Der Agent erhält auf dem Host nur /workspace und nichts anderes. Ausgedrückt als Richtlinie handelt es sich dabei um eine Erlaubnisliste.
Allowed:
/workspace
Everything else:
unavailable
Weil der Rest des Dateisystems aus Sicht des Agents einfach nicht existiert, verlieren Pfadtricks, Symbole und Hilfeprozesse den größten Teil ihrer Wirkung. Container, dedizierte virtuelle Maschinen und eingeschränkte Benutzerkonten sind gängige Methoden, dies umzusetzen. OpenAI’s Agents SDK bietet genau zu diesem Zweck eine native Sandbox-Exekution, sodass Agenten Abhängigkeiten installieren, Dateien bearbeiten und Befehle in einer kontrollierten Umgebung ausführen können.
Netzwerk- und Ressourcenbeschränkungen gehören in die Sandbox
Die Isolierung des Dateisystems reicht nicht aus. Ein Agent, der Fähigkeiten wie diese besitzt, weist ein völlig anderes Bedrohungsprofil auf:
curl https://example.com
Mit Ausgangsnetzwerkzugang kann der Agent:
- beliebige Software herunterladen und ausführen
- Daten an einen externen Host übertragen
- Drittanbieter-APIs aufrufen
Eine echte Sandbox umfasst daher mehrere Aspekte, nicht nur Dateien.
Filesystem
Network
Processes
Environment variables
Secrets
CPU
Memory
Time
Prozesse erben Umgebungsvariablen und Geheimnisse stillschweigend, und CPU-, Speicher- sowie Zeitlimits verhindern unkontrollierte Ausführungen. Genau diese Vielfalt führt dazu, dass moderne Laufzeiten die Sandbox als vollständige Ausführungsumgebung gestalten und nicht nur als dünne Schalenverpackung.
Schicht 3: persistenter Zustand, der die Sitzung überdauert
Bei langen Aufgaben tritt ein anderes Problem auf. Ein Agent verbringt eine Stunde damit, einen Repository zu durchforsten, und lernt dabei eine wichtige architektonische Regel.
The authentication service must never directly access the database.
All database operations go through Repository classes.
Dann füllt sich das Kontextfenster, die Sitzung wird neu gestartet, und dieses Wissen geht verloren. Die nächste Sitzung hat keine Ahnung, warum das Design so aussieht, und könnte es gerne missachten. Die Gesprächsverlauf ist nicht der richtige Ort für diese Art von Informationen. Ein nützliches System trennt mindestens drei Kategorien mit unterschiedlichen Lebenszyklen voneinander.
Conversation state
↓
temporary
Project state
↓
persistent
Harness configuration
↓
persistent + globally enforced
Ein konkretes Beispiel für jede Kategorie:
Conversation:
"Let's investigate the login bug."
Project:
"Authentication uses OAuth."
Harness:
"Never modify generated migrations."
Der Gesprächspunkt kann sicher verschwinden, wenn die Aufgabe beendet ist. Die Projektinformationen sollten über Sessions hinweg erhalten bleiben, zum Beispiel in einer versionierten Notizdatei oder einem Speicher für Informationen im Arbeitsspeicher. Die Regel sollte bei jedem Ausführungsvorgang angewendet werden, unabhängig davon, was das Modell derzeit in Erinnerung hat – was normalerweise bedeutet, dass sie im Konfigurations- und Durchsetzungscode statt im Text gespeichert werden. Je länger die Sessions dauern, desto wichtiger wird diese Trennung. OpenAI’s Agents API beinhaltet beispielsweise Funktionen zur Kontextverwaltung für langlaufende Agenten, darunter eine automatische Komprimierung, wenn eine Session ihrem Kontextlimit nahekommt. Genau in diesem Moment gehen ungespeicherte Projektinformationen verloren, weshalb es sinnvoll ist, sie vorher absichtlich zu speichern. Für eine ausführlichere Behandlung der Speicherebenen siehe die vierstufige Agentenspeicherung mit.
LangGraph und Bedrock.Schicht 4: Überprüfung, ob der Agent nicht Eigentümer ist
Agenten können mit voller Überzeugung falsch liegen, daher sollte der Agent, der eine Änderung vorgenommen hat, nicht das letzte Wort darüber haben, ob diese korrekt ist. Nehmen wir diesen Ausgabebeispiel:
def calculate_total(items):
return sum(item.price for item in items) + 1
Der zusätzliche + 1 mag für das Modell, das ihn geschrieben hat, absichtlich erscheinen. Ein unabhängiger Überprüfungsschritt kann die Änderung anhand mehrerer Signale bewerten.
Code
Tests
Type checking
Linting
Security rules
Expected behavior
Was dies wertvoll macht, ist die Trennung zwischen Erstellung und Beurteilung.
Agent
│
↓
Changes
│
↓
Verification
↙ ↘
PASS FAIL
↓ ↓
Continue Investigate
Ein Erfolg ermöglicht es dem Loop, fortzufahren; ein Misserfolg schickt den Agenten zurück, um weiter zu untersuchen. Eine Verbesserung, die leicht übersehen wird: Der Prüfer sollte Probleme melden anstatt sie heimlich zu beheben. Wenn der Überprüfer den Fehler stillschweigend repariert, geht das Signal verloren, dass der ursprüngliche Agent versagt hat, und Ihre Erfolgsmetriken werden ungenau.
Simulationsläufe als Standard für risikoreiche Änderungen
Für besonders wichtige Operationen sollte das Vorschauen des Standardverhaltens der Standard sein. Anstelle einer sofort wirksamen Anwendefunktion:
apply_change()
sollte eine Funktion bereitgestellt werden, deren sicheres Standardverhalten ein Simulationslauf ist:
apply_change(dry_run=True)
Der Agent erhält zunächst eine Beschreibung der Auswirkungen.
Would modify:
src/auth.py
tests/test_auth.py
Nur ein expliziter, separater Schritt – idealerweise einer, der eine Genehmigung erfordert – führt vom Vorschauen zur Ausführung. Dadurch haben sowohl der Überprüfer als auch jeder menschliche Prüfer etwas Konkretes, das sie vor einer Änderung untersuchen können.
Schicht 5: Kontextengineering
Jeder in den Kontext eingefügte Token kostet Geld, konkurriert um die Aufmerksamkeit des Modells und neigt bei langen Aufgaben dazu, schneller anzuziehen, als er wieder entfernt wird. Angenommen, das Agent benötigt eine Funktion aus einer Datei mit 5.000 Zeilen. Ein naiver Ansatz sendet die gesamte Datei, anschließend die vollständige Ausgabe der nächsten Suche, dann das Ergebnis des nächsten Tools und so weiter. Bald enthält der Kontext all dies:
Task
+ entire repository
+ previous searches
+ tool output
+ logs
+ previous reasoning
+ repeated instructions
Technisch gesehen kann das Modell jeden Token sehen, doch Sichtbarkeit bedeutet nicht Verständnis. Ein besseres Design betrachtet den Kontext als eine Pipeline, die Informationen vor ihrem Erreichen des Hauptagents komprimiert.
Main Agent
│
├── Search Agent
│ │
│ └── 50,000 tokens
│
│ ↓
│
└── 1,000-token summary
Hier kann ein Suchagent bei der Erkundung bis zu 50.000 Token verbrauchen, doch die Hauptsession erhält lediglich eine Zusammenfassung mit 1.000 Token über die wichtigsten Erkenntnisse. Dies ist ein starker Argument für Subagenten. Claude Code beschreibt beispielsweise Subagenten als solche, die in eigenen, isolierten Kontextfenstern arbeiten und nur ihr endgültiges Ergebnis in das Hauptgespräch zurückgeben, wodurch umfangreiche Nebenuntersuchungen den primären Kontext nicht überlasten. Der Trade-off besteht darin, dass eine Zusammenfassung Details enthalten kann, die der Hauptagent später benötigt; daher sollten Zusammenfassungen auf Zeiger (Dateipfade, Zeilenbereiche) verweisen, die es dem Agenten ermöglichen, bei Bedarf konkrete Informationen abzurufen.
Die Wirtschaftlichkeit: Der Preis pro Token ist nicht die Kosten pro Aufgabe
Die Kontextverwaltung ist ebenfalls eine Frage des Budgets. Erinnern Sie sich an die Studie, in der bis zu einem 40-fachen Unterschied in den Tokens pro gelöster Aufgabe zwischen den verschiedenen Frameworks festgestellt wurde, wobei die Unterschiede in der Bestehensrate deutlich geringer waren. Das verändert die Frage, die es zu stellen lohnt. Anstatt „Welches Modell ist am günstigsten?“ zu fragen, sollte man sich erkundigen, wie viele Tokens das gesamte Agentensystem benötigt, um eine Aufgabe zu erledigen. Vergleichen Sie dabei zwei Konfigurationen.
Agent A: günstigeres Modell, ressourcenintensives Framework
Model:
$X / million tokens
Task:
500k tokens
Agent B: teureres Modell, effizienteres Framework
Model:
2X / million tokens
Task:
100k tokens
Agent B zahlt doppelt so viel pro Token, verwendet aber nur ein Fünftel der Tokens, sodass jede abgeschlossene Aufgabe etwa 40 Prozent dessen kostet, was Agent A ausgibt – noch bevor man die Unterschiede in der Erfolgsrate berücksichtigt. Die Preiskalkulation des Modells ist eine Eingabe; die Wirtschaftlichkeit der Agenten wird durch die Menge an Arbeit bestimmt, die das Framework dem Modell abverlangt. Unser Kostenmodell für agentebasierte KI, das auf der Architektur basiert untersucht dieses Thema ausführlicher.
Sinnlose Schritte und Beendigungsrichtlinien
Ein Teil des Verschwendens ist in den Metriken pro Anfrage nicht sichtbar. Stellen Sie sich einen Agenten vor, der nur seine Absichten bekannt gibt, ohne tatsächlich zu handeln:
I should inspect the repository.
und wieder im nächsten Schritt:
I should inspect the repository.
und nochmals:
I should inspect the repository.
Es ändert sich nichts, doch jeder Turn verbraucht Token, Latenzzeit, Rechenleistung, Kontextspeicher und möglicherweise Geld. Die gleiche Studie zur Harness-Struktur beschreibt diese Überhead-Kosten als eine Wartegebühr pro Aufgabe und nicht nur als Token-Gebühr: Die Benutzer warten auf Turns, die nichts bewirken. Der Harness benötigt Beendigungsregeln, wobei die einfachste Lösung eine Obergrenze für die Anzahl der Turns ist.
MAX_TURNS = 30
if agent.turns >= MAX_TURNS:
stop()
Eine Obergrenze dient lediglich als Sicherheitsnetz, nicht als Strategie. Nützlichere Harnesses erkennen die Signale, die auf einen blockierten Ablauf hindeuten.
No progress
Repeated tool calls
Repeated identical observations
No state change
Test suite unchanged
Agent oscillation
Budget exhausted
Mehrfache, identische Aufrufe von Tools, unveränderte Beobachtungen, keine Änderungen im Dateisystem, ein Testsuite, die weiterhin auf dieselbe Weise fehlschlägt, Schwankungen zwischen zwei Zuständen oder ein aufgebrauchter Budget – all das deutet darauf hin, dass eine Fortsetzung wahrscheinlich nicht hilft. In solchen Fällen sollte das System aufhören, zusammenfassen und die Situation weiterleiten. Unser Leitfaden zu begrenzten agierenden Schleifen in TypeScript zeigt diese Muster im Code.
Von Tool-Wrapper zu Plattform
Das Design von Coding-Harnesses entwickelt sich zunehmend zu einer eigenständigen Disziplin. Eine kürzliche Studie am Quellcode von elf produktiven Coding-Agent-Systemen fand wiederkehrende architektonische Muster in ihnen: Tool-Ausführung, Kontextverwaltung, Sicherheitskontrollen sowie Orchestrierungs- und Erweiterungsmöglichkeiten. Die Autoren kommen zu dem Schluss, dass Coding-Harnesses von einfachen Tools zu vollwertigen Plattformen geworden sind. Frühe Agenten sahen so aus:
LLM + tools
Die aktuellen Systeme ähneln einem Stack.
LLM
↓
Agent loop
↓
Tool router
↓
Policy engine
↓
Sandbox
↓
Context manager
↓
Memory
↓
Verification
↓
Observability
↓
Orchestration
Das Modell bleibt weiterhin das Kernstück, doch die um es herum liegende Laufzeitumgebung – vom Tool-Router und Policy-Engine über den Sandbox, den Kontextmanager, das Speichermanagement, die Überprüfungsfunktionen, die Observabilität bis hin zur Orchestrierung – hat sich zu einem eigenständigen Produkt entwickelt.
Ein Referenzlayout für einen Coding-Agent
Eine sinnvolle Ausgangsarchitektur für einen Programmieragenten platziert den Agentenzyklus direkt unter dem Modell und gliedert ihn in drei Bereiche auf: einen Tool-Router, einen Kontextmanager sowie das Speichersystem. Toolaufrufe gelangen über einen Policy-Engine in den Sandbox, die Ergebnisse durchlaufen eine Überprüfung, und alles wird durch Mechanismen zur Beobachtbarkeit aufgezeichnet.
┌──────────────┐
│ Model │
└──────┬───────┘
│
↓
┌─────────────────┐
│ Agent Loop │
└────────┬────────┘
│
┌─────────────┼─────────────┐
↓ ↓ ↓
Tool Router Context Memory
│ Manager │
↓ │ ↓
Policy Engine │ Persistent State
│ │
↓ ↓
Sandbox ←────── Tools
│
↓
Verification
│
↓
Observability
Sicherstellen Sie, dass jede Komponente unabhängig getestet werden kann: Führen Sie Unit-Tests für die Policy-Engine mit künstlichen Aufrufen durch, prüfen Sie die Handhabung von Pfaden auf Fehleranfälligkeit und bewerten Sie den Überprüfer anhand bekannter fehlerhafter Patches – alles ohne Aufruf eines Modells.
Entwickeln Sie das Framework aus Fehlern, nicht aus einem vorgefertigten Rahmen
Um diese Vorteile zu erlangen, benötigen Sie kein umfangreiches Agentenframework. Der zentrale Zyklus kann auch nach Hinzufügen von Policy-Engine, Sandboxing und Überprüfung weiterhin klein bleiben.
while turns < MAX_TURNS:
action = model.next_action(context)
if action.is_final:
return action.answer
if not policy.allows(action):
context.append("Action denied")
continue
result = sandbox.execute(action)
verification = verifier.check(result)
context.append(
summarize(result, verification)
)
Achten Sie auf die Reihenfolge: Die Richtlinienprüfung erfolgt vor der Ausführung, eine abgelehnte Aktion wird an das Modell zurückgemeldet, anstatt den Loop zum Absturz zu bringen. Die Ausführung geht stets durch den Sandbox, und was wieder in den Kontext gelangt, ist eine Zusammenfassung des Ergebnisses sowie seiner Überprüfung – nicht die Rohausgabe. Erst aufgrund eines festgestellten Fehlers sollte dort Komplexität hinzugefügt werden.
Agent deleted something?
→ add execution policy
Agent accessed the wrong file?
→ strengthen sandbox
Agent forgets architecture?
→ add persistent project memory
Agent produces bad code?
→ add verification
Agent becomes expensive?
→ optimize context
Agent loops?
→ add termination detection
Jedes Symptom entspricht genau einer Schicht. Das ist weitaus besser, als bereits fünfzig Abstraktionen einzuführen, bevor man weiß, welches Problem vorliegt. Für eine ausführlichere Diskussion darüber, ob man diesen Loop selbst bauen oder eines verwenden sollte, siehe runtime harnesses vs composed frameworks.
Das Repository als Wissensbasis des Agents
In der agentgetriebenen Entwicklung ist ein Repository mehr als nur Quellcode. Es kann alles enthalten, was ein Agent zum Arbeiten am Projekt benötigt: Architekturentscheidungen, Entwicklungs- und Testbefehle, Domänenvokabular, Schemata, Pläne, Betriebsanleitungen sowie agent-spezifische Anweisungen – alles wird zusammen mit dem von ihnen beschriebenen Code versioniert. OpenAI betont in seinen Schriften zur Engineering-Methodik, dass lokal im Repository gespeicherte, versionierte Artefakte als offizielles Dokumentensystem dienen, aus dem ein Agent wissen muss, um ein Projekt zu verstehen und zu ändern, und empfiehlt stattdessen eine Karte, die auf spezifische Dokumente verweist, anstatt auf ein riesiges Anweisungsfile. Die Folgerung ist klar: Eine Designentscheidung, die nur im Kopf einer Person oder in einem Chatverlauf existiert, existiert für den Agenten nicht. Das Machbar machen von Wissen zugänglich ist zu einem Bestandteil der Softwarearchitektur geworden.
Hooks: Verhalten, das das Modell sich nicht merken muss
Hooks gehören zu den nützlichsten Primitiven von Harnesses. Ein Hook ermöglicht es der Laufzeit, auf ein Lebenszyklusereignis mit deterministischem Code zu reagieren. Der offensichtlichste dient dazu, Aufrufe von Tools zu steuern.
Before tool call
↓
Check policy
↓
Allow / deny
Ein weiterer sorgt dafür, dass die Codequalität nach jeder Änderung konstant bleibt.
After file edit
↓
Run formatter
↓
Run type checker
Ein dritter schützt das Wissen, bevor der Kontext komprimiert wird.
Before context compaction
↓
Persist important state
Ein vierter erstellt eine Auditrückverfolgung.
After task completion
↓
Generate audit record
Claude Code dokumentiert Hooks als durch Lebenszyklusereignisse ausgelöste Befehle, die deterministisch ausgeführt werden und unter anderem einen Toolaufruf vor seiner Ausführung blockieren können. Ihre Stärke liegt darin, das Verhalten vollständig aus der Logik des Modells herauszulösen. Anstatt in einer Anweisung „Bitte den Formatierer ausführen“ zu schreiben und darauf zu hoffen, führt die Laufzeit einfach jedes Mal den Formatierer aus.
Lassen Sie niemals das Modell die Grenzen bestimmen
Modelle sind probabilistisch; Sicherheitsgrenzen jedoch nicht. Dieses Anti-Muster delegiert die Entscheidung an das Modell:
if model_says_safe:
execute()
Dieses Muster delegiert die Entscheidung an Infrastruktur, von der man keine andere Antwort erhalten kann:
if operating_system_allows:
execute()
Verwenden Sie das Modell für Entscheidungen, bei denen Urteilsvermögen von Vorteil ist, und deterministische Infrastruktur für Entscheidungen, bei denen Garantien erforderlich sind. In der Praxis beantwortet jede Schicht ihre eigene Frage.
Model:
Should I modify this file?
Harness:
Is this file inside the workspace?
OS:
Can this process write to the file?
Human:
Should this high-risk action proceed?
Das Modell entscheidet, ob eine Änderung eine gute Idee ist, das Harness überprüft, ob das Ziel sich im Arbeitsbereich befindet, das Betriebssystem entscheidet, ob der Prozess die Datei schreiben darf, und ein Mensch entscheidet, ob eine hochriskante Aktion durchgeführt werden soll. Solche schichtweisen Entscheidungen sind weitaus robuster als die Erwartung, dass ein einzelner Komponente alles richtig macht.
Harnesses verstärken Modelle; sie ersetzen sie nicht
Es ist verlockend, zu dem Schluss zu kommen, dass Leitungen wichtiger sind als Modelle. Die Beweise stützen das jedoch nicht. In der untersuchten Konfiguration hatte die Wahl der Leitungen einen großen Einfluss auf die Effizienz der Token, aber nur einen viel geringeren Einfluss auf den Erfolg der Aufgabe – und keine Menge an Optimierungen kann ein schwaches Modell in einen starken Softwareingenieur verwandeln. Eine klare Art, die beiden voneinander zu trennen:
Model capability
=
What the agent can reason about
Harness quality
=
How effectively that capability is deployed
Ein brillantes Modell in einer schlechten Laufzeitumgebung verschwendet enorme Mengen an Ressourcen und Geld. Eine sorgfältig entwickelte Laufzeitumgebung um ein schwaches Modell herum liefert weiterhin schwache Entscheidungen – nur sicherer und effizienter. Beides ist notwendig.
Fünf Fragen, die man stellen sollte, bevor man einen Agenten einsetzt
1. Was kann er tun?
Erstellen Sie eine Liste aller Tools und kennzeichnen Sie jede gefährliche Operation.
read
write
delete
execute
network
deploy
send_message
2. Was kann er erreichen?
Die Definitionen der Tools erzählen nur einen Teil der Geschichte. Überprüfen Sie, auf was der Prozess tatsächlich zugreifen kann:
filesystem
network
environment
secrets
processes
credentials
3. Was bleibt nach einem Neustart übrig?
Starten Sie den Agenten erneut und finden Sie es heraus:
What does it remember?
What does it forget?
Where is important state stored?
4. Wer überprüft das Ergebnis?
Für folgenreiche Operationen reicht ein zweistufiger Workflow nicht aus:
generate → approve
Fügen Sie unabhängige Überprüfungen zwischen Erstellung und Freigabe ein:
generate
↓
test
↓
review
↓
approve
5. Was kostet jede Aufgabe tatsächlich?
Token-Zahlen pro Anfrage sind für sich genommen irreführend:
tokens per request
Messen Sie stattdessen die Ergebnisse:
tokens per successful task
latency per successful task
tool calls per task
retries per task
human interventions
Token, Latenzzeit, Toolaufrufe, Wiederholungsversuche sowie menschliche Eingriffe pro erfolgreicher Aufgabe sind die Kennzahlen, die zeigen, ob das System den Betrieb lohnt.
Eine funktionierende Definition eines Produktionsagenten
Durch die Kombination der Schichten ergibt sich eine ehrlichere Definition.
Agent =
Model
+ Tools
+ Execution Environment
+ Policy
+ Memory
+ Context Management
+ Verification
+ Observability
Jeder Bestandteil hat seine Berechtigung. Ohne Modell gibt es keine Intelligenz; ohne Werkzeuge gibt es keine Handlung; ohne Ausführungsumgebung und Richtlinien kann der Agent gefährlich werden; ohne Speicher werden lange Aufgaben anfällig; ohne Kontextverwaltung steigen die Kosten exponentiell an; ohne Überprüfung breiten sich Fehler unbemerkt aus; und ohne Beobachtbarkeit lässt sich nicht rekonstruieren, was passiert ist, wenn etwas schiefgeht.
Zusammenfassung
Die Diskussion in der Branche wandelt sich von der Frage, welches Modell eine Benchmark am besten meistert, hin zur Frage, welche Laufzeitumgebung es einem Modell ermöglicht, zuverlässig nützliche Arbeit zu leisten. Die Anbieter konzentrieren sich auf dieselben Grundbausteine: OpenAI verkauft nun verwaltete Agent-Infrastrukturen, die Sandboxes, Kontextverarbeitung, Tool-Suche, Tool-Aufrufe aus Code sowie langanhaltende Ausführungen beinhalten, während Anthropic persistente Anweisungen, Fähigkeiten, Subagenten und deterministische Verknüpfungen bereitstellt. Die Forschung beginnt, den Agent als experimentelle Variable zu bewerten, anstatt das Modell als Ganzessystem zu betrachten. Diese Funktionen entwickeln sich schnell, daher sollten Sie die aktuelle Dokumentation prüfen.
Das naive Rezept für einen Agent ist kurz:
Pick LLM
+
Add tools
=
Agent
Das realistische sieht so aus:
Model
↓
Agent Runtime
↓
┌─────────┼─────────┐
↓ ↓ ↓
Policy Context Memory
↓ ↓ ↓
Sandbox Tools Persistence
└─────────┼─────────┘
↓
Verification
↓
Observability
Das Modell trifft Entscheidungen; die Umgebung definiert die Bedingungen, unter denen diese Entscheidungen zu Aktionen werden. Bevor man ein Framework wählt, sollte man prüfen, was passiert, wenn das Modell falsch liegt, und die Umgebung entsprechend dieser Erkenntnis aufbauen.
- Festlegen Sie deterministische Regeln im Code und in den Hooks, nicht in Anfragen.
- Betrachten Sie die Richtlinien der Tools als erste Schutzschicht und den OS-Sandbox, einschließlich Netzwerk- und Ressourcenbeschränkungen, als die eigentliche Grenze.
- Trennen Sie den Zustand der Konversation, des Projekts und der Umgebung nach ihrer Lebensdauer voneinander und speichern Sie Projektdaten vor der Komprimierung ab.
- Lassen Sie die Überprüfung unabhängig erfolgen und bitten Sie die Prüfer, Berichte zu erstellen anstatt direkt Fehler zu beheben.
- Optimieren Sie die Anzahl der Tokens pro erfolgreich abgeschlossenem Task und beenden Sie Laufvorgänge, die keinen Fortschritt mehr erzielen.
Ziel ist kein Agent, der niemals Fehler macht, sondern ein System, in dem ein Modellfehler nicht automatisch zu einem Produktionsproblem wird.