DEV Community

Cover image for OpenAPI a Herramientas de Agentes de IA: Sin Wrappers Escritos a Mano
Roobia
Roobia

Posted on Originally published at apidog.com

OpenAPI a Herramientas de Agentes de IA: Sin Wrappers Escritos a Mano

Genera herramientas de agentes desde OpenAPI y evita esquemas manuales

Las definiciones de herramientas escritas a mano se desvían: la API cambia, la especificación se actualiza y el agente sigue enviando cargas antiguas hasta que aparecen errores 400. Usa tu documento OpenAPI como fuente única de verdad para generar herramientas, mantenerlas sincronizadas y validar sus tipos antes de producción.

Prueba Apidog hoy

Generación de herramientas de agentes desde OpenAPI

La conversión solo será fiable si la especificación también lo es. Herramientas, documentación, mocks y pruebas deben partir del mismo contrato, como ocurre en Apidog.

Por qué dejar de escribir herramientas a mano

Con cinco endpoints, mantener esquemas manuales parece aceptable. Con veinte o más, aparecen tres problemas:

  • Deriva: el equipo de API mantiene OpenAPI; otra persona mantiene las herramientas. Sin automatización, divergen.
  • Descripciones insuficientes: el modelo selecciona herramientas a partir de sus descripciones. Un texto pobre reduce la precisión. Consulta esta guía sobre diseño de esquemas de herramientas para agentes.
  • Errores tardíos: declarar string donde la API espera integer produce un 422 cuando el agente intenta ejecutar una tarea real.

Generar las herramientas desde OpenAPI elimina la duplicación: tipos, campos requeridos y descripciones provienen del mismo contrato que valida el servidor.

Mapea una operación OpenAPI a una herramienta

Considera esta 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]
Enter fullscreen mode Exit fullscreen mode

La herramienta resultante puede ser:

{
  "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"] }
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Aplica estas reglas:

  1. Convierte operationId en el nombre de la herramienta. Si falta, genera uno estable con método y ruta, y añádelo después a la especificación.
  2. Aplana parámetros de ruta, consulta y cuerpo en properties. El ejecutor conserva la ubicación real de cada campo.
  3. Une summary y description para crear una descripción útil para el modelo.
  4. Fusiona todos los campos obligatorios en un único array required.

El ejecutor solo necesita reconstruir la petición HTTP:

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)
Enter fullscreen mode Exit fullscreen mode

Corrige la especificación antes de generar

Una exportación directa rara vez produce herramientas que un modelo use bien. Añade estas normalizaciones al generador:

  • Resuelve $ref: inserta referencias de components en línea. Para esquemas recursivos, limita la profundidad y describe el resto en texto.
  • Elimina o transforma palabras clave no soportadas: fusiona allOf; para oneOf, usa la variante dominante o crea herramientas separadas. Revisa también discriminator y nullable.
  • Reduce anidamientos profundos: si la entrada contiene customer.address.postal_code, expón una interfaz más plana y reconstruye el objeto en el ejecutor.
  • No incluyas respuestas en la definición: las herramientas describen entradas. Gestiona las salidas por separado; consulta cómo mantener respuestas de API dentro de la ventana de contexto.
  • Propaga controles de seguridad: marca las operaciones de escritura, por ejemplo mediante x-agent-requires-approval, y envíalas a una puerta de aprobación. Combínalo con estas barreras de seguridad para agentes de IA.

No entregues 200 endpoints al modelo

Una lista masiva llena el contexto y reduce la precisión entre herramientas similares. Limita la superficie con este orden de preferencia:

  1. Filtra por etiquetas. Un agente de reembolsos necesita orders y payments, no admin ni analytics.
  2. Usa una lista de permitidos. Genera únicamente los operationId autorizados. Además de simplificar la selección, evita llamadas accidentales a endpoints fuera de alcance. Este enfoque coincide con la recomendación de evitar que los agentes destruyan tu API.
  3. Recupera herramientas bajo demanda. Para APIs muy grandes, indexa operaciones y selecciona unas pocas según la tarea. Úsalo cuando el filtrado y la curación ya no basten.

También puedes exponer las herramientas mediante el Protocolo de Contexto de Modelo (MCP). Un servidor MCP respaldado por OpenAPI crea un único punto de integración. Consulta qué es MCP y cómo construir un servidor MCP con Apidog.

