content is "" but the request returned 200finish_reason: "length" on a short promptUsage shows output tokens spent with nothing to show for themThe same prompt works on a non-reasoning modelRaising max_tokens suddenly makes it workLos modelos de razonamiento emiten dos tipos de tokens de salida: la cadena interna y la respuesta que ves. La facturación cuenta ambos. max_tokens limita ambos. Un valor que era generoso para un modelo sin razonamiento puede consumirse por completo antes del primer carácter visible.
El fallo es silencioso por diseño. La API hizo lo que se le pidió: generó hasta el límite y paró. finish_reason: "length" es la única pista, y es fácil pasarla por alto cuando tu código lee choices[0].message.content y encuentra una inofensiva cadena vacía.
Nos topamos con esto en una herramienta interna de puntuación de documentos. max_tokens estaba en 2500: suficiente para el modelo anterior, muy lejos de bastar en cuanto el modelo empezó a razonar primero. Durante un tiempo el síntoma pareció un proxy roto, porque las peticiones tenían éxito, la latencia era normal y el coste era real. Lo delató la factura: cargos sin ningún texto que les correspondiera.
Mira finish_reason y el recuento de tokens, no solo el contenido:
curl -s 'YOUR_BASE_URL/chat/completions' \
-H 'Authorization: Bearer YOUR_KEY' \
-H 'Content-Type: application/json' \
-d '{"model":"YOUR_MODEL","max_tokens":64,
"messages":[{"role":"user","content":"What is 17 * 23? Answer with the number only."}]}' \
| python3 -m json.tool
"finish_reason": "length" junto con un content vacío y un recuento de tokens de salida distinto de cero es la firma. Ejecútalo de nuevo con max_tokens en 4000 y el mismo prompt responderá.
Revisado por última vez el 2026-10-01. Escrito a partir de problemas diagnosticados en una pasarela compatible con OpenAI en producción, no recopilado de otras webs.