Phase 13 - Lesson 01

A Interface de Ferramentas — Por que os Agentes Precisam de E/S Estruturada

This lesson includes a graded coding exercise that runs in your browser, unlocked with lifetime access.

Um modelo de linguagem produz tokens. Um programa executa ações. A lacuna entre os dois é a interface de ferramentas: um contrato que permite ao modelo solicitar uma ação e ao host executá-la. Toda stack de 2026 — chamadas de função na OpenAI, Anthropic e Gemini; tools/call do MCP; partes de tarefas do A2A — é uma codificação diferente do mesmo loop de quatro etapas. Esta lição nomeia o loop e mostra a infraestrutura mínima para executá-lo.

Tipo: Aprender Linguagens: Python (stdlib, sem LLM) Pré-requisitos: Fase 11 (APIs de completamento de LLM) Tempo: ~45 minutos

Objetivos de Aprendizado

  • Explicar por que um LLM que só consegue gerar texto não pode, por si só, realizar ações no mundo real.
  • Desenhar o loop de chamada de ferramenta de quatro etapas (descrever → decidir → executar → observar) e nomear quem é o responsável por cada etapa.
  • Escrever uma descrição de ferramenta composta por três partes: nome, entrada JSON Schema e uma função executora determinística.
  • Distinguir entre ferramentas puras e de efeito colateral e explicar por que essa divisão é importante para a segurança.

O Problema

Um LLM emite uma distribuição de probabilidade sobre o próximo token. Essa é toda a sua superfície de saída. Se você perguntar a um modelo de chat "como está o clima em Bengaluru agora", ele pode escrever uma frase plausível, mas não pode se conectar a uma API de clima. A frase pode estar certa por coincidência ou estar desatualizada por três dias.

Fechar essa lacuna é o propósito da interface de ferramentas. O programa host — o runtime do seu agente, Claude Desktop, ChatGPT, Cursor ou um script personalizado — anuncia uma lista de ferramentas chamáveis para o modelo. O modelo, quando decide que uma ação é necessária, emite um payload estruturado nomeando uma ferramenta e seus argumentos. O host analisa esse payload, executa a ferramenta de verdade e envia o resultado de volta. O loop continua até que o modelo decida que não são necessárias mais chamadas.

A primeira versão desse contrato foi lançada em junho de 2023 como o parâmetro "functions" da OpenAI. A Anthropic seguiu com blocos de tool_use no Claude 2.1. O Gemini adicionou functionDeclarations alguns meses depois. Cada provedor agora expõe o mesmo formato: uma lista de ferramentas tipada com JSON-Schema na entrada, e uma chamada de ferramenta em payload JSON na saída. O Model Context Protocol (novembro de 2024) generalizou o contrato para que um único registro de ferramentas atenda a todos os modelos. O A2A (abril de 2026, v1.0) aplicou a mesma primitiva para delegação de agente para agente.

O loop de quatro etapas é a invariante por trás de tudo isso. Todo o resto na Fase 13 é um detalhamento.

O Conceito

Passo um: descrever

O host declara cada ferramenta com três campos.

  • Nome. Um identificador estável legível por máquina. get_weather, e não "weather thing".
  • Descrição. Um resumo em linguagem natural de um parágrafo. "Use quando o usuário perguntar sobre as condições atuais para uma cidade específica. Não use para dados históricos."
  • Schema de entrada. Um objeto JSON Schema (draft 2020-12) descrevendo os argumentos da ferramenta.

O modelo recebe a lista. Os provedores modernos serializam essas declarações no prompt do sistema usando um template específico do provedor, de modo que você, como desenvolvedor, lida apenas com a forma estruturada.

Passo dois: decidir

Com base na mensagem do usuário e nas ferramentas disponíveis, o modelo escolhe um de três comportamentos.

  1. Responder diretamente em texto. Sem chamada de ferramenta.
  2. Chamar uma ou mais ferramentas. Emitir objetos de chamada estruturados. Sob parallel_tool_calls: true (padrão na OpenAI e Gemini, opt-in na Anthropic), o modelo pode emitir múltiplas chamadas em um único turno.
  3. Recusar. Saídas estruturadas em modo estrito podem produzir um bloco refusal tipado em vez de uma chamada.

O payload de uma chamada de ferramenta possui três campos estáveis: um id da chamada, um name da ferramenta e um objeto JSON arguments. O id existe para que o host possa correlacionar o resultado posterior com a chamada específica, o que é importante quando as chamadas paralelas retornam fora de ordem.

Passo três: executar

O host recebe a chamada, valida os argumentos em relação ao schema declarado e executa o executor. Argumentos inválidos significam que o modelo alucinou um campo ou usou o tipo errado — um modo de falha muito comum em modelos mais fracos. Os hosts de produção fazem uma de três coisas em caso de argumentos inválidos: falham rapidamente e expõem o erro ao modelo, corrigem o JSON com um parser restrito ou tentam novamente com o modelo incluindo o erro de validação no prompt.

