hiddenrows

Guías prácticas para trabajar con agentes de IA, con un laboratorio al final de cada una

última edición=16 de octubre · 24 piezas · 14 breves
regla=solo lo verificado como hecho
llamadas a un modelo por visita=0
Guía práctica

Para que tu programa pueda leer la respuesta del agente: pídela con esquema

Pedir el formato en palabras y confiar funciona casi siempre, y «casi siempre» es lo que rompe un proceso automático. Un esquema convierte la petición en una garantía, se prueba con tu suscripción y sin clave de API, y deja tres casos en los que la respuesta puede no cumplirlo: los tres se detectan.

6 min de lectura laboratorio: generador publicado el 16 oct 2026

1El problema

Le pides al agente que te devuelva el resultado «en JSON, con los campos nombre, importe y estado», y te lo devuelve. Catorce veces seguidas. A la quince te llega con una frase de cortesía delante, o el importe entre comillas, o un campo que se llama status porque el documento de origen estaba en inglés.

Mientras lo lees tú, da igual: lo ves y lo arreglas. El problema aparece cuando al otro lado hay un programa que esperaba un número y recibe un texto. Entonces no tienes un formato irregular, tienes un proceso parado, y el fallo llega tarde: no cuando el agente responde, sino cuando algo más abajo intenta usar la respuesta.

Pedir el formato con palabras es una recomendación. Lo que necesitas cuando hay un programa detrás es una garantía, y eso es otra cosa y se pide de otra manera.

2Qué cambia cuando lo pides con esquema

Un esquema es la descripción de la forma que tiene que tener la respuesta, escrita en JSON Schema: qué campos hay, de qué tipo es cada uno, cuáles son obligatorios y qué valores se admiten. No es una instrucción más dentro del encargo: va en un sitio aparte de la petición.

Y el mecanismo tampoco es el mismo. El esquema se compila en una gramática que restringe lo que el modelo puede escribir mientras lo escribe. V No es que se le pida que cumpla el formato y luego se compruebe: es que, token a token, lo que no encaja en el esquema no está disponible. Por eso deja de ser una recomendación.

De ahí salen las dos cosas que vienen después en esta guía, y conviene verlas juntas. Compilar una gramática cuesta, así que hay límites a lo complicado que puede ser tu esquema. Y restringir la escritura no alcanza a lo que ocurre antes de escribir, así que quedan tres huecos por donde la respuesta puede salir sin cumplirlo. I

3Pruébalo hoy, con tu suscripción

No hace falta clave de API para verlo funcionando. Claude Code lo trae en la orden, con --json-schema, y vale con la suscripción que ya tienes. V

claude -p --json-schema '{"type":"object","properties":{"titular":{"type":"string"},"palabras":{"type":"integer"}},"required":["titular","palabras"],"additionalProperties":false}' \
  "Lee README.md y devuelve un titular y cuántas palabras tiene"

Tres cosas que conviene saber antes de teclearlo:

  • Funciona solo en modo impresión, es decir con -p. No es algo que puedas pedir en mitad de una sesión interactiva. V
  • La validación ocurre cuando el agente termina su trabajo, no en cada paso: el agente hace lo que tenga que hacer, lee ficheros, ejecuta órdenes, y lo que se obliga a tener forma es el resultado final. V
  • Si el esquema está mal escrito, Claude Code sale con error en vez de intentarlo, que es lo que quieres. Eso sí: acepta la palabra format como anotación y no la comprueba por su cuenta, así que no confes su validación a un "format": "email". V

4Los tres casos en que la respuesta no cumple el esquema

refusalla negativa: llega con código 200 y se te cobran los tokens
max_tokensel corte: la respuesta va incompleta
enumlas mayúsculas: termina bien y sin aviso de ninguna clase

La garantía es fuerte, no absoluta, y lo honesto es saber por dónde se escapa. Son tres casos, y el tercero es el que muerde porque no se parece a un fallo. V

1. El modelo se niega. Si rechaza la petición por seguridad, la respuesta trae stop_reason: "refusal", llega con un código 200 —no es un error de red ni de programación—, se te cobran los tokens generados, y el texto de la negativa tiene prioridad sobre el esquema. V Cómo lo detectas: mirando stop_reason antes de intentar interpretar nada.

Hay una variante de esto que se provoca sin querer: si entre los campos del esquema pides el razonamiento paso a paso del modelo, eso puede desencadenar una negativa de tipo reasoning_extraction. La recomendación de la fuente es pedir una explicación corta en vez del razonamiento. V

2. La respuesta se corta. Si choca con el tope de max_tokens, llega incompleta y por tanto no cumple el esquema, con stop_reason: "max_tokens". V Cómo lo detectas: el mismo campo. Y se arregla reintentando con un tope más alto.

3. Las mayúsculas de un enum. Este es el que hay que aprenderse. Cuando un campo está limitado a una lista de valores con enum o const, las mayúsculas no están garantizadas: puedes recibir un valor que se diferencia del tuyo solo en una letra mayúscula, típicamente la primera de una palabra que va detrás de un espacio. V

