IA

Decisions API de OpenAI: qué es y cómo usarla para clasificar, enrutar y puntuar

OpenAI abrió en beta pública la Decisions API, un endpoint que no genera texto: responde preguntas cerradas sobre texto e imágenes con probabilidades, opciones o puntuaciones. Te explico cómo funciona, sus tres tipos de pregunta, el precio y ejemplos en curl, Python y JavaScript.

  • Javi Mata
  • 12 min de lectura
Tabla de contenido

El 6 de octubre de 2026 OpenAI abrió en beta pública la Decisions API, una API pensada para una sola cosa: tomar decisiones rápidas. No escribe respuestas ni redacta textos. Le das una entrada (texto, imágenes o ambos), le haces una o varias preguntas cerradas y te devuelve respuestas tipadas que tu aplicación puede usar directamente: la probabilidad de que algo sea cierto, una opción de una lista fija o una puntuación sobre una escala.

Según la documentación oficial, devuelve esas respuestas “about 10x faster than the Responses API” (unas 10 veces más rápido que la Responses API). Está impulsada por GPT-6 Luna, que por ahora es el único modelo disponible.

Este artículo describe la API tal como está documentada el 8 de octubre de 2026. Está en beta y OpenAI dice que espera llevarla a disponibilidad general “in the coming weeks”, así que algunos detalles pueden cambiar. Revisa la guía oficial antes de ponerla en producción.

Para qué sirve (y para qué no)

La documentación la resume así: sirve para clasificar contenido, enrutar solicitudes y priorizar trabajo dentro de tu aplicación. Algunos ejemplos que aparecen en la guía y en el video de presentación:

  • Revisar si la foto de un producto muestra daños visibles.
  • Mandar una queja de cliente al departamento correcto.
  • Calificar la gravedad de un reporte de error.
  • Clasificar un documento como factura, recibo o contrato.
  • Elegir el carril de un coche en un videojuego a partir de un fotograma.

Lo que no hace es generar contenido. La propia guía lo deja claro: si necesitas un objeto que siga tu propio esquema JSON (por ejemplo, campos extraídos o una explicación escrita), usa Structured Outputs con la Responses API. Si necesitas que el modelo pida ejecutar una herramienta con argumentos, usa function calling. Decisions es para cuando la respuesta cabe en “sí/no con probabilidad”, “una de estas opciones” o “un punto de esta escala”.

Cómo es una petición

Todo pasa por un endpoint propio:

POST /v1/decisions

Una petición tiene tres partes:

CampoPara qué sirve
modelEl modelo que evalúa la petición. Por ahora solo se admite gpt-6-luna.
inputLa evidencia compartida por todas las preguntas: un texto o mensajes de usuario con texto e imágenes.
questionsLo que quieres evaluar: el tipo de cada pregunta, sus instrucciones y, según el tipo, las opciones o niveles permitidos.

La respuesta trae un arreglo answers. Cada pregunta lleva un name único y la API lo repite en su respuesta, así sabes qué respuesta corresponde a qué pregunta.

Para usar los SDK oficiales, la guía pide estas versiones o posteriores: Python 3.26.0, JavaScript 7.30.0, Go 3.73.0, Ruby 0.101.0 y Java 4.78.0.

Los tres tipos de pregunta

TipoÚsalo paraResultado principal
predicateComprobar una condición, como un daño visible o si un texto es relevante.probability: una estimación de 0 a 1 de que la condición se cumple.
choiceElegir una opción, como un departamento o una categoría de contenido.choice: uno de los valores que tú proporcionaste.
scoreCalificar una entrada sobre niveles ordenados, como la gravedad de un problema.score: el promedio de los índices de los niveles, ponderado por su probabilidad.

La diferencia entre choice y score es importante: ambos devuelven probabilidades sobre opciones discretas, pero choice es para categorías sin orden (departamentos, tipos de documento) y score para niveles ordenados (baja, media, alta).

Ejemplo 1: predicate para revisar una foto

Este es el ejemplo de la documentación en curl. Revisa la foto de un producto y pregunta si tiene daños visibles:

IMAGE_BASE64="$(base64 < product.png | tr -d '\r\n')"

curl https://api.openai.com/v1/decisions \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<JSON
{
  "model": "gpt-6-luna",
  "input": [{
    "role": "user",
    "content": [
      {"type": "input_text", "text": "Inspect the product in this photo."},
      {"type": "input_image", "image_url": "data:image/png;base64,$IMAGE_BASE64"}
    ]
  }],
  "questions": [{
    "type": "predicate",
    "name": "visible_damage",
    "instructions": "Does the product have visible damage, such as a crack, tear, or dent? Ignore shadows and damage to the packaging."
  }]
}
JSON

Fíjate en las instrucciones: no solo preguntan “¿está dañado?”, también dicen qué cuenta como daño (grieta, rotura, abolladura) y qué ignorar (sombras y daños en el empaque).

