Saltar al contenido

Un equipo editorial y una comunidad que crean con IA

← Prompt engineering

Prompt engineering · · 7 min de lectura

Chain-of-thought vs structured outputs: cuándo usar cada uno

Cuándo necesitas razonamiento y cuándo un JSON rígido. La tensión entre ambos, los costos y una guía de decisión.

Chain-of-thought (CoT) y structured outputs son dos herramientas que tiran del modelo en direcciones opuestas. CoT quiere que el modelo piense en voz alta: con detalle, en formato libre, paso a paso. Structured output quiere que el modelo encierre su respuesta en una forma rígida: un JSON que supere la validación del esquema. Esa tensión es real y, si eliges mal, te cuesta dinero, latencia y fiabilidad. Este artículo desglosa ambos enfoques y ofrece una guía de decisión concreta para quienes construyen sobre la API.

Qué es chain-of-thought y cuándo ayuda de verdad

CoT es un prompt que le pide al modelo generar pasos de razonamiento antes de la respuesta final. Es el clásico “think step by step”, pero hoy va mucho más allá: los modelos de razonamiento producen un flujo de pensamiento separado antes de emitir la respuesta para el usuario.

CoT ayuda cuando la tarea requiere razonamiento en varios pasos: matemáticas y aritmética, depuración de lógica (“¿por qué este código devuelve undefined?”), planificación de una secuencia de acciones de un agente, comparación de muchas condiciones, inferencia jurídica o diagnóstico. Cuando la respuesta depende de una cadena de conclusiones intermedias, forzar esa cadena aumenta de verdad la precisión. El modelo no “adivina” el final: lo deduce.

CoT no ayuda en tareas de un solo paso: clasificar un texto corto, extraer un campo de una factura, tomar una decisión de sí o no a partir de una única regla. Ahí, el razonamiento añade tokens, latencia y a veces ruido que reduce la calidad. Generar 400 tokens de “reflexiones” para devolver una sola etiqueta es un desperdicio.

Qué son los structured outputs

Los structured outputs son mecanismos que obligan al modelo a devolver los datos con una forma predecible. Hay tres formas principales:

  • JSON mode: el modelo garantiza un JSON sintácticamente válido, pero sin control sobre los campos concretos.
  • response_format con un esquema (por ejemplo, JSON Schema / constrained decoding): el modelo garantiza un JSON conforme a {"type":"object","required":["score"]}. Esto es grammar-constrained decoding: el sampler rechaza los tokens que romperían el esquema.
  • Function calling / tool schemas: el modelo elige una herramienta y rellena sus argumentos según la declaración, por ejemplo get_weather(city: string).

La ventaja es evidente: un pipeline de producción recibe datos que van directos a JSON.parse y a la validación con Zod sin necesidad de parsear con regex. Se acabó lo de “el modelo añadió una frase antes de la llave”. Fiabilidad al nivel de un contrato, no de una esperanza.

Dónde está la tensión

