MÓDULO 4.6

🔀 Handoffs e Roteamento

A transferência formal de controle entre agentes com garantia de consistência. Aprenda critérios de roteamento (conteúdo, carga, habilidade, custo), rollback quando o destino falha, e os 4 padrões de handoff que cobrem todos os casos reais.

6
Tópicos
45
Minutos
Interm.
Nível
Padrões
Tipo
1

🤝 O que é um handoff

Um handoff não é apenas "agente A termina e agente B começa". É uma transferência formal de controle e contexto, com verificação de consistência antes da transferência e confirmação de recebimento pelo agente destino. A formalidade é o que garante que nada se perde na transição.

🤝 O protocolo de handoff formal

1 Agente A finaliza trabalho e verifica que estado está consistente
2 Agente A prepara o handoff packet (resultado + contexto relevante + metadados)
3 Orquestrador registra o handoff no log de auditoria
4 Agente B recebe e confirma recebimento (acknowledge)
5 Agente A libera os recursos e encerra sua execução
! Se Agente B não confirma em X segundos → rollback automático

O handoff packet

task_id: "T3"

from_agent: "executor_A"

to_agent: "reviewer_B"

result: {dados_do_resultado}

context_summary: "resumo do que foi feito"

handoff_reason: "task_complete"

timestamp: 1748345678

Handoff informal (o problema)

Sem protocolo formal, handoffs informais causam:

  • Contexto perdido na transição
  • Agente destino começa sem confirmação
  • Nenhum log de auditoria da transferência
  • Sem rollback quando destino falha
2

🎛️ Critérios de roteamento

O roteamento define qual agente recebe qual tarefa. A decisão errada desperdiça tokens (agente errado para o domínio) ou tempo (agente sobrecarregado). Quatro critérios cobrem a maioria dos casos reais — use o mais simples que resolve o seu problema.

1

Roteamento por Conteúdo

O tipo da tarefa determina o agente destino. Análise jurídica → agente jurídico. Código → agente de engenharia. Redação → agente de conteúdo.

if "contrato" in task: → legal_agent

elif "def " in task: → code_agent

else: → general_agent

2

Roteamento por Carga

O agente com menos tarefas em fila recebe a próxima. Load balancing clássico aplicado a agentes. Ideal quando agentes são equivalentes entre si.

agent = min(agents,

key=lambda a: a.queue_size)

3

Roteamento por Habilidade

O agente com maior success_rate histórico para esse tipo de tarefa é selecionado. Self-learning routing — melhora com o uso.

agent = max(capable_agents,

key=lambda a: a.success_rate(

task_type=task.type))

4

Roteamento por Custo

Para orçamento restrito, o agente mais barato compatível com os requisitos da tarefa é selecionado. Balanceia custo e qualidade.

agent = min(capable_agents,

key=lambda a: a.cost_per_token)

3

🧠 Roteamento dinâmico com LLM classifier

Quando regras determinísticas não são suficientes para classificar a tarefa corretamente, um LLM leve atua como classificador: analisa o input e decide qual agente tem a melhor combinação de habilidades para lidar com ele.

🧠 Implementação do classifier

CLASSIFIER_PROMPT

= """

Você é um roteador de tarefas. Analise a tarefa e escolha o agente mais adequado.

Agentes disponíveis:

- researcher: pesquisa web, coleta de dados, fact-checking

- analyst: análise quantitativa, modelagem, métricas

- writer: redação, síntese, geração de relatórios

- coder: código Python/JS, scripts, automação

Tarefa: {task_description}

Responda APENAS com o nome do agente (sem explicação):

"""

async def

route_task(task: str) -> str:

response = await llm.complete(

CLASSIFIER_PROMPT.format(task_description=task),

model="claude-haiku-3", # barato

max_tokens=10

)

agent_name = response.strip().lower()

if agent_name not in AVAILABLE_AGENTS:

return "general" # fallback seguro

return agent_name

✓ Quando usar LLM classifier

  • Tarefas em linguagem natural ambígua
  • Múltiplos domínios que se sobrepõem
  • Quando regras determinísticas ficam complicadas

✗ Quando usar regras determinísticas

  • Quando você quer zero latência de classificação
  • Quando o tipo de tarefa é sempre explícito no input
  • Quando o custo do classifier não é aceitável
