Conteúdo da trilha
8 minNarração em inglês, legenda em portuguêsPodcast (RSS)
Capítulos
  1. 0:00Abertura
  2. 0:31A ideia
  3. 0:43Antes e depois
  4. 1:48Um caso real
  5. 2:36Por que funciona
  6. 3:33Um desafio
  7. 4:14Passo a passo seguro
  8. 5:38Riscos
  9. 7:26Fechamento
Transcrição

Abertura

Você conheceu o agente de faturas na aula passada. Ele abre o portal do fornecedor, clica em próxima página e lê a lista. Uma noite o botão continua visível e não carrega nada. Sem limite, o loop clica milhares de vezes, e o único alarme é a fatura.

O smell contou essa história. Esta refatoração coloca o freio. E você vai ver que o freio é só metade. A outra metade é o que o agente diz quando para.

A ideia

Dê a toda execução um orçamento explícito, de passos, tempo e custo. Confira antes de cada turno. E defina o que o agente entrega quando o orçamento acaba.

Antes e depois

Antes, a única saída é o modelo parar. Tarefa, modelo, ferramenta, e de novo. Até o modelo dizer que terminou.

Depois, o seu código tem uma segunda saída. A tarefa chega com um orçamento definido pela sua política, não pelo modelo.

Antes de cada turno, o código confere os passos, o tempo decorrido e o custo acumulado.

O modelo é chamado como sempre, e a resposta final continua sendo uma saída legítima. As ferramentas rodam, e o custo delas também conta, quando existe.

A tarefa termina dentro do orçamento.

Ou termina no limite, com o que foi encontrado até ali, e o motivo da parada.

No código, é uma mudança pequena. While true vira: enquanto o orçamento permitir. Com 25 passos, 5 minutos e 80 centavos.

Depois de cada chamada, o orçamento é cobrado com o consumo que a API informou.

E quando acaba, o agente encerra, com o motivo.

Um caso real

Com os mesmos números ilustrativos da última vez. Uma execução normal, dez turnos, uns cinquenta e dois mil tokens.

Uma execução presa sem limite, duzentos turnos, uns oito milhões e seiscentos mil.

E a mesma execução presa, com limite de vinte e cinco, uns duzentos mil. A curva nunca chega aos milhões.

E aqui está o encerramento no portal quebrado. Não uma exceção vazia. Li a primeira página, faturas um a vinte de trezentas e quarenta. Próxima página voltou ok, e a lista não mudou, três vezes. Parei por repetição. Faltam as páginas dois a dezessete.

A operação termina o trabalho na mão. E o trace vira um caso de eval.

Por que funciona

Um loop de agente tem duas fontes de término. A decisão do modelo, e a decisão do código. Sem orçamento, só a primeira existe. E ela falha justamente nos casos ruins. Uma ferramenta que não progride, uma tarefa impossível, um conteúdo que confunde. O orçamento coloca uma decisão determinística bem ao lado da probabilística.

O encerramento é a metade que costuma faltar. Um limite que só lança exceção troca um custo alto por uma tarefa perdida. Um limite com encerramento entrega algo útil. Li catorze dos vinte arquivos, a causa provável é esta, ainda preciso confirmar aquela.

E o orçamento transforma mau comportamento em dado. Toda execução que bate no limite é um caso para entender. O limite revela o problema. Ele não existe para você esconder o problema subindo o número.

Um desafio

Uma pergunta para você. Entre as execuções de sucesso, 95% terminam em até catorze passos. O time quer um limite de dezesseis, para cortar cedo. O que você espera ver no eval?

O custo no máximo cai. E a taxa de conclusão das tarefas saudáveis cai junto. Cinco por cento das execuções de sucesso já passam de catorze passos, e algumas passam de dezesseis. Você cortaria os sucessos de hoje para economizar demais na execução presa de amanhã.

Um ponto de partida comum é duas a três vezes esse percentil 95. O limite deve pegar as execuções presas, não as longas.

Passo a passo seguro

Agora, o passo a passo. Passo zero, medir. Rode o eval do agente e tire dos traces a distribuição de passos, tempo e custo por tarefa.

Escolha os limites a partir desses dados. Se o percentil 95 é catorze passos, e o máximo saudável é dezenove, um limite de vinte e cinco dá folga. Um de duzentos, não.

Confira antes de cada chamada, não depois. Inclua o custo de ferramentas pagas, como busca ou navegador. E use o consumo que a API devolve, não uma tabela de preços desatualizada.