La documentación muestra este extracto de respuesta, marcado como ilustrativo:

{
  "answers": [
    {
      "type": "predicate",
      "name": "visible_damage",
      "probability": 0.92
    }
  ]
}

Ese 0.92 es la estimación del modelo de que la condición es verdadera. Con eso decides tú: por ejemplo, mandar a revisión manual las fotos que pasen de cierto umbral.

Un detalle con las imágenes: deben ir como data URL en base64 dentro de la petición. Según la guía, este endpoint no acepta URLs HTTP o HTTPS de imágenes alojadas ni entradas con file_id.

Ejemplo 2: choice para enrutar una queja

Aquí el ejemplo oficial en Python. Clasifica una queja entre cuatro departamentos:

from openai import OpenAI

client = OpenAI()

decision = client.decisions.create(
    model="gpt-6-luna",
    input="I was charged twice for my order.",
    questions=[
        {
            "type": "choice",
            "name": "department",
            "instructions": "Which department should handle this complaint?",
            "choices": [
                {"value": "billing", "description": "Payments, invoices, and refunds."},
                {"value": "technical", "description": "Problems using the product."},
                {"value": "shipping", "description": "Delivery and tracking."},
                {"value": "other", "description": "Requests outside these categories."},
            ],
        }
    ],
)

answer = decision.answers[0]
if answer.type == "refusal":
    print(f"Refused: {answer.name}")
elif answer.type == "choice":
    print(f"Department: {answer.choice} (confidence: {answer.confidence})")

Y el extracto ilustrativo de respuesta de la documentación:

{
  "answers": [
    {
      "type": "choice",
      "name": "department",
      "choice": "billing",
      "probabilities": [
        { "value": "billing", "probability": 0.95 },
        { "value": "technical", "probability": 0.02 },
        { "value": "shipping", "probability": 0.01 },
        { "value": "other", "probability": 0.02 }
      ],
      "confidence": 0.93
    }
  ]
}

Además de la opción elegida (choice), recibes la distribución completa (probabilities) y un campo confidence.

Dos consejos de la guía que vale la pena seguir:

  • Usa valores distintos entre sí y una description que explique cuándo aplica cada opción.
  • Incluye una opción de respaldo como "other" cuando tus categorías no cubran todos los casos. Así tu aplicación puede mandar esas respuestas a una cola de revisión general.

Observa también el manejo de refusal: la respuesta puede ser de tipo refusal en lugar del tipo que pediste, así que tu código debe contemplarlo.

Ejemplo 3: score para medir gravedad

Para niveles ordenados se usa score. Este es el ejemplo oficial en JavaScript:

import OpenAI from "openai";

const client = new OpenAI();

const decision = await client.decisions.create({
  model: "gpt-6-luna",
  input: "Export fails in Safari but works in Chrome.",
  questions: [
    {
      type: "score",
      name: "severity",
      instructions: "How severe is this issue?",
      levels: [
        {
          label: "Cosmetic",
          description: "Appearance only; no lost functionality.",
        },
        {
          label: "Workaround available",
          description: "A task fails, but another way works.",
        },
        {
          label: "Fully blocked",
          description: "A task fails with no workaround.",
        },
      ],
    },
  ],
});

const answer = decision.answers[0];
if (answer.type === "refusal") {
  console.log(`Refused: ${answer.name}`);
} else if (answer.type === "score") {
  console.log(`Severity: ${answer.score} (confidence: ${answer.confidence})`);
}

Los niveles se ordenan de menor a mayor y sus índices empiezan en 0: aquí 0 es “cosmético”, 1 es “hay alternativa” y 2 es “bloqueo total”. En el extracto ilustrativo de la documentación, las probabilidades por nivel son 0.1, 0.7 y 0.2, lo que da un score de 1.1:

0 × 0.1 + 1 × 0.7 + 2 × 0.2 = 1.1

Como es un promedio ponderado, el resultado puede caer entre niveles. Si lo que necesitas es una sola categoría, la guía recomienda usar choice.

Varias preguntas en una sola petición

Puedes meter preguntas independientes en el mismo arreglo questions para evaluar la misma entrada de una vez, y cada una puede ser de un tipo distinto. Por ejemplo, con una foto de producto puedes preguntar si tiene daños (predicate) y a qué categoría pertenece (choice) en la misma llamada.

Si una pregunta depende de la respuesta de otra, la guía indica enviarlas en peticiones separadas: primero compruebas si hay daño y, según el resultado, haces la siguiente pregunta.

La documentación también da tres reglas para redactar preguntas:

  1. Escríbelas alrededor de criterios observables.
  2. Separa cada asunto en su propia pregunta.
  3. Da a las opciones significados distintos y define los niveles de score para que dos niveles contiguos tengan criterios claramente diferentes.

Cómo interpretar las respuestas y elegir umbrales

Los predicate devuelven la probabilidad estimada de que la condición se cumpla. Las respuestas choice y score devuelven una distribución de probabilidades y un campo confidence aparte.

