La mayoría de las bases de código de agentes contienen un archivo que nadie disfruta mantener. Contiene cuarenta definiciones de herramientas, cada una un esquema JSON escrito a mano que describe un endpoint que ya tiene un esquema en otro lugar. El equipo de la API lanza un nuevo campo requerido, la especificación se actualiza, la documentación se actualiza, y el agente sigue enviando la carga útil antigua hasta que alguien nota los 400s.
Ya tienes una descripción legible por máquina de cada endpoint. Es el documento OpenAPI. La tarea es convertirlo en definiciones de herramientas que el modelo pueda llamar, y mantener los dos sincronizados automáticamente en lugar de hacerlo de memoria.
Esta guía cubre cómo las operaciones OpenAPI se mapean a esquemas de herramientas, qué tiene que corregir el generador en el camino, cómo reducir una especificación de 200 endpoints a algo que un modelo pueda entender, y cómo probar que las herramientas generadas se comportan correctamente. Si te encuentras en una etapa anterior de la pila, nuestra publicación sobre si aún necesitas una herramienta de API cuando los agentes escriben el código establece el contexto más amplio.
Apidog es importante aquí porque la especificación debe ser correcta antes de que cualquier cosa generada a partir de ella pueda serlo. Una definición de herramienta hereda cada deficiencia del documento del que proviene.
El costo de las definiciones de herramientas escritas a mano
Escribir herramientas a mano parece bien con cinco endpoints. Deja de serlo alrededor de veinte, por tres razones.
Las definiciones se desvían. La especificación se genera a partir del código o es mantenida por el equipo de la API. El archivo de herramientas es mantenido por quienquiera que haya construido el agente. Nada los conecta, por lo que divergen silenciosamente, y el primer síntoma es un agente que "de repente" dejó de funcionar.
Las descripciones se vuelven escasas. Cuando una persona escribe cuarenta esquemas a mano, los últimos veinte obtienen descripciones de una sola línea. Los modelos eligen herramientas leyendo esas descripciones, por lo que el texto escaso degrada directamente la selección de herramientas. Nuestra publicación sobre el diseño de esquemas de herramientas de API para agentes profundiza en por qué la redacción tiene tanto peso.
Los errores son invisibles hasta el tiempo de ejecución. Un esquema escrito a mano que dice que un campo es una cadena cuando la API espera un entero produce un 422 la primera vez que el agente lo intenta, en producción, en una tarea real.
Generar a partir de la especificación soluciona los tres problemas a la vez. Hay una única fuente de verdad, las descripciones provienen del mismo texto que utilizan tus documentos, y los tipos provienen del mismo esquema contra el que valida el servidor.
Cómo una operación OpenAPI se convierte en una herramienta
El mapeo es más directo de lo que parece. Considera una sola operación:
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]
La definición de herramienta que resulta de ello:
{
"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"] }
}
}
}
Cuatro reglas hacen la mayor parte del trabajo:
operationIdse convierte en el nombre de la herramienta. Si una operación no tiene unoperationId, genera uno estable a partir del método más la ruta, y luego añádelo a la especificación.- Los parámetros de ruta, consulta y cuerpo se aplanan en un objeto de propiedades. Al modelo no le importa dónde viaja un valor por el cable. A tu ejecutor sí, así que mantén una tabla auxiliar que registre qué parámetro va a dónde.
summarymásdescriptionse convierte en la descripción de la herramienta. Ambos, unidos. Solo el resumen suele ser demasiado conciso para guiar la selección.- Los arrays requeridos se fusionan. Un parámetro de ruta requerido y un campo de cuerpo requerido aterrizan en la misma lista
required.
El ejecutor es la otra mitad, y es pequeño:
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)
Ese es todo el puente. Todo lo demás es limpieza en el proceso.
Lo que el generador tiene que corregir
Una descarga ingenua de la especificación en esquemas de herramientas produce herramientas que los modelos manejan mal. Cinco ajustes son importantes.
Resolver punteros $ref. La mayoría de las APIs de llamada a herramientas aceptan un subconjunto de JSON Schema y no seguirán las referencias a una sección de components. Insértalos en línea. Atención a los esquemas recursivos, cuya inserción en línea se expandirá indefinidamente; corta la recursión a una profundidad fija y describe la estructura más profunda en prosa.
Eliminar palabras clave no soportadas. oneOf, allOf, discriminator, y nullable son comunes en las especificaciones y están poco soportadas por los esquemas de herramientas. Colapsa allOf fusionando propiedades. Para oneOf, elige la variante dominante o divide la operación en dos herramientas, una por forma. Esa segunda opción suele producir una mejor selección de herramientas de todos modos.
Aplanar anidamientos profundos. Un cuerpo con tres niveles de anidamiento es difícil de rellenar correctamente para un modelo. Si tu carga útil de creación de pedidos anida customer.address.postal_code, considera una superficie de herramienta más plana y vuelve a ensamblar la forma anidada en el ejecutor.
Podar esquemas de respuesta. Las definiciones de herramientas describen entradas. El esquema completo de respuesta no pertenece a la definición, e incluirlo desperdicia contexto. La apariencia de la respuesta importa cuando se recibe el resultado, y ese es un problema aparte cubierto en nuestra publicación sobre mantener las respuestas de la API dentro de la ventana de contexto del agente.
Llevar las banderas de seguridad. Las operaciones de escritura deben marcarse para que tu ejecutor pueda dirigirlas a través de una puerta de aprobación. Si tu especificación usa una extensión como x-agent-requires-approval, léela y respétala. Combina esto con los patrones de nuestra guía de barreras de seguridad para agentes de IA.
No le des al modelo los 200 endpoints
El mayor problema práctico no es la conversión. Es el volumen. Una API madura tiene cientos de operaciones, y pegar todas ellas en la lista de herramientas produce dos fallos a la vez: el contexto se llena de esquemas antes de que comience la tarea, y la precisión de selección disminuye porque el modelo está eligiendo entre opciones casi idénticas.
Tres formas de reducirlo, aproximadamente en orden de cuán bien funcionan.
Filtrar por etiqueta. Las operaciones OpenAPI llevan etiquetas, y las etiquetas suelen mapear a áreas de producto. Un agente que gestiona reembolsos necesita las etiquetas orders y payments, no admin o analytics. Este es un filtro de una línea y típicamente elimina la mayor parte de la superficie.
Crea una lista de permitidos. Escribe las operaciones que este agente tiene permitido llamar, por operationId, y genera solo esas. Esto funciona también como un control de seguridad, ya que un agente que no tiene una herramienta para un endpoint no puede llamarlo por accidente. Nuestra publicación sobre evitar que los agentes destruyan tu API aboga exactamente por este tipo de superficie estrecha.
Recuperar herramientas bajo demanda. Para APIs muy grandes, indexa las operaciones y selecciona unas pocas por turno basándose en la tarea. Esto añade un paso de recuperación y sus propios modos de fallo, así que recurre a ello solo después de que el filtrado y la curación dejen de ser suficientes.
También existe la ruta del protocolo. El Protocolo de Contexto de Modelo (MCP) estandariza cómo un servidor expone herramientas a un cliente, y un servidor MCP respaldado por tu documento OpenAPI te da un único punto de integración en lugar de uno por cada framework. Nuestra explicación sobre qué es MCP cubre el modelo, y construir un servidor MCP con Apidog cubre la construcción.

