O agente de triagem diz que encontrou o problema e passa o caso para um especialista. O segundo agente recebe uma frase curta, abre as mesmas ferramentas e pergunta de novo pelo identificador que o primeiro já tinha confirmado.

Esse é o problema do handoff. O erro não está apenas no modelo que respondeu. Está na fronteira entre duas execuções: o que foi realmente concluído, qual evidência sustenta a conclusão, quais ações o próximo agente pode fazer e como ele deve reagir se o pacote estiver incompleto.

Um handoff útil é um contrato pequeno, não uma cópia da conversa. Ele deve levar o próximo objetivo, estado confirmado, referências de evidência, autoridade limitada, critérios de aceite e uma forma explícita de falhar. O agente receptor valida esse contrato antes de continuar.

Este artigo apresenta um modelo de projeto e um schema ilustrativo em TypeScript. O código não foi executado contra um provedor ou um runtime multiagente. A pesquisa combina a documentação atual do OpenAI Agents SDK sobre handoffs, a documentação de handoffs do LangChain e discussões públicas recentes. Para a arquitetura mais ampla, veja a orquestração de múltiplos coding agents com TypeScript.

Resposta curta

  • Use handoff quando outro agente deve assumir a responsabilidade pela próxima etapa, em vez de apenas responder como uma ferramenta do agente atual.
  • Passe estado confirmado e referências verificáveis, não o transcript inteiro como fonte de verdade.
  • Limite as ferramentas e a autoridade do receptor. O segundo agente não herda automaticamente todas as permissões do primeiro.
  • Rejeite pacotes ausentes, antigos ou inconsistentes antes de iniciar uma ação externa.

Quando um agente deve entregar o controle?

Um handoff faz sentido quando um agente especialista deve assumir a conversa ou a etapa seguinte. A documentação do OpenAI Agents SDK, "Handoffs", consultada em 25/09/2026, separa esse caso do padrão em que um agente chama outro como ferramenta e continua dono da resposta.

Essa escolha muda quem decide o próximo passo. Em um padrão de gerente, o agente principal chama um especialista, recebe um resultado e mantém o controle. Em um handoff, a triagem deixa de ser responsável pela execução seguinte. O receptor passa a interpretar o contexto, chamar suas próprias ferramentas e encerrar a etapa.

Não use handoff apenas porque existem dois prompts. Se a tarefa é curta, compartilha as mesmas ferramentas e precisa de uma síntese central, um agente com ferramentas pode ser mais simples de operar. Adicione a fronteira quando houver uma mudança real de responsabilidade, de dados disponíveis, de permissões ou de critérios de aceite.

Antes de transferir, responda a quatro perguntas:

  • O que o próximo agente precisa produzir?
  • Qual estado já foi confirmado, e por qual evidência?
  • Quais ferramentas e efeitos estão fora da autoridade dele?
  • O que acontece se ele não conseguir continuar?

Se essas respostas ainda vivem apenas no prompt da triagem, o handoff está sendo tratado como mensagem. Escreva o contrato antes de escolher o framework.

O que deve entrar no contrato de handoff?

O contrato mínimo que uso como modelo editorial tem seis blocos: objetivo, estado, evidência, autoridade, aceite e recuperação. Esses nomes não são um padrão universal. São uma forma compacta de tornar explícitas as decisões que um receptor teria de adivinhar.

O objetivo diz qual etapa começa agora. O estado informa o que já aconteceu, além do pedido original. A evidência aponta para artefatos, resultados ou identificadores que podem ser verificados. A autoridade lista o que o receptor pode fazer e o que continua proibido. O aceite define quando a etapa está pronta. A recuperação dá um destino para rejeição, bloqueio ou estado antigo.

Um schema pode tornar essa fronteira concreta:

import { z } from "zod";

const HandoffContract = z.object({
  version: z.literal(1),
  taskId: z.string().min(1),
  nextObjective: z.string().min(1),
  confirmedState: z.enum(["ready", "blocked", "needs-review"]),
  evidence: z.array(z.object({
    kind: z.enum(["artifact", "check", "decision"]),
    reference: z.string().min(1),
  })).min(1),
  authority: z.object({
    allowedTools: z.array(z.string()),
    forbiddenActions: z.array(z.string()),
  }),
  acceptance: z.array(z.string().min(1)).min(1),
  recovery: z.object({
    onReject: z.enum(["repair", "escalate", "stop"]),
    resumeFrom: z.string().nullable(),
  }),
});

type HandoffContract = z.infer<typeof HandoffContract>;