E cobre os subagentes do orçamento do pai. Passe para baixo o que sobrou. Não dê um orçamento novo para cada filho.

Escreva o encerramento. Uma última chamada curta, sem ferramentas, que resume o que foi feito e o que falta. Ou uma mensagem fixa com o estado. E o texto precisa dizer que parou no limite.

Registre o motivo da parada no trace. Passos, tempo, custo, repetição, ou concluído.

Coloque detecção de repetição. A mesma ferramenta, com os mesmos argumentos, três vezes seguidas, também encerra o loop.

E meça de novo. A taxa de conclusão não pode cair. O custo nos piores casos deve cair. E as tarefas que pararam no limite viram casos de eval.

Riscos

Alguns riscos. Um limite baixo demais começa a derrubar tarefas longas legítimas. Você vê isso na taxa de conclusão.

Uma estimativa de custo errada. Se a conta usa preços velhos, ou ignora tokens de cache, o limite de dinheiro não protege.

Um encerramento que mente. Uma resposta parcial escrita como se estivesse completa engana o usuário.

Um orçamento contado só em passos. Um passo que resume um arquivo de duzentos mil tokens custa mais que dez passos curtos somados. Limite tokens ou dinheiro também.

E um orçamento novo para cada filho. Cada subagente ganha vinte passos novos, sem limite de profundidade, e o loop volta, agora como uma árvore.

Esse último se esconde bem. Olhe este loop. Ele tem limite de vinte passos. Então parece seguro.

Mas toda chamada de delegar abre um loop novo de vinte passos, sem limite de profundidade e sem orçamento compartilhado. Com três delegações por passo, o total explode. Além disso, o resultado do subagente é jogado fora. E terminar com uma exceção de timeout não deixa estado nenhum.

A correção é passar o mesmo orçamento para todo filho, e tirar a ferramenta de delegar depois de dois níveis. Depois, acrescentar o resultado de cada filho às observações do pai e terminar com um encerramento, não com uma exceção.

Mais uma armadilha. Um time escreve o encerramento como uma última chamada ao modelo, com ferramentas, pedindo para terminar a tarefa com o que tem. Com ferramentas, esse turno extra é o loop de novo, sem o limite que você acabou de bater. E o texto que sai finge ser um sucesso. Encerramento é curto, não tem ferramenta e admite o limite.

Fechamento

Então, a ideia para levar. Passos, tempo e dinheiro, escolhidos a partir dos seus dados, conferidos antes de cada chamada, compartilhados pela árvore inteira. E quando o orçamento acaba, o agente diz o que fez, o que falta e por que parou. É assim que uma fatura surpresa vira um caso de eval.

Na próxima aula, vamos olhar o padrão completo para onde essa refatoração aponta: stop conditions, inclusive quando um agente deve desistir, ou pedir ajuda. Até lá.

RefatoraçãoMovendo controle

Adicionar Orçamento ao Loop

Add Loop Budget

Adicionar Orçamento ao Loop (Add Loop Budget) é uma refatoração de IA para sistemas com LLM, do grupo Movendo controle. Limitar passos, tempo e dinheiro de cada execução e definir o que acontece no limite.

Elemento
11/35
Nível
Intermediário
Leitura
5 min
Atualizado
Nesta página 8
  1. 01Problema
  2. 02Solução
  3. 03Antes e depois
  4. 04Por que funciona
  5. 05Passo a passo seguro
  6. 06Riscos
  7. 07Desafio
  8. 08Teste seu entendimento
  9. ··Perguntas rápidas

Problema

O agente roda até o modelo decidir parar, sem limite de passos, tempo ou dinheiro. É o smell Loop Sem Fim, e as variações Subagentes em Cascata e Custo Sem Teto.

O agente de boletos abre o portal do fornecedor, clica em “Próxima página” e lê a lista. Numa noite o botão continua visível e não carrega nada. Sem teto, o loop faz milhares de cliques. O único alarme é o da fatura. O smell conta essa história; esta refatoração põe o freio. O padrão de destino é Condições de Parada.

Solução

Dê a cada execução um orçamento explícito de passos, tempo e custo, checado antes de cada volta, e defina o que o agente entrega quando o orçamento acaba.

Antes e depois

 def run_agent(task):
     messages = [task]