La especificación tiene que ser correcta primero
La generación traslada el problema de calidad río arriba. Una descripción vaga en tu documento OpenAPI se convierte en una descripción vaga de la herramienta, y el modelo elige el endpoint incorrecto. Un campo opcional que el servidor realmente requiere se convierte en una herramienta que el agente llama incorrectamente en el primer intento.
Así que audita la especificación a través de los ojos de un agente antes de generar cualquier cosa:
- Cada operación tiene un
operationId, y se lee como un verbo más un sustantivo. - Cada operación tiene una descripción que dice qué hace, qué cambia y cuándo no usarla. "Elimina un usuario" no es suficiente. "Elimina permanentemente un usuario y todas sus sesiones. No se puede deshacer. Usa
deactivateUserpara deshabilitar el acceso temporalmente." sí lo es. - Cada parámetro tiene una descripción con unidades y formato.
amountes ambiguo. "Cantidad en centavos, mínimo 50" no lo es. - Los enumeradores se declaran en lugar de describirse en prosa, para que el modelo obtenga un conjunto cerrado en lugar de adivinar.
Requiredes preciso. Las especificaciones tienden a marcar todo como opcional, lo que empuja los fallos de validación al tiempo de ejecución.
Esto es higiene ordinaria de la especificación, y vale la pena el doble, porque el mismo texto impulsa tus documentos publicados. En Apidog, la especificación, la documentación, el servidor mock y las pruebas provienen de un solo proyecto, por lo que ajustar una descripción los mejora a todos a la vez. Nuestra guía sobre la gestión de versiones de API en Apidog cubre la otra mitad para mantener las herramientas generadas honestas con el tiempo.
Comparte el conjunto de herramientas, no lo copies
Un conjunto de herramientas generado es configuración, y la configuración que reside en el entorno de un desarrollador se desvía de la misma manera que lo hacen los esquemas escritos a mano. La lista de filtros, la lista de permitidos y la versión de especificación fijada deben ser artefactos compartidos, versionados junto a la especificación de la que provienen.
Algunas plataformas hacen de esto la unidad predeterminada. En Sharkly, un Agente es una configuración de trabajo guardada en lugar de un prompt de una sola vez: sus instrucciones, Runtime, Habilidades, repositorios y configuraciones de ejecución viajan con él y pueden ser compartidos a través de un Espacio, por lo que una configuración de herramientas funcional se convierte en algo que un equipo reutiliza en lugar de algo que cada persona reconstruye. El tiempo de ejecución subyacente sigue siendo Claude Code, Codex, o lo que ya estés ejecutando. Lo que cambia es que la configuración a su alrededor deja de ser local.

