Pensamiento preservado
El pensamiento preservado permite que un modelo use un bloque de pensamiento de un turno anterior solo si ese modelo o uno de un conjunto fijo de otros modelos lo produjo y nada antes del bloque ha cambiado.
El "preserved thinking" (pensamiento preservado) es una propiedad de los modelos Claude más recientes que protege contra la "distillation" (destilación). Determina si el modelo puede usar un bloque de pensamiento que envías de vuelta desde un turno anterior. A partir de Claude Fable 5.1, cuando un bloque thinking o redacted_thinking vuelve en una solicitud, la API verifica dos cosas en la signature del bloque:
- El modelo puede leer el bloque. Cada modelo lee sus propios bloques de pensamiento y los de un conjunto fijo de otros modelos. Claude Fable 5.1 lee bloques de Claude Opus 5 y, en la API de Claude, de Claude Opus 5.5; ni Claude Opus 5 ni Claude Opus 5.5 leen bloques de Claude Fable 5.1. Si el modelo actual no puede leer un bloque, la API lo descarta de esa solicitud sin generar un error. Consulta Cambiar de modelo a mitad de la conversación.
- Nada antes del bloque de pensamiento ha cambiado. La indicación del sistema
systemde nivel superior,toolsy losmessagesanteriores al bloque son su "prefix" (prefijo). Si el prefijo difiere de lo que enviaste cuando se produjo el bloque, ese bloque y todos los bloques de pensamiento posteriores son inválidos, y la API rechaza la solicitud con un error 400 o descarta los bloques inválidos, según lo que elijas. Consulta Mantener el prefijo sin cambios.
Los bloques de pensamiento de Claude Sonnet 5.5 y Claude Haiku 5.5 también están vinculados a la cuenta que los produjo. Consulta Los bloques de pensamiento permanecen con la cuenta que los produjo para saber dónde aplica esto la API.
La verificación del modelo se aplica a todas las cuentas. La API aplica la verificación del prefijo de forma predeterminada para las cuentas creadas a partir del 31 de agosto de 2026, 00:00 UTC. En las cuentas más antiguas, aplica la verificación del prefijo solo en las solicitudes que establecen thinking.block_binding.prefix_mismatch_behavior. Haz que tu integración sea de solo anexar ("append-only") sin importar la antigüedad de tu cuenta, para que el mismo código funcione en todas las cuentas, incluidas las cuentas más nuevas en las que se aplica de forma predeterminada.
Quién necesita cambiar algo
No cambia nada para ti si Claude Code, claude.ai, Claude Managed Agents o el Claude Agent SDK construyen tus solicitudes, o si tu código mantiene system y tools fijos durante una sesión y solo anexa a messages. Claude Mythos 5.1 y los modelos anteriores a Claude Fable 5.1 no ejecutan la verificación del prefijo. Si nunca envías bloques de pensamiento de vuelta, la verificación del prefijo no tiene nada que rechazar, y el modelo no recibe nada de su razonamiento anterior.
Revisa tu integración si, entre dos solicitudes de una misma conversación, hace alguna de las siguientes cosas. Cada elemento enlaza a lo que debes hacer en su lugar:
- Reconstruye la indicación del sistema
system: la fecha, un indicador de modo, instrucciones del proyecto releídas, o un plugin o servidor MCP que se conecta después del primer turno - Vuelve a renderizar el contexto en el primer mensaje del usuario
- Borra o acorta resultados de herramientas antiguos, o vuelve a codificar imágenes antiguas
- Resume o descarta turnos antiguos en el cliente y conserva los turnos recientes con su pensamiento
- Agrega, elimina o edita entradas en
tools - Agrega un recordatorio a un turno del usuario y luego lo elimina o lo reescribe
- Descarta algunos bloques
thinkingy conserva los posteriores, o los elimina y luego los vuelve a poner - Reconstruye una sesión guardada a partir de plantillas en lugar de reproducir lo que envió
En una cuenta más antigua, ninguno de estos casos produce un error a menos que la solicitud establezca prefix_mismatch_behavior, así que una ejecución sin errores con tu propia clave no muestra si tu código está afectado. Si otras personas ejecutan tu herramienta con sus propias claves de API, quienes tengan cuentas más nuevas recibirán el error 400 antes que tú. Para ver lo que ellos ven sin cambiar el comportamiento de tus solicitudes, envía el encabezado beta thinking-binding-controls-2026-08-01. En una cuenta más antigua, cada respuesta marca entonces los bloques que no pasan la verificación, y el modelo aún los lee (consulta Establecer el comportamiento ante discrepancias y leer input_transformations).
Revisa también tu integración si envía bloques de pensamiento de Claude Sonnet 5.5 o Claude Haiku 5.5 de una cuenta en una solicitud hecha por otra cuenta. Consulta Los bloques de pensamiento permanecen con la cuenta que los produjo.
Cambiar de modelo a mitad de la conversación
Claude Fable 5.1 y Claude Mythos 5.1 leen los bloques de pensamiento producidos por el otro y por modelos Claude anteriores. Ningún otro modelo lee bloques de pensamiento de Claude Fable 5.1 ni de Claude Mythos 5.1.
Claude Opus 5.5 lee bloques de pensamiento de Claude Opus 5, de modelos Opus, Sonnet y Haiku anteriores y, en la API de Claude y Google Cloud, de Claude Sonnet 5.5 y Claude Haiku 5.5, pero no de los modelos Claude Fable ni Claude Mythos. En la API de Claude, Claude Fable 5.1 y Claude Mythos 5.1 leen bloques de pensamiento de Claude Opus 5.5; ningún otro modelo lo hace. Así, una conversación que pasa de Claude Opus 5 a Claude Opus 5.5 conserva su razonamiento, y también lo conserva una que sube de Claude Opus 5.5 a Claude Fable 5.1 o Claude Mythos 5.1 en la API de Claude. Una que pasa de Claude Fable 5.1 o Claude Mythos 5.1 a Claude Opus 5.5, o de Claude Opus 5.5 a cualquier modelo distinto de esos dos, ejecuta los turnos posteriores al cambio sin el razonamiento del modelo anterior. Los bloques se descartan, no se rechazan, como se describe más adelante en esta sección.
Claude Sonnet 5.5 lee bloques de pensamiento de Claude Sonnet 5, Claude Opus 4.8, Claude Haiku 4.5 y modelos anteriores, y, en la API de Claude y Google Cloud, de Claude Haiku 5.5, pero no de Claude Opus 5, Claude Opus 5.5 ni de ningún modelo Claude Fable o Claude Mythos. En la API de Claude y Google Cloud, Claude Opus 5.5 lee bloques de pensamiento de Claude Sonnet 5.5; ningún otro modelo lo hace. Así, una conversación que pasa de Claude Sonnet 5 a Claude Sonnet 5.5 conserva su razonamiento, y también lo conserva una que sube de Claude Sonnet 5.5 a Claude Opus 5.5 en la API de Claude y Google Cloud. Una que pasa a Claude Sonnet 5.5 desde Claude Opus 5, Claude Opus 5.5 o un modelo Claude Fable o Claude Mythos ejecuta los turnos posteriores al cambio sin el razonamiento del modelo anterior. Lo mismo ocurre con cualquier otro cambio que se aleje de Claude Sonnet 5.5, por ejemplo un fallback del lado del servidor a Claude Sonnet 5.
Claude Haiku 5.5 lee bloques de pensamiento de Claude Sonnet 5, Claude Opus 4.8, Claude Haiku 4.5 y modelos anteriores, pero no de Claude Opus 5, Claude Opus 5.5, Claude Sonnet 5.5 ni de ningún modelo Claude Fable o Claude Mythos. En la Claude API y Google Cloud, Claude Opus 5.5 y Claude Sonnet 5.5 leen bloques de pensamiento de Claude Haiku 5.5; ningún otro modelo lo hace. Así, una conversación que pasa de Claude Haiku 4.5 a Claude Haiku 5.5 conserva su razonamiento, y también lo conserva una que sube de Claude Haiku 5.5 a Claude Opus 5.5 o Claude Sonnet 5.5 en la Claude API y Google Cloud. Una que pasa a Claude Haiku 5.5 desde Claude Opus 5, Claude Opus 5.5, Claude Sonnet 5.5 o un modelo Claude Fable o Claude Mythos ejecuta los turnos posteriores al cambio sin el razonamiento del modelo anterior, y lo mismo ocurre con cualquier otro cambio que se aleje de Claude Haiku 5.5.
- Una conversación que pasa a Claude Fable 5.1 desde un modelo anterior, o desde Claude Opus 5.5 en la Claude API, conserva su razonamiento. Los bloques de pensamiento del modelo anterior siguen siendo legibles, por lo que el modelo piensa como de costumbre desde el primer turno después del cambio.
- Una conversación que pasa de Claude Fable 5.1 a cualquier modelo distinto de Claude Mythos 5.1 pierde el razonamiento de Claude Fable 5.1 para esa solicitud. Esto ocurre cuando un enrutador envía un turno a un modelo más económico, después de un fallback por rechazo del clasificador, o durante un fallback del lado del servidor. La API elimina los bloques ilegibles antes de que el prompt llegue al modelo. No se facturan y no cuentan para
input_tokens.
Sigue enviando el historial completo en cada solicitud, incluidos los bloques de pensamiento, y deja que la API descarte lo que el modelo actual no puede leer. La API nunca edita tu arreglo messages, así que los bloques descartados permanecen en tu historial. Cuando el mismo historial vuelve a Claude Fable 5.1, sus bloques vuelven a ser legibles, junto con el pensamiento del modelo anterior. El razonamiento se pierde definitivamente solo si tu cliente elimina los bloques por sí mismo, por ejemplo un harness que quita el pensamiento al cambiar de modelo o que reconstruye el historial a partir de lo que usó cada modelo.
Con el encabezado beta thinking-binding-controls-2026-08-01, la respuesta enumera cada bloque descartado en un arreglo input_transformations de nivel superior con reason: "model_binding_mismatch":
{
"input_transformations": [
{
"type": "thinking_dropped",
"path": "messages.3.content.0",
"reason": "model_binding_mismatch"
}
]
}Sin el encabezado, el descarte es silencioso. Esta entrada no es un error en tu integración, y prefix_mismatch_behavior no tiene efecto sobre ella: un bloque que el modelo actual no puede leer siempre se descarta.
Los bloques de pensamiento permanecen con la cuenta que los produjo
Los bloques de pensamiento que produce Claude Sonnet 5.5 o Claude Haiku 5.5 funcionan solo en la cuenta que los produjo, o en una cuenta vinculada a ella. Cuando otra cuenta envía uno de estos bloques, la API descarta el bloque antes de que el modelo lo vea, y la solicitud se completa correctamente. El modelo responde sin el razonamiento de los bloques descartados. Los bloques de modelos anteriores no se ven afectados.
En la API de Claude y Google Cloud, con el encabezado beta thinking-binding-controls-2026-08-01, la respuesta enumera cada bloque descartado en input_transformations como una entrada thinking_dropped con reason: "organization_binding_mismatch". Sin el encabezado, el descarte es silencioso.
Mantener el prefijo sin cambios
En Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 y Claude Haiku 5.5, un bloque de pensamiento sigue siendo válido solo mientras todo lo que enviaste antes de él permanezca sin cambios en las solicitudes posteriores. El prefijo verificado tiene tres partes:
- La indicación del sistema
systemde nivel superior - El conjunto de
tools - Cada
messageanterior al bloque
Nota: Con la compactación del lado del servidor, el prefijo verificado comienza en el bloque de compactación más reciente.
Los parámetros de la solicitud fuera de esos tres campos, como effort, max_tokens, output_config, tool_choice y metadata, no forman parte de la verificación del prefijo, y tampoco los marcadores cache_control. Qué cuenta como una edición tiene la lista completa.
Los bloques de pensamiento anteriores no están en el prefijo, pero cada bloque de pensamiento registra qué bloque de pensamiento vino antes que él, a lo largo de los turnos. Puedes eliminar bloques de pensamiento del inicio del historial (los más antiguos primero), del final, o todos. Lo que falla es un hueco: los bloques de pensamiento que conserves deben ser una secuencia ininterrumpida de la secuencia original, así que eliminar uno del medio invalida los bloques de pensamiento posteriores. Una vez que elimines un bloque, déjalo fuera. Volver a ponerlo invalida los bloques de pensamiento producidos mientras no estaba.
Mantén system y tools fijos durante la sesión y trata messages como de solo anexar. La misma disciplina mantiene estable el prefijo para el almacenamiento en caché de prompts: las ediciones que invalidan el pensamiento son las mismas que reinician la caché.
Qué hace la API con un bloque no válido
Lo eliges con thinking.block_binding.prefix_mismatch_behavior:
"error"(el valor predeterminado): la API rechaza la solicitud con uninvalid_request_error400 que nombra el primer bloque que falla."drop_block": la API descarta cada bloque que falla y todos los bloques de pensamiento posteriores, y la solicitud se completa correctamente. Los bloques descartados no se facturan. El modelo responde ese turno sin usar el razonamiento de los bloques descartados, y la caché de prompts se reinicia en el punto de la edición. La respuesta enumera cada bloque descartado eninput_transformations(en el eventomessage_startcuando usas streaming) conreason: "prefix_binding_mismatch".
Cuenta las respuestas de cada sesión cuyo input_transformations tenga una entrada prefix_binding_mismatch, genera alertas sobre ellas y reemplaza cada edición con el patrón correspondiente en Hacer cambios sin editar el prefijo. En la Message Batches API, un elemento que deja el campo sin establecer no falla. Donde la API aplica la verificación de forma predeterminada, en su lugar descarta los bloques que fallan. Establece "error" explícitamente en ese caso si quieres que los elementos del lote fallen.
Tanto el campo como el arreglo input_transformations requieren el encabezado beta thinking-binding-controls-2026-08-01. Establecer el comportamiento ante discrepancias y leer input_transformations muestra la solicitud en cada SDK.
El mensaje del error 400 comienza así:
messages.1.content.0: Invalid `signature` in `thinking` block. The block is bound to a different conversation. Remove the block, or set `thinking.block_binding.prefix_mismatch_behavior` to "drop_block".Si la solicitud no envió el encabezado beta, el mensaje continúa así:
That setting requires the `thinking-binding-controls-2026-08-01` value in the `anthropic-beta` header.Normalmente termina con una oración que indica qué cambió, por ejemplo, que la indicación del sistema system o la lista de tools difiere de cuando se creó el bloque. Solución de problemas del pensamiento describe lo que puede indicar esa oración.
Una firma manipulada o que no se puede descifrar es un fallo distinto. Siempre devuelve un 400 (Invalid `signature` in `thinking` block sin ninguna oración sobre la conversación), y prefix_mismatch_behavior no se aplica a ella.
Costo en tokens de salida de "drop_block"
En las pruebas de Anthropic con un benchmark de programación de múltiples turnos, descartar bloques de pensamiento una vez por sesión aumentó los tokens de salida en un 2.5% con esfuerzo bajo, 3.9% con medio, 4.5% con alto y 20.1% con máximo. Descartarlos en cada turno después del primero aumentó los tokens de salida en un 4.6% con esfuerzo bajo, 9.7% con medio, 10.3% con alto y 67.1% con máximo. Estas cifras son estimaciones con amplios márgenes de error, y el impacto en tu carga de trabajo depende de tu harness.
Cuando Claude ya no puede leer el razonamiento de turnos anteriores, vuelve a crear ese razonamiento, por lo que las solicitudes que descartan bloques de pensamiento generan más tokens de salida y pueden tardar más en responder. Un descarte en cada turno cuesta más que un descarte ocasional, y cuánto más depende de tu harness: con qué frecuencia edita el prefijo y cuánto se basa cada turno en el razonamiento anterior.
Antes de depender de "drop_block", ejecuta evaluaciones en tu propia carga de trabajo para medir el aumento. Si es pequeño, "drop_block" puede hacer que las solicitudes sigan completándose correctamente mientras corriges la edición. En cualquier caso, corregir la edición con un patrón de Hacer cambios sin editar el prefijo es una mejor solución a largo plazo.
Manejar el error en el código
Este es el invalid_request_error 400 mostrado anteriormente en esta sección. No reenvíes el mismo cuerpo: falla de la misma manera cada vez. Reintenta una vez con el encabezado beta y prefix_mismatch_behavior: "drop_block", como solución provisional ("drop_block" puede aumentar los tokens de salida), y guarda esa elección con la sesión para que cada solicitud posterior también la envíe, incluso después de un reinicio. En Claude Sonnet 5.5 y Claude Haiku 5.5, block_binding funciona solo con thinking: {"type": "adaptive"}. Con between_tools en Claude Sonnet 5.5, o thinking: {"type": "disabled"} en Claude Haiku 5.5, mantén el historial de solo anexar, o elimina los bloques de pensamiento desde el turno editado en adelante. Si no puedes enviar el encabezado beta, elimina todos los bloques thinking y redacted_thinking del historial una vez, déjalos fuera y continúa. Luego corrige la edición que causó la discrepancia.
Establecer el comportamiento ante discrepancias y leer input_transformations
El encabezado beta thinking-binding-controls-2026-08-01 agrega:
- Un arreglo
input_transformationsde nivel superior en cada respuesta - Un objeto
block_bindingen la configuración dethinking, cuyo único campo esprefix_mismatch_behavior
block_binding se acepta junto con thinking.type: "adaptive" y thinking.type: "enabled". En Claude Sonnet 5.5 y Claude Haiku 5.5, block_binding solo funciona con thinking: {"type": "adaptive"}. Enviarlo con between_tools en Claude Sonnet 5.5, o con thinking: {"type": "disabled"} en Claude Haiku 5.5, devuelve un error 400. Enviarlo sin el encabezado beta devuelve un error 400 cuyo mensaje termina en block_binding: Extra inputs are not permitted. Los modelos que no ejecutan la verificación del prefijo aceptan el objeto e informan solo los descartes de la verificación del modelo, así que un mismo cuerpo de solicitud funciona en todos los modelos. La referencia de la API llama a la verificación del prefijo la verificación de la conversación.
La siguiente solicitud opta por descartar en lugar de rechazar. En un primer turno no hay nada que reproducir, así que input_transformations vuelve vacío:
client = anthropic.Anthropic()
response = client.beta.messages.create(
model="claude-fable-5-1",
max_tokens=16000,
thinking={
"type": "adaptive",
"block_binding": {"prefix_mismatch_behavior": "drop_block"},
},
messages=[
{
"role": "user",
"content": "What is the greatest common divisor of 1071 and 462?",
}
],
betas=["thinking-binding-controls-2026-08-01"],
)
for block in response.content:
if block.type == "text":
print(block.text)
print(f"Input transformations: {len(response.input_transformations or [])}")The greatest common divisor of 1071 and 462 is 21.
Input transformations: 0Con el encabezado beta, cada respuesta de un modelo con capacidad de pensamiento incluye input_transformations. Cada entrada identifica un bloque de pensamiento por su path (por ejemplo messages.1.content.0) e indica un reason. Hay dos tipos de entrada:
thinking_dropped: la API descarta el bloque antes de que el modelo lo lea, y el bloque no se factura. Elreasonesprefix_binding_mismatchomodel_binding_mismatch(consulta Cambiar de modelo a mitad de la conversación). Elreasontambién puede serorganization_binding_mismatch, lo que significa que el bloque vino de otra cuenta (consulta Los bloques de pensamiento permanecen con la cuenta que los produjo).thinking_mismatch_allowed: el bloque no pasa la verificación del prefijo, pero la API no aplica esa verificación para esta solicitud, así que el bloque llega al modelo sin cambios y se factura. Elreasonsiempre esprefix_binding_mismatch. Esta entrada aparece solo en solicitudes en las que la API no aplica la verificación de forma predeterminada, como las de una cuenta más antigua (consulta Cuándo aplica la API la verificación). Establecerprefix_mismatch_behavioren cualquiera de sus valores hace que la solicitud opte por la aplicación, así que una solicitud que lo establece nunca recibe esta entrada.
El arreglo está vacío cuando no se descartó ningún bloque y ninguno falló la verificación del prefijo. Ignora las entradas cuyo type o reason no reconozcas, porque las verificaciones futuras agregarán valores.
Al usar streaming, el arreglo llega en el objeto message del evento message_start. Después de un fallback del lado del servidor a mitad del stream, el evento message_delta final lo incluye de nuevo con las entradas del modelo que atiende la solicitud. En un lote de mensajes, un elemento cuyo bloque falla la verificación del prefijo con un "error" explícito se resuelve como errored. Un elemento que deja el campo sin establecer no falla. Donde la API aplica la verificación de forma predeterminada, en su lugar descarta los bloques que fallan. El endpoint de conteo de tokens ejecuta la misma verificación del prefijo y devuelve el mismo 400.
Cuándo aplica la API la verificación
La API aplica la verificación del prefijo en Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 y Claude Haiku 5.5 para las cuentas nuevas.
- Cuentas creadas a partir del 31 de agosto de 2026, 00:00 UTC: la API verifica las solicitudes a Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 y Claude Haiku 5.5 y aplica
"error"a menos que establezcas"drop_block". La misma definición de cuenta nueva se aplica a la API de Claude y a las plataformas en la nube. - Cuentas más antiguas: la API aplica la verificación solo en las solicitudes que establecen
prefix_mismatch_behavior. Establecer el campo hace que una solicitud opte por la aplicación, así que puedes ver lo que ve una cuenta nueva sin crear una. En las solicitudes que lo dejan sin establecer, la API sigue ejecutando la verificación pero deja pasar al modelo los bloques que fallan. Con el encabezado beta, la respuesta enumera cada uno eninput_transformationscomothinking_mismatch_allowed, así que puedes encontrar ediciones del prefijo sin cambiar lo que recibe el modelo.
Para saber en qué grupo está tu cuenta, toma una conversación de Claude Fable 5.1 que contenga un bloque de pensamiento, cambia algo antes de ese bloque y envíala a Claude Fable 5.1 sin el encabezado beta ni el campo block_binding. Una respuesta 400 que nombra el encabezado significa que en tu cuenta se aplica de forma predeterminada. Una respuesta 200 significa que no. Para confirmarlo, envía la misma solicitud de nuevo con el encabezado beta, todavía sin block_binding: la respuesta enumera cada bloque de pensamiento posterior a tu edición en input_transformations como thinking_mismatch_allowed.
Qué cuenta como una edición
Cada fila compara dos solicitudes consecutivas:
| Cambio entre solicitudes | Bloques de pensamiento posteriores |
|---|---|
| Agregar mensajes al final | Válidos |
Agregar una herramienta con defer_loading: true a la que nada ha hecho referencia todavía | Válidos |
Eliminar bloques thinking del inicio del historial, del final, o todos | Válidos (el modelo pierde ese razonamiento) |
Cambiar cualquier parámetro de la solicitud fuera de system, tools y messages (effort, max_tokens, output_config, tool_choice, metadata, thinking.display, etc.) | Válidos |
Agregar, mover o eliminar marcadores cache_control | Válidos |
| Una URL firmada rotativa que devuelve los mismos bytes | Válidos |
| La compactación o la edición de contexto del lado del servidor elimina o reemplaza contenido | Válidos (la verificación compara lo que enviaste, no la copia editada del servidor) |
| Un mensaje del sistema con alcance de turno ya borrado que se deja en su lugar | Válidos |
Editar, reordenar o eliminar cualquier mensaje user, assistant o system anterior | Inválidos, excepto cuando el bloque firmado de la compactación bajo demanda reemplaza los mensajes que resume, bajo las condiciones para que el pensamiento conservado siga siendo válido |
| Volver a renderizar con un valor cambiado el contexto que pusiste en el primer mensaje del usuario | Inválidos para todos los bloques de pensamiento |
Borrar o acortar un tool_result anterior, volver a codificar una imagen anterior o cambiar la entrada de un tool_use anterior | Inválidos para todos los bloques de pensamiento posteriores |
| Agregar un bloque de texto a un turno del usuario anterior, o eliminar uno que agregaste la vez anterior | Inválidos |
Cambiar la cadena o los bloques de system de nivel superior | Inválidos |
Agregar, eliminar, renombrar o editar una herramienta en tools | Inválidos |
Eliminar un bloque thinking del medio del historial y conservar los posteriores | Inválidos para todos los bloques de pensamiento posteriores |
Volver a poner un bloque thinking que eliminaste en una solicitud anterior | Inválidos para los bloques de pensamiento producidos mientras no estaba |
| Una URL de imagen o documento que devuelve bytes diferentes en la siguiente solicitud | Inválidos |
| El mismo mensaje con alcance de turno eliminado o reformulado en una solicitud posterior | Inválidos |
Verificar si tu código edita el prefijo
Primero, compara lo que envías. Captura los cuerpos de las solicitudes que envía tu integración durante algunos turnos normales, incluida una compactación o un cambio de herramientas. Para cada par de solicitudes consecutivas, compara system, tools y los messages que comparten. Deben ser idénticos hasta los turnos recién anexados.
Luego confírmalo con la API. Agrega el encabezado beta thinking-binding-controls-2026-08-01, establece prefix_mismatch_behavior en "drop_block" y ejecuta una sesión normal de varios turnos a través de tu integración en . El siguiente ejemplo ejecuta dos turnos como debería hacerlo tu integración: messages solo crece, cada turno del asistente vuelve exactamente como lo devolvió la API, incluidos los bloques thinking, y block_binding se establece en cada solicitud. Después de cada turno imprime el número de bloques thinking en la respuesta y el número de bloques descartados:
client = anthropic.Anthropic()
user_turns = [
"How many positive integers below 500 have exactly 6 positive divisors?",
"How many of those are odd?",
]
# messages crece entre turnos: cada turno del asistente se reenvía tal como se devolvió
messages = []
for user_turn in user_turns:
messages.append({"role": "user", "content": user_turn})
response = client.beta.messages.create(
model="claude-fable-5-1",
max_tokens=16000,
thinking={
"type": "adaptive",
"block_binding": {"prefix_mismatch_behavior": "drop_block"},
},
messages=messages,
betas=["thinking-binding-controls-2026-08-01"],
)
messages.append({"role": "assistant", "content": response.content})
thinking_blocks = sum(block.type == "thinking" for block in response.content)
dropped = len(response.input_transformations or [])
print(f"thinking blocks: {thinking_blocks}, dropped: {dropped}")thinking blocks: 1, dropped: 0
thinking blocks: 1, dropped: 0Ningún turno descarta un bloque porque nada anterior cambió. Verifica que la primera respuesta contenga un bloque thinking. Con el pensamiento adaptativo, algunas respuestas no tienen ninguno. Si ninguna respuesta de la sesión tiene uno, no hay nada que verificar y el conteo de descartados es 0 sin importar lo que cambies, así que vuelve a ejecutar el ejemplo.
Registra input_transformations en cada turno de tu propia integración. Cuando la API descarta un bloque, la entrada se ve así:
{
"input_transformations": [
{
"type": "thinking_dropped",
"path": "messages.1.content.0",
"reason": "prefix_binding_mismatch"
}
]
}- Vacío en cada turno de una sesión que contiene bloques
thinking: tu integración mantiene el prefijo intacto. reason: "prefix_binding_mismatch": algo antes del bloque enpathcambió desde la solicitud anterior. Comparasystem,toolsymessageshasta ese turno para encontrarlo, o vuelve a enviar la solicitud con"error": el 400 normalmente termina con una oración que nombra lo que cambió. Luego busca el reemplazo correspondiente en Hacer cambios sin editar el prefijo.reason: "model_binding_mismatch": la conversación pasó a un modelo que no puede leer los bloques del modelo anterior. Esto no es una edición del prefijo. Consulta Cambiar de modelo a mitad de la conversación.reason: "organization_binding_mismatch": el bloque vino de otra cuenta. Consulta Los bloques de pensamiento permanecen con la cuenta que los produjo.
Para ver un fallo a propósito, envía un tercer turno del ejemplo anterior y agrega una indicación del sistema system solo a esa solicitud, de modo que difiera de las dos primeras solicitudes, que no tenían ninguna. Con "drop_block", el conteo de descartados ya no es 0: la respuesta tiene una entrada por cada bloque de pensamiento del historial, cada una con reason: "prefix_binding_mismatch". Con "error", la solicitud devuelve el 400 descrito en Qué hace la API con un bloque no válido, y su última oración nombra la indicación del sistema system. En las pestañas de cURL y CLI, quita el filtro jq para ver el cuerpo del error. Si el conteo sigue siendo 0, no había nada que verificar: confirma que el modelo sea , que la solicitud establezca block_binding, que el historial que enviaste contenga bloques thinking y que las dos primeras solicitudes no tuvieran indicación del sistema system.
Dos turnos simples rara vez muestran el problema. Ejecuta una sesión a través de cada uno de los siguientes casos, con "error" establecido para que una regresión haga fallar tu CI:
- La primera compactación o recorte del lado del cliente
- Una herramienta, plugin o servidor MCP que se conecta después del primer turno
- Un cambio de modo o de instrucciones
- Un bucle largo de herramientas, si agregas recordatorios o acortas resultados de herramientas antiguos
- Un cambio a otro modelo y de vuelta
- Un guardado, un reinicio y una reanudación en una fecha posterior
En una cuenta más antigua, también puedes observar el tráfico de producción sin optar por la aplicación: envía el encabezado beta, deja fuera block_binding y registra input_transformations. Enviar solo el encabezado no cambia lo que recibe el modelo. Cada bloque de pensamiento que viene después del contenido que editaste falla la verificación y recibe su propia entrada thinking_mismatch_allowed, con los mismos campos path y reason que una entrada thinking_dropped. Los bloques anteriores a la edición siguen pasando. Una edición de system o tools viene antes de todos los bloques, así que hace fallar todos los bloques de pensamiento de la solicitud. Una entrada se ve así:
{
"input_transformations": [
{
"type": "thinking_mismatch_allowed",
"path": "messages.1.content.0",
"reason": "prefix_binding_mismatch"
}
]
}Ejecuta el siguiente ejemplo desde una cuenta más antigua, porque una cuenta más nueva rechaza su tercera solicitud con el 400. El ejemplo envía el encabezado sin block_binding y extiende la sesión anterior con una tercera solicitud que agrega una indicación del sistema, lo que cambia el prefijo a propósito. Después de cada turno imprime el número de bloques thinking y de bloques marcados:
client = anthropic.Anthropic()
user_turns = [
"How many positive integers below 500 have exactly 6 positive divisors?",
"How many of those are odd?",
"And how many of the odd ones are below 100?",
]
# messages crece entre turnos: cada turno del asistente se reenvía tal como se devolvió
messages = []
for turn, user_turn in enumerate(user_turns, start=1):
messages.append({"role": "user", "content": user_turn})
response = client.beta.messages.create(
model="claude-fable-5-1",
max_tokens=16000,
thinking={"type": "adaptive"},
# Solo la última solicitud agrega una indicación del sistema, lo que cambia el prefijo a propósito
system="Answer briefly." if turn == len(user_turns) else anthropic.omit,
messages=messages,
betas=["thinking-binding-controls-2026-08-01"],
)
messages.append({"role": "assistant", "content": response.content})
thinking_blocks = sum(block.type == "thinking" for block in response.content)
flagged = sum(
transformation.type == "thinking_mismatch_allowed"
for transformation in response.input_transformations or []
)
print(f"thinking blocks: {thinking_blocks}, flagged: {flagged}")thinking blocks: 1, flagged: 0
thinking blocks: 1, flagged: 0
thinking blocks: 1, flagged: 2La tercera respuesta marca todos los bloques de pensamiento de los turnos anteriores, uno por turno en esta ejecución, porque la nueva indicación del sistema viene antes de todos ellos. El modelo aun así los leyó.
Maneja estas entradas como lo harías con los descartes prefix_binding_mismatch. La edición está antes del primer bloque enumerado: compara system, tools y messages hasta el path de ese bloque con la solicitud anterior para encontrarla, y luego reemplázala con el patrón correspondiente en Hacer cambios sin editar el prefijo. En una cuenta nueva, o en cualquier solicitud que establezca prefix_mismatch_behavior, la API en cambio rechaza la solicitud o descarta los bloques que fallan. Las entradas son un límite inferior de lo que eliminaría la aplicación: con "drop_block", un bloque que falla también arrastra el resto de los bloques de pensamiento de ese turno, y eliminar un bloque puede hacer que el siguiente también falle. Cuando la API solo registra la verificación, juzga cada bloque por separado y enumera un bloque solo si ese bloque falla.
Hacer cambios sin editar el prefijo
Cada edición común del prefijo tiene un reemplazo que le da al modelo la misma información y deja sin cambios los bytes anteriores, así que el pensamiento posterior sigue siendo válido. Busca en la primera columna la edición que hace tu código hoy:
| En lugar de | Usa | Encabezado beta |
|---|---|---|
Reconstruir la indicación del sistema system de nivel superior | Un mensaje del sistema a mitad de la conversación | Ninguno |
| Volver a renderizar el contexto de tu primer mensaje del usuario (entorno, fecha, memoria, instrucciones del proyecto) en cada solicitud | Renderízalo una vez y vuelve a enviarlo sin cambios. Cuando algo cambie, pon la nueva versión en el turno más reciente | Ninguno |
Borrar o acortar contenido antiguo de tool_result, o volver a codificar imágenes antiguas, en el mismo lugar | Acorta un resultado de herramienta o reduce la resolución de una imagen antes de enviarlo por primera vez, no después. Para borrar resultados antiguos más adelante, recorta el contexto en el servidor con clear_tool_uses_20250919 | context-management-2025-06-27 |
| Inyectar un recordatorio y eliminarlo en la siguiente solicitud | Un mensaje del sistema con alcance de turno (clear_at: "next_user_message") | mid-conversation-system-clear-at-2026-08-21 |
Agregar o eliminar entradas en tools | Bloques tool_addition y tool_removal | inline-tools-2026-09-15 (agrega mcp-client-2026-09-15 cuando la herramienta proviene de un servidor MCP conectado a través del conector MCP), o el más antiguo mid-conversation-tool-changes-2026-07-01, que funciona en la API de Claude, Amazon Bedrock y Google Cloud |
Cambiar output_config.effort de nivel superior (reinicia la caché, no afecta el pensamiento) | Un output_config por mensaje | mid-conversation-output-config-2026-07-01 |
| Descartar o resumir turnos antiguos en el cliente | Compactación bajo demanda para conservar los turnos recientes con su pensamiento, otra compactación o edición de contexto del lado del servidor, o compactación del lado del cliente que no conserve pensamiento obsoleto | compact-2026-09-04 |
| Una URL de imagen o documento cuyos bytes cambian entre solicitudes | Un file_id de la Files API, o base64 | Ninguno |
Todos estos suponen que envías los turnos del asistente de vuelta exactamente como se devolvieron. Los mensajes del sistema a mitad de la conversación, los mensajes del sistema con alcance de turno y los cambios de herramientas no están disponibles en todos los modelos: Mensajes del sistema y cambios de herramientas a mitad de conversación enumera los modelos que los aceptan. Si tu código atiende a varios modelos, sigue editando la indicación del sistema system de nivel superior para los modelos que no los aceptan.
Para usar varias betas en una solicitud en la API de Claude, combina sus nombres en un solo encabezado anthropic-beta:
anthropic-beta: thinking-binding-controls-2026-08-01,mid-conversation-system-clear-at-2026-08-21,inline-tools-2026-09-15Otras plataformas que ofrecen estas betas usan los mismos nombres. Para enviarlas allí, consulta Funciones beta en otras plataformas.
Enviar los turnos del asistente de vuelta exactamente como se devolvieron
Guarda el arreglo content de cada respuesta y envíalo de vuelta sin cambios como el turno del asistente: cada tipo de bloque, en el orden recibido, incluidos los bloques thinking cuyo campo thinking esté vacío. Un serializador que descarta tipos de bloque desconocidos, descarta campos vacíos o reordena bloques edita el prefijo para todos los turnos posteriores.
En Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 y Claude Haiku 5.5, el campo thinking está vacío de forma predeterminada y la signature lleva el razonamiento, por lo que un serializador que omite bloques vacíos elimina el pensamiento. Si los elimina todos, nada falla y el modelo pierde su razonamiento anterior en cada turno. Si analizas el stream tú mismo, conserva el bloque incluso cuando no llegue texto de pensamiento: se abre, recibe su signature en un evento signature_delta y se cierra. Un bloque devuelto con una signature vacía falla.
Agregar instrucciones con un mensaje del sistema a mitad de conversación
Algunos harnesses reconstruyen la indicación del sistema system de nivel superior en cada solicitud para incluir la hora actual, un presupuesto de tokens, un indicador de modo o contexto del proyecto recién descubierto. Eso invalida todos los bloques de pensamiento de la conversación. En su lugar, congela system al inicio de la sesión. Cuando algo cambie, agrega un mensaje role: "system" en el punto de messages donde el cambio se vuelve cierto:
{
"role": "system",
"content": "The user switched the workspace to read-only mode. Do not write files until told otherwise."
}El modelo trata este mensaje con la autoridad de una indicación del sistema, y todo lo anterior permanece sin cambios. En un bucle de herramientas, coloca el mensaje después del mensaje del usuario con el tool_result, nunca entre un tool_use del asistente y su tool_result (consulta Limitaciones). Una vez enviado, el mensaje forma parte del prefijo para el pensamiento posterior: déjalo en su lugar en las solicitudes posteriores.
Poner el contexto cambiante en el turno más reciente
Algunos harnesses ponen un bloque de entorno en el primer mensaje del usuario (directorio de trabajo, rama, fecha, memoria, instrucciones del proyecto) y lo vuelven a renderizar en cada solicitud. Cuando cambia cualquier valor, messages[0] cambia, y todos los bloques de pensamiento de la conversación dejan de ser válidos. Renderiza ese bloque una vez y reenvíalo tal como estaba. Cuando un valor cambie, indícalo en el turno más reciente: agrega un bloque de texto al mensaje del usuario que estás por enviar, o agrega un mensaje del sistema a mitad de conversación si el cambio proviene de ti como operador.
{
"role": "user",
"content": [
{
"type": "text",
"text": "Environment update: the current branch is now release-2."
},
{ "type": "text", "text": "Run the tests again." }
]
}Una vez enviado, ese bloque de texto forma parte del prefijo para el pensamiento posterior: déjalo en su lugar en las solicitudes posteriores.
Envía recordatorios por turno como mensajes de sistema con alcance de turno
Una edición común del prefijo es el recordatorio por turno: una línea como "solicita las lecturas independientes juntas" o "hace tiempo que no le das una actualización al usuario" que tu código agrega después de cada lote de resultados de herramientas. Para evitar que los recordatorios se acumulen, envía cada recordatorio como un mensaje del sistema a mitad de conversación con clear_at: "next_user_message", colocado después del mensaje del usuario con el tool_result. clear_at requiere el encabezado beta mid-conversation-system-clear-at-2026-08-21. El siguiente arreglo messages es la solicitud después de dos llamadas a herramientas y sus resultados. messages[3] es el recordatorio de la solicitud anterior, dejado en su lugar, y messages[6] es la copia de esta solicitud:
[
{ "role": "user", "content": "Fix the failing test." },
{
"role": "assistant",
"content": [
{ "type": "thinking", "thinking": "", "signature": "..." },
{
"type": "tool_use",
"id": "toolu_01",
"name": "read_file",
"input": { "path": "tests/test_auth.py" }
}
]
},
{
"role": "user",
"content": [{ "type": "tool_result", "tool_use_id": "toolu_01", "content": "..." }]
},
{
"role": "system",
"clear_at": "next_user_message",
"content": "Request every independent read in one turn."
},
{
"role": "assistant",
"content": [
{ "type": "thinking", "thinking": "", "signature": "..." },
{
"type": "tool_use",
"id": "toolu_02",
"name": "read_file",
"input": { "path": "src/auth.py" }
}
]
},
{
"role": "user",
"content": [{ "type": "tool_result", "tool_use_id": "toolu_02", "content": "..." }]
},
{
"role": "system",
"clear_at": "next_user_message",
"content": "Request every independent read in one turn."
}
]Un mensaje del usuario que solo contiene bloques tool_result cuenta como el "siguiente mensaje del usuario", así que messages[3] ya está borrado. No agrega nada a lo que ve el modelo ni consume tokens de entrada, pero como sigue en el arreglo, el pensamiento de messages[4] sigue siendo válido. messages[6] es la copia que el modelo ve en este turno. En las solicitudes posteriores, deja ambos donde están y agrega una copia nueva después del siguiente mensaje con tool_result.
Agregar o eliminar herramientas con tool_addition y tool_removal
Editar el arreglo tools a mitad de la sesión invalida los bloques de pensamiento preservados. Deja el arreglo tal como lo enviaste la primera vez. Para cambiar qué herramientas puede usar el modelo, agrega al final un mensaje role: "system" que contenga bloques tool_addition o tool_removal. Estos son cambios de herramientas a mitad de la conversación y necesitan el encabezado beta inline-tools-2026-09-15, que está disponible en la Claude API. El encabezado anterior mid-conversation-tool-changes-2026-07-01 sigue funcionando para los cambios que nombran una herramienta por referencia, en la Claude API, Amazon Bedrock y Google Cloud.
Tienes dos formas de usar estos bloques:
- Declarar todas las herramientas desde el principio. Pon en
tools, en la primera solicitud, todas las herramientas que la sesión pueda necesitar, condefer_loading: trueen las que el modelo todavía no deba ver. Después, activa y desactiva herramientas con bloquestool_additionytool_removalque las nombren. - Empezar con una instantánea y agregar herramientas sobre la marcha. Pon en
tools, en la primera solicitud, las herramientas que conoces. Cuando aparezca una herramienta nueva, defínela dentro de un bloquetool_additionen lugar de editartools.
De cualquier forma, tools nunca cambia, por lo que el pensamiento anterior sigue siendo válido y la caché de prompts sigue acertando, con la única excepción que se indica más adelante en esta sección.
Por ejemplo, para retirar una herramienta peligrosa después de un cambio de modo:
{
"role": "system",
"content": [
{ "type": "tool_removal", "tool": { "type": "tool_reference", "name": "delete_branch" } },
{ "type": "text", "text": "Branch deletion is disabled for the rest of this session." }
]
}Para activar una herramienta que declaraste con defer_loading: true, agrega un bloque tool_addition que la nombre:
{
"role": "system",
"content": [
{ "type": "tool_addition", "tool": { "type": "tool_reference", "name": "deploy" } },
{ "type": "text", "text": "Authentication succeeded. Deployment is now available." }
]
}A veces no puedes declarar una herramienta desde el principio porque todavía no conoces su esquema: una herramienta que tu aplicación descubre en tiempo de ejecución, o un servidor MCP que se conecta después del primer turno. Defínela dentro del bloque tool_addition en lugar de modificar tools. Con inline-tools-2026-09-15, el tool del bloque puede ser {"type": "tool_definition", "definition": {...}}, con la misma entrada que habrías puesto en tools:
{
"role": "system",
"content": [
{
"type": "tool_addition",
"tool": {
"type": "tool_definition",
"definition": {
"name": "db_query",
"description": "Run a read-only SQL query against the analytics database.",
"input_schema": {
"type": "object",
"properties": { "sql": { "type": "string" } },
"required": ["sql"]
}
}
}
}
]
}La nueva herramienta llega en messages, tools nunca cambia y el pensamiento anterior sigue siendo válido. Mantén al menos una herramienta sin defer_loading: true en tools: si todas las herramientas allí están diferidas, la primera herramienta que definas de esta forma cuesta un fallo completo de la caché de prompts.
Si la API se conecta al servidor MCP por ti mediante el conector MCP, envía también mcp-client-2026-09-15. Cubre todo lo que hace mcp-client-2025-11-20, así que envíalo en lugar de ese. El definition del bloque puede ser entonces un mcp_toolset para un servidor incluido en mcp_servers. Cuando la API tiene que obtener la lista de herramientas de un servidor, la respuesta comienza con un bloque mcp_tool_listing para ese servidor. Devuélvelo sin cambios junto con el resto del turno del asistente, y sigue enviando mcp-client-2026-09-15 en cada solicitud posterior que lo incluya. El bloque fija el conjunto de herramientas a esa lista, así que la API no vuelve a contactar al servidor para obtenerla. Estas funciones del conector MCP están disponibles en la Claude API.
Con solo el encabezado más antiguo, aún puedes agregar a tools una herramienta que descubras a mitad de sesión con defer_loading: true y luego ofrecerla con un bloque tool_addition. Es seguro porque la verificación del prefijo ignora una herramienta diferida hasta que un bloque tool_addition hace referencia a ella. Agregar una herramienta sin defer_loading: true cambia el prefijo e invalida el pensamiento anterior.
Los mensajes role: "system" que contienen estos bloques pasan a formar parte del prefijo para el pensamiento posterior. Déjalos en su lugar en las solicitudes posteriores.
Cambiar el esfuerzo con un output_config por mensaje
Cambiar output_config.effort de nivel superior entre solicitudes no invalida el pensamiento, porque el esfuerzo no forma parte del prefijo. Cambiar el esfuerzo de nivel superior sí reinicia la caché de prompts. Donde el modelo y la plataforma admitan esfuerzo por mensaje, úsalo en su lugar: añade un mensaje role: "system" con content vacío y el nuevo nivel. Necesita el encabezado beta mid-conversation-output-config-2026-07-01. En Claude Haiku 5.5, el esfuerzo por mensaje está disponible en la Claude API y Google Cloud y necesita pensamiento adaptativo.
{ "role": "system", "content": [], "output_config": { "effort": "low" } }Cuándo entra en vigor el nuevo nivel depende de dónde coloques el mensaje. Directamente después de un mensaje user con nueva entrada, comienza con la respuesta de Claude a ese mensaje. En cualquier otro lugar, como después de un mensaje assistant o después de un mensaje user que contiene solo bloques tool_result, comienza con el siguiente mensaje user con nueva entrada, por lo que un bucle de herramientas ya en curso mantiene el nivel actual hasta entonces. Una vez enviado, el mensaje forma parte de messages y, por lo tanto, del prefijo para el pensamiento posterior: déjalo en su lugar en las solicitudes posteriores y añade otro para volver a cambiar el esfuerzo.
Recortar el contexto en el servidor
Otra edición común del prefijo es el recorte del lado del cliente: descartar o resumir los turnos más antiguos y conservar los recientes textualmente. Los bloques de pensamiento de los turnos conservados se produjeron cuando el historial eliminado todavía estaba presente, así que no pasan la verificación. Los equivalentes del lado del servidor no cuentan como ediciones, porque la verificación compara la conversación tal como la enviaste:
- La compactación bajo demanda (beta) devuelve el resumen desde una solicitud separada, que puede ejecutarse en segundo plano. Luego envías el bloque devuelto en lugar de los mensajes que resume. La verificación acepta ese reemplazo, así que los turnos que conservas pueden mantener su pensamiento válido, bajo las condiciones para el pensamiento conservado. Solicitar un resumen muestra la solicitud e indica el encabezado beta que necesita.
- La compactación al alcanzar un umbral de tokens resume los turnos más antiguos en un bloque de compactación cuando el contexto se acerca a un umbral que tú estableces. El prefijo verificado se reinicia desde ese bloque. Su parámetro
instructionsacepta tu propio prompt de resumen, como "conserva cada ticker, tamaño de posición y supuesto declarado". - La edición de contexto borra resultados de herramientas antiguos o bloques de pensamiento antiguos según reglas, empezando por los más antiguos. Las estrategias son
clear_tool_uses_20250919yclear_thinking_20251015.
Compactar en el cliente
También puedes compactar en el cliente. Si escribes el resumen tú mismo, no devuelvas ningún bloque de pensamiento que se haya producido antes de la reescritura. Si la API escribe el resumen con compactación bajo demanda, consulta Condiciones para que el pensamiento conservado siga siendo válido para saber cuándo el pensamiento conservado sigue siendo válido.
Compactación simple (recomendada)
Cuando la conversación se vuelva demasiado larga, resume toda la sesión en un solo mensaje del usuario y envía solo ese mensaje más la siguiente instrucción. No se reproduce nada anterior, por lo que no queda pensamiento que pueda fallar la verificación, y el modelo razona de nuevo a partir del resumen.
[
{
"role": "user",
"content": "<summary of the session so far>\n\n<the next instruction>"
}
]Los modelos Claude se entrenan en tareas de largo horizonte con este esquema y, para la mayoría de las cargas de trabajo, funciona bien.
Compactación con conservación de la cola
La "keep-tail compaction" (compactación con conservación de la cola) resume los turnos más antiguos y conserva textualmente los turnos más recientes, de modo que el modelo sigue viendo palabra por palabra los últimos intercambios. Si escribes el resumen tú mismo, rompe la regla: los turnos del asistente conservados aún llevan bloques de pensamiento que se produjeron cuando los turnos originales, no el resumen, los precedían. Esos bloques fallan.
Para conservar ese pensamiento, haz que la API escriba el resumen con compactación bajo demanda. Compactación que conserva los turnos recientes muestra cómo hacerlo, y Condiciones para que el pensamiento conservado siga siendo válido indica cuándo el pensamiento conservado sigue siendo válido.
El resto de esta sección trata sobre un resumen que escribes tú mismo.
Solución: conserva los turnos exactamente como están y envía prefix_mismatch_behavior: "drop_block". La API descarta los bloques de pensamiento obsoletos, el modelo lee los bloques text y tool_use de los turnos conservados, y la solicitud tiene éxito.
Pasa el historial compactado como messages y establece block_binding en la configuración de thinking. En el siguiente ejemplo, compacted_messages es el arreglo que produjo tu paso de compactación: el mensaje de resumen seguido de los turnos conservados exactamente como los devolvió la API, incluidos los bloques thinking:
client = anthropic.Anthropic()
# compacted_messages: el mensaje de resumen y luego los turnos conservados tal como se devuelven
response = client.beta.messages.create(
model="claude-fable-5-1",
max_tokens=16000,
thinking={
"type": "adaptive",
"block_binding": {"prefix_mismatch_behavior": "drop_block"},
},
messages=compacted_messages,
betas=["thinking-binding-controls-2026-08-01"],
)
print(response.input_transformations)La respuesta contiene el nuevo turno del asistente como de costumbre, más una entrada input_transformations por cada bloque descartado. Para el historial del diagrama, eso corresponde al pensamiento en los turnos 3 y 4 del asistente:
{
"input_transformations": [
{
"type": "thinking_dropped",
"path": "messages.2.content.0",
"reason": "prefix_binding_mismatch"
},
{
"type": "thinking_dropped",
"path": "messages.4.content.0",
"reason": "prefix_binding_mismatch"
}
]
}Sigue enviando "drop_block" en las solicitudes posteriores mientras esos dos turnos permanezcan en el historial. El pensamiento que el modelo produce a partir de esta solicitud sigue al resumen y sigue siendo válido. Si prefieres no depender del encabezado beta, la alternativa es eliminar tú mismo los bloques thinking y redacted_thinking de los turnos del asistente conservados cuando construyas el historial compactado.
Compactación en segundo plano (asíncrona)
La compactación en segundo plano construye el resumen fuera de la ruta crítica mientras la conversación continúa, y lo sustituye unas cuantas solicitudes después. Para conservar el pensamiento producido mientras tanto, haz que la API escriba el resumen con compactación bajo demanda. Compactación en segundo plano describe los pasos. Ese pensamiento sigue siendo válido bajo las mismas condiciones para el pensamiento conservado que los turnos recientes conservados.
Un resumen que construyes tú mismo rompe la regla de la misma manera que keep-tail, pero con un retraso: cada turno del asistente producido mientras se construía el resumen lleva pensamiento anterior al intercambio, y todo falla en el momento en que llega el resumen. Si usas uno, trata el intercambio como keep-tail y envía "drop_block" desde el intercambio en adelante, o compacta de forma síncrona.
Patrones que no funcionan con el pensamiento preservado
- Recortar turnos del medio. Eliminar turnos individuales invalida cada bloque de pensamiento posterior a ellos, y ningún esquema de compactación lo evita. Si estabas recortando un turno para cambiar una instrucción, añade en su lugar un mensaje del sistema a mitad de conversación. Para eliminar selectivamente resultados de herramientas antiguos o pensamiento antiguo, usa la edición de contexto del lado del servidor.
- Compactar en medio de una ronda de herramientas. No compactes entre el
tool_usede un turno del asistente y eltool_resultque lo responde. Devuelve ese turno del asistente con su pensamiento intacto para que el modelo termine la ronda con su razonamiento. Consulta Preservar bloques de pensamiento.
Referencia archivos por ID, no por una URL cuyo contenido cambia
Para un bloque image o document con una fuente url, la verificación cubre los bytes obtenidos, no la cadena de la URL. Una URL cuyo contenido cambia invalida el pensamiento posterior: un endpoint de "última captura de pantalla", o un documento que alguien edita entre turnos. Una URL firmada rotativa para el mismo archivo no lo hace. Para el contenido que referencias a lo largo de varios turnos, súbelo una vez con la Files API y usa el file_id, o envía base64.
Bibliotecas, proxies y gateways
Una biblioteca, proxy o gateway se sitúa entre el historial de otra persona y la API, por lo que sus propias reescrituras cuentan como ediciones, y sus usuarios no pueden verlas ni corregirlas.
- Transmite lo que no reconozcas. Reenvía sin cambios los valores
anthropic-betaythinking.block_bindingdel llamador, y devuélveleinput_transformations. Un esquema de opciones que rechaza claves desconocidas impide que tus usuarios elijan"drop_block". - Deja un mensaje
role: "system"donde el llamador lo puso. Moverlo al camposystemde nivel superior cambiasystemen esa solicitud e invalida cada bloque de pensamiento de la conversación. - Para desactivar el uso de herramientas en una solicitud, envía
tool_choice: {"type": "none"}. No eliminestools. - No ocultes el 400. Si tu código lo captura, elimina el pensamiento y reintenta en nombre del llamador, registra que lo hizo: su historial sigue editado, y el modelo pierde su razonamiento anterior en cada solicitud posterior.
Preguntas frecuentes
No. Envía el encabezado beta thinking-binding-controls-2026-08-01 y establece thinking.block_binding.prefix_mismatch_behavior. Establecer el campo hace que esa solicitud se someta a la verificación independientemente de la antigüedad de la cuenta. "error" rechaza un historial editado con el mismo 400 que recibe una cuenta nueva, y "drop_block" deja pasar la solicitud y lista lo que se descartó en input_transformations. Para encontrar ediciones del prefijo desde una cuenta más antigua sin aplicar la verificación, envía el encabezado y deja el campo sin establecer: los bloques que fallan siguen llegando al modelo, e input_transformations los lista como thinking_mismatch_allowed. Consulta Verificar si tu código edita el prefijo.
No. Lo que falla es el pensamiento que ya está en el historial después del punto que cambiaste, y tú eliges qué le sucede. Con prefix_mismatch_behavior: "drop_block", la API descarta esos bloques y la solicitud tiene éxito: el modelo responde ese turno sin ese razonamiento, y la caché de prompts se reinicia en la edición. Con el valor predeterminado "error", la API rechaza la solicitud con un 400 hasta que deshagas la edición o la reenvíes con "drop_block". Consulta Qué hace la API con un bloque no válido. Qué cuenta como una edición indica qué cambios importan.
No. output_config.effort, max_tokens y la configuración de thinking no forman parte del prefijo verificado, que cubre solo system, tools y messages. Un cambio de esfuerzo de nivel superior invalida la mayor parte de la caché de prompts. Donde el modelo y la plataforma admitan esfuerzo por mensaje, un cambio de esfuerzo por mensaje conserva la caché de prompts y se usa como el nuevo nivel de esfuerzo hasta que se cambie de nuevo.
No edites tools. Declara el conjunto completo al inicio de la sesión, marca las herramientas que aún no están disponibles con defer_loading: true, y ofrécelas o retíralas con bloques tool_addition y tool_removal. Si conoces el esquema de una herramienta solo a mitad de la sesión, defínela dentro del bloque tool_addition (inline-tools-2026-09-15, más mcp-client-2026-09-15 para un servidor al que llega el conector MCP de la API) y deja tools sin cambios. Los mensajes role: "system" que contienen estos bloques se unen al prefijo para el pensamiento posterior, así que no los muevas, reformules ni elimines después. Consulta Agregar o eliminar herramientas con tool_addition y tool_removal.
Sí, si la API escribe el resumen. La compactación bajo demanda (encabezado beta compact-2026-09-04) resume los turnos más antiguos en un bloque firmado que envías en lugar de ellos. Los turnos recientes conservan su pensamiento bajo las condiciones para el pensamiento conservado.
Si escribes el resumen tú mismo, el pensamiento de los turnos conservados no pasa la verificación, porque esos bloques se produjeron con el historial que reemplazaste. Elimina los bloques thinking y redacted_thinking de los turnos que trasladas y conserva sus bloques text y tool_use, o envía prefix_mismatch_behavior: "drop_block" y deja que la API los descarte. La compactación simple no deja pensamiento que pueda fallar y es el enfoque recomendado: un mensaje de resumen más el siguiente turno del usuario, sin reproducir turnos anteriores. La compactación y la edición de contexto del lado del servidor no cuentan como ediciones. Consulta Compactar en el cliente.
Cárgalos una vez al inicio de la sesión y mantén fijos la indicación del sistema system de nivel superior y tools. Cuando un archivo cambie, añade la nueva versión en ese punto de messages en lugar de editar el original. Usa un mensaje del sistema a mitad de la conversación para las instrucciones que provienen de ti como operador. Para el texto de archivos que tratas como no confiable, que no debería tener la autoridad de la indicación del sistema, coloca el contenido en el siguiente turno user. Consulta Agregar instrucciones con un mensaje del sistema a mitad de conversación y Limitaciones.
Sí. Una sesión reanudada es una solicitud de seguimiento ordinaria: system, tools y los messages anteriores deben tener el mismo contenido que lo que enviaste por última vez. El formato JSON y el orden de las claves no importan; los valores sí. Guarda exactamente lo que enviaste y recibiste, y reprodúcelo: la indicación del sistema renderizada, las definiciones de herramientas y cada turno del asistente tal como se devolvió. No vuelvas a renderizar a partir de entradas que podrían haber cambiado desde entonces, como la fecha, un archivo de instrucciones actualizado o una nueva versión de una herramienta. Todo lo nuevo va en un mensaje añadido. Consulta Enviar los turnos del asistente de vuelta exactamente como se devolvieron.
El historial almacenado contiene una edición, por lo que reproducirlo no puede tener éxito. Envía esa sesión con prefix_mismatch_behavior: "drop_block" de ahora en adelante, o elimina sus bloques thinking y redacted_thinking una vez y continúa. En Claude Sonnet 5.5 y Claude Haiku 5.5, block_binding funciona solo con thinking: {"type": "adaptive"}. Con between_tools en Claude Sonnet 5.5, o thinking: {"type": "disabled"} en Claude Haiku 5.5, mantén el historial de solo anexar, o elimina los bloques de pensamiento desde el turno editado en adelante. El pensamiento que el modelo produce a partir de ese punto sigue siendo válido mientras nada anterior vuelva a cambiar. Luego encuentra la edición para que las sesiones nuevas no la encuentren. Consulta Manejar el error en el código.
No, siempre que se añadan después del historial existente y nada anterior cambie: un mensaje del asistente sin bloques de pensamiento es un mensaje añadido como cualquier otro. Envía la salida del otro modelo como contenido text y tool_use.
No a una conversación diferente. Un bloque de pensamiento solo se puede usar cuando sigue exactamente a los system, tools y messages a partir de los cuales se produjo. Una rama que reproduce ese historial sin cambios hasta el punto de bifurcación conserva su pensamiento. Una conversación que comienza a partir de cualquier otra cosa no puede usarlo, así que comienza esa conversación a partir de un resumen del estado de la tarea, como en la compactación simple: el objetivo, las decisiones tomadas, los archivos y resultados hasta el momento, y el siguiente paso. Los bloques de pensamiento de Claude Sonnet 5.5 y Claude Haiku 5.5 tampoco se pueden reutilizar desde otra cuenta (consulta Los bloques de pensamiento permanecen con la cuenta que los produjo).
Próximos pasos
Diagnostica y corrige las fallas de pensamiento más comunes: errores 400 de configuración, bloques de pensamiento vacíos o faltantes, detenciones por max_tokens y fallos de caché.
Cambia las instrucciones del sistema o la disponibilidad de herramientas a mitad de una conversación sin invalidar el prefijo en caché que las precede.
Compactación de contexto del lado del servidor para administrar conversaciones largas que se acercan a los límites de la ventana de contexto.
Almacena en caché prefijos de prompts con cache_control para reducir costos y latencia, usando caché automática o puntos de interrupción explícitos con TTL de 5 minutos o 1 hora.
Was this page helpful?