O taskId evita que o receptor trate um pacote de outra execução como se fosse o atual. version permite mudar o contrato sem interpretar um formato antigo como novo. confirmedState separa pronto de bloqueado. A lista de evidências não precisa carregar logs enormes: pode apontar para um artefato versionado, um teste, uma decisão persistida ou um resultado redigido.

O schema acima é ilustrativo e não foi executado. Em um sistema real, a validação também deve conferir se cada referência pertence à tarefa, se a versão ainda é válida e se a autoridade pedida não excede a política do receptor.

Como passar contexto sem copiar a conversa inteira?

Comece pelo contrato, depois filtre o histórico. O OpenAI Agents SDK, "Handoffs" informa que o receptor recebe o histórico inteiro por padrão e que inputFilter permite modificar o que atravessa a fronteira. A própria documentação separa inputType, que descreve argumentos do handoff, de RunContext, que carrega estado e dependências já existentes.

Isso evita uma confusão comum. Um resumo gerado pelo modelo pode explicar por que a triagem escolheu um especialista. Ele não prova que uma ferramenta foi executada, que um arquivo está numa versão específica ou que uma aprovação ainda é válida. O contrato deve apontar para o estado verificável. O histórico pode explicar o raciocínio, mas não deve ser a única fonte de verdade.

Em handoffs entre subgrafos, a documentação do LangChain, "Handoffs", consultada em 25/09/2026, chama atenção para a validade da sequência de mensagens. Uma chamada de ferramenta e sua resposta precisam continuar pareadas quando essa história é levada ao agente seguinte. Filtrar contexto exige preservar as unidades que o runtime espera, em vez de cortar mensagens pelo meio.

Uma política de filtro pode seguir esta ordem:

  1. Remova credenciais, prompts internos e dados que o receptor não precisa.
  2. Remova chamadas de ferramentas antigas quando elas não fazem parte da tarefa atual.
  3. Preserve as mensagens necessárias para a validade do protocolo do provedor.
  4. Acrescente o contrato validado como um objeto separado do texto narrativo.
  5. Registre qual filtro foi aplicado para que a transferência seja auditável.

Não transforme inputType em depósito de estado. A documentação do SDK diz que esse campo serve para metadados decididos pelo modelo no momento do handoff, como motivo, idioma ou prioridade. Estado da aplicação, dependências e permissões devem vir de uma fonte controlada pelo runtime.

Como o agente receptor valida o pacote?

O receptor deve validar antes de escolher a primeira ferramenta. Essa validação precisa tratar ausência, versão, identidade da tarefa, estado, autoridade e evidência como condições de entrada. Se uma delas falhar, o resultado deve ser uma rejeição explicável, não uma tentativa de adivinhar o que a triagem quis dizer.

Uma função de validação pode devolver um resultado discriminado:

type HandoffResult =
  | { ok: true; contract: HandoffContract }
  | { ok: false; reason: "invalid" | "stale" | "unauthorized" };

function acceptHandoff(
  value: unknown,
  expectedTaskId: string,
  allowedTools: ReadonlySet<string>,
): HandoffResult {
  const parsed = HandoffContract.safeParse(value);

  if (!parsed.success || parsed.data.taskId !== expectedTaskId) {
    return { ok: false, reason: "invalid" };
  }

  const hasUnknownTool = parsed.data.authority.allowedTools.some(
    (tool) => !allowedTools.has(tool),
  );

  if (hasUnknownTool) {
    return { ok: false, reason: "unauthorized" };
  }

  return { ok: true, contract: parsed.data };
}

Esse exemplo faz apenas três verificações. Ele valida a forma, confere a tarefa e impede que o pacote peça uma ferramenta fora da allowlist do receptor. Um runtime também pode comparar a versão do estado, exigir que as referências existam e recusar confirmedState: "ready" quando a evidência registrada está incompleta.

A verificação de autorização não pode depender do texto do handoff. Se o agente de triagem escrever "pode publicar" dentro de nextObjective, isso continua sendo uma intenção. A política do receptor deve ler a autoridade estruturada e aplicar seus próprios limites antes de chamar uma ferramenta. A documentação do OpenAI Agents SDK, "Handoffs" também alerta que isEnabled não autoriza valores internos de argumentos gerados pelo modelo; quando a decisão depende dos campos recebidos, a checagem deve ocorrer no início de onHandoff, antes de efeitos colaterais.

O que acontece quando o handoff é rejeitado?