Probando herramientas generadas
Las herramientas generadas fallan de maneras en que las escritas a mano no lo hacen, así que prueba tanto la generación como las llamadas.
Comienza con una verificación de ida y vuelta del esquema. Para cada herramienta generada, construye un ejemplo válido a partir del esquema y envíalo. Cualquier cosa que devuelva 400 o 422 significa que el esquema de la herramienta y el servidor no concuerdan, y la especificación es lo que hay que arreglar.
Luego, prueba la selección. Escribe un pequeño conjunto de prompts de tareas con una herramienta correcta conocida, ejecútalos y registra qué herramienta eligió el modelo. Esta es una suite de regresión económica que detecta el día en que alguien renombra una operación o acorta una descripción. Dado que la salida no es determinística, verifica el nombre de la herramienta en lugar de los argumentos exactos, siguiendo las líneas de nuestra guía para probar agentes no determinísticos.
Finalmente, ejecuta el agente contra mocks antes de cualquier cosa en vivo. Un servidor mock generado a partir de la misma especificación te proporciona respuestas realistas sin efectos secundarios, y te permite inyectar los 500s y los tiempos de espera que tu lógica de reintentos debe manejar.
Dónde te deja esto
La especificación es el contrato, y la lista de herramientas debe ser una proyección de ella, no una copia paralela mantenida a mano. Genera las herramientas, fíltralas rigurosamente, mantén las descripciones honestas y prueba tanto las formas como la selección.
Comienza exportando tu documento OpenAPI y contando las operaciones que no tienen descripción. Ese número es la cantidad de trabajo que hay entre tú y las herramientas de agente en las que puedes confiar. Descarga Apidog si quieres la especificación, los mocks y las pruebas en un solo lugar mientras lo arreglas.
Preguntas frecuentes
¿Puedo generar herramientas a partir de un documento Swagger 2.0? Sí, pero conviértelo primero a OpenAPI 3.x. El modelo de cuerpo 2.0 difiere lo suficiente como para que los generadores lo manejen de manera inconsistente, y 3.x es lo que la tooling actual apunta. El repositorio de especificaciones OpenAPI documenta las diferencias.
¿Cuántas herramientas puede manejar un modelo a la vez? La precisión comienza a degradarse mucho antes del límite técnico, y el techo práctico suele ser de unas pocas docenas. Trata cualquier lista que exceda eso como una señal para filtrar por etiqueta o seleccionar una lista de permitidos, en lugar de como un límite a probar.
¿Los nombres de las herramientas deben coincidir exactamente con operationId? Sí, cuando el operationId es legible. Te proporciona una búsqueda directa desde la llamada de la herramienta de vuelta a la operación de la especificación, lo que facilita mucho el rastreo y la depuración. Renombra en la especificación si el nombre es incorrecto, no en el generador.
¿Qué hay de las APIs de GraphQL? La misma idea se aplica con una fuente diferente: introspecciona el esquema y genera una herramienta por consulta o mutación. El problema del volumen es peor porque un esquema de GraphQL expone más superficie, por lo que el filtrado es aún más importante.
¿Todavía necesito escribir herramientas a mano? Algunas. Las herramientas compuestas que encadenan varias llamadas en una sola acción, y las herramientas que envuelven algo distinto de HTTP, todavía se escriben manualmente. El punto es que los wrappers de un solo endpoint rutinarios dejan de ser un trabajo manual.
¿Cómo evito que el agente llame a endpoints de escritura durante las pruebas? Genera un conjunto de herramientas de solo lectura para las ejecuciones de prueba filtrando por método HTTP, y dirige al agente a un mock para cualquier cosa que escriba. Nuestra publicación sobre por qué los agentes deben usar mocks, no producción cubre la configuración.
