Errores de API Recuperables para Agentes de IA: Diseño y Estrategias

"Entrada no válida" no le dice nada a un agente, por lo que reintenta indefinidamente. Aprenda el formato de error que los agentes pueden usar: detalles del problema RFC 9457, un indicador de reintento, causas a nivel de campo y rutas de fallo probadas.

Ashley Innocent

Ashley Innocent

26 August 2026

Errores de API Recuperables para Agentes de IA: Diseño y Estrategias

Apidog para empresas

Despliegue local

SSO & RBAC

Conforme con SOC 2

Explorar Apidog Enterprise

Tu API devuelve 400 Bad Request con el cuerpo {"error": "invalid input"}. Un desarrollador humano abre la documentación, revisa la carga útil, detecta el campo que falta y lo corrige en un minuto. Un agente lee las mismas dos palabras, no tiene nada sobre lo que actuar y hace lo único que puede: envía la misma solicitud de nuevo. Y otra vez. Luego se rinde y le dice al usuario que la API está rota.

Las respuestas de error son la parte de una API de la que los agentes dependen más y que los equipos diseñan al final. Un buen error le dice a quien llama qué salió mal, si reintentarlo podría ayudar y qué cambiar. Un agente puede actuar sobre los tres. Un error vago convierte un problema recuperable en una tarea fallida.

Esta guía está escrita para el lado de la API de la relación. Nuestra publicación sobre recuperación de errores del agente cubre lo que el cliente debe hacer con los reintentos, el retroceso y los interruptores de circuito. Esta cubre lo que tu API tiene que devolver para que esa lógica del cliente funcione en absoluto.

Apidog es importante aquí porque las respuestas de error son la parte menos probada de la mayoría de las APIs. Puedes definirlas en la especificación, simularlas y verificarlas en el mismo lugar donde pruebas el camino feliz.

Las tres preguntas que un error debe responder

Cada respuesta de error que recibe un agente debe permitirle responder tres cosas sin adivinar.

¿Es mi culpa o tuya? Un 4xx significa que la solicitud fue incorrecta y repetirla sin cambios fallará de nuevo. Un 5xx significa que algo salió mal en el servidor y la misma solicitud podría tener éxito más tarde. Los agentes que no pueden distinguirlos reintentan indefinidamente en un error de validación o se rinden ante un problema transitorio.

¿Debo reintentar y cuándo? Algunos errores 4xx son reintentables y otros no. Un 429 es reintentable después de una espera. Un 409 puede ser reintentable después de volver a leer el estado. Un 422 no es reintentable sin cambiar la carga útil. Di cuál, explícitamente.

¿Qué cambio exactamente? Este es el campo que la mayoría de las APIs omiten. "Validation failed" (Validación fallida) es inútil. "The field customer.postal_code is required when country is US" (El campo customer.postal_code es obligatorio cuando country es US) es una corrección que el agente puede aplicar en el siguiente intento.

Incluye estas tres en cada error y la mayoría de las tormentas de reintentos de agentes desaparecerán.

Usa un formato de error estructurado

No inventes una forma. RFC 9457, Problem Details for HTTP APIs, define una y está bien soportada:

{
  "type": "https://api.example.com/errors/validation-failed",
  "title": "Validation failed",
  "status": 422,
  "detail": "The field 'customer.postal_code' is required when 'country' is 'US'.",
  "instance": "/v1/orders",
  "errors": [
    {
      "field": "customer.postal_code",
      "code": "required_conditional",
      "message": "Required when country is US. Provide a 5-digit or 9-digit US postal code.",
      "example": "94107"
    }
  ],
  "retryable": false,
  "next_action": "Add customer.postal_code to the request body and send again."
}

Cuatro partes soportan el peso para un agente.

detail es una oración completa que nombra el campo real y la regla real. No una categoría. La cosa específica que falló en esta solicitud.

El array errors es legible por máquina, una entrada por problema, con una ruta de campo que un agente puede mapear de vuelta a la carga útil que envió. Devuelve todos los fallos a la vez. Devolverlos uno por uno convierte una única corrección en cinco viajes de ida y vuelta.

retryable es un booleano, no algo a inferir de un código de estado. Esta es la extensión que más ayuda a los agentes, y solo cuesta un campo.

next_action es texto de instrucción simple. Los modelos siguen instrucciones explícitas en un cuerpo de respuesta de forma más fiable de lo que razonan a partir de códigos de error, y una frase aquí a menudo convierte una tarea fallida en una completada.

La guía de diseño de errores de API de Google llega a conclusiones similares desde una dirección diferente, notablemente que los detalles del error pertenecen a una lista estructurada en lugar de prosa.

Di cuándo volver

Para cualquier cosa transitoria, di cuándo. Un agente que sabe que debe esperar 30 segundos, espera 30 segundos. Un agente que no lo sabe elegirá algo, y ese algo suele ser demasiado corto.

HTTP/1.1 429 Too Many Requests
Retry-After: 30
Content-Type: application/problem+json

