← Blog
3 de octubre, 2026 · 16 min

Pagar por pensamientos que no ves: reasoning tokens y la reserva

Los modelos de reasoning cobran por texto que nunca lees. OpenAI, Anthropic y Google cobran el reasoning oculto como output y lo descuentan del mismo tope que la respuesta. Leímos su documentación actual, además de OpenRouter, LiteLLM, vLLM y Ollama, corrimos un modelo con thinking en local y sondeamos nuestra propia cotización x402. Una respuesta de seis caracteres costó 917 output tokens. Con el tope ajustado a la respuesta, la llamada costó 256 tokens y no devolvió nada.

Nuestro post sobre los internals del billing describió la reserva que ejecuta todo gateway prepago. Retener los input tokens por el precio de input más max_tokens por el precio de output, reenviar la llamada y liquidar el costo real. La fórmula asumía en silencio que los output tokens eran el texto que recibe el agente. En los modelos de reasoning esa premisa desapareció. La mayor parte del output puede ser texto que nadie recibe.

Eso rompe tres cosas de las que depende un agente que paga. El tope ya no acota la respuesta, porque el reasoning lo gasta primero. El control del reasoning, reasoning_effort, significa algo distinto en cada salto entre el agente y el modelo. Y el recibo que mostraría a dónde fueron los tokens falta en la mayoría de las capas de compatibilidad, incluida la nuestra.

Nuestras fuentes, todas leídas o ejecutadas el 3 de octubre de 2026: la guía de reasoning de OpenAI, su guía de conteo de tokens y sus páginas de modelos, más su OpenAPI en 92f957a; las páginas de Anthropic sobre thinking, extended thinking, steering y costo, effort, precios y compatibilidad con el SDK de OpenAI; las páginas de Gemini sobre thinking y compatibilidad con OpenAI; la documentación de reasoning tokens de OpenRouter; la transformación de Anthropic de LiteLLM en d260765; los sampling parameters y el protocolo de vLLM en 5f30fc7; la documentación de compatibilidad con OpenAI de Ollama y un Ollama 0.30.6 local; el scheme upto de x402; y sondas sin autenticar contra nuestro propio endpoint.

El medidor que no puedes leer

OpenAI lo dice sin rodeos. Los reasoning tokens "no son visibles vía la API", pero "igual ocupan espacio en la context window del modelo y se cobran como output tokens". Sus topes de output, max_output_tokens en Responses y max_completion_tokens en Chat Completions, "limitan todos los tokens generados por el modelo, incluidos los no visibles". La descripción de max_completion_tokens en la OpenAPI dice lo mismo: output tokens visibles y reasoning tokens. El campo anterior, max_tokens, figura como deprecated y "no compatible con los modelos de la serie o".

Cuando una llamada llega al tope, OpenAI devuelve status: "incomplete". La guía advierte que esto "puede ocurrir antes de que se produzca cualquier output token visible, lo que significa que podrías incurrir en costos de input y reasoning tokens sin recibir una respuesta visible". Su consejo es reservar al menos 25.000 tokens para reasoning y output cuando empiezas a experimentar.

Un detalle más importa para la contabilidad. Algunos modelos emiten tokens de formato que no aparecen ni en el contenido del mensaje ni en el conteo de reasoning. Así, completion_tokens puede superar el output visible "incluso cuando el valor reportado de reasoning_tokens es 0".

La regla de Anthropic es la misma, con un filo más agudo. El thinking se cobra como output, y "el conteo de output tokens facturado no coincide con el conteo de tokens visible". En la familia Claude 5 la parte visible muchas veces es nada. Ahí display tiene por defecto "omitted", así que los thinking blocks llegan con el campo thinking vacío mientras se cobra el reasoning completo.

max_tokens es el tope duro de Anthropic para thinking más texto. Pero en un tool loop, "cada request del turno tiene su propio max_tokens, así que no acota el gasto del turno completo".

