Os LLMs não acessam o seu código – eles entregam uma requisição, e você executa a função. Esse fato simples derruba o mito de que "o modelo chama magicamente minha rotina Python" e força os desenvolvedores a repensarem a depuração e a segurança.
O loop de despacho, passo a passo
Quando um modelo de linguagem (LLM) precisa de uma ferramenta, ele segue uma sequência determinística:
- Planejamento – o modelo decide que uma ação é necessária (ex: "reembolsar um pagamento").
- Geração de uma requisição – ele gera um texto estruturado — geralmente JSON — que nomeia a ferramenta e fornece os argumentos.
- Parsing – seu app ou um framework de suporte lê esse texto.
- Correspondência (Matching) – o framework procura o nome no registro das funções reais que você expôs.
- Validação – ele verifica se os argumentos correspondem ao schema da função e se o chamador está autorizado.
- Execução – a função correspondente é executada no seu ambiente, realizando o trabalho.
- Retorno – o resultado é empacotado e enviado de volta ao modelo para raciocínio adicional.
Pense no LLM como um planejador, no framework como um despachante e na função como o trabalhador que realmente move dados ou dinheiro.
Por que o mito da "mágica" persiste
A maioria dos desenvolvedores vê uma única linha de saída do modelo que se parece com uma chamada de função e assume que o modelo realizou a operação por conta própria. O termo "tool calling" nas documentações dos provedores soa como se o modelo estivesse invocando o código diretamente.
Na realidade, o modelo apenas produz texto que descreve uma chamada. O seu processo faz o trabalho pesado — busca, verificação de tipos, aplicação de permissões e tratamento de erros.
Frameworks que escondem os detalhes internos
Bibliotecas como PydanticAI e LangChain abstraem o loop para que você possa focar na lógica de negócio. Elas automaticamente:
- Validam argumentos contra um schema (ex: um modelo Pydantic).
- Aplicam permissões, garantindo que o usuário possa acionar a ferramenta.
- Tentam novamente em caso de falha, voltando ao modelo quando uma ferramenta retorna um erro.
- Protegem contra loops descontrolados, limitando o número de chamadas consecutivas de ferramentas.
- Mantêm o estado da conversa, integrando os resultados das ferramentas ao diálogo.
Mesmo com esses auxiliares, o padrão permanece o mesmo: o modelo nunca executa código.
Suporte nativo a tool-calling dos provedores
Alguns provedores oferecem uma interface de "tool-calling" nativa que padroniza as definições de ferramentas e os formatos de requisição. Isso facilita a integração, mas não remove a etapa de despacho. Você ainda escreve (ou importa) o código que realmente executa a operação solicitada.
A depuração torna-se mais fácil quando você renomeia o problema
Em vez de culpar um "agente confuso", diga que o problema é que "a resposta do modelo não continha chamadas de ferramenta". A distinção é importante:
- Sem chamada de ferramenta (No tool call) – o modelo respondeu diretamente ou falhou ao gerar uma requisição formatada corretamente.
- Requisição malformada – o JSON está sintaticamente incorreto ou faltam campos obrigatórios, fazendo com que o despachante o rejeite.
- Falha de validação – os argumentos não correspondem ao schema, disparando um erro antes da execução.
Categorizar as falhas permite registrar cada etapa do loop e identificar exatamente onde as coisas saíram do trilho.
Dicas práticas para um pipeline confiável
- Trate a saída do modelo como uma entrada não confiável. Passe cada requisição por uma validação determinística antes de invocar qualquer código com efeitos colaterais.
- Registre a requisição bruta (raw request) e o resultado de cada etapa de validação. Isso cria um rastro reproduzível quando algo der errado.
- Defina limites explícitos para chamadas de ferramentas consecutivas; um loop descontrolado pode esgotar recursos ou atingir limites de taxa (rate limits).
- Envolva cada função em um bloco try/except que retorne um objeto de erro estruturado que o modelo possa entender, incentivando uma nova tentativa ou um fallback gracioso.
- Separe as verificações de permissão da lógica de negócio. Verifique os direitos do chamador antes da execução da função, especialmente para ações privilegiadas como "deletar usuário".
- Use definições baseadas em schema (ex: modelos Pydantic) para que o framework possa gerar automaticamente o schema JSON que o modelo deve seguir.
O que observar a seguir
À medida que os provedores refinam as APIs de tool-calling nativas, espere contratos mais rígidos em torno dos formatos de requisição e códigos de erro mais detalhados. Essas mudanças facilitarão a validação e permitirão que os desenvolvedores construam barreiras de segurança mais rigorosas. Fique de olho nas atualizações das bibliotecas — muitas estão adicionando suporte nativo para os novos recursos dos provedores.
Conclusão
O LLM é um gerador de texto sofisticado, não um executor. Seu código permanece como a única autoridade que realiza ações, e o dispatcher que você constrói (ou importa) é o guardião que valida, autoriza e executa essas ações. Reformular o fluxo de trabalho elimina o mito da “mágica”, torna a depuração mais precisa e impõe a disciplina de segurança que todo sistema de produção exige.