O executor em si é um código comum. Python, TypeScript, um comando de shell, uma consulta de banco de dados. Ele produz um resultado, que geralmente é uma string, mas pode ser qualquer valor JSON ou um bloco de conteúdo estruturado (texto, imagem ou referência de recurso no MCP). O resultado deve ser serializável.

Passo quatro: observar

O host anexa o resultado da ferramenta à conversa (como uma mensagem com a função tool e o id correspondente) e chama o modelo novamente. O modelo agora tem a saída da ferramenta no contexto e pode produzir uma resposta final ou solicitar mais chamadas. Isso continua até que o modelo pare de emitir chamadas ou o host atinja um limite de segurança no número de iterações.

A divisão de confiança

As ferramentas vêm em dois tipos importantes para a segurança.

  • Pura. Somente leitura, determinística, sem efeitos colaterais. get_weather, search_docs, get_current_time. Segura para chamar especulativamente.
  • De efeito colateral (Consequencial). Altera o estado, gasta dinheiro, toca em dados do usuário. send_email, delete_file, execute_trade. Deve ser controlada.

A "Regra de Dois" de 2026 da Meta para segurança de agentes diz que um único turno pode combinar no máximo dois de: entrada não confiável, dados confidenciais, ação de efeito colateral. A interface de ferramentas é onde você impõe essa regra — rejeitando chamadas, exigindo confirmação do usuário ou escalando escopos. Consulte a Fase 13 · 15 para o capítulo completo sobre segurança e a Fase 14 · 09 para políticas de permissão em nível de agente.

Onde o loop vive

Contexto Quem descreve Quem decide Quem executa
Chamada de função de turno único (OpenAI/Anthropic/Gemini) Desenvolvedor do app LLM Desenvolvedor do app
MCP Servidor MCP LLM via cliente MCP Servidor MCP
A2A Publicador do Agent Card Agente chamador Agente chamado
Navegador web (agente de chamada de função) Extensão do navegador / WebMCP LLM Runtime do navegador

Por que não apenas pedir ao modelo para emitir JSON?

"Pedir ao modelo para responder em JSON" era o padrão antes das chamadas de função. Ele falha de ~5 a 15 por cento das vezes em modelos de fronteira, e muito mais em modelos menores. Os modos de falha incluem chaves ausentes, vírgulas flutuantes, campos alucinados e tipos incorretos. Você então precisa de uma etapa de reparo do JSON, uma nova tentativa ou um decodificador com restrições.

A chamada de função nativa é melhor por três motivos. Primeiro, o provedor treina o modelo de ponta a ponta no formato exato da chamada, fazendo com que a taxa de JSON válido suba para 98 a 99 por cento no modo estrito. Segundo, o payload da chamada fica em seu próprio slot de protocolo, não dentro do texto livre — portanto, uma chamada de ferramenta nunca vaza para a resposta visível ao usuário. Terceiro, os provedores impõem a conformidade com o schema usando decodificação restrita (modo estrito da OpenAI, tool_use da Anthropic, responseSchema do Gemini). A validação da saída é garantida.

A Fase 13 · 02 analisa as três APIs de provedores lado a lado. A Fase 13 · 04 se aprofunda em saídas estruturadas.

Disjuntores (Circuit Breakers)

O loop termina quando o modelo para de emitir chamadas ou o host atinge uma contagem máxima de turnos. Os hosts de produção definem isso entre 5 e 20 turnos. Além disso, é quase certo que você esteja em um loop do qual o modelo não consegue sair. O Claude Code usa 20 por padrão; os OpenAI Assistants usam 10; o modo agente do Cursor usa 25.

A alternativa — loops infinitos — aparece a cada seis meses como relatos de "o agente gastou US$ 400 em chamadas de API durante a noite". Não envie para produção sem um limite.

A Fase 14 · 12 cobre recuperação de erros e autocorreção em detalhes; a Fase 17 cobre limites de taxa em produção.

Para onde a Fase 13 vai a partir daqui

  • As Lições 02 a 05 refinam a interface de chamada de ferramentas no nível do provedor.
  • As Lições 06 a 14 generalizam o loop no MCP.
  • As Lições 15 a 18 defendem o loop contra servidores hostis, usuários adversários e superfícies de autenticação remota não autenticadas.
  • As Lições 19 a 22 estendem o padrão para colaboração agente a agente, observabilidade, roteamento e empacotamento.
  • A Lição 23 lança um ecossistema completo usando cada primitiva.

Cada lição restante é um detalhamento deste loop de quatro etapas. Guarde-o na mente como a invariante.

Use It

code/main.py roda o loop de quatro etapas sem um LLM. Uma função decodificadora falsa ("fake decider") simula o modelo por meio de correspondência de padrões (pattern-matching) na mensagem do usuário; o executor, o validador de schema e o harness da etapa de observação são reais. Execute-o para ver toda a coreografia de requisição/resposta com estados intermediários imprimíveis, e depois substitua o decodificador falso por qualquer provedor real em uma lição posterior.

