How to Build an AI Agent
How to Build an AI Agent
s10

Protocoles d'équipe

Collaboration

Shared Communication Rules

419 LOC12 outilsrequest_id correlation for two protocols
One request-response pattern drives all team negotiation

s01 > s02 > s03 > s04 > s05 > s06 | s07 > s08 > s09 > [ s10 ] s11 > s12

"Les co-écutants ont besoin de règles de communication partagées" -- un modèle demande-réponse gère toutes les négociations.

Problème

Dans s09, les co-écutants travaillent et communiquent mais manquent de coordination structurée :

Arrêt : Tuer un thread laisse des fichiers à moitié écrits et config.json obsolète. Vous avez besoin d'une poignée de main : le lead demande, le co-équiper approuve (termine et sort) ou rejette (continue de travailler).

Approbation de plan : Quand le lead dit "refactorer le module auth", le co-équiper commence immédiatement. Pour les changements à haut risque, le lead devrait d'abord revoir le plan.

Les deux partagent la même structure : un côté envoie une demande avec un ID unique, l'autre répond en référençant cet ID.

Solution

Protocole d'arrêt           Protocole d'approbation de plan
==================           ======================

Lead             Co-équiper    Co-équiper           Lead
  |                 |           |                 |
  |--shutdown_req-->|           |--plan_req------>|
  | {req_id:"abc"}  |           | {req_id:"xyz"}  |
  |                 |           |                 |
  |<--shutdown_resp-|           |<--plan_resp-----|
  | {req_id:"abc",  |           | {req_id:"xyz",  |
  |  approve:true}  |           |  approve:true}  |

FSM partagé:
  [pending] --approve--> [approved]
  [pending] --reject---> [rejected]

Trackers:
  shutdown_requests = {req_id: {target, status}}
  plan_requests     = {req_id: {from, plan, status}}

Comment Ça Marche

  1. Le lead initie l'arrêt en générant un request_id et envoyant via la boite aux lettres.
shutdown_requests = {}

def handle_shutdown_request(teammate: str) -> str:
    req_id = str(uuid.uuid4())[:8]
    shutdown_requests[req_id] = {"target": teammate, "status": "pending"}
    BUS.send("lead", teammate, "Please shut down gracefully.",
             "shutdown_request", {"request_id": req_id})
    return f"Shutdown request {req_id} sent (status: pending)"
  1. Le co-équiper reçoit la demande et répond avec approve/reject.
if tool_name == "shutdown_response":
    req_id = args["request_id"]
    approve = args["approve"]
    shutdown_requests[req_id]["status"] = "approved" if approve else "rejected"
    BUS.send(sender, "lead", args.get("reason", ""),
             "shutdown_response",
             {"request_id": req_id, "approve": approve})
  1. L'approbation de plan suit le modèle identique. Le co-équiper soumet un plan (générant un request_id), le lead revise (référençant le même request_id).
plan_requests = {}

def handle_plan_review(request_id, approve, feedback=""):
    req = plan_requests[request_id]
    req["status"] = "approved" if approve else "rejected"
    BUS.send("lead", req["from"], feedback,
             "plan_approval_response",
             {"request_id": request_id, "approve": approve})

Une FSM, deux applications. La même machine à états pending -> approved | rejected gère tout protocole demande-réponse.

Qu'est-ce qui a Changé par Rapport à s09

ComposantAvant (s09)Après (s10)
Outils912 (+shutdown_req/resp +plan)
ArrêtSortie naturelle seulementPoignée de main demande-réponse
Plan gatingNoneSoumettre/revoir avec approbation
CorrélationNonerequest_id par demande
FSMNonepending -> approved/rejected

Essayer

python agents/s10_team_protocols.py
  1. Générer alice comme codeuse. Ensuite demander son arrêt.
  2. Lister les co-écutants pour voir le statut d'alice après l'approbation de l'arrêt
  3. Générer bob avec une tâche de refactoring risquée. Reviser et rejeter son plan.
  4. Générer charlie, lui faire soumettre un plan, puis l'approuver.
  5. Tapez /team pour surveiller les statuts