-    while True:
+    budget = Budget(max_steps=25, max_seconds=300, max_usd=0.80)
+    while budget.allows():
         reply = call_model(messages, tools=TOOLS)
+        budget.charge(reply.usage)
         if reply.stop_reason != "tool_use":
             return reply.text
         messages += run_tools(reply)
+    return wrap_up(messages, reason=budget.exhausted_reason())

Antes: a única saída é o modelo parar.

flowchart TD
  T(["1. Tarefa"]):::io --> M(["2. Modelo"]):::llm
  M --> D{"3. Terminou?"}
  D -->|não| F["4. Ferramenta"]:::tool
  F --> M
  D -->|sim| R(["5. Resposta"]):::io

Depois: o código tem uma segunda saída, com comportamento definido.

flowchart TD
  T(["1. Tarefa"]):::io --> B{"2. Cabe no orçamento?"}
  B -->|sim| M(["3. Modelo"]):::llm
  M --> D{"4. Terminou?"}
  D -->|não| F["5. Ferramenta"]:::tool
  F --> B
  D -->|sim| R(["6. Resposta"]):::io
  B -->|não| W(["7. Fechamento: parcial ou pedido de ajuda"]):::io
  1. A tarefa chega com um orçamento atribuído pela sua política, não pelo modelo.
  2. Antes de cada volta, o código confere passos, tempo decorrido e custo acumulado.
  3. O modelo é chamado normalmente.
  4. A resposta final continua sendo uma saída legítima.
  5. Ferramentas rodam e o custo delas também entra na conta quando houver.
  6. A tarefa termina dentro do orçamento.
  7. A tarefa termina no limite, com o que foi apurado até ali e o motivo da parada.

Exemplo trabalhado

Os números abaixo são ilustrativos. System prompt e ferramentas: 3.000 tokens. Cada volta acrescenta uns 400 tokens de chamada e resultado.

Execução Voltas Tokens enviados no total (aprox.)
Normal 10 52 mil
Presa, sem teto 200 8,6 milhões
Presa, teto 25 25 cerca de 200 mil

Vinte vezes mais voltas custam muito mais que vinte vezes o preço, porque cada volta reenvia o histórico. O teto de 25 não deixa a curva chegar na casa dos milhões.

O fechamento, no portal quebrado, não é uma exceção vazia. É: “Li a primeira página (faturas 1 a 20 de 340). O botão Próxima página respondeu ok e a lista não mudou, três vezes. Parei por repetição. Faltam as páginas 2 a 17.” Ops termina o trabalho; o trace vira caso de eval.

O OpenAI Agents SDK oferece max_turns. O LangGraph oferece recursion_limit. O texto “Building effective agents” da Anthropic (dezembro de 2024) recomenda um número máximo de iterações. Essas peças são o teto de passos. Tempo, dinheiro, repetição e fechamento honesto você escreve.

Checagem +20 XP de primeiraO loop é while True, mas a ferramenta tem rate limit de 10 chamadas por minuto. O time diz que o custo por minuto já é baixo. Falta orçamento?

Por que funciona

Um loop de agente tem duas fontes de término: a decisão do modelo e a decisão do código. Sem orçamento, só a primeira existe, e ela falha exatamente nos casos ruins: ferramenta que não progride, tarefa impossível, conteúdo que confunde. O orçamento põe uma decisão determinística ao lado da probabilística.

O fechamento (passo 7) é a metade que costuma faltar. Um teto que só lança exceção troca um custo alto por uma tarefa perdida. Um teto com fechamento entrega algo útil: “li 14 dos 20 arquivos, a causa provável é X, faltou confirmar Y”.

Por fim, o orçamento transforma comportamento ruim em dado. Toda execução que bate no teto é um caso para entender e, muitas vezes, um caso novo para o eval. O teto revela o problema; não existe para escondê-lo subindo o número.