La documentación de Gemini cierra el conjunto. max_output_tokens incluye los thought tokens. Si el modelo lo alcanza mientras razona, se detiene con status "incomplete" y "devuelve output truncado o vacío (aunque igual cobra los thinking tokens generados)". El precio "se basa en todos los thought tokens que el modelo necesita generar, aunque la API solo devuelva el resumen".

Tres proveedores, una regla. El tope es compartido, la factura es completa, la vista es parcial.

Thinking que no puedes apagar

El siguiente cambio es más silencioso. En los modelos más nuevos, el reasoning ya no es opcional.

La tabla por modelo de Anthropic es explícita. En Claude Opus 5.5, Claude Fable 5.1 y Claude Fable 5, un request sin campo thinking recibe adaptive thinking, y thinking: {type: "disabled"} devuelve un 400. Claude Sonnet 5.5 también rechaza disabled. Su ajuste más bajo es "between_tools", aceptado con effort high o menor. Claude Opus 5 puede apagar el thinking, pero solo con effort high o menor. Modelos anteriores como Claude Opus 4.8 todavía tienen el thinking apagado por defecto.

Los defaults de effort también difieren. El de Anthropic es medium en Claude Opus 5.5 y high en los demás modelos que soportan effort. gpt-5.5 de OpenAI usa medium por defecto.

Los modelos más nuevos de OpenAI estrechan el rango desde el otro lado. GPT-6 Astra acepta de low a max, y enviar none "devuelve HTTP 400". GPT-6.1 Sol no soporta ni none ni minimal y usa medium por defecto. La documentación de compatibilidad de Google dice que el reasoning "no se puede apagar en Gemini 2.5 Pro ni en los modelos 3".

Así que el reasoning_effort: "none" que está en la config de un agente es ahora un pedido que una parte creciente de los modelos no puede cumplir. Lo que le pase depende de quién esté en el medio.

Un string, siete significados

Rastreamos un único valor, reasoning_effort: "high", por cada capa que pudimos leer. Cada una lo convierte en algo distinto.

# reasoning_effort "high", por capa (docs y código leídos el 3 oct 2026)
OpenAI Chat Completions          valor del enum; el modelo decide cuántos tokens
Gemini, compatibilidad OpenAI    thinking_level "high" (modelos Gemini 3 de su tabla)
                                 thinking_budget 24.576 (Gemini 2.5)
Anthropic, compatibilidad OpenAI ignorado
LiteLLM → Claude, budget manual  thinking.budget_tokens 4.096
LiteLLM → Claude, adaptive       thinking adaptive + output_config.effort "high"
OpenRouter → budget Anthropic    budget_tokens = 0,8 × max_tokens, acotado 1.024–128.000
Ollama 0.30.6, qwen3             thinking encendido, idéntico a no enviar nada

La misma palabra fija un thinking budget de 4.096 tokens en un camino, de 24.576 en otro, el 80 por ciento del tope que pongas en un tercero, y nada en absoluto en un cuarto.

El extremo bajo diverge todavía más. Google mapea minimal a low en Gemini 3.1 Pro, lo mantiene como minimal en Gemini 3 Flash y lo convierte en un budget de 1.024 tokens en Gemini 2.5. none apaga el thinking solo en los modelos 2.5. OpenRouter envía minimal a Claude como low y rechaza none. La documentación actual de Ollama hace alias de minimal a low para modelos sin metadata de niveles. En los modelos que la tienen, los nombres no soportados "se resuelven al default del modelo". El build 0.30.6 que corrimos rechaza minimal con un 400.

LiteLLM maneja none eliminando tanto thinking como output_config del request a Anthropic. Leído contra la tabla de Anthropic, ese request llega a Claude Fable 5.1 sin campo thinking. Eso significa adaptive thinking con el effort por defecto del modelo, high. Según nuestra lectura, pedirle a LiteLLM none en ese modelo compra más reasoning que pedirle low. No ejecutamos esa llamada. La conclusión se sigue del código y de la tabla.

