Zurück zum Blog

Agenten-Status ist kein Ergebnis: Artefakte prüfen statt Statusfelder glauben

Ein Auftrag steht auf completed, der Fehlertext ist leer, geliefert wurde nichts. Warum Statusfelder über die Arbeit eines Agenten nichts aussagen, an welchen drei Stellen der Erfolgspfad den Fehlerpfad verschluckt und wie ein Torwächter am Artefakt das löst.

4 Min. Lesezeitvon Daniel AlischAI, Agenten, Development

Ein delegierter Auftrag steht auf completed, der Fehlertext ist leer, und der Zweig, den er erzeugen sollte, existiert nicht. Diese Kombination habe ich beim Betrieb eigener Agentensysteme oft genug gesehen, um sie nicht mehr für einen Zufall zu halten. Sie ist die Normalform eines Fehlers, den man nur findet, wenn man aufhört, dem Statusfeld zu glauben.

Der Status beschreibt den Lauf, nicht das Ergebnis

Ein Orchestrator, der Aufgaben an Agenten verteilt, führt über zwei völlig verschiedene Dinge Buch: ob ein Prozess normal zu Ende gelaufen ist, und ob dabei etwas Brauchbares entstanden ist. Das Erste ist leicht zu messen, das Zweite nicht. Also messen die meisten Systeme das Erste und nennen es Erfolg.

Das ist kein Schlampigkeitsfehler, sondern eine Design-Entscheidung, die sich im Normalbetrieb nie rächt. Ein Agent, der seine Arbeit macht, läuft normal zu Ende — Status und Ergebnis stimmen überein, über lange Zeit. Erst wenn der Agent abbricht, nachdem er seinen Abschlussbericht geschrieben hat, laufen die beiden Größen auseinander. Und das ist genau der Fall, der sich im Dashboard nicht von Erfolg unterscheiden lässt.

Die praktische Folge: Wer die Gesundheit einer Agentenflotte an der Statusspalte misst, misst die Zuverlässigkeit seines Prozess-Managements. Über die gelieferte Arbeit sagt diese Zahl nichts.

Wo der Erfolgspfad den Fehlerpfad schluckt

Die Ursachen, die ich in eigenem Code und eigenen Logs tatsächlich nachweisen konnte, fallen in drei Gruppen.

Rückfallwerte ohne Herkunft. Wenn eine Bewertungs- oder Klassifikationsfunktion fehlschlägt und still auf einen Standardwert zurückfällt, ist dieser Standardwert sehr oft der harmlose Fall. Ein Lauf, dessen Selbstbewertung nicht zustande kam, erscheint dann als erledigt — nicht weil jemand das behauptet hätte, sondern weil „erledigt“ der Default war. Der Fix ist nicht, den Default zu ändern, sondern die Herkunft des Werts mitzuführen: gemessen oder geraten.

Ausnahmen mit leerer Textform. Mehrere Ausnahmeklassen in Python haben eine leere Stringdarstellung. Ein Logeintrag, der nur {exc} formatiert, produziert dann eine Zeile, die den Fehler bestätigt und seinen Grund verschweigt. Wer nach diesen Zeilen greppt, findet sie und kann sie nicht klassifizieren. Protokolliere den Typ, nicht nur den Text.

Abbrüche nach dem Bericht. Kontingentgrenzen externer Modellanbieter, Container-Neustarts, Speicherlimits. Hier ist der Status sogar formal korrekt: der Prozess ist beendet. Der Grund steht, wenn es gut läuft, als letzter Satz im Ergebnisfeld — nicht im Statusfeld, nicht im Fehlerfeld. Diese Fälle findet man nur, indem man den Inhalt des Ergebnisses klassifiziert.

Das Vorgehen: ein Torwächter am Artefakt, nicht am Status

Was bei mir funktioniert, ist unspektakulär: Jeder delegierte Auftrag bekommt ein Artefakt, dessen Existenz prüfbar ist — ein Zweig, eine Datei an einem festgelegten Pfad, ein Eintrag mit einem bestimmten Schlüssel. Nach dem Lauf fragt nicht der Orchestrator den Agenten, sondern eine kleine Funktion das Artefakt.

python
def hat_geliefert(auftrag):
    """True nur, wenn das versprochene Artefakt wirklich existiert."""
    if not zweig_existiert(auftrag.zielzweig):
        return False
    if anzahl_geaenderter_dateien(auftrag.zielzweig) == 0:
        return False
    return all(pfad_existiert(p) for p in auftrag.pflichtdateien)

Der Gewinn liegt weniger in der Prüfung selbst als in der Reihenfolge. Wenn das Artefakt da ist, braucht niemand den Statustext zu interpretieren — auch dann nicht, wenn der Lauf mitten im Abschlussbericht gestorben ist. Mir ist genau das passiert: Ein Teilschritt hatte seine Datei fertig geschrieben, der Bericht kam nie an, und die naheliegende Reaktion wäre gewesen, die Arbeit neu zu vergeben. Erst das Artefakt zu prüfen hat einen kompletten zweiten Durchlauf erspart.

Zwei Details, die nicht offensichtlich sind. Erstens: Prüfe mit Gleichheit, nicht mit Teilstrings. Eine Suche nach einer Fehlersignatur findet zuverlässig die eigenen Berichte über diese Signatur mit, und dann zählt man seine eigenen Notizen als Vorfälle. Zweitens: Prüfe, seit wann die Marke existiert, nach der du suchst. Wenn eine Logzeile erst vor zwei Wochen in den Code gekommen ist, misst eine Rückschau über drei Monate das Alter des Log-Statements, nicht die Häufigkeit des Ereignisses.

Was ich nicht mehr tue

Ich zähle keine Status mehr, um eine Aussage über Liefertreue zu treffen. Ich vergebe keine Arbeit neu, bevor ich das Artefakt des ersten Versuchs gesucht habe. Und ich drehe keine Alarmschwelle, bevor ich geprüft habe, ob sich die beiden Klassen überhaupt trennen lassen — wenn sich die Randwerte von „gesund“ und „ausgefallen“ nicht überschneiden, braucht man keine Heuristik, sondern eine exakte Regel. Das ist der angenehmste Befund dieser ganzen Fehlerklasse: Oft ist das Problem nicht unscharf, sondern nur falsch gemessen.

Fazit

Ein Statusfeld ist eine Aussage über einen Prozess, kein Beleg für eine Lieferung. Wer Agenten produktiv betreibt, braucht pro Auftrag ein prüfbares Artefakt und eine Funktion, die es anschaut — und sollte in Rückfallwerten, leeren Fehlertexten und Abbrüchen nach dem Abschlussbericht die drei Stellen vermuten, an denen der Erfolgspfad den Fehlerpfad verschluckt. Es ist wenig Code. Der Unterschied ist, dass man danach weiß, was passiert ist, statt es zu hoffen.

Weiterlesen