Passo a passo seguro

  1. Meça. Rode o eval do agente e extraia dos traces a distribuição de passos, tempo e custo por tarefa. Sem eval, comece por Criar Eval Antes de Mexer no Prompt.
  2. Escolha os tetos a partir dos dados. Um ponto de partida comum é duas a três vezes o p95 de execuções bem-sucedidas. O teto não deve cortar tarefas que hoje dão certo. Se o p95 é 14 passos e o máximo saudável é 19, um teto de 25 deixa folga; um teto de 200 não.
  3. Implemente a checagem antes de cada chamada, não depois. Inclua o custo das ferramentas pagas (busca, browser, APIs externas). Use o usage que a API devolve, não uma tabela de preços desatualizada.
  4. Some subagentes ao orçamento do pai. Passe o orçamento restante para baixo; não dê um orçamento novo a cada filho.
  5. Escreva o fechamento. Uma última chamada curta, sem ferramentas, que resume o que foi feito e o que falta, ou uma mensagem fixa com o estado. O texto precisa dizer que parou no limite.
  6. Registre o motivo da parada no trace: stop.reason = steps | time | cost | repeat | done.
  7. Acrescente detecção de repetição: a mesma ferramenta com os mesmos argumentos três vezes seguidas também encerra o loop.
  8. Meça de novo. Compare a taxa de conclusão (não pode cair), o custo no p95 e no máximo (devem cair) e quantas tarefas pararam no teto. As que pararam viram eval.
Checagem +20 XP de primeiraVocê colocou teto de 40 passos. Quando bate, o código lança TimeoutError e a tarefa some da fila, sem mensagem ao usuário. O orçamento está completo?

Riscos

  • Teto baixo demais. Tarefas legítimas e longas passam a falhar. Detecte pela taxa de conclusão no eval e pela fração de execuções com stop.reason = steps.
  • Custo estimado errado. Se a conta usa preço desatualizado ou ignora tokens de cache, o teto de dinheiro não protege. Use o usage que a API devolve em cada resposta.
  • Fechamento que mente. Uma resposta parcial escrita como se fosse completa engana o usuário. O texto do fechamento deve dizer que parou no limite.
  • Orçamento só por passo. Um passo com um documento enorme custa mais que dez passos curtos. Limite também tokens ou dinheiro.
  • Orçamento por filho. Cada subagente com 20 passos novos, sem profundidade, recria o loop na árvore. O desafio abaixo é esse caso.

Desafio

Este loop tem um teto, mas ainda é um Loop Sem Fim na prática. Encontre o motivo antes de abrir a solução.

def run(task, depth=0):
    for _ in range(20):
        reply = call_model(task, tools=[search, delegate])
        if reply.done:
            return reply.text
        for call in reply.tool_calls:
            if call.name == "delegate":
                run(call.args["subtask"], depth + 1)
            else:
                execute(call)
    raise TimeoutError()
Ver solução

Cada chamada a delegate abre um novo loop de 20 passos, sem limite de profundidade e sem orçamento compartilhado. Com três delegações por passo, o total explode. Além disso, o resultado do subagente é descartado e o fim por TimeoutError não deixa estado.

def run(task, budget, depth=0):
    while budget.allows():
        reply = call_model(task, tools=[search, delegate] if depth < 2 else [search])
        budget.charge(reply.usage)
        if reply.done:
            return reply.text
        for call in reply.tool_calls:
            if call.name == "delegate":
                result = run(call.args["subtask"], budget, depth + 1)  # mesmo orçamento
                task.add_observation(call, result)
            else:
                task.add_observation(call, execute(call))
    return wrap_up(task, reason=budget.exhausted_reason())

Teste seu entendimento

Checagem +20 XP de primeiraUma semana depois do teto, 2% das execuções param com stop.reason=steps. Qual é o próximo passo mais útil?

Checagem +20 XP de primeiraO teto é 25 passos. Um passo resume um PDF de 200 mil tokens; dez passos curtos somam 20 mil. Só o teto de passos protege o dinheiro dessa tarefa?

Checagem +20 XP de primeiraO p95 das execuções que dão certo é 14 passos. O time quer teto 16 ‘para cortar cedo’. O que você espera no eval?

Checagem +20 XP de primeiraO fechamento chama o modelo uma última vez, com ferramentas, e pede ‘termine a tarefa com o que tiver’. Qual é o problema?

Perguntas rápidas

O que é Adicionar Orçamento ao Loop?

Adicionar Orçamento ao Loop (Add Loop Budget) é uma refatoração de IA para sistemas com LLM, do grupo Movendo controle. Limitar passos, tempo e dinheiro de cada execução e definir o que acontece no limite.

Que problema Adicionar Orçamento ao Loop resolve?

Trata Loop Sem Fim, Subagentes em Cascata e Custo Sem Teto.

Aonde Adicionar Orçamento ao Loop leva?

Ao padrão de projeto Condições de Parada e Orçamento de Custo.

Para ir além

Relações

Aparece nas trilhas 1
Buscar