Solo una de las capas que leímos ofrece un tope duro sobre el reasoning por sí solo. El sampling parameter thinking_token_budget de vLLM es el "número máximo de tokens permitidos para operaciones de thinking". Cuando se agota, el sampler fuerza la secuencia de fin de reasoning del modelo fijando el logit de ese token en 1e9. Las APIs hosteadas ofrecen controles más blandos. Anthropic llama al effort "una señal de comportamiento, no un token budget estricto", y a su budget_tokens legacy "un objetivo más que un tope estricto". Solo el output total tiene tope duro.

Los recibos divergen tanto como los controles. El schema de OpenAI incluye completion_tokens_details.reasoning_tokens. La API nativa de Anthropic reporta usage.output_tokens_details.thinking_tokens, que en streams aparece solo en el evento message_delta final. La Interactions API de Gemini reporta total_thought_tokens. El protocolo de vLLM también define un campo reasoning_tokens.

Pero el propio endpoint compatible con OpenAI de Anthropic lista usage.completion_tokens_details como "Always empty", marca reasoning_effort como "Ignored" y aclara que "el SDK de OpenAI no devuelve el thinking de Claude". En la familia Claude 5, donde el thinking está encendido por defecto, un agente que usa esa superficie paga reasoning que no puede ver, que no puede ajustar con el campo que conoce y que no puede desglosar.

Lo corrimos: una respuesta de seis caracteres

Para ver la mecánica de punta a punta, corrimos un modelo pequeño con thinking a través del endpoint compatible con OpenAI de Ollama. El setup: Ollama 0.30.6 (la última release es la 0.35.1, del 29 de septiembre), qwen3:1.7b en Q4_K_M, solo CPU, una context window de 4.096 tokens, temperature 0 y un seed fijo. Un solo prompt: un comercio cobra 0,0025 USDC por llamada, un agente hace 37 llamadas y luego 12 más, ¿cuál es el total? Responde solo con el número.

# Ollama 0.30.6, qwen3:1.7b, POST /v1/chat/completions, 3 oct 2026
# request                          finish    completion_tokens  contenido visible
default (thinking on)              stop         917             "0.1225"
reasoning_effort "low"             stop         917             idéntico
reasoning_effort "high"            stop         917             idéntico
reasoning_effort "none"            stop          38             "0.0025 × (37 + 12) = 0.0025 × 49 = 0.1225 USDC"
max_tokens 256                     length       256             "" (vacío)
max_tokens 256, effort "low"       length       256             ""
stream + include_usage, tope 300   length       300             0 chunks de content, 298 de reasoning
reasoning_effort "minimal"         HTTP 400     invalid reasoning value
reasoning_effort "xhigh"           HTTP 400     invalid reasoning value

La respuesta fue correcta siempre. La factura no fue estable. Con thinking encendido, seis caracteres visibles costaron 917 completion tokens. Con thinking apagado, una oración completa con el cálculo costó 38. Es una diferencia de 24x para la misma pregunta y el mismo número correcto. Una primera corrida, antes de fijar la context window y la cantidad de threads, cobró 1.457 tokens por los mismos seis caracteres.

low y high produjeron un output idéntico a no enviar nada. medium y max también dejaron el thinking encendido. En este modelo el campo es un interruptor con una sola posición que funciona, none.

Las llamadas con tope son la falla que importa para el billing. Con max_tokens en 256, el modelo gastó los 256 tokens razonando y devolvió un content vacío con finish_reason: "length". Todos los tokens fueron facturables. Ninguno fue utilizable.

El stream mostró lo mismo chunk por chunk: 298 chunks de reasoning, cero chunks de content y un bloque de usage final que reportó 300 completion tokens. Dos tokens nunca aparecieron en ninguno de los dos campos.

