A maioria das bases de código de agentes contém um arquivo que ninguém gosta de manter. Ele possui quarenta definições de ferramentas, cada uma com um esquema JSON escrito à mão descrevendo um endpoint que já tem um esquema em outro lugar. A equipe da API lança um novo campo obrigatório, a especificação é atualizada, a documentação é atualizada, e o agente continua enviando a carga antiga até que alguém perceba os 400s.
Você já possui uma descrição legível por máquina de cada endpoint. É o documento OpenAPI. O trabalho é transformá-lo em definições de ferramentas que o modelo possa chamar, e manter os dois sincronizados automaticamente em vez de manualmente.
Este guia aborda como as operações OpenAPI se mapeiam para esquemas de ferramentas, o que o gerador precisa corrigir ao longo do caminho, como reduzir uma especificação de 200 endpoints para algo que um modelo possa entender, e como testar se as ferramentas geradas se comportam. Se você está em uma camada anterior da stack, nosso post sobre se você ainda precisa de uma ferramenta de API quando agentes escrevem o código define o contexto mais amplo.
Apidog é importante aqui porque a especificação precisa estar correta antes que qualquer coisa gerada a partir dela possa estar. Uma definição de ferramenta herda cada lacuna do documento de onde veio.
O custo das definições de ferramentas escritas à mão
Escrever ferramentas à mão parece bom com cinco endpoints. Deixa de ser bom em algum lugar por volta dos vinte, por três razões.
As definições se desviam. A especificação é gerada a partir do código ou mantida pela equipe da API. O arquivo da ferramenta é mantido por quem construiu o agente. Nada os conecta, então eles divergem silenciosamente, e o primeiro sintoma é um agente que "de repente" parou de funcionar.
As descrições ficam superficiais. Quando uma pessoa escreve quarenta esquemas à mão, os últimos vinte recebem descrições de uma linha. Os modelos escolhem as ferramentas lendo essas descrições, então o texto superficial degrada diretamente a seleção da ferramenta. Nosso post sobre o design de esquemas de ferramentas de API para agentes se aprofunda no porquê da formulação ter tanto peso.
Os erros são invisíveis até o tempo de execução. Um esquema escrito à mão que diz que um campo é uma string quando a API quer um inteiro produz um 422 na primeira vez que o agente tenta, em produção, em uma tarefa real.
Gerar a partir da especificação corrige os três de uma vez. Há uma única fonte de verdade, as descrições vêm do mesmo texto que sua documentação usa, e os tipos vêm do mesmo esquema que o servidor valida.
Como uma operação OpenAPI se torna uma ferramenta
O mapeamento é mais direto do que parece. Considere uma única operação:
paths:
/orders/{orderId}/refund:
post:
operationId: refundOrder
summary: Refund an order
description: >
Issues a full or partial refund against a completed order.
Refunds are irreversible. Partial refunds require an amount
no greater than the remaining refundable balance.
parameters:
- name: orderId
in: path
required: true
schema: { type: string }
description: The order to refund.
requestBody:
required: true
content:
application/json:
schema:
type: object
required: [reason]
properties:
amount:
type: integer
description: Amount in cents. Omit for a full refund.
reason:
type: string
enum: [duplicate, fraudulent, requested_by_customer]
A definição da ferramenta que resulta disso:
{
"name": "refundOrder",
"description": "Issues a full or partial refund against a completed order. Refunds are irreversible. Partial refunds require an amount no greater than the remaining refundable balance.",
"input_schema": {
"type": "object",
"required": ["orderId", "reason"],
"properties": {
"orderId": { "type": "string", "description": "The order to refund." },
"amount": { "type": "integer", "description": "Amount in cents. Omit for a full refund." },
"reason": { "type": "string", "enum": ["duplicate", "fraudulent", "requested_by_customer"] }
}
}
}
Quatro regras fazem a maior parte do trabalho:
operationIdse torna o nome da ferramenta. Se uma operação não tiveroperationId, gere um estável a partir do método mais o caminho, e então adicione-o à especificação.- Parâmetros de caminho, consulta e corpo se nivelam em um único objeto de propriedades. O modelo não se importa onde um valor trafega no fio. Seu executor se importa, então mantenha uma tabela lateral que registra qual parâmetro vai para onde.
summarymaisdescriptionse torna a descrição da ferramenta. Ambos, juntos. O resumo sozinho geralmente é muito conciso para guiar a seleção.- Arrays obrigatórios se mesclam. Um parâmetro de caminho obrigatório e um campo de corpo obrigatório ambos aparecem na mesma lista
required.
O executor é a outra metade, e é pequeno:
def execute(tool_name, args, spec_index, http):
op = spec_index[tool_name] # method, path template, param locations
path = op.path
query, body = {}, {}
for name, value in args.items():
location = op.locations[name] # "path" | "query" | "header" | "body"
if location == "path":
path = path.replace("{" + name + "}", str(value))
elif location == "query":
query[name] = value
elif location == "body":
body[name] = value
return http.request(op.method, path, params=query, json=body or None)
Essa é a ponte inteira. Tudo o mais é limpeza no caminho.
O que o gerador precisa corrigir
Um despejo ingênuo da especificação em esquemas de ferramentas produz ferramentas que os modelos lidam mal. Cinco ajustes importam.
Resolver ponteiros $ref. A maioria das APIs de chamada de ferramentas aceita um subconjunto de JSON Schema e não seguirá referências para uma seção components. Incorpore-os. Cuidado com esquemas recursivos, que a incorporação expandirá infinitamente; corte a recursão em uma profundidade fixa e descreva a estrutura mais profunda em prosa.
Remover palavras-chave não suportadas. oneOf, allOf, discriminator e nullable são comuns em especificações e mal suportados por esquemas de ferramentas. Colapse allOf mesclando propriedades. Para oneOf, escolha a variante dominante ou divida a operação em duas ferramentas, uma para cada formato. Essa segunda opção geralmente produz uma melhor seleção de ferramentas de qualquer maneira.
Aplanar aninhamento profundo. Um corpo com três níveis de profundidade é difícil para um modelo preencher corretamente. Se sua carga de criação de pedido aninha customer.address.postal_code, considere uma superfície de ferramenta mais plana e remonte a forma aninhada no executor.
Podar esquemas de resposta. As definições de ferramentas descrevem entradas. O esquema completo de resposta não pertence à definição, e incluí-lo desperdiça contexto. Como a resposta se parece importa quando o resultado retorna, e esse é um problema separado coberto em nosso post sobre manter as respostas da API dentro da janela de contexto do agente.
Levar as bandeiras de segurança. As operações de escrita devem ser marcadas para que seu executor possa roteá-las através de um portão de aprovação. Se sua especificação usa uma extensão como x-agent-requires-approval, leia-a e honre-a. Combine isso com os padrões em nosso guia de guardrails de agentes de IA.
Não dê ao modelo todos os 200 endpoints
O maior problema prático não é a conversão. É o volume. Uma API madura tem centenas de operações, e colar todas elas na lista de ferramentas produz duas falhas de uma vez: o contexto se enche de esquemas antes mesmo da tarefa começar, e a precisão da seleção cai porque o modelo está escolhendo entre opções quase idênticas.
Três maneiras de reduzir isso, aproximadamente na ordem de quão bem funcionam.
Filtrar por tag. As operações OpenAPI possuem tags, e as tags geralmente mapeiam para áreas de produto. Um agente que lida com reembolsos precisa das tags orders e payments, não admin ou analytics. Este é um filtro de uma linha e geralmente remove a maior parte da superfície.
Curar uma lista de permissões. Anote as operações que este agente tem permissão para chamar, por operationId, e gere apenas essas. Isso também serve como um controle de segurança, já que um agente que não tem uma ferramenta para um endpoint não pode chamá-lo acidentalmente. Nosso post sobre como impedir que agentes destruam sua API defende exatamente esse tipo de superfície estreita.
Recuperar ferramentas sob demanda. Para APIs muito grandes, indexe as operações e selecione algumas por turno com base na tarefa. Isso adiciona uma etapa de recuperação e seus próprios modos de falha, então use-o apenas depois que a filtragem e a curadoria deixarem de ser suficientes.
Há também a rota do protocolo. O padrão Model Context Protocol padroniza como um servidor expõe ferramentas a um cliente, e um servidor MCP apoiado pelo seu documento OpenAPI oferece um ponto de integração em vez de um por framework. Nosso explicador sobre o que é MCP aborda o modelo, e construir um servidor MCP com Apidog aborda a construção.

