Gymnasia: como declarar tools confiáveis para OpenAI, Anthropic e Google

Gymnasia: como declarar tools confiáveis para OpenAI, Anthropic e Google

Uma tool é um contratolink image

Quando um modelo decide usar uma ferramenta, ele não vê a função TypeScript que será executada. Recebe apenas três elementos: name, description e inputSchema. Esse bloco determina se ele escolhe a ferramenta certa e se constrói argumentos que o aplicativo pode aceitar.

name

O identificador estável devolvido pelo modelo e usado pelo executor para encontrar o handler.

description

Explica quando usar a tool, o que ela garante e quais passos anteriores exige. Faz parte do prompt do agente.

inputSchema

O JSON Schema que limita campos, tipos e argumentos obrigatórios antes de executar o código local.

O Gymnasia mantém as 13 definições em apps/mobile/agent/toolDefinitions.ts. Memória pessoal, medidas, dieta, exercícios, rotinas e pedidos de melhorias partem desse único array. Não existe uma cópia independente para cada provedor.

Esta é uma definição real do catálogo:

{
  name: "read_measurement",
  description:
    "Lee las medidas corporales del usuario para una fecha específica. " +
    "Devuelve el registro de medidas de ese día si existe. " +
    "Usa esta herramienta cuando el usuario pregunte por sus medidas de un día concreto.",
  inputSchema: {
    type: "object",
    properties: {
      date: stringProperty("Fecha en formato YYYY-MM-DD")
    },
    required: ["date"]
  }
}

Os nomes atuais são save_personal_data, list_personal_data_keys, read_field_description, read_field_value, read_measurement, write_measurement, read_meal_foods, search_foods, add_meal_food, search_exercises, read_routines, create_routine e create_feature_issue.

A descrição também é promptlink image

Uma descrição fraca como "Lê medidas" documenta a função para uma pessoa, mas deixa o modelo sem critério: não diz qual data usar, o que retorna nem quando a chamada é apropriada.

A versão real explica intenção, resultado e contexto. Ferramentas com dependências também impõem a ordem: add_meal_food informa que search_foods deve ser executada antes, enquanto create_routine exige nomes exatos obtidos por search_exercises. Essa informação influencia mais a precisão da escolha do que qualquer comentário interno, porque é o que o modelo realmente consegue ler.

Três provedores, uma definiçãolink image

OpenAI, Anthropic e Google expressam o mesmo contrato com invólucros diferentes. CHAT_TOOLS projeta o catálogo no momento de montar a requisição:

OpenAI

type: "function", com o schema em parameters.

Anthropic

Nome e descrição diretos, com o schema em input_schema.

Google

Declarações dentro de functionDeclarations, com o schema em parameters.

const CHAT_TOOLS = {
  openai: definitions.map(tool => ({
    type: "function", name: tool.name,
    description: tool.description, parameters: tool.inputSchema
  })),
  anthropic: definitions.map(tool => ({
    name: tool.name, description: tool.description,
    input_schema: tool.inputSchema
  })),
  google: [{ functionDeclarations: definitions.map(tool => ({
    name: tool.name, description: tool.description,
    parameters: tool.inputSchema
  })) }]
};

A sintaxe muda; o nome, a descrição e o schema não. Adicionar ou corrigir uma ferramenta no catálogo atualiza os três formatos.

Definição e execução locallink image

Declarar uma tool não significa implementá-la. apps/mobile/agent/toolExecutor.ts mantém o mapa AGENT_TOOL_HANDLERS: cada nome do catálogo deve ter exatamente um handler, e nenhum handler pode ficar órfão.

Os handlers leem ou alteram o estado local, o AsyncStorage e os repositórios JSON incluídos no aplicativo. Depois devolvem texto ao laço agentic para que o modelo continue. Não há banco de dados nem backend do Gymnasia entre a tool e os dados do usuário; o aplicativo móvel mantém o controle da execução.

Testes contra divergênciaslink image

O contrato é verificado em várias camadas. Os testes exigem nomes únicos e válidos, descrições significativas, schemas de objeto e campos required declarados em properties. O Ajv compila os 13 JSON Schemas para detectar construções inválidas.