Ninguna respuesta incluyó completion_tokens_details. La única evidencia de cómo se repartieron los 917 tokens fue el propio texto de reasoning, que un cliente tendría que volver a tokenizar para auditar. Apagar el thinking también cambió el lado del input: prompt_tokens pasó de 53 a 59.

Es un modelo de 2.000 millones de parámetros en una CPU, no una API de frontera. Las magnitudes en los modelos hosteados son otras. La mecánica no. Los proveedores documentan los mismos comportamientos que medimos: un tope compartido, una respuesta vacía al llegar al tope que igual se cobra, y ningún desglose en al menos una capa de compatibilidad importante.

Lo que el reasoning le hace a la reserva

Pon esos hechos en la fórmula de la reserva. El tope es ahora el único límite duro del costo de una llamada, y tiene que cubrir thinking que el agente nunca pidió ver.

# Lado output de la reserva = tope × precio de lista de output (sin input)
# modelo            $/MTok out   tope 1.000   tope 25.000   tope 128.000
GPT-6 Astra           50          $0,05        $1,25         $6,40
Claude Fable 5.1      50          $0,05        $1,25         $6,40
Claude Opus 5.5       20          $0,02        $0,50         $2,56
GPT-5                 10          $0,01        $0,25         $1,28

La recomendación inicial de OpenAI de 25.000 tokens pone el lado output de la reserva en $1,25 por llamada en GPT-6 Astra o Claude Fable 5.1. Con el límite de output de 128.000 tokens de cualquiera de los dos, son $6,40. Por encima de 272.000 input tokens, OpenAI cobra el request completo de GPT-6 Astra a 1,5x la tarifa de output y 2x la de input, así que las llamadas de contexto largo retienen más.

El instinto del agente es dimensionar el tope para la respuesta que quiere. Ese es justo el ajuste que falla. Un tope de 1.000 tokens en un modelo que piensa por defecto reproduce nuestro resultado de 256 tokens a mayor escala: termina por length, content vacío, cobro completo. Un retry ingenuo con el mismo tope vuelve a pagar por el mismo resultado vacío.

Cuatro efectos más se acumulan a lo largo de un loop de agente.

Tool loops. Cada request de un turno con tool use lleva su propio tope, así que ningún max_tokens individual acota lo que cuesta un turno. La reserva acota llamadas. Solo una política de gasto acota una tarea.

Historial multi-turno. Anthropic mantiene en contexto los thinking blocks de turnos anteriores en Claude Opus 4.5 y los Opus posteriores, Sonnet 4.6 y los Sonnet posteriores, y los modelos Fable. Esos bloques "se cobran como input tokens igual que el resto del historial de la conversación". El reasoning se paga dos veces: una como output al generarse y otra como input en cada turno posterior que lo arrastra. La familia GPT-5.6 de OpenAI ahora también renderiza por defecto el reasoning de turnos anteriores en el contexto.

Caching. Anthropic renderiza el effort resuelto dentro del prompt, así que cambiar el effort entre requests invalida los cache breakpoints. Un gateway que baja el effort en algunas llamadas para ahorrar puede perder más en cache misses de lo que ahorra en thinking. Anthropic, en beta, y OpenAI, en la familia GPT-6, ya ofrecen cambios de effort por mensaje que mantienen intacto el prefix cacheado. Calculamos el lado del cache de esto en el post sobre prompt caching.

Fallback. Un thinking block solo lo puede leer el modelo que lo produjo y un conjunto fijo de otros. Anthropic descarta los bloques que el modelo destino no puede leer "sin error y sin cobrarlos". Pasar de Claude Opus 5.5 a Claude Fable 5.1 conserva el reasoning anterior en la Claude API. Pasar en sentido inverso lo descarta. OpenAI omite el reasoning entre familias de modelos. Una cadena de fallback que cruza esas líneas pierde la continuidad del reasoning a mitad de conversación. También puede caer en un modelo cuyo default de thinking es el opuesto al del primer eslabón.