A especificação precisa estar correta primeiro
A geração move o problema de qualidade para cima. Uma descrição vaga em seu documento OpenAPI se torna uma descrição de ferramenta vaga, e o modelo escolhe o endpoint errado. Um campo opcional que o servidor realmente exige se torna uma ferramenta que o agente chama incorretamente na primeira tentativa.
Então, audite a especificação sob a ótica de um agente antes de gerar qualquer coisa:
- Cada operação tem um
operationId, e ele se parece com um verbo mais um substantivo. - Cada operação tem uma descrição que diz o que faz, o que altera e quando não deve ser usada. "Exclui um usuário" não é suficiente. "Exclui permanentemente um usuário e todas as suas sessões. Não pode ser desfeito. Use deactivateUser para desabilitar o acesso temporariamente." é.
- Cada parâmetro tem uma descrição com unidades e formato.
amounté ambíguo. "Valor em centavos, mínimo 50" não é. - Enums são declarados em vez de descritos em prosa, para que o modelo obtenha um conjunto fechado em vez de adivinhar.
- O campo "required" é preciso. As especificações tendem a marcar tudo como opcional, o que empurra as falhas de validação para o tempo de execução.
Esta é uma higiene de especificação comum, e ela compensa duas vezes, porque o mesmo texto impulsiona sua documentação publicada. No Apidog, a especificação, a documentação, o servidor de mock e os testes vêm de um único projeto, então ajustar uma descrição melhora todos eles de uma vez. Nosso guia sobre gerenciamento de versionamento de API no Apidog cobre a outra metade de manter as ferramentas geradas honestas ao longo do tempo.
Compartilhe o conjunto de ferramentas, não o copie
Um conjunto de ferramentas gerado é uma configuração, e a configuração que reside no checkout de um único desenvolvedor se desvia da mesma forma que os esquemas escritos à mão. A lista de filtros, a lista de permissões e a versão da especificação fixada devem ser artefatos compartilhados, versionados ao lado da especificação de onde vieram.
Algumas plataformas tornam isso a unidade padrão. No Sharkly, um Agente é uma configuração de trabalho salva, em vez de um prompt único: suas instruções, tempo de execução, habilidades, repositórios e configurações de execução viajam com ele e podem ser compartilhados em um Espaço, de modo que uma configuração de ferramenta funcional se torna algo que uma equipe reutiliza em vez de algo que cada pessoa reconstrói. O tempo de execução subjacente ainda é Claude Code, Codex, ou o que você já executa. O que muda é que a configuração ao redor deixa de ser local.