La recomendación oficial es fijar los umbrales con ejemplos etiquetados de tu propia aplicación, pensando en lo que te cuesta un falso positivo frente a un falso negativo.

Por ejemplo, este es un ejemplo propio (no viene de la documentación) de cómo podrías usar una respuesta predicate para decidir qué pasa con una reseña de una tienda en línea. Los umbrales son inventados: los tuyos deben salir de tus datos.

# Ejemplo ilustrativo: los umbrales 0.85 y 0.5 son inventados.
answer = decision.answers[0]

if answer.type == "refusal":
    enviar_a_revision_manual(resena)
elif answer.probability >= 0.85:
    ocultar_resena(resena)
elif answer.probability >= 0.5:
    enviar_a_revision_manual(resena)
else:
    publicar_resena(resena)

Precio y disponibilidad

Según la sección de precios de la guía:

  • Con gpt-6-luna, la entrada cuesta $0.10 por cada millón de tokens.
  • Solo pagas tokens de entrada: no hay cargos por lectura ni escritura de caché, ni por tokens de salida.
  • Se aplican los recargos por procesamiento regional y los multiplicadores de precio para contexto largo.
  • Estas tarifas son para /v1/decisions. Si usas gpt-6-luna desde otros endpoints, aplica el precio normal del modelo.

Sobre datos y cumplimiento, la guía indica que la API admite Zero Data Retention (ZDR) y uso con HIPAA para clientes elegibles, y que hay residencia de datos y procesamiento regional en Estados Unidos y Europa (EEA + Suiza). Los requisitos de elegibilidad están en la documentación de controles de datos de OpenAI.

También puedes probarla en el Playground antes de escribir código, como sugiere la propia guía.

Lo que muestra el video de presentación

OpenAI publicó el video Introducing the Decisions API el 6 de octubre de 2026. Según su descripción, combina la Decisions API con GPT-Live-1 y un robot Microduck para juntar voz, comprensión visual y decisiones rápidas. Sus capítulos son:

  • Clasificar texto y enrutar prospectos de ventas.
  • Tomar decisiones a partir de imágenes.
  • Añadir expresiones a conversaciones de voz.
  • Guiar a Lavender, el robot.

La guía oficial también enlaza a una forma de añadir control por voz: usar la delegación al cliente de la Live API para elegir acciones a partir de lo que dice el usuario.

Primeras impresiones de la comunidad

En el hilo del anuncio del foro de desarrolladores de OpenAI, varios usuarios compartieron pruebas. Son pruebas personales, no resultados oficiales, pero sirven como aviso:

  • Un usuario reportó que, con una moneda cargada para salir cara el 70% de las veces, la pregunta tipo predicate le devolvía cara cerca del 70% de las veces, mientras que planteada como choice elegía cara el 98% de las veces. También comentó que el orden de las opciones cambiaba las probabilidades.
  • Otro usuario la comparó con Jev, un modelo de decisión de otra empresa, y en sus pruebas Jev salió mejor parado; él mismo aclaró que fueron unos cientos de preguntas y no un benchmark general.
  • Otro participante señaló que Jev todavía no admite imágenes y que en esos casos la Decisions API puede ser útil.

Mi lectura: si vas a usar choice para algo donde importa la distribución de probabilidades y no solo la opción ganadora, pruébalo con tus propios datos antes de confiar en esos números.

Contexto: no es el único “modelo de decisión”

Según The New Stack (7 de octubre de 2026), OpenAI no está sola en esto: TypeSafe lanzó Jev el mes anterior, y Perplexity, Cloudflare y Amazon publicaron este mes sus propios modelos de decisión con pesos abiertos, que puedes descargar y correr en tu infraestructura. La diferencia que destaca el artículo es que OpenAI mantiene el suyo solo como API alojada. No he verificado esos otros modelos en sus fuentes oficiales, así que aquí solo los menciono como contexto.

Mi recomendación para empezar

  1. Empieza con predicate. Es el tipo más simple de entender y, en la prueba de la moneda que compartió un usuario del foro, fue el que mejor reflejó la probabilidad real.
  2. Redacta las instrucciones como un criterio de revisión, con lo que cuenta y lo que no cuenta, igual que en el ejemplo de la foto.
  3. Reúne ejemplos etiquetados de tu caso real y ajusta los umbrales con ellos, en lugar de suponer que 0.5 es el corte correcto.
  4. Siempre maneja refusal y, en choice, incluye una opción "other".
  5. No la uses para generar nada. Si necesitas texto o un JSON con campos extraídos, eso sigue siendo trabajo de la Responses API.

Para quienes trabajamos con tiendas en línea, los casos obvios son moderar reseñas, revisar fotos de devoluciones o clasificar mensajes de soporte. Son tareas de “decidir rápido y barato” donde una API que solo cobra la entrada puede tener mucho sentido.

Fuentes