upto pone precio al techo, no al pensamiento

El scheme upto de x402 se escribió justo para esta varianza. El cliente autoriza un máximo. El servidor liquida un monto real "determinado al momento del settlement según el consumo del recurso". El monto liquidado no puede superar el máximo y "PUEDE ser 0". El primer caso de uso de ejemplo de la spec es "pagar por la generación de tokens de un LLM". Cada autorización se liquida como máximo una vez, y el streaming con múltiples settlements queda explícitamente fuera de alcance.

Eso cubre la brecha entre nuestras llamadas de 917 y de 38 tokens. No le dice al servidor qué significa "real" cuando el reasoning se comió el tope y la respuesta volvió vacía. El upstream le cobra esos tokens al gateway de todas formas. Si el agente los paga, y si puede probar qué pagó, es una política que el gateway tiene que declarar y un recibo que tiene que emitir.

Sondeamos nuestra propia superficie walk-up para ver qué cotiza hoy. Un POST /v1/chat/completions sin autenticar devuelve HTTP 402 con un requirement exact en USDC sobre Base. Variamos solo el modelo y los campos de tokens.

# api.llm4agents.com, POST /v1/chat/completions sin autenticar, 3 oct 2026
# body (un mensaje: "hi")                          monto del 402 (USDC, 6 decimales)
openai/gpt-5, sin tope                              50000      $0,05
openai/gpt-5, sin tope, reasoning_effort "high"     50000      $0,05
openai/gpt-5, max_completion_tokens 100000          50000      $0,05
openai/gpt-5, max_tokens 256                        10000      $0,01
openai/gpt-5, max_tokens 1000                       20000      $0,02
openai/gpt-5, max_tokens 100000                     1210000    $1,21
openai/gpt-5, max_tokens 100000, effort "low"       1210000    $1,21
openai/gpt-5, max_tokens 1000000                    12010000   $12,01
anthropic/claude-opus-5.5, sin tope                 100000     $0,10
anthropic/claude-fable-5.1, sin tope                250000     $0,25
openai/gpt-6-astra, sin tope                        250000     $0,25
nonexistent/model-x                                 10000      $0,01

Destacan cuatro cosas. La cotización sigue a max_tokens e ignora max_completion_tokens, el campo que la spec de OpenAI dice que cubre el reasoning y al que apunta su aviso de deprecación. Ignora reasoning_effort, lo cual es defendible, porque el effort es blando y lo que obliga es el tope. No está acotada al límite de output del modelo: un tope de 1.000.000 tokens en GPT-5 produjo una cotización de $12,01, mientras que el límite de output de 128.000 tokens de GPT-5 vale $1,28 a precio de lista. Y un slug de modelo desconocido igual recibió una cotización.

Las cotizaciones sin tope son las que importan para el reasoning. Para GPT-5, Claude Opus 5.5, Claude Fable 5.1 y GPT-6 Astra, la cotización por defecto cubre como máximo 5.000 output tokens al precio de lista de cada proveedor. Es una quinta parte de la recomendación inicial de OpenAI para modelos de reasoning, en modelos que piensan por defecto. La cotización y el límite del upstream deberían ser el mismo número. Nuestro contrato público no dice cómo se concilian los dos cuando un agente omite el tope.

Qué significa para LLM4Agents

Nuestra OpenAPI pública describe un request de Chat Completions con model o un array de fallback models, messages, temperature, max_tokens y stream. Define additionalProperties: true, así que otros campos pasan la validación, pero no documenta ninguno de los controles de reasoning. El objeto usage de la respuesta lista prompt_tokens, completion_tokens y total_tokens. Los headers de billing son X-Tokens-Input, X-Tokens-Output, X-Cost-Usd-Cents y X-Model-Used. Nada le dice a un agente cuánto de X-Tokens-Output fue thinking.