Uma rejeição precisa ser um estado operacional. invalid significa que a estrutura não passa no schema. stale significa que a tarefa mudou desde que o pacote foi criado. unauthorized significa que a transferência pede uma capacidade que o receptor não pode usar. Cada caso deve ter um próximo passo diferente.

Para invalid, devolva o erro à triagem com os campos ausentes ou inconsistentes. Para stale, recarregue o estado atual e gere um novo pacote. Para unauthorized, pare e escale ou reduza a autoridade. Não faça um retry cego. Repetir a mesma transferência só cria outra chance de esconder a causa.

Se o handoff atravessar um processo, uma fila ou uma aprovação humana, persista o contrato e sua versão. A execução durável para agentes de IA trata do estado que precisa sobreviver a falhas. Um handoff dentro de uma única execução pode usar memória do runtime, mas ainda deve ter uma rejeição observável.

Também separe handoff de compactação. A compactação de contexto em agentes reduz o histórico que um mesmo agente envia ao modelo. Um handoff muda o responsável por uma etapa. Os dois podem usar filtros e resumos, mas resolvem fronteiras diferentes.

Como testar uma fronteira de handoff?

Teste o contrato como uma interface, incluindo o caminho feliz e as rejeições do workflow. O guia para testar a trajetória de um agente de IA cobre a avaliação de tools, argumentos, ordem, estado e decisões de parada. O handoff acrescenta uma unidade menor: o pacote que deve chegar ao próximo agente.

Uma matriz inicial pode conter estes casos:

  • pacote válido com todas as referências disponíveis;
  • campo obrigatório ausente;
  • taskId de outra execução;
  • versão de estado mais antiga que a atual;
  • ferramenta pedida fora da autoridade do receptor;
  • evidência que aponta para um artefato removido ou substituído;
  • transferência repetida depois de uma confirmação;
  • rejeição que produz reparo, escalonamento ou parada conforme a política.

Para cada caso, verifique mais que a resposta final. Confirme qual agente recebeu o controle, quais ferramentas foram expostas, qual estado foi persistido e se uma rejeição impediu efeitos externos. Se o teste só examina a frase final, ele não sabe se o receptor recebeu uma permissão que não deveria ter.

Um trace também ajuda a depurar a fronteira, mas não substitui o contrato. Registre o identificador da tarefa, a versão do pacote, o agente de origem, o agente de destino, o resultado da validação e a razão da rejeição. Evite registrar o conteúdo integral do histórico por padrão.

Quais são os limites desse padrão?

Handoff não transforma um conjunto de agentes em um sistema confiável sozinho. Ele torna a mudança de responsabilidade explícita. Ainda é preciso definir estado persistente, política de ferramentas, limites de custo, timeout, observabilidade e uma forma de corrigir dados antigos.

Também há um custo de coordenação. Um agente com ferramentas pode resolver uma tarefa curta com menos contratos, menos pontos de falha e menos contexto duplicado. A documentação de orquestração do OpenAI Agents SDK, consultada em 25/09/2026, trata handoffs e agentes como ferramentas como escolhas complementares, não como uma escada automática de maturidade.

Os nomes e formatos variam entre SDKs. inputType e inputFilter são mecanismos do OpenAI Agents SDK. A ideia mais durável é a fronteira: um pacote versionado, validável, com autoridade limitada e recuperação explícita. Se o provedor mudar, você pode trocar o adaptador sem deixar a responsabilidade escondida no prompt.

Conclusão

Um handoff confiável permite que o segundo agente comece sem repetir a investigação e sem herdar permissões por acidente. Para chegar lá, trate a transferência como uma interface: escreva o próximo objetivo, o estado confirmado, as evidências, a autoridade, o aceite e a recuperação.

Valide o pacote no receptor. Filtre o histórico com respeito ao protocolo do runtime. Persista a transferência quando ela atravessar processos. Teste estado antigo, ferramenta proibida, evidência ausente e repetição. O agente pode escolher quando pedir o handoff, mas o código deve decidir se a transferência é válida.

Como esta análise foi feita

Samuel Fajreldines é o autor responsável por este artigo. A pesquisa comparou a documentação atual do OpenAI Agents SDK e do LangChain, os owners existentes de orquestração, contexto, execução durável e trajetória, e discussões públicas recentes. O contrato de seis partes, o schema e a matriz de rejeição são síntese editorial original. O código é ilustrativo e não foi executado contra um provedor ou runtime multiagente. A assistência de IA apoiou descoberta, redação, geração da imagem, localização e revisão de consistência; não forneceu experiência de produção nem substituiu a verificação das fontes. O autor também mantém o RemoteCode como ferramenta de trabalho.

Fontes consultadas