Audita OpenAPI desde la perspectiva del agente

Antes de generar, verifica lo siguiente:

  • Cada operación tiene un operationId legible: verbo + sustantivo.
  • Cada descripción explica qué hace, qué cambia y cuándo no debe usarse.
  • Cada parámetro indica formato y unidades: amount debe ser “Cantidad en centavos, mínimo 50”.
  • Los valores cerrados se expresan con enum, no solo en prosa.
  • required coincide exactamente con lo que exige el servidor.

Una descripción como “Elimina un usuario” es ambigua. Prefiere: “Elimina permanentemente un usuario y todas sus sesiones. No se puede deshacer. Usa deactivateUser para deshabilitar el acceso temporalmente”.

Esta higiene mejora a la vez documentación, mocks, pruebas y herramientas. Para mantener el contrato consistente entre versiones, revisa la guía de gestión de versiones de API en Apidog.

Versiona la configuración de herramientas

El filtro por etiquetas, la lista de permitidos y la versión fijada de OpenAPI deben vivir en el repositorio junto a la especificación. Una configuración local también se desvía.

Plataformas como Sharkly permiten guardar agentes como configuraciones reutilizables: instrucciones, runtime, habilidades, repositorios y parámetros de ejecución se comparten dentro de un espacio. El runtime puede seguir siendo Claude Code, Codex u otro sistema; lo importante es que la configuración deja de depender de cada entorno local.

Validación y pruebas de herramientas generadas

Prueba generación y ejecución

Valida las herramientas en tres capas:

  1. Prueba de ida y vuelta del esquema. Genera un ejemplo válido para cada herramienta y envíalo al servidor. Un 400 o 422 indica que el esquema de herramienta y la API no coinciden.
  2. Prueba de selección. Crea prompts con una herramienta correcta conocida, ejecuta el agente y registra el nombre de la herramienta elegida. No verifiques argumentos exactos: la salida puede variar. Esta estrategia sigue las prácticas para probar agentes no determinísticos.
  3. Prueba contra mocks. Ejecuta primero contra un servidor mock generado desde la misma especificación. Así puedes probar reintentos, errores 500 y timeouts sin efectos secundarios.

Conclusión

La lista de herramientas debe ser una proyección del contrato OpenAPI, no una copia manual. Genera las herramientas, limita su superficie, conserva descripciones precisas y prueba tanto la forma de las peticiones como la selección del modelo.

Empieza exportando tu OpenAPI y contando operaciones sin descripción: ese número representa la distancia entre tu API actual y unas herramientas de agente fiables. Descarga Apidog si quieres gestionar especificación, documentación, mocks y pruebas desde un mismo proyecto.

Preguntas frecuentes

¿Puedo generar herramientas desde Swagger 2.0?

Sí, pero conviértelo primero a OpenAPI 3.x. El modelo de cuerpo de Swagger 2.0 difiere lo suficiente como para que los generadores lo traten de forma inconsistente. Consulta las diferencias en el repositorio de especificaciones OpenAPI.

¿Cuántas herramientas puede manejar un modelo?

La precisión suele degradarse antes del límite técnico. Trata una lista de más de unas pocas docenas como una señal para filtrar por etiqueta, crear una lista de permitidos o recuperar herramientas bajo demanda.

¿Los nombres de herramientas deben coincidir con operationId?

Sí, cuando operationId es legible. Facilita rastrear una llamada desde el agente hasta su operación OpenAPI. Si el nombre es malo, corrígelo en la especificación, no en el generador.

¿Qué ocurre con GraphQL?

La misma idea se aplica: introspecciona el esquema y genera una herramienta por consulta o mutación. Como GraphQL suele exponer más superficie, el filtrado es todavía más importante.

¿Aún debo escribir algunas herramientas a mano?

Sí. Las herramientas compuestas que encadenan varias llamadas y las que no envuelven HTTP siguen siendo candidatas a implementación manual. Los wrappers rutinarios de un endpoint no deberían serlo.

¿Cómo evito endpoints de escritura durante las pruebas?

Genera un conjunto de solo lectura filtrando por método HTTP y dirige cualquier operación de escritura a un mock. Consulta por qué los agentes deben usar mocks, no producción.

Top comments (0)