antonio leandro

claude, na prática

Writing effective tools for AI agents

post · núcleo · 02 · ferramentas · Anthropic ·

a tese

ferramenta para agente não é api com outro nome: o gargalo é o contexto do modelo, então poucas ferramentas grossas, resposta enxuta e descrição bem escrita rendem mais que cobertura de endpoint.

o que fica

  1. Uma tool é um contrato entre um sistema determinístico e um agente não-determinístico — por isso envolver endpoint de api um-para-um é o erro mais comum de quem começa.
  2. O contexto do agente é caro e a memória do programa é barata: um list_contacts obriga o modelo a ler a lista inteira token a token, enquanto search_contacts entrega só a página certa.
  3. Trocar uuid alfanumérico por nome legível (ou até um id 0-indexado) na resposta da tool aumentou a precisão do claude em tarefas de retrieval e reduziu alucinação.
  4. Não existe formato de resposta universalmente melhor: xml, json ou markdown, e namespace por prefixo ou sufixo, mudam o resultado conforme o modelo — quem decide é a sua eval, não a intuição.
  5. Refinar a descrição da tool é um dos métodos mais eficazes que a anthropic encontrou; foi o que levou o sonnet 3.5 ao estado da arte no swe-bench verified.
  6. O que o agente omite no feedback importa mais do que o que ele escreve — ler só o chain-of-thought engana, é preciso abrir o transcript cru com as chamadas e respostas.

o problema

Software tradicional é um contrato entre sistemas determinísticos. getWeather("NYC") faz sempre a mesma coisa, do mesmo jeito, e quem chama sabe exatamente por que chamou. Tool é outra categoria: um contrato entre um sistema determinístico e um agente não-determinístico. Diante de “preciso levar guarda-chuva hoje?”, o agente pode chamar a ferramenta de clima, responder de cabeça, pedir a cidade — ou alucinar o uso da tool. Escrever essa camada como se escreve uma api para outro desenvolvedor é o erro de base.

O sintoma mais comum é o wrapper: alguém expõe cada endpoint existente como uma tool e chama de servidor MCP. Só que o agente tem afordâncias diferentes das de um programa. Memória de computador é barata e abundante; contexto de LLM, não. Um programa percorre a lista de contatos um a um sem custo; um agente que recebe todos os contatos precisa lê-los token a token, gastando espaço finito com informação irrelevante. É procurar um nome na agenda lendo página por página, do começo. Com centenas de tools disponíveis vindas de servidores diferentes, o problema piora: ferramentas que se sobrepõem ou têm propósito vago fazem o agente escolher errado.

a ideia

Duas mudanças. A primeira é de projeto: construir poucas ferramentas pensadas para fluxos de alto impacto, cada uma correspondendo a uma subdivisão natural da tarefa — do jeito que um humano dividiria o trabalho com os mesmos recursos. No lugar de list_users, list_events e create_event, um schedule_event que acha a disponibilidade e agenda. No lugar de read_logs, um search_logs que devolve as linhas relevantes com contexto ao redor. Isso empurra computação de volta para dentro da chamada e tira do contexto tudo que era saída intermediária.

A segunda é de método: parar de discutir design de tool no achismo e medir. O post inteiro se apoia numa eval sobre workspace interno real, e o próprio texto admite que a maior parte dos conselhos saiu de rodar essa eval repetidamente com o Claude Code refatorando as ferramentas.

como funciona

O ciclo tem três etapas. Protótipo: subir as tools num servidor MCP local ou extensão de desktop (claude mcp add <nome> <comando>), ou passá-las direto na chamada de api, e usar você mesmo para achar as arestas.

Eval: gerar dezenas de tarefas ancoradas em dados e serviços reais, não em sandbox. Tarefa boa exige várias chamadas encadeadas — “o cliente 9182 diz que foi cobrado três vezes; ache os logs e veja se outros clientes foram afetados”. Tarefa fraca é customer_id=9182 no log de pagamentos. Cada prompt vem com um resultado verificável, por comparação de string ou com o Claude como juiz, evitando verificador estrito demais que reprova resposta certa por formatação. A execução é um while por tarefa, alternando chamada de api e chamada de tool, com o system prompt pedindo blocos de raciocínio e feedback antes das chamadas (ou interleaved thinking ligado). Além da acurácia, colete tempo por chamada, número de chamadas, tokens e erros: muita chamada redundante indica paginação mal dimensionada; muito erro de parâmetro indica descrição ruim.

Refino: concatenar os transcripts e jogar no Claude Code, que refatora muitas tools de uma vez mantendo implementação e descrição consistentes. Os princípios que saíram disso são concretos. Namespacing por serviço e recurso (asana_search, asana_projects_search) delimita fronteiras. A resposta devolve name e file_type, não uuid e mime_type. Um enum response_format com concise e detailed deixa o agente escolher a verbosidade — no exemplo do Slack, 206 tokens caem para 72, e a versão detalhada existe porque o thread_ts é necessário para buscar respostas de thread. Toda tool que possa estourar contexto ganha paginação, filtro e truncamento com defaults sensatos; o Claude Code corta resposta de tool em 25.000 tokens. Truncamento e erro viram texto instrutivo, com exemplo de input correto, no lugar de traceback. E parâmetro se chama user_id, nunca user.

o que isso custou

O custo real é a eval. Ela precisa espelhar workflows complexos com projetos, documentos e mensagens de verdade, e precisa de conjunto de teste separado para não sobreajustar — foi justamente o held-out set que mostrou ganho além das implementações escritas por pesquisadores. Quem não tem esse ambiente fica com heurística.

E boa parte das recomendações é condicional. O formato da resposta não tem vencedor: xml, json e markdown variam por tarefa e por agente, porque o modelo vai bem no que se parece com o treino dele. Prefixo versus sufixo no namespacing tem efeito não-trivial e depende do LLM. Consolidar ferramentas também tem preço: ferramenta demais distrai, mas ferramenta grossa demais esconde estratégias válidas, e a complexidade removida do contexto reaparece na implementação. O feedback do agente é fonte enviesada — LLM nem sempre diz o que quer dizer, e o que ele omite costuma importar mais. Os ganhos nas tools internas de Slack e Asana aparecem como gráficos; o texto não traz os números.

onde isso aparece hoje

O post é o manual de estilo por trás do próprio ecossistema MCP da Anthropic: as anotações de tool que sinalizam acesso open-world ou mudança destrutiva, o carregamento dinâmico das definições no system prompt, o limite de 25.000 tokens do Claude Code. O caso mais citado é o de descrição como prompt: o Sonnet 3.5 chegou ao estado da arte no SWE-bench Verified depois de refinamentos precisos nas descrições das ferramentas, sem tocar na implementação. O outro é o web search do Claude, que anexava “2025” à query por conta própria e enviesava os resultados até a descrição ser corrigida.

lido na íntegra por pipeline de llm, revisado por antonio leandro antes de publicar ·