Leçon 11 · Collaboration

L'agent qui trouve lui-même du travail

« L'agent trouve lui-même du travail. » Pas besoin d'affectation humaine — il prend des tickets depuis le tableau de bord.

⏱ ~12 min · 📝 3 widgets interactifs · 🧑‍💻 Basé sur shareAI-lab · s11_autonomous_agents.py

De « réveillé par un autre » à « qui se cherche du travail »

Les teammates de s09 / s10 sont passifs : quelqu'un doit leur envoyer un message pour qu'ils démarrent ; une fois la tâche finie, ils retournent en idle, attendant d'être rappelés.

Le teammate autonome de s11 est actif : même sans activité, il ne s'arrête pas vraiment — il scanne .tasks/ toutes les 5 secondes. S'il voit une tâche sans propriétaire, il appelle claim_task et commence à travailler.

Lifecycle d'un teammate :
  +-------+
  | spawn |
  +---+---+
      |
      v
  +-------+
  | WORK  | <-- boucle LLM tool_use
  +---+---+
      |
      | stop_reason != tool_use OU tool_use("idle")
      v
  +-------+
  | IDLE  | poll toutes les 5s, 12 fois max = 60s timeout
  +---+---+
      |
      +--> inbox avec nouveaux messages ? → reprendre WORK
      |
      +--> scan .tasks/, trouve une tâche non réclamée → claim → reprendre WORK
      |
      +--> 60s sans rien → status = shutdown, thread se termine

Auto-claim · « prendre un ticket » sur le tableau

La fonction centrale :

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

Trois filtres = pending + sans owner + sans blockedBy. Les trois sont nécessaires.

Le claim lui-même est protégé par un verrou (_claim_lock) pour éviter que deux agents voient simultanément la même tâche libre et tentent de la prendre — sous le verrou, on relit l'état, on vérifie que owner est encore vide, puis on écrit « in_progress » + owner sur disque.

Simulation de plusieurs agents scannant simultanément le tableau

3 teammates en idle, 3 tâches en attente. Cliquez sur « Prochain scan » pour voir qui s'empare de quelle tâche en premier.

Réinjection d'identity · après compression, l'agent se souvient-il de lui ?

s06 nous a montré qu'auto_compact remplace messages[] par un résumé. Un agent autonome qui tourne plusieurs heures peut facilement déclencher ce mécanisme — après compression, le modèle ne sait plus comment il s'appelle ni quel rôle il joue.

La technique de s11 : quand une nouvelle tâche est réclamée et que len(messages) ≤ 3 (signe qu'une compression vient d'avoir lieu), un bloc d'identity est automatiquement inséré au début :

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."})

Ce pattern s'appelle identity reinjection — on construit artificiellement un tour de dialogue pour « dire au modèle qui il est » et lui redonner le sens de son rôle.

Interactif

Widget 1 · Task Scanner · 3 agents se disputent 3 tâches

alice, bob et charlie sont tous en idle. Cliquez sur le scan, voyez qui claim en premier la première tâche disponible (ordre alphabétique).

Répertoire .tasks/
Statut des teammates
Tout le monde en idle, en attente du scan
Interactif

Widget 2 · Identity Drift · l'agent se souvient-il de lui après compression ?

Simulation avant/après compression de contexte — l'agent répond-il correctement à « qui es-tu ? » ? Que se passe-t-il sans réinjection d'identity ?

Sans réinjection d'identity
Avec réinjection d'identity
Interactif

Widget 3 · Autonome vs Assisté · quels rôles conviennent à l'autonomie ?

Décidez si ce rôle doit tourner en boucle autonome ou attendre passivement. Réfléchissez au « coût d'une erreur » et à la fréquence d'intervention humaine nécessaire.

Correct : 0 / 5