El protocolo de handshake entre dos agents
Los agents también necesitan «firmar contratos». El request_id es el número de contrato.
¿Por qué hacen falta protocolos?
Con send_message de s09 se puede enviar cualquier contenido. Pero cuando dos agents necesitan llegar a un acuerdo sobre algo (por ejemplo, «¿puedo apagarte?»), solo enviar strings no es suficiente — necesitas:
- Identidad de la solicitud (request_id), para que la respuesta pueda emparejarse con la solicitud correcta.
- Máquina de estados: pending → approved | rejected, con consecuencias claras para cada estado.
- Campos consistentes: ambas partes saben que
approve: truetiene un significado específico.
De ahí vienen shutdown_request / shutdown_response / plan_approval / plan_approval_response.
Flujo completo del protocolo de shutdown
lead quiere que alice termine su jornada:
lead: # Envía shutdown_request; el servidor registra el request_id req_id = uuid4()[:8] shutdown_requests[req_id] = {"target": "alice", "status": "pending"} send("alice", "shutdown_request", extra={"request_id": req_id}) alice: # En el siguiente turno lee el inbox, ve shutdown_request # Decide: terminar la tarea actual primero, luego aceptar tool_use("shutdown_response", request_id=req_id, approve=True) lead: # Recibe shutdown_response, actualiza el tracker a approved shutdown_requests[req_id]["status"] = "approved" # El hilo de alice detecta la aceptación, pone status=shutdown y sale del bucle
Visualización del FSM de shutdown
Recorre la máquina de estados paso a paso. Alice también puede rechazar — diciéndole que «está en un momento crítico y no puede parar ahora».
Plan Approval · el mismo patrón aplicado a otro dominio
Un teammate envía un plan para pedir aprobación antes de hacer cambios importantes:
alice: tool_use("plan_approval", plan="Voy a reescribir el módulo auth completo usando JWT") # alice queda en idle esperando a lead lead: # Ve la solicitud plan_approval_response de alice tool_use("plan_approval", request_id="...", approve=False, feedback="No toques auth por ahora; el mes que viene hacemos un refactor global")
Si observas el código fuente de s10 verás que los dos protocolos usan exactamente el mismo patrón de seguimiento por request_id — solo cambia el nombre del diccionario (shutdown_requests vs plan_requests). Un patrón, dos dominios.
¿Por qué no abstraer una clase base Protocol genérica? s10 lo evita deliberadamente. Con solo dos protocolos el beneficio de la abstracción no está claro; mantenerlos explícitos facilita entender cada uno de forma independiente. Si llegan el cuarto o quinto protocolo, entonces tiene sentido refactorizar (rule of three).