aicert.study
Trilha de Estudo/Um erro de ferramenta também é uma resposta

Um erro de ferramenta também é uma resposta

75 min

Recomendamos ver antes: MCP separa capacidade de host

Objetivos da lição

  • Devolver erros estruturados e passíveis de nova tentativa
  • Expor catálogos e schemas como recursos em vez de chamadas repetidas
  • Desenhar descoberta progressiva para catálogos grandes de ferramentas

O problema

Um servidor MCP interno cresceu de 6 para 40 ferramentas em três meses. Cada ferramenta nova entrou no mesmo padrão: uma descrição de uma linha, exposta direto no catálogo que o Claude recebe no início de cada sessão. O contexto ficou pesado, a seleção de ferramenta piorou (o modelo confunde update_invoice com update_invoice_line_item com alguma frequência) e, quando uma chamada falha, o erro que volta é a exceção Python crua, com stack trace e tudo. O agente tenta de novo. Falha de novo. Tenta mais uma vez. Três tentativas depois, ainda é o mesmo erro — porque a causa era uma credencial inválida, não uma instabilidade passageira, e nenhuma retentativa jamais teria resolvido isso.

Dois problemas distintos estão misturados aqui, e a prova gosta de testar se você separa os dois: como o catálogo de ferramentas é exposto e como um erro de ferramenta é comunicado de volta. Resolver só um dos dois deixa o outro te mordendo.

Erros são uma resposta, não um obstáculo

Um erro de ferramenta mal desenhado devolve texto livre — uma mensagem pensada para um humano ler no log, não para o modelo decidir o próximo passo. Um erro bem desenhado é um contrato estruturado com pelo menos três campos: o tipo do erro, se é seguro tentar de novo e uma instrução de recuperação.

{
  "error_type": "rate_limited",
  "retryable": true,
  "guidance": "Aguarde e tente novamente com backoff exponencial."
}

versus

{
  "error_type": "invalid_credentials",
  "retryable": false,
  "guidance": "Escale para um humano — a credencial configurada não é válida."
}

A diferença entre os dois não é o tom, é a ação correta. rate_limited é uma condição transitória do sistema — o loop deve esperar e tentar de novo. invalid_credentials é uma condição permanente até que alguém troque a credencial — nenhuma quantidade de retentativa resolve isso, e insistir só desperdiça orçamento de tokens e tempo enquanto o problema real (uma credencial expirada, digamos) continua sem solução. O distrator clássico de cenário de prova é "adicionar mais tentativas" como resposta universal a qualquer falha de ferramenta — funciona para uma classe de erro e mascara a outra, fazendo um erro terminal parecer transitório.

Vale generalizar essa distinção para qualquer taxonomia de erro que seu sistema use: existe uma classe que se resolve sozinha com tempo (rate limit, timeout de rede, indisponibilidade momentânea) e uma classe que não se resolve sem intervenção (autenticação inválida, permissão negada, entrada que viola uma regra de negócio). Um harness de orquestração competente trata as duas de formas visivelmente diferentes — não porque é mais elegante, mas porque tratar as duas igual desperdiça recursos em um caso e finge resolver o outro.

Descoberta progressiva: pare de despejar o catálogo inteiro

O segundo problema — 40 ferramentas competindo por atenção em todo prompt — tem uma solução estrutural, não uma de prompt engineering. Em vez de listar todas as ferramentas em todo turno, exponha uma ferramenta de busca (search_tools(query)) ou um recurso de catálogo por categoria, e deixe o Claude carregar a definição completa só das ferramentas relevantes para a tarefa atual. Isso é descoberta progressiva: o catálogo existe, mas nada obriga o contexto a carregá-lo inteiro toda vez.

O mesmo raciocínio vale para schemas grandes e documentação de referência: eles pertencem a recursos que podem ser buscados sob demanda, não a texto embutido em toda chamada de ferramenta. Se uma ferramenta de consulta a banco de dados precisa do schema completo de 30 tabelas para funcionar bem, o schema é um recurso que a ferramenta busca quando necessário — não um bloco de 2.000 tokens repetido em cada mensagem do sistema.

A pergunta de arquitetura que resume as duas metades desta lição é sempre a mesma: o que precisa estar no contexto agora, e o que só precisa estar acessível quando for pedido? Um catálogo de ferramentas pertence à segunda categoria quase sempre. Um erro que acabou de acontecer pertence à primeira — e precisa chegar formatado de um jeito que permita ao modelo decidir corretamente, não só reagir.

Coloque em prática

No laboratório desta lição você recebe um conjunto de exceções cruas vindas de um serviço externo simulado e precisa classificá-las em um contrato de erro estruturado (error_type, retryable, guidance), decidindo caso a caso se a resposta correta é retentativa com backoff ou escalonamento imediato.

Laboratório prático

Clone o repositório e rode localmente:

git clone https://github.com/aicertstudy/labs
cd labs/ccar-f/lessons/18-tool-contracts-errors-and-progressive-discovery
Ver pasta no GitHub

Pronto pra testar de verdade?

Faça o simulado completo do CCAR-F, no mesmo formato da prova oficial.

Ver simulados

Checkpoint da lição

Carregando quiz...