Aquí se pone interesante. El constrained decoding limita el espacio de tokens que el modelo puede generar: en cada paso solo se permiten los tokens que llevan a un JSON válido. Pero el razonamiento es, por naturaleza, de formato libre. Si obligas al modelo a emitir {"answer": desde el primer token, le quitas espacio para pensar. El efecto: en tareas difíciles de matemáticas o de lógica la calidad puede caer, porque el modelo “salta a la respuesta” en lugar de deducirla.

No es teoría. Cualquiera que haya conectado un esquema rígido de response_format a una tarea que exige análisis ha visto cómo las respuestas se vuelven superficiales. El modelo obtiene una forma, pero pierde el proceso. Y en las tareas de razonamiento, el proceso es la calidad.

Cómo te dejan combinarlos los modelos modernos

Buena noticia: no tienes que elegir. Hay tres patrones probados para combinar uno con otro.

Patrón 1: primero el razonamiento, luego un campo estructurado

Un esquema con dos campos: {"reasoning": string, "answer": ...}, donde reasoning va primero. El modelo lo rellena con texto libre (tiene espacio para el CoT) y después, cuando ya “ha pensado”, produce el answer estructurado. El orden de los campos en el esquema importa: el razonamiento debe ir antes que la respuesta, porque el modelo genera de forma secuencial. Un campo reasoning después de answer no sirve de nada: eso es racionalización, no razonamiento.

Patrón 2: reasoning tokens + una respuesta estructurada

Los modelos de razonamiento separan el “pensamiento” de la “respuesta” a nivel de API. El modelo piensa libremente en un flujo aparte, y la respuesta final para el usuario puede restringirse con un esquema. Obtienes CoT completo y un JSON limpio a la salida, sin concesiones. Hoy es la opción más potente para tareas difíciles que tienen que acabar en un pipeline.

Patrón 3: dos llamadas

Llamada A: CoT en formato libre, devuelve texto. Llamada B: toma ese texto y lo “traduce” a un esquema estricto (una extracción barata de un solo paso). Es más caro y más lento (dos round-trips), pero da control total y funciona con cualquier modelo, incluidos los que no tienen modo de razonamiento nativo. Es un buen fallback para modelos más antiguos y ofrece un aislamiento total de errores: si el parseo falla, sabes que la culpa es de la llamada B, no del razonamiento.

Latencia y costo

Cada token de razonamiento es tiempo y dinero. CoT puede multiplicar por 5-20 los tokens de salida en comparación con una respuesta directa. Con los modelos de razonamiento, los reasoning tokens suelen facturarse como output y pueden salir caros. Tres consecuencias:

  • Latencia: una salida más larga implica más tiempo hasta el último token. En una UI síncrona (chat, autocompletado) eso puede ser letal.
  • Costo: una tarea con CoT puede costar varias veces más con la misma entrada. Con un millón de peticiones al mes, eso es una partida real del presupuesto.
  • El patrón de dos llamadas duplica los round-trips de red: sumas la sobrecarga de latencia de la conexión, no solo la de la generación.

Regla: no pagues por razonamiento donde no lo necesitas. Una clasificación en un modelo pequeño sin CoT suele ser 10× más barata y más rápida, con idéntica calidad.

Fiabilidad en pipelines de producción

La producción tiene un listón distinto al de un prototipo. Aquí lo que cuenta es cuántas peticiones de cada diez mil necesitan intervención manual. El CoT puro que devuelve texto es frágil: tienes que parsear el formato libre con regex y, cada cierto tiempo, el modelo cambia el formato y el parser se cae. Structured output con constrained decoding elimina esa clase de bugs: el JSON es válido por definición.

Por eso, para cualquier salida que alimente a otro sistema (una base de datos, una cola, el siguiente paso de un agente), usa structured output por defecto. Deja el texto libre para la salida que lee una persona. Y cuando necesites tanto calidad de razonamiento como fiabilidad en la forma, combínalos con el patrón 1 o el 2. Valida siempre el resultado con Zod en la frontera del sistema, incluso con constrained decoding: el esquema del proveedor y tu contrato de dominio no son lo mismo.

Guía de decisión

Usa CoT cuando: la tarea tenga varios pasos (matemáticas, lógica, depuración, planificación de agentes), la precisión mejore con un razonamiento explícito y, además, o bien la salida la lea una persona, o bien tengas presupuesto de tokens y de latencia. Señal de alarma: si no sabes nombrar los pasos intermedios, probablemente CoT no te aporte nada.

Usa structured output cuando: el resultado alimente un pipeline, la tarea sea de un solo paso (extracción, clasificación, enrutamiento, relleno de argumentos de herramientas) y lo que importe sea la fiabilidad del parseo y una latencia baja. Un modelo pequeño más un esquema suele ser la solución más barata y más fiable.

Combínalos cuando: necesites razonamiento y una salida legible por máquina. Elige reasoning tokens + una respuesta estructurada (patrón 2) si el modelo lo admite. Si no, un esquema {reasoning, answer} con el razonamiento primero (patrón 1). Reserva el patrón de dos llamadas como fallback para modelos más antiguos o para cuando necesites un aislamiento total de errores.

Errores frecuentes

  • Un campo reasoning después de answer en el esquema. El modelo ya ha respondido; el resto es teatro. El razonamiento, siempre primero.
  • Un esquema rígido en una tarea difícil, sin espacio para pensar. Ganas forma y pierdes calidad. Añade un campo para el CoT o usa reasoning tokens.
  • CoT de 400 tokens en una clasificación donde bastaría una etiqueta. Pagas por ruido.
  • No validar con Zod “porque el esquema del proveedor garantiza el JSON”. Garantiza la sintaxis, no tu contrato de dominio ni los rangos de valores.

TL;DR

CoT mejora la calidad en tareas de varios pasos, pero cuesta tokens y latencia. Structured output da fiabilidad en el parseo, pero un esquema rígido ahoga el razonamiento. Para tareas de un solo paso dentro de un pipeline, structured. Para razonamientos que lee una persona, CoT. Cuando necesites ambos, combínalos: reasoning tokens + una respuesta estructurada, o un esquema con un campo reasoning antes de answer. Y valida siempre el resultado en la frontera del sistema.

Chain-of-thought vs structured outputs: cuándo usar cada uno | vibecoding.inc