const ajv = new Ajv({ allErrors: true, strict: true });

for (const definition of AGENT_TOOL_DEFINITIONS) {
  expect(() => ajv.compile(definition.inputSchema)).not.toThrow();
}

Outros testes comparam o conjunto completo de definições com os handlers e com as projeções dos três provedores. validateToolInput também recebe entradas arbitrárias por meio do fast-check: nunca deve lançar uma exceção e sempre deve produzir um resultado de validação estruturado.

O resultado é simples de manter: uma única fonte de verdade, três adaptadores mecânicos e testes que tornam qualquer divergência visível antes de chegar ao agente.

Voltar ao índice da série sobre o agente do Gymnasia.

Continuar lendo

Últimos posts -->

Você viu esses projetos?

Gymnasia

Gymnasia Gymnasia
Expo
React Native
TypeScript
OpenAI
Anthropic

App de fitness com dois agentes que são executados integralmente no dispositivo, sem backend, de forma que os dados do usuário nunca saem do celular. Um coach conversacional BYOK com adaptadores para OpenAI, Anthropic e Google, 12 tools locais e system prompt remoto com fallback offline, e um subagente de visão que estima macronutrientes a partir de fotos de comida, com leitura de códigos de barras contra o OpenFoodFacts.

LangGraph Deep Researcher

LangGraph Deep Researcher LangGraph Deep Researcher
Python
LangGraph
FastAPI
React
TypeScript
Docker

Sistema multiagente de pesquisa construído com LangGraph. Um supervisor decompõe sua pergunta em tópicos e lança subagentes de busca em paralelo; cada um comprime seus achados antes de repassá-los a um agente redator que escreve o relatório final em markdown com suas fontes. Streaming ao vivo por WebSockets, modelo configurável por papel e chaves de API próprias que nunca são armazenadas no servidor.

Tau

Tau Tau
Python
LangChain

Sistema multiagente de tutoria para estudantes do ensino médio, com um agente por disciplina e material de curso elaborado e validado por uma equipe de professores. Chegou a ser usado com alunos reais em um colégio privado na Espanha e em uma escola de ensino médio na Colômbia.

Ver todos os projetos -->
>_ Disponível para projetos

Tem um projeto com IA?

Vamos conversar.

maximofn@gmail.com

Especialista em Machine Learning e Inteligência Artificial. Desenvolvo soluções com IA generativa, agentes inteligentes e modelos personalizados.

Quer assistir alguma palestra?

Últimas palestras -->

Quer melhorar com essas dicas?

Últimos tips -->

Use isso localmente

Os espaços do Hugging Face nos permitem executar modelos com demos muito simples, mas e se a demo quebrar? Ou se o usuário a deletar? Por isso, criei contêineres docker com alguns espaços interessantes, para poder usá-los localmente, aconteça o que acontecer. Na verdade, se você clicar em qualquer botão de visualização de projeto, ele pode levá-lo a um espaço que não funciona.

Flow edit

Flow edit Flow edit

Edite imagens com este modelo de Flow. Baseado em SD3 ou FLUX, você pode editar qualquer imagem e gerar novas

FLUX.1-RealismLora

FLUX.1-RealismLora FLUX.1-RealismLora
Ver todos os contêineres -->
>_ Disponível para projetos

Tem um projeto com IA?

Vamos conversar.

maximofn@gmail.com

Especialista em Machine Learning e Inteligência Artificial. Desenvolvo soluções com IA generativa, agentes inteligentes e modelos personalizados.

Você quer treinar seu modelo com esses datasets?

short-jokes-dataset

HuggingFace

Dataset com piadas em inglês

Uso: Fine-tuning de modelos de geração de texto humorístico

231K linhas 2 colunas 45 MB
Ver no HuggingFace →

opus100

HuggingFace

Dataset com traduções de inglês para espanhol

Uso: Treinamento de modelos de tradução inglês-espanhol

1M linhas 2 colunas 210 MB
Ver no HuggingFace →

netflix_titles

HuggingFace

Dataset com filmes e séries da Netflix

Uso: Análise de catálogo Netflix e sistemas de recomendação

8.8K linhas 12 colunas 3.5 MB
Ver no HuggingFace →
Ver mais datasets -->