Lição 3: Condições de parada: quando um agente deve desistir
Objetivos de aprendizado:
- Explicar por que deixar o modelo devolver
end_turn por conta própria não basta para encerrar um loop, e enunciar a tensão de forma clara: você tem que confiar no modelo, e ainda assim ele pode seguir por muitos turnos
- Adicionar uma trava rígida de turno máximo a um loop esqueleto, e explicar por que o contador só funciona se viver fora do loop
- Distinguir uma parada rígida (interrupção forçada no teto) de uma parada suave / suspensão (pausa para um humano, retomável), e listar as condições sob as quais um dado agente deve parar
Pré-requisitos: Você leu a Lição 2, consegue escrever um loop while dirigido por stop_reason, e sabe que o loop termina por conta própria quando end_turn volta | Anterior: Lição 2 << | Próxima: Lição 4 >>
Não conte com o modelo para dar o basta
O loop esqueleto da Lição 2 para por exatamente um motivo: em alguma rodada o modelo deixa de pedir ferramentas, stop_reason vira de tool_use para end_turn, a condição do while fica falsa, e o loop termina por si.1 Dito de outro jeito, a decisão sobre girar de novo foi entregue inteiramente ao modelo — o loop para quando o modelo diz que terminou de falar.
Na maior parte das vezes isso funciona, mas fique claro sobre quem toma a decisão. Um agente é, por definição, um sistema em que o modelo dirige dinamicamente seu próprio processo e seu próprio uso de ferramentas,2 e decidir quando desistir faz parte disso. Autonomia é exatamente o que torna um agente útil, mas o outro lado da mesma moeda é que "The autonomous nature of agents means higher costs, and the potential for compounding errors."2 (A natureza autônoma dos agentes significa custos maiores e o potencial de erros que se acumulam.) E a frase que mais importa aqui: "The LLM will potentially operate for many turns, and you must have some level of trust in its decision-making."2 (O LLM vai potencialmente operar por muitos turnos, e você precisa ter algum nível de confiança na tomada de decisão dele.)
A palavra em que se demorar é confiança. Confiança não é o mesmo que deixar o modelo sem supervisão. Se o modelo empaca em algum passo, ou é puxado para fora do rumo por algo que uma ferramenta devolveu, e simplesmente nunca devolve end_turn, um loop que só vigia o stop_reason não vai se impacientar no seu lugar. Ele fará companhia ao modelo, rodada após rodada, girando — porque nada na condição do while que você escreveu diz "chega de voltas". Então a autoterminação pelo modelo não basta por si só. Você precisa de condições de parada que o host decide, que não esperam o humor do modelo.
Primeiro, uma trava rígida no loop: turnos máximos
A condição de parada mais básica de todas é nomeada bem ali na orientação de engenharia da Anthropic: "it's also common to include stopping conditions (such as a maximum number of iterations) to maintain control."2 (também é comum incluir condições de parada — como um número máximo de iterações — para manter o controle.) Traduzido em código, é um teto em quantas vezes o loop tem permissão para girar.
Sobre o esqueleto da Lição 2, a mudança é pequena:
Duas coisas carregam o peso aqui. Primeiro, let turns = 0 é declarado fora do loop. Ele tem que permanecer vivo entre rodadas e somar cada uma, ou a trava não faz ideia de quantas voltas já se passaram; mova-o para dentro do corpo do loop e você ganha exatamente a armadilha que o exercício de Nível 2 desmonta. Segundo, a trava não se importa por que o modelo ainda está pedindo ferramentas — empacado, girando em círculos, puxado para fora do rumo pela saída de uma ferramenta, ela nunca pergunta. Uma vez que a contagem de voltas bate no teto, o host para, não envia mais requisição, e retoma o controle para o seu próprio lado.
Isso é uma parada rígida: na fronteira ela interrompe incondicionalmente e o loop acabou. É coisa diferente da conclusão suave do end_turn, em que o modelo decide que terminou — uma é um teto que você define, a outra é o julgamento do próprio modelo. Note que não há resposta padrão para quão grande MAX_TURNS deveria ser; depende de aproximadamente quantas rodadas a tarefa deveria precisar. O 10 aqui é um valor de exemplo. O que importa é que a trava exista e consiga de fato parar um loop que se descontrolou.
Além da parada rígida, outro tipo: parar para esperar um humano
Travas como turnos máximos compartilham uma propriedade: bater em uma é o fim da linha — o loop acabou e não vai continuar por conta própria. Mas esse não é o único tipo de condição de parada. O mesmo artigo nomeia outro: "Agents can then pause for human feedback at checkpoints or when encountering blockers."2 (Agentes podem então pausar para feedback humano em checkpoints ou ao encontrar bloqueios.) É um bicho diferente de uma parada rígida, e vale desmontar:
- Parada rígida: no teto ela interrompe, o loop terminou de vez, nada continua automaticamente. Turnos máximos e orçamento esgotado pertencem aqui. É um estado terminal.
- Parada suave / suspensão: o loop deliberadamente interrompe em um checkpoint, entrega o controle a uma pessoa, e consegue retomar daquele exato ponto uma vez que ela tenha respondido. Não é um fim; é uma pausa retomável.
No código a diferença cai sobre o que você retorna. Uma parada rígida retorna um resultado final — foi aqui que terminou. Uma parada suave tem que preservar estado: ela retorna um instantâneo da cena a partir do qual dá para retomar, entregando o messages atual junto com a ação pendente em que empacou, de modo que, uma vez que um humano tenha lidado com ela, aquele instantâneo baste para prosseguir:
O caso clássico de parada suave é o próximo passo do modelo ser algo irreversível — apagar um banco de dados, disparar um e-mail, submeter um pedido — e você querer que uma pessoa olhe antes de ir adiante; ou o modelo reportar por conta própria que empacou e precisa de mais informação. Traçar a linha parada rígida / parada suave já basta por ora. Como o needsHumanApproval de fato decide, e como o loop retoma daquele instantâneo uma vez que uma pessoa responde, é o assunto principal da Lição 5, sobre manter um humano no loop.
Um framework: comece perguntando "sob que condições isto deve parar?"
Com paradas rígidas e paradas suaves em mãos, projetar um agente ganha uma jogada de abertura conveniente. Antes de escrever qualquer loop, tenha uma pergunta respondida: sob que condições esta coisa deve parar? Liste as respostas e elas normalmente se resumem a estas quatro:
- A tarefa terminou — o modelo devolve
end_turn. Esta é a mais suave das quatro, julgada pelo modelo, e você ainda tem que confirmar que ela de fato terminou em vez de ter desistido pelo caminho.
- O teto de turnos — uma parada rígida. É a trava
MAX_TURNS acima, pegando o pior caso em que o loop deslancha e não consegue se conter.
- Um bloqueio que precisa de decisão humana — uma parada suave / suspensão, pausando para feedback humano.2 Disparada por operações irreversíveis, ou pelo modelo reportando explicitamente que está bloqueado.
- Orçamento esgotado — uma parada rígida. Tokens, gasto ou tempo decorrido: o que bater no seu teto primeiro para o loop. Os detalhes (como contar, onde instrumentar) esperam a Lição 4.
Enfileire essas quatro e algo fica visível: a decisão de parar não fica toda com o modelo. A número 1 pertence ao modelo, as números 2 e 4 pertencem ao host (elas param na marca independentemente do que o modelo pensa), e a número 3 é compartilhada. Aquele loop esqueleto da Lição 2 implementou só a número 1 e deixou de fora as outras três — esta lição adiciona a número 2, a trava rígida mais básica, enquanto as números 3 e 4 chegam na Lição 5 e na Lição 4, respectivamente.
O valor do framework não é memorizar quatro itens. É construir um hábito: antes de você escrever o loop, conte as condições de "deve parar" explicitamente, em vez de deixá-las enterradas sob a suposição-padrão de que o modelo vai parar de qualquer forma.
Condições de parada são seguro barato, não excesso de engenharia
Alguém pode resmungar que essas travas transformam um loop simples em um complicado. O que traz à tona um princípio ao qual a Anthropic sempre volta: "you should consider adding complexity only when it demonstrably improves outcomes."2 (você deveria considerar adicionar complexidade só quando ela comprovadamente melhora os resultados.) Essa linha costuma ser citada para dissuadir as pessoas de empilhar maquinaria elaborada, mas para condições de parada ela aponta para o outro lado — ela as deixa passar.
Faça a conta e fica óbvio. Um contador de turno máximo é uma declaração fora do loop e uma comparação dentro dele, algumas linhas de código. O que ele barra — um loop que não para de girar, custos escalando fora de controle, uma ação irreversível tomada sobre uma saída manipulada ou malformada — custa muito mais. A autonomia de agentes já carrega custos maiores e o potencial de erros que se acumulam,2 e uma condição de parada é o freio mais barato mirado exatamente nesse risco.
Então uma condição de parada não é o tipo de complexidade que você deveria adicionar só quando ela comprovadamente melhora os resultados2 — ela ultrapassa essa barra de saída. Ela comprime a fronteira do pior caso de "ilimitado" para "limitado", o que em si é uma melhora verificável nos resultados. É o controle mais básico que faz de um loop autônomo algo que você se atreve a deixar rodar, não um extra decorativo.
Recapitulação
- O loop termina naturalmente no
end_turn, mas esse é o julgamento do próprio modelo; você só consegue depositar algum nível de confiança na tomada de decisão dele, e ele pode operar por muitos turnos, então confiar só na autoterminação do modelo não basta2
- A trava rígida mais básica é uma contagem máxima de turnos: incluir uma condição de parada explícita, como um número máximo de iterações, para manter o controle é uma prática comum2; o contador tem que ficar fora do loop para acumular entre rodadas, e movê-lo para o corpo o transforma em código morto que não para nada
- Além das paradas rígidas há as paradas suaves / suspensões: pausar para feedback humano em checkpoints ou ao encontrar bloqueios2 — não um estado terminal, mas uma pausa retomável que prossegue a partir de um instantâneo da cena
- Ao projetar um agente, pergunte primeiro sob que condições ele deve parar: tarefa terminada (
end_turn, a decisão do modelo), teto de turnos (parada rígida, a decisão do host), um bloqueio precisando de decisão humana (parada suave, compartilhada), orçamento esgotado (parada rígida, coberta na Lição 4)
- Condições de parada são controle barato com grande retorno: a autonomia já traz custos maiores e erros que se acumulam,2 e uma trava de turnos máximos pega exatamente o pior caso; contra o princípio de adicionar complexidade só quando ela comprovadamente melhora os resultados,2 ela ultrapassa a barra de saída — comprimir o ilimitado em limitado é uma melhora verificável
>> Lição 4: Descontrole e fallback: loops mortos, giro em falso, esgotamento de orçamento