Aula 10 · Colaboração

O handshake entre dois agents

Agents também precisam "assinar contratos". O request_id é o número do contrato.

⏱ ~10 min · 📝 3 componentes interativos · 🧑‍💻 Baseado em shareAI-lab · s10_team_protocols.py

Por que precisamos de protocolos?

No s09, o send_message podia transmitir qualquer conteúdo. Mas quando dois agents precisam chegar a um consenso sobre algo (por exemplo, "posso encerrar agora?"), só enviar uma string não basta — você precisa de:

  • Identidade clara no request (request_id), para que a resposta possa ser correlacionada.
  • Máquina de estados: pending → approved | rejected, com consequências claras para cada transição.
  • Campos consistentes: ambos os lados sabem o que approve: true significa.

É por isso que existem shutdown_request / shutdown_response / plan_approval / plan_approval_response.

Fluxo completo do protocolo de shutdown

O lead quer que alice encerre:

lead:
  # envia shutdown_request, o servidor registra request_id
  req_id = uuid4()[:8]
  shutdown_requests[req_id] = {"target": "alice", "status": "pending"}
  send("alice", "shutdown_request", extra={"request_id": req_id})

alice:
  # próximo loop lê a inbox, vê shutdown_request
  # decide: termina o que está fazendo e aprova
  tool_use("shutdown_response", request_id=req_id, approve=True)

lead:
  # recebe shutdown_response, atualiza tracker para approved
  shutdown_requests[req_id]["status"] = "approved"
  # thread de alice detecta o shutdown aceito, define status=shutdown e sai do loop

Visualização do FSM de shutdown

Acompanhe a máquina de estados passo a passo. Alice também pode rejeitar — dizendo "estou em trabalho crítico, não posso parar agora".

Plan Approval · o mesmo padrão, domínio diferente

Antes de uma ação de grande impacto, o teammate submete um plano para aprovação do lead:

alice:
  tool_use("plan_approval", plan="Vou reescrever o módulo auth inteiro com JWT")
  # alice fica idle aguardando o lead

lead:
  # vê o pedido de plan_approval_response de alice
  tool_use("plan_approval", request_id="...", approve=False,
           feedback="Não mexa no auth ainda, vamos fazer um refactor geral no próximo mês")

Se você olhar o código do s10, vai perceber: os dois protocolos usam exatamente o mesmo padrão de rastreamento com request_id — apenas com nomes de dicionários diferentes (shutdown_requests vs plan_requests). É "um padrão, dois domínios".

Por que não abstrair uma classe base Protocol? O s10 deliberadamente não abstrai. Motivo: com apenas dois protocolos, o ganho da abstração não compensa; cada um pode ser entendido de forma independente. Quando houver um quarto ou quinto protocolo, aí sim vale refatorar (regra dos três).
Interativo

Widget 1 · Shutdown FSM · percorra a máquina de estados completa

Clique em "Próximo" para avançar um passo e ver como o request_id estabelece a correlação entre os dois agents.

🧑‍💼 Lead
👩‍💻 Alice
tabela shutdown_requests
{}
Interativo

Widget 2 · request_id correlação · não confunda os contratos

Múltiplos requests em estado pending ao mesmo tempo — clique em uma resposta e veja qual request é atualizado. Essa é a chave para o protocolo funcionar com concorrência.

Requests aguardando resposta
Respostas simuladas (clique para acionar)
Interativo

Widget 3 · Protocol Design · projete seu próprio terceiro protocolo

Um novo cenário — aplique o padrão de request_id para projetar o handshake. Escolha a opção correta para passar.

Acertos: 0 / 5