O que observar:

  • O registro de ferramentas (tool registry) guarda três campos por ferramenta: nome, descrição, schema e uma referência do executor.
  • O validador é um subconjunto mínimo de JSON Schema (tipos, campos obrigatórios, enum, min/max) escrito apenas em stdlib. A lição Fase 13 · 04 traz uma implementação mais completa.
  • O loop limita a contagem de iterações em cinco. Agentes de produção precisam exatamente desse tipo de disjuntor (circuit breaker).

Ship It

Esta lição produz outputs/skill-tool-interface-reviewer.md. Dada uma definição provisória de ferramenta (nome + descrição + schema + esboço do executor), a habilidade (skill) a audita quanto à adequação ao loop: se o nome é estável por máquina, se a descrição é um resumo completo de uso, se o schema usa o JSON Schema 2020-12 corretamente e se a classificação pura-vs-consequencial é explícita.

Exercícios

  1. Adicione uma quarta ferramenta ao code/main.py chamada get_stock_price(ticker). Escreva sua descrição como "Use quando o usuário solicitar o preço atual de uma ação pelo ticker. Não use para preços históricos ou resumos de mercado." Execute o harness e confirme se o decodificador falso roteia as consultas que mencionam tickers para a nova ferramenta.

  2. Quebre o validador de schema. Passe uma chamada cujo objeto arguments não contenha um campo obrigatório e confirme se o host a rejeita antes da execução. Em seguida, passe uma chamada com um campo extra desconhecido. Decida: o host deve rejeitar ou ignorar? Justifique sua escolha com um argumento de segurança.

  3. Classify each tool in the harness as pure or consequential. Add a consequential: true flag to the registry entries that need it, and change the loop to print a "would confirm with user" line whenever a consequential tool is chosen. This is the shape of the confirmation gate every production host needs. (Wait! Did I translate this above? Yes, let me double check. Yes: "Classifique cada ferramenta no harness como pura ou de efeito colateral (consequencial). Adicione uma flag consequential: true às entradas do registro que precisarem dela e altere o loop para imprimir uma linha "confirmaria com o usuário" sempre que uma ferramenta consequencial for escolhida. Esse é o formato da barreira de confirmação que todo host de produção precisa." Wait, let's keep it translated to Portuguese in the final markdown!) Let's correct that:

  4. Classifique cada ferramenta no harness como pura ou de efeito colateral (consequencial). Adicione uma flag consequential: true às entradas do registro que precisarem dela e altere o loop para imprimir uma linha "confirmaria com o usuário" sempre que uma ferramenta consequencial for escolhida. Esse é o formato da barreira de confirmação que todo host de produção precisa.

  5. Desenhe o loop de quatro etapas no papel com a tabela de colunas de provedores preenchida para o seu cliente favorito (Claude Desktop, Cursor, ChatGPT ou uma stack personalizada). Faça uma referência cruzada com a variante específica do MCP na Fase 13 · 06.

  6. Leia o guia de chamadas de função da OpenAI de ponta a ponta. Identifique o único campo que faz parte da requisição, mas não está no loop de quatro etapas apresentado aqui. Explique o que ele adiciona e por que ele é conveniente, em vez de essencial.

Termos-Chave

Termo O que dizem O que realmente significa
Ferramenta (Tool) "Algo que o modelo pode chamar" Uma tupla contendo nome + entrada tipada por JSON-Schema + função executora
Chamada de função (Function calling) "Uso nativo de ferramentas" Suporte de API a nível de provedor para emitir chamadas estruturadas de ferramentas em vez de prosa
Chamada de ferramenta (Tool call) "A solicitação de ação do modelo" Um payload JSON com id, name, arguments emitido pelo modelo
Resultado de ferramenta (Tool result) "O que a ferramenta retornou" A saída do executor, envelopada em uma mensagem de papel tool com o id correspondente
Chamadas paralelas de ferramentas "Várias chamadas de uma vez" Múltiplos objetos de chamada em um único turno do modelo, independentes e ordenáveis por id
Modo estrito (Strict mode) "JSON garantido" Decodificação restrita que força a saída do modelo a se validar contra o schema declarado
Ferramenta pura (Pure tool) "Ferramenta somente leitura" Sem efeitos colaterais; segura para reexecução
Ferramenta de efeito colateral (Consequential tool) "Ferramenta de ação" Altera o estado externo; exige uma barreira de confirmação, auditoria ou consentimento do usuário
Loop de quatro etapas "O ciclo de chamada de ferramenta" descrever → decidir → executar → observar
Host "Runtime do agente" O programa que mantém o registro de ferramentas, chama o modelo e executa o executor

Leitura Adicional

0 lifetime access. Curriculum based on AI Engineering from Scratch by Rohit Ghumare (MIT, used under attribution).