Y lo peor es cómo llega: la respuesta termina con normalidad, sin error y sin ningún stop_reason especial. V Tu programa compara con ==, no encaja, y el caso se va por la rama de «valor desconocido» sin que nada haya fallado. Qué hacer: compara los valores sin distinguir mayúsculas, y no uses valores de enum que se diferencien solo en eso. V

Y uno más, si lo lanzas desde Claude Code: una ejecución puede terminar diciendo que fue bien —subtype: success— y no traer ningún resultado estructurado, por ejemplo si el agente terminó sin llegar a producirlo. La propia documentación dice que eso se trate como un fallo. V Así que la condición que vale es doble: que diga que fue bien y que el resultado esté ahí.

5Los límites, y que se suman en toda la petición

20herramientas estrictas como máximo por petición
24parámetros opcionales, sumando todos los esquemas
16parámetros con tipos alternativos, también sumados

Como el esquema se compila, hay un tope a lo complicado que puede ser. Tres límites declarados, y la trampa está en que no son por esquema sino por petición: se suman todos los esquemas estrictos que viajen juntos. V

  • 20 herramientas con strict: true. Las que no son estrictas no cuentan.
  • 24 parámetros opcionales en total, contando los de las herramientas estrictas y los de los esquemas de salida. Cuenta como opcional todo el que no esté en required.
  • 16 parámetros con tipos alternativos, los que usan anyOf o una lista de tipos como ["string", "null"]. Son los más caros porque el coste de compilar crece de forma exponencial.

El ejemplo que da la fuente explica la trampa mejor que la regla: con 4 herramientas de 6 parámetros opcionales cada una ya has llegado al tope de 24, y ninguna de las cuatro parece complicada. V

Por debajo de esos tres hay además límites internos al tamaño de la gramática compilada, porque estas cosas se multiplican entre sí. Si los pasas, recibes un 400 que dice que el esquema es demasiado complejo para compilarlo, aunque cada límite de la tabla se respete. Y hay un tope final de tiempo: 180 segundos para compilar. V

Estas cifras son de la API, no de Claude Code: son el límite de lo que el servidor acepta compilar, así que valen igual lo lances desde donde lo lances. I

6Si te pasas de complejidad, en este orden

La fuente da cuatro salidas y las ordena, que es lo útil: la primera es la que más quita y la última la que más trabajo cuesta. V

  1. Marca como estrictas solo las herramientas que lo necesitan. Resérvalo para aquellas en las que saltarse el formato causa un problema de verdad, y fíate del comportamiento normal del modelo para las sencillas.
  2. Haz obligatorios los parámetros que puedas. Cada opcional aproximadamente duplica una parte del espacio de estados de la gramática. Si un campo siempre tiene un valor razonable por defecto, pídelo como obligatorio y que el modelo escriba ese valor.
  3. Aplana lo que esté anidado. Un objeto dentro de otro, con campos opcionales en los dos, multiplica el problema en vez de sumarlo.
  4. Parte la petición en varias. Si tienes muchas herramientas estrictas, repártelas entre peticiones distintas o entre subagentes.

Si te quedas atascado con un esquema que es válido y aun así no compila, la recomendación de la fuente es escribir al soporte con el esquema delante. V

7Pruébalo

8Llévatelo a tu caso

Para qué sirve esto en un equipo

  • Sacar datos de documentosSi lo que viene detrás es una hoja de cálculo o una base de datos, pide el esquema con los tipos puestos y deja de limpiar la respuesta a mano.
  • Clasificar con etiquetas fijasUsa <code>enum</code> para que la etiqueta salga de tu lista y no de la imaginación del modelo, y compara después sin distinguir mayúsculas.
  • Un paso dentro de un proceso automáticoCuando nadie va a mirar la respuesta antes de usarla, la condición para seguir es doble: que la ejecución diga que fue bien y que el resultado esté ahí.

Hasta dónde llega: esta guía trata la salida con esquema, no la fiabilidad de lo que dice el contenido. Un esquema garantiza la forma, nunca que el dato sea correcto. Las cifras de límites son de la API.

¿Te compensa?

Marca las que se cumplan en tu caso.

Si quieres seguir

Pruébalo tú

Usa el laboratorio de arriba con tu propio caso.

Entiéndelo mejor

Las piezas que lo completan.

¿Dudas o correcciones?

Si algo no encaja con tu caso, o si encuentras un error, escríbeme: se corrige y se anota.

Escríbeme

9Fuentes

  1. Claude Platform — Structured outputs, apartados de salidas inválidas y límites de complejidad · consultado el 16-oct-2026
  2. Claude Code — Referencia de la orden, opción --json-schema · consultado el 16-oct-2026
  3. Claude Agent SDK — Salida estructurada: cómo se informa de un fallo · consultado el 16-oct-2026
hiddenrows · proyecto personal de divulgación de Miguel Yepes Contenido divulgativo, puede contener errores · sin garantías · Aviso legal · Privacidad · llms.txt