Agents, die sich selbst Arbeit suchen
"The agent finds work itself." Keine menschliche Zuweisung nötig — es nimmt sich Aufgaben vom Board.
Von "aufgeweckt werden" zu "selbst Arbeit finden"
Die Teammates aus s09/s10 sind passiv: jemand sendet eine Nachricht, dann fangen sie an; nach der Aufgabe idle, beim nächsten Aufruf wieder aktiv.
Der autonome Teammate aus s11 ist aktiv: auch wenn keine Arbeit anliegt, scannt er alle 5 Sekunden das .tasks/-Verzeichnis — sieht er einen unübernommenen Task, führt er claim_task aus und beginnt.
Teammate lifecycle:
+-------+
| spawn |
+---+---+
|
v
+-------+
| WORK | <-- LLM tool_use Schleife
+---+---+
|
| stop_reason != tool_use ODER tool_use("idle")
v
+-------+
| IDLE | alle 5s pollen, 12 Versuche = 60s Timeout
+---+---+
|
+--> Postfach hat neue Nachricht? → zurück zu WORK
|
+--> .tasks/ scan, unübernommener Task → claim → zurück zu WORK
|
+--> 60s ohne Ergebnis → status = shutdown, Thread beendet
Auto-claim · Aufgaben vom Board nehmen
Die Kernfunktion:
def scan_unclaimed_tasks() -> list: unclaimed = [] for f in sorted(TASKS_DIR.glob("task_*.json")): task = json.loads(f.read_text()) if (task.get("status") == "pending" and not task.get("owner") and not task.get("blockedBy")): unclaimed.append(task) return unclaimed
Drei Filter = pending + kein Owner + kein blockedBy. Alle drei sind notwendig.
Der claim-Vorgang ist gesperrt (_claim_lock), um Race Conditions zu verhindern — zwei Agents sehen denselben unübernommenen Task gleichzeitig. Im Lock: nochmal lesen, prüfen ob Owner noch leer, dann als in_progress markieren und owner auf Disk schreiben.
Mehrere Agents scannen gleichzeitig das Task-Board
3 Teammates im idle-Zustand, 3 Tasks warten. Nächste Runde klicken und sehen, wer den ersten unübernommenen Task bekommt.
Identity-Reinjektion · Nach Komprimierung weiß der Agent noch, wer er ist
auto_compact kann messages[] durch ein Summary ersetzen. Ein autonomer Agent, der stundenlang läuft, wird das wahrscheinlich auslösen — nach der Komprimierung weiß das Modell nicht mehr, wie es heißt oder welche Rolle es hat.
s11-Lösung: Beim Claim eines neuen Tasks wird geprüft, ob len(messages) ≤ 3 (Hinweis auf gerade komprimiert) — dann wird automatisch ein identity-Block an den Anfang gestellt:
if len(messages) <= 3: messages.insert(0, { "role": "user", "content": f"<identity>You are 'alice', role: coder, team: my-team. Continue your work.</identity>", }) messages.insert(1, {"role":"assistant", "content": f"I am alice. Continuing."})
Dieses Muster heißt identity reinjection — eine künstlich konstruierte Konversationsrunde, die dem Modell mitteilt, wer es ist, damit es seine Rolle wiederfinden kann.