Lección 11 · Colaboración

Un agent que busca trabajo por su cuenta

"The agent finds work itself." Sin necesidad de que alguien lo llame: toma tareas del tablero por su cuenta.

⏱ ~12 min · 📝 3 widgets interactivos · 🧑‍💻 Basado en shareAI-lab · s11_autonomous_agents.py

De «que te llamen» a «buscar trabajo tú mismo»

El teammate de s09/s10 es pasivo: alguien necesita enviar un mensaje al inbox para que empiece; al terminar queda idle y espera a que lo llamen de nuevo.

El autonomous teammate de s11 es activo: cuando no tiene trabajo tampoco se detiene del todo; cada 5 segundos escanea el directorio .tasks/. Si ve una task sin dueño la reclama con claim_task y empieza a trabajar.

Teammate lifecycle:
  +-------+
  | spawn |
  +---+---+
      |
      v
  +-------+
  | WORK  | <-- bucle LLM tool_use
  +---+---+
      |
      | stop_reason != tool_use OR tool_use("idle")
      v
  +-------+
  | IDLE  | poll cada 5 s, 12 veces = timeout 60 s
  +---+---+
      |
      +--> ¿hay mensajes nuevos en inbox?  → retomar WORK
      |
      +--> scan .tasks/, tarea sin dueño → claim → retomar WORK
      |
      +--> 60 s sin nada → status = shutdown, hilo termina

Auto-claim · «Coger tarea» del tablero

Función principal:

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

Tres filtros = pending + sin owner + sin blockedBy. Los tres son imprescindibles.

La acción de claim tiene un lock (_claim_lock) para evitar que dos agents reclamen la misma task simultáneamente: dentro del lock se vuelve a leer, se comprueba que owner sigue vacío y se escribe en disco la marca «in_progress» + owner.

Simula varios agents escaneando el tablero a la vez

3 teammates en estado idle y 3 tasks esperando ser reclamadas. Pulsa «Siguiente poll» para ver quién llega primero.

Identity reinjection · Saber quién eres después del compactado

s06 explicó que auto_compact reemplaza los mensajes con un resumen. Un autonomous agent que lleva horas corriendo puede activar esto fácilmente; tras el compactado el modelo no sabe su nombre ni su rol.

La solución de s11: al reclamar una nueva task, si len(messages) ≤ 3 (indica que acaba de compactarse), inserta automáticamente un bloque de identidad al inicio:

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

Este patrón se llama identity reinjection: se construye artificialmente un turno de conversación para «decirle al modelo quién es» y que recupere su sentido de rol.

Interactivo

Widget 1 · Task Scanner · 3 agents compiten por 3 tasks

alice / bob / charlie están todos idle. Pulsa «Poll» para ver quién reclama en orden alfabético la primera task libre.

Directorio .tasks/
Estado de los teammates
Todos idle, esperando escanear
Interactivo

Widget 2 · Identity Drift · ¿Recuerda el agent quién es tras el compactado?

Simula la comparativa de respuesta a «¿quién eres?» antes y después del compactado de contexto. ¿Qué pasa sin identity reinjection?

Sin identity reinjection
Con identity reinjection
Interactivo

Widget 3 · Autónomo vs Asistido · ¿Qué roles son aptos para autonomía?

Decide si dejar que este rol corra en bucle autónomo o que espere de forma pasiva. Piensa en el «coste del descontrol» y la «frecuencia de intervención humana».

Correctas 0 / 5