La amenaza es una migración que nadie anuncia. A medida que los agentes pasan a la familia Claude 5 y a GPT-6, el thinking llega por defecto. Los topes dimensionados para texto visible empiezan a devolver respuestas vacías que igual se cobran. Las cadenas de fallback que mezclan modelos con thinking obligatorio y opcional cambian el costo por salto en un orden de magnitud, como mostró la diferencia de 24x incluso en un modelo diminuto.

La superficie que hablamos también tiene un nuevo límite duro. La guía de reasoning de OpenAI dice que Chat Completions "no soporta function calling con GPT-6 Astra ni GPT-6.1 Sol". Para agentes que usan tools en esos modelos, la superficie Responses que auditamos ayer es un requisito, no una opción.

La oportunidad es que el gateway es la única parte que ve ambos lados. Puede llamar a la API nativa de cada proveedor, donde el conteo de reasoning existe, en lugar de a un endpoint de compatibilidad, donde puede no existir. Puede conocer el default de thinking, el vocabulario de effort y el límite de output de cada modelo. Un agente que paga por llamada no puede armar esa tabla por su cuenta. Un gateway que la publica, la hace cumplir y la pone en el recibo vende algo que los propios endpoints de compatibilidad de los proveedores no venden.

Cómo mantenerse en la frontera

Primero, corregir los inputs de la cotización. Respetar max_completion_tokens como tope siempre que esté presente. Acotar el tope al límite de output del modelo. Rechazar slugs de modelo desconocidos antes de emitir un 402. Reenviar explícitamente al upstream el tope con el que se calculó la cotización, para que la cotización y el límite sean un solo número.

Segundo, poner el reasoning en el recibo. Devolver completion_tokens_details.reasoning_tokens en cada respuesta y en el chunk final del stream, mapeado desde el campo nativo de cada proveedor. Agregar un header X-Tokens-Reasoning junto a X-Tokens-Output. Cuando un upstream no reporte el desglose, preferir la API nativa de ese proveedor. Si eso es imposible, etiquetar la cifra como estimada en lugar de omitirla.

Tercero, publicar la tabla de effort y fallar con honestidad. Una fila por modelo: default de thinking, valores de effort aceptados, a qué se mapea cada valor en el upstream y si el thinking se puede apagar. Cuando un agente pida algo que el modelo no puede hacer, como none en Claude Fable 5.1 o GPT-6 Astra, devolver un 400 que lo diga. Nunca convertir en silencio.

Cuarto, agregar un piso de reasoning. En modelos que piensan por defecto, advertir o rechazar cuando el tope esté por debajo de un piso publicado, partiendo de la guía de 25.000 tokens de OpenAI. Detectar el caso vacío-en-el-tope, finish_reason: "length" con content vacío y reasoning presente, y marcarlo en un header para que los clientes no reintenten con el mismo tope.

Quinto, mover el walk-up de LLM a upto. Cotizar el techo, liquidar los tokens medidos e incluir el conteo de reasoning en el recibo de settlement. Eso es reserve-proxy-settle sobre el riel x402.

Sexto, darle al fallback una regla de reasoning. Cotizar las cadenas con el tope y el precio del peor eslabón. Mantener el effort fijo durante una conversación, usando cambios de effort por mensaje donde el upstream los soporte, para que el cache sobreviva. Fijar las conversaciones que llevan thinking blocks a modelos que puedan leerlos, o descartar los bloques de forma explícita y avisarlo.

Séptimo, exponer topes duros donde existan, y después medir. Para upstreams self-hosted sobre vLLM, mapear un campo documentado a thinking_token_budget, el único tope duro de reasoning que encontramos. Correr el set de sondas de este post contra cada modelo enrutado de forma periódica, cubriendo la tasa de vacío-en-el-tope, la proporción de reasoning en el output y los valores de effort que devuelven 400, y publicar los resultados.

Paga por thinking que puedas auditar

Un gateway compatible con OpenAI, pagado por llamada en USDC sobre x402.

Registra tu agente