4

↩️ Rollback de handoff

O que acontece quando o agente destino falha após receber o handoff? Sem rollback definido, a tarefa fica em limbo — nem no agente origem, nem no destino — e o sistema trava silenciosamente. O rollback formal é o que garante que nenhuma tarefa se perde.

↩️ Two-phase commit para handoffs

Fase 1: Prepare

  • → Agente A prepara handoff packet e registra no log como "pending"
  • → Agente B é notificado e reserva recursos para receber
  • → Agente B confirma "ready" ou responde "not ready"

Fase 2: Commit (ou Abort)

  • → Se B confirmou: handoff executado, log atualizado para "committed"
  • → Se B não confirmou em timeout: handoff abortado, log como "rolled_back"
  • → Rollback: tarefa retorna ao agente A (ou vai para agente de fallback)

⚠️ O handoff fantasma

Sem two-phase commit, existe o risco do "handoff fantasma": Agente A entregou (do ponto de vista dele), mas Agente B nunca recebeu (crash antes de confirmar). Nenhum dos dois sabe que a tarefa está perdida. O sistema continua funcionando, mas sem completar aquela tarefa específica — descoberto pelo usuário final horas depois.

5

📦 Context passing eficiente

Passar contexto demais é o erro mais comum em handoffs. Se o Agente A processou 50 documentos e passa todo o histórico para o Agente B, você paga pelo contexto duas vezes e pode exceder a context window. Contexto mínimo necessário é uma habilidade de engenharia.

📦 Estratégias de context compression

1

Sumarização semântica

Use um LLM para sumarizar o trabalho do Agente A em 3-5 bullet points antes de passar para o B. De 10.000 tokens para 200 tokens com 90% da informação relevante preservada.

2

Extração de entidades relevantes

Identifique e passe apenas as entidades que o Agente B vai usar: nomes, números, URLs, decisões. O resto é irrelevante para a próxima tarefa.

3

Contexto hierárquico

Passe dois níveis: summary (sempre) + full_context (disponível via referência se o agente precisar). O agente começa com o summary e solicita detalhes sob demanda.

6

🗺️ Os 4 padrões de handoff

Quatro padrões cobrem praticamente todos os casos de handoff em sistemas reais. Escolha sempre o mais simples que resolve o seu caso — simplicidade é confiabilidade.

➡️

Sequential (A→B→C)

Cada agente completa e passa para o próximo em sequência linear. O mais simples e previsível.

+ Fácil de auditar e debugar
- Mais lento (sem paralelismo)
🔀

Conditional (se X→B, se Y→C)

O agente destino é escolhido com base em uma condição avaliada pelo orquestrador ou pelo próprio agente A.

+ Flexível para diferentes tipos de tarefa
- Lógica de condição pode crescer indefinidamente

Parallel (A→B e C simultaneamente)

Agente A passa o resultado para múltiplos agentes simultaneamente. Todos processam em paralelo e os resultados são combinados no fan-in.

+ Muito rápido para tarefas independentes
- Custo multiplicado, lógica de merge necessária
🧠

Dynamic (A decide em runtime)

O Agente A decide em runtime para qual agente fazer handoff, baseado no resultado do seu próprio processamento. Máxima flexibilidade.

+ Adapta a resultado de execução
- Mais difícil de prever e testar

💡 Regra de escolha de padrão

Comece sempre com Sequential. Mude para Conditional quando o destino depende de critério claro. Use Parallel quando latência importa mais que custo. Reserve Dynamic apenas para sistemas que genuinamente não podem ser determinísticos — são os mais difíceis de operar em produção.

Resumo do Módulo 4.6

Handoff formal tem 5 passos com confirmação — handoff informal garante contexto perdido em produção
4 critérios de roteamento — conteúdo, carga, habilidade e custo, podendo ser combinados
Two-phase commit elimina o "handoff fantasma" — a tarefa nunca fica em limbo
Context compression — sumarização, entidades e contexto hierárquico reduzem custo de handoff
4 padrões de handoff — sequential, conditional, parallel, dynamic. Use o mais simples que resolve.

Próximo Módulo:

4.7 — Execução Paralela: fan-out, fan-in, asyncio.gather() e como gerenciar timeout e custo de agentes paralelos.