{
  "type": "https://api.example.com/errors/rate-limited",
  "title": "Rate limit exceeded",
  "status": 429,
  "detail": "You have used 1000 of 1000 requests in the current minute window.",
  "retryable": true,
  "retry_after_seconds": 30,
  "next_action": "Wait 30 seconds before sending this request again. Do not retry sooner."
}

El encabezado Retry-After acepta un retraso en segundos o una fecha HTTP; los segundos son más fáciles de usar para un cliente. Envíalo como un encabezado para clientes estándar y repítelo en el cuerpo para el modelo. La duplicación es barata y ambos consumidores obtienen lo que mejor leen. Los detalles del límite de velocidad se cubren en nuestra guía sobre exceder el límite de velocidad y en cómo implementar la limitación de velocidad de API si estás en el lado del servidor.

El mismo patrón se aplica a 503 durante el mantenimiento y a 409 en un recurso bloqueado. Cualquier error donde esperar sea la respuesta correcta debe llevar un número.

Nunca filtres internos, nunca devuelvas nada

Dos modos de fallo se sitúan en extremos opuestos, y ambos perjudican a los agentes.

El primero es el rastreo de la pila. Devolver texto de excepción interno expone versiones de frameworks, rutas de archivos y, a veces, fragmentos de consultas. Es un problema de seguridad antes de ser un problema de agente, y las preocupaciones de nuestra publicación sobre probar APIs contra entradas no confiables se aplican directamente. También inunda la ventana de contexto con texto sobre el que el modelo no puede actuar.

El segundo es el error vacío: un 500 sin cuerpo, o {"error": true}. El agente no aprende nada, y sus únicas opciones son reintentar o rendirse.

El camino intermedio es un error público estable con un ID de correlación:

{
  "type": "https://api.example.com/errors/internal",
  "title": "Internal error",
  "status": 500,
  "detail": "The order could not be created due to an internal error. No order was created.",
  "retryable": true,
  "retry_after_seconds": 5,
  "request_id": "req_01J8ZK3M2Q",
  "next_action": "Retry once after 5 seconds. If it fails again, stop and report request_id req_01J8ZK3M2Q."
}

La frase "No se creó ningún pedido" es la parte más valiosa. Los agentes que se enfrentan a una escritura ambigua tienen que decidir si reintentar implica el riesgo de un duplicado, y la mayoría decide mal. Diles en qué estado te encuentras. Donde no puedas prometer eso, haz la operación idempotente y díselo, que es el patrón en nuestra publicación sobre claves de idempotencia para agentes de IA.

El request_id te devuelve el hilo a tus registros cuando un humano finalmente lee la transcripción. Combínalo con las prácticas de nuestra guía de observabilidad de API para que el ID realmente se resuelva en algo.

Los errores pertenecen a la especificación

Si la forma de un error no está en tu documento OpenAPI, no existe en lo que respecta a los clientes generados, las simulaciones y las herramientas de los agentes. La mayoría de las especificaciones describen un 200 en detalle y luego hacen un gesto a todo lo demás.

responses:
  '201':
    description: Order created
    content:
      application/json:
        schema: { $ref: '#/components/schemas/Order' }
  '422':
    description: >
      Validation failed. Not retryable without changing the request body.
      The errors array names each invalid field.
    content:
      application/problem+json:
        schema: { $ref: '#/components/schemas/Problem' }
  '429':
    description: >
      Rate limited. Retryable. Wait for retry_after_seconds before sending again.
    content:
      application/problem+json:
        schema: { $ref: '#/components/schemas/Problem' }

Esas descripciones no son decoración. Cuando generas herramientas de agente a partir de la especificación, como en nuestra guía para convertir una especificación OpenAPI en herramientas de agente, ese texto se convierte en lo que el modelo lee sobre el caso de fallo. Una descripción que dice "reintentable, espera primero" produce un mejor comportamiento que una que dice "Demasiadas solicitudes".

Prueba los errores, no solo los éxitos

Las rutas de error son donde la cobertura de pruebas colapsa, porque activarlas requiere esfuerzo. La simulación elimina el esfuerzo.

Define cada respuesta de error en tu proyecto de API, luego simúlalas para que el agente pueda encontrarse con cada caso bajo demanda. En Apidog puedes añadir las respuestas de fallo a la definición del endpoint y cambiar una simulación entre ellas, lo que te da una forma repetible de ejecutar el agente contra un 422, un 429 y un 500 sin romper nada real. Nuestra publicación sobre ejecutar agentes contra simulaciones en lugar de producción cubre el hábito más amplio.

Cinco casos a construir:

Guarda el conjunto como escenarios para que se ejecuten en CI. El manejo de errores retrocede silenciosamente, usualmente cuando alguien refactoriza un serializador, y la suite de camino feliz no lo notará.

El valor de mejores errores

El valor aparece en tres lugares, y es fácil de medir una vez que lo miras.

Menos reintentos desperdiciados. Un agente que se enfrenta a {"error": "invalid input"} normalmente reintenta la carga útil idéntica dos o tres veces antes de renunciar. Cada intento cuesta un turno de modelo y la conversación completa como contexto. Una respuesta que nombra el campo que falta suele producir un intento corregido. Esa es la diferencia entre cuatro llamadas y dos en un desliz de validación rutinario.