Testando ferramentas geradas
As ferramentas geradas falham de maneiras que as escritas à mão não falham, então teste tanto a geração quanto as chamadas.
Comece com uma verificação de ida e volta do esquema. Para cada ferramenta gerada, construa um exemplo válido a partir do esquema e envie-o. Qualquer coisa que retorne 400 ou 422 significa que o esquema da ferramenta e o servidor discordam, e a especificação é o que precisa ser corrigido.
Em seguida, teste a seleção. Escreva um pequeno conjunto de prompts de tarefa com uma ferramenta correta conhecida, execute-os e registre qual ferramenta o modelo escolheu. Esta é uma suíte de regressão barata que detecta o dia em que alguém renomeia uma operação ou encurta uma descrição. Como a saída não é determinística, afirme o nome da ferramenta em vez de argumentos exatos, seguindo as diretrizes do nosso guia sobre teste de agentes de IA não determinísticos.
Finalmente, execute o agente contra mocks antes de qualquer coisa real. Um servidor mock gerado a partir da mesma especificação oferece respostas realistas sem efeitos colaterais, e permite injetar os 500s e timeouts que sua lógica de retry deveria lidar.
Onde isso te deixa
A especificação é o contrato, e a lista de ferramentas deve ser uma projeção dela, não uma cópia paralela mantida manualmente. Gere as ferramentas, filtre-as rigorosamente, mantenha as descrições honestas e teste tanto as formas quanto a seleção.
Comece exportando seu documento OpenAPI e contando as operações que não têm descrição. Esse número é o quanto de trabalho está entre você e as ferramentas de agente em que você pode confiar. Baixe o Apidog se você quiser a especificação, mocks e testes em um só lugar enquanto você o corrige.
Perguntas frequentes
Posso gerar ferramentas a partir de um documento Swagger 2.0? Sim, mas converta-o para OpenAPI 3.x primeiro. O modelo de corpo do 2.0 difere o suficiente para que os geradores o tratem de forma inconsistente, e 3.x é o que as ferramentas atuais visam. O repositório da especificação OpenAPI documenta as diferenças.
Quantas ferramentas um modelo pode lidar de uma vez? A precisão começa a degradar bem antes do limite técnico, e o teto prático geralmente é algumas dezenas. Trate qualquer lista que ultrapasse isso como um sinal para filtrar por tag ou organizar uma lista de permissões, em vez de um limite a ser testado.
Os nomes das ferramentas devem corresponder exatamente ao operationId? Sim, quando o operationId é legível. Isso oferece uma pesquisa direta da chamada da ferramenta de volta à operação da especificação, o que torna o rastreamento e a depuração muito mais fáceis. Renomeie na especificação se o nome for ruim, não no gerador.
E as APIs GraphQL? A mesma ideia se aplica com uma fonte diferente: introspectar o esquema e gerar uma ferramenta por consulta ou mutação. O problema do volume é pior porque um esquema GraphQL expõe mais superfície, então a filtragem é ainda mais importante.
Ainda preciso escrever alguma ferramenta manualmente? Algumas. Ferramentas compostas que encadeiam várias chamadas em uma única ação, e ferramentas que encapsulam algo diferente de HTTP, ainda são escritas manualmente. O ponto é que os wrappers rotineiros de um único endpoint deixam de ser trabalho manual.
Como impeço o agente de chamar endpoints de escrita durante os testes? Gere um conjunto de ferramentas somente leitura para execuções de teste, filtrando por método HTTP, e aponte o agente para um mock para qualquer coisa que escreva. Nosso post sobre por que os agentes devem usar mocks, não produção aborda a configuração.
