aicert.study
Trayecto de Estudio/Um loop de ferramentas é delegação controlada

Um loop de ferramentas é delegação controlada

90 min

Contenido original en portugués — traducción próximamente.
Recomendamos ver antes: Saída estruturada é um contrato que não é confiável por padrão

Objetivos de la lección

  • Implementar o ciclo de vida completo de tool_use até o resultado
  • Preservar a identidade de cada chamada em execuções concorrentes
  • Reconhecer quando o loop deve parar em vez de continuar indefinidamente

O problema

Um assistente de suporte recebe uma pergunta que exige duas informações: o status do pedido e o histórico de pagamento do cliente. O modelo responde com stop_reason: "tool_use" pedindo duas ferramentas, get_order_status e get_payment_history, no mesmo turno. O time que construiu o harness tem duas escolhas na hora de montar a resposta: executar as duas chamadas e devolver os resultados como um parágrafo corrido resumindo os dois, ou executar cada uma separadamente e devolver cada resultado amarrado ao tool_use_id que o originou.

A primeira opção parece mais limpa — é só um texto explicando o que foi encontrado. Mas ela quebra o contrato do protocolo: se uma das chamadas falhar, não há como o modelo saber qual delas, porque a identidade de cada chamada se perdeu no resumo. A segunda opção é mais verbosa, mas é a única que preserva informação suficiente para o loop continuar de forma confiável.

Esse é o tipo de decisão que esta lição trata: um loop de ferramentas não é "deixar o modelo trabalhar sozinho". É delegação controlada, onde o harness que você escreve é responsável por manter o protocolo íntegro em cada volta.

O ciclo de vida, sem atalho

O ciclo de uma chamada de ferramenta tem um formato fixo:

  1. O modelo responde com stop_reason: "tool_use" e um ou mais blocos tool_use, cada um com um id único.
  2. O harness executa a ferramenta correspondente a cada bloco.
  3. O harness devolve um tool_result por tool_use_id, na mesma ordem de turno, como parte da próxima mensagem do usuário.
  4. O modelo continua a conversa com esse resultado disponível — e pode pedir outra ferramenta, ou terminar com stop_reason: "end_turn".

O ponto que mais gera erro em produção: quando o modelo pede duas ou mais ferramentas independentes no mesmo turno, elas podem ser executadas em paralelo (se não houver dependência entre elas), mas os resultados precisam manter a associação com o id original. Combinar os resultados num texto solto, ou devolvê-los fora de ordem sem a referência ao id, é a causa mais comum de loops que "esquecem" o que já foi perguntado.

Onde a decisão pode ir errada

Um padrão que aparece com frequência em cenários de prova: dado que uma chamada é determinística (como calcular um checksum ou formatar uma data), a resposta "óbvia" costuma ser delegar isso para outra chamada de ferramenta, ou pior, para um subagente. Mas se a operação tem uma implementação exata e sem ambiguidade, ela deve ser resolvida em código convencional dentro do próprio harness — não vale a pena pagar o custo de uma chamada de modelo, e menos ainda o de um subagente inteiro, para algo que uma função pura resolve.

A regra prática: reserve o loop de ferramentas (e, com mais razão, subagentes) para passos que exigem julgamento, ambiguidade ou acesso a um sistema externo. Everything else é código.

Outro erro comum é não ter uma condição de parada clara. Um loop que continua pedindo ferramentas indefinidamente porque cada resposta "parece incompleta" para o modelo drena orçamento e tempo sem necessidade. O harness deve impor um limite de iterações e, quando esse limite é atingido, devolver um estado explícito de "não concluído" em vez de deixar o loop rodar até estourar o tempo da requisição.

Erros, limites e cancelamento também são parte do loop

Em produção, um harness de tool use robusto trata como estados de primeira classe:

  • Erro na execução da ferramenta: o tool_result deve indicar a falha explicitamente (por exemplo, com um campo de erro), não silenciar o problema devolvendo uma string vazia.
  • Cancelamento pelo usuário: a requisição em andamento precisa ser interrompida de forma limpa, sem deixar o histórico da conversa em um estado inconsistente (um tool_use sem tool_result correspondente quebra a próxima chamada).
  • Limite de tempo ou de iterações: como já mencionado, precisa de um teto explícito, não implícito.

Coloque em prática

O laboratório desta lição pede pra você implementar um harness mínimo de loop de ferramentas em Python: ele recebe uma lista de chamadas de ferramenta simuladas (algumas independentes, uma dependente de outra), precisa executar as independentes preservando a associação por id, detectar quando uma chamada determinística deveria ter sido resolvida em código puro, e impor um limite de iterações. Os testes verificam que a associação entre chamada e resultado nunca se perde, mesmo quando a ordem de execução não é a ordem de chegada.

Laboratorio práctico

Clona el repositorio y ejecútalo localmente:

git clone https://github.com/aicertstudy/labs
cd labs/ccar-f/lessons/10-tool-use-and-agentic-loops
Ver carpeta en GitHub

¿Listo para ponerlo a prueba de verdad?

Haz el simulacro completo del CCAR-F, con el mismo formato del examen oficial.

Ver simulacros

Checkpoint de la lección

Cargando quiz...