Menos escalaciones. Los agentes que no pueden recuperarse entregan la tarea a un humano. Cada entrega evitable es el resultado costoso que se suponía que el agente debía prevenir. Los errores que nombran una solución mantienen la ejecución dentro de la automatización.

Depuración más corta. Cuando algo sí necesita una persona, request_id más un detail preciso convierte una búsqueda a través de los registros en una sola consulta. Este es el mismo argumento que nuestra guía de observabilidad de API hace sobre la correlación, aplicado al momento en que una ejecución falla.

Hay un cuarto beneficio que es fácil de pasar por alto: las mismas mejoras ayudan a los desarrolladores humanos. Nadie se ha quejado nunca de que un mensaje de error fuera demasiado específico sobre qué campo estaba mal.

Diseña también para la escalada

Algunos errores son genuinamente irrecuperables por el agente. Un alcance faltante, una cuenta cerrada, una regla que necesita una decisión humana. Para esos, el trabajo del error es entregar limpiamente: decir qué pasó, decir qué necesita hacer una persona y llevar el ID de correlación que hace que la entrega sea barata.

Esa respuesta debe llegar a algún lugar que un humano lea. Si el agente es un entorno de ejecución de código que trabaja en tareas asignadas, la plataforma circundante suele ser donde llega. Sharkly mantiene el resultado del agente y el rastro de ejecución en la Tarea y enruta los elementos que necesitan una respuesta o revisión a una Bandeja de entrada, de modo que una ejecución bloqueada es visible como trabajo en lugar de como una línea en un registro. Tu texto de error es lo que hace útil esa entrega, porque un mensaje que dice "entrada inválida" no le da al revisor más de lo que le dio al agente.

No hagas que el agente analice prosa

Un último anti-patrón, común en APIs que crecieron orgánicamente. El código de estado es correcto, el cuerpo es una oración, y cada fallo distinto recibe una redacción diferente:

{ "message": "Sorry, that didn't work. Please check your details and try again." }

Un agente solo puede responder a esto adivinando. Peor aún, los equipos a menudo lo combinan con un estado 200, por lo que la biblioteca cliente ni siquiera ve un fallo.

Dos reglas lo solucionan. Da a cada fallo distinto un código estable legible por máquina, para que el agente pueda ramificarse en insufficient_funds en lugar de en la frase "no hay suficiente". Y nunca devuelvas un fallo con un código de estado de éxito, sea cual sea el argumento de conveniencia del lado del cliente. Un 200 con un error dentro es invisible para cada política de reintento, cada panel de control y cada alerta que posees.

Una lista de verificación para errores legibles por agentes

Los errores son una interfaz. Diseñalos para el interlocutor que realmente tienes, que cada vez más es un modelo que hará exactamente lo que le indique el cuerpo de tu respuesta. Descarga Apidog para definir las formas de error y simularlas antes de que el agente las encuentre de verdad.

Preguntas frecuentes

¿Debo usar RFC 9457 o mi propio formato de error? Usa RFC 9457 a menos que ya tengas un formato consistente en producción. La consistencia supera la estandarización: cambiar la mitad de tus endpoints a una nueva forma es peor que mantener una única forma en todas partes. Añade las extensiones retryable y next_action a cualquiera que uses.

¿Es seguro incluir el texto de next_action en una respuesta de API? Sí, cuando tu servicio lo genera a partir de un conjunto fijo de plantillas. Nunca hagas eco de contenido proporcionado por el usuario en ese campo, ya que un agente lo lee como una instrucción y eso es una ruta de inyección de prompts. Nuestra publicación sobre pruebas de APIs contra entradas no confiables cubre el riesgo.

¿Deben los errores de validación ser 400 o 422? Usa 400 cuando la solicitud está mal formada, como un JSON roto, y 422 cuando la solicitud se analiza pero falla las reglas de negocio. Los agentes se benefician de la división porque las soluciones son diferentes. Si ya usas uno para ambos, documéntalo en lugar de cambiarlo.

¿Cuánto detalle es demasiado? Detente en el punto donde el interlocutor tenga suficiente para actuar. El nombre del campo, la regla y un valor de ejemplo suelen ser suficientes. Los identificadores internos, el texto de la consulta y los marcos de pila ya superan el límite.

¿Cuentan los mensajes de error en la ventana de contexto? Sí, y un error verboso repetido en varios reintentos se acumula rápidamente. Mantenlos por debajo de unos pocos cientos de tokens. Nuestra publicación sobre recorte de respuestas de API para agentes se aplica tanto a los fallos como a los éxitos.

¿Cómo evito que un agente reintente un error no reintentable? Establece retryable: false, indícalo en next_action y refuérzalo en el envoltorio de la herramienta para que el juicio del modelo no sea la única salvaguarda. Aquí es correcto ser redundante.

Practica el diseño de API en Apidog

Descubre una forma más fácil de construir y usar APIs