Compactación bajo demanda
Pide a Claude que resuma una conversación cuando tu aplicación lo decida y luego continúa a partir del resumen.
Con la "on-demand compaction" (compactación bajo demanda), tu aplicación decide cuándo se resume una conversación: envías una solicitud con el parámetro compaction y Claude devuelve un resumen en lugar de una respuesta.
Cómo funciona la compactación bajo demanda
Una solicitud de compactación es independiente de los turnos de tu conversación. Envías la conversación tal como está con el parámetro compaction, y la respuesta contiene un único bloque compaction. El bloque contiene el resumen como texto que puedes leer, y una firma. Envíalo en solicitudes futuras exactamente como llegó.
A partir de entonces, el bloque ocupa el lugar de los mensajes que resume. Va primero en messages, los mensajes resumidos se eliminan y tu siguiente turno va después de él. Claude ve el resumen donde estaban esos mensajes.
Solicitar un resumen
Envía el encabezado beta compact-2026-09-04 en la solicitud que pide el resumen y en cada solicitud posterior que lleve el bloque firmado. Para comprobar si un modelo admite la compactación bajo demanda, llama a la API de Models con el encabezado beta y lee el capabilities.compaction de cada modelo. No puedes combinar compaction con context_management en una misma solicitud.
Envía la conversación tal como está con "compaction": {"type": "summarize"}. La API resume todos los mensajes de la solicitud una sola vez, no genera ninguna respuesta después y devuelve solo el bloque con stop_reason "compaction". Envía el mismo "system prompt" (indicación del sistema) en system y las mismas tools que usas para el resto de la conversación. El resumidor los lee, y si conservas turnos después del bloque en un modelo con "preserved thinking" (pensamiento preservado), el pensamiento de esos turnos sigue siendo válido solo si system y tools coinciden. La conversación de este ejemplo no tiene indicación del sistema en system ni herramientas, así que la solicitud no envía ninguna de las dos:
from anthropic.types.beta import BetaMessageParam
client = anthropic.Anthropic()
history: list[BetaMessageParam] = [
{
"role": "user",
"content": "I am building a recipe app. Help me name the main entities in the data model.",
},
{
"role": "assistant",
"content": "Start with Recipe, Ingredient, and Step. Add a RecipeIngredient entry that holds the quantity and unit for each ingredient in a recipe.",
},
{"role": "user", "content": "Good. Now suggest field names for Recipe."},
]
response = client.beta.messages.create(
model="claude-opus-5-5",
# max_tokens limita toda la llamada, incluido cualquier pensamiento, así que permite varios miles de tokens.
max_tokens=4096,
betas=["compact-2026-09-04"],
messages=history,
compaction={"type": "summarize"},
)
print(f"Stop reason: {response.stop_reason}"){
"id": "msg_013Zva2CMHLNnXjNJJKqJ2EF",
"type": "message",
"role": "assistant",
"model": "claude-opus-5-5",
"content": [
{
"type": "compaction",
"content": "Summary of the conversation: the user is designing the data model for a recipe app. The entities agreed so far are Recipe, Ingredient, Step, and RecipeIngredient, which holds the quantity and unit. The user then asked for field names for Recipe.",
"signature": "EuYBCkQY..."
}
],
"stop_reason": "compaction",
"usage": {
"input_tokens": 0,
"output_tokens": 0,
"iterations": [{ "type": "compaction", "input_tokens": 144, "output_tokens": 276 }]
}
}La llamada de resumen usa el modelo, system, tools, la configuración de pensamiento y max_tokens de la solicitud. El resumidor lee las definiciones de herramientas pero nunca ejecuta una herramienta, y la respuesta no incluye pensamiento. max_tokens limita toda la llamada, incluido cualquier pensamiento que el modelo realice antes de escribir el resumen, así que permite varios miles de tokens. Contar el uso de la compactación muestra cómo se factura la llamada.
Si el último turno de assistant termina en una llamada a herramienta que aún no tiene resultado, la API rechaza la solicitud. Envía primero los resultados de herramientas de ese turno. Omite también stop_sequences, el output_config.format de salida estructurada y un tool_choice de tipo any o tool. No tendrían ningún efecto en una llamada de resumen, y la API los rechaza. La conversación aún debe caber en la "context window" (ventana de contexto) del modelo, así que compacta antes de superarla, no después.
Cuando haces streaming de la respuesta, el bloque llega completo. Recibes un evento content_block_start que lleva el bloque completo, luego content_block_stop, sin eventos content_block_delta. Los eventos ping pueden llegar antes o entre ellos.
Continuar a partir del resumen
En tu historial, reemplaza los mensajes que enviaste con el mensaje de asistente devuelto. Conserva el bloque compaction exactamente como lo devolvió la API, incluida su signature. Cualquier turno realizado después de que enviaste la solicitud de compactación va después del bloque sin cambios, que es en lo que se basa Compactación en segundo plano. Envía el bloque primero en cada solicitud posterior, con el encabezado beta:
{
"model": "claude-opus-5-5",
"max_tokens": 2048,
"messages": [
{
"role": "assistant",
"content": [
{
"type": "compaction",
"content": "Summary of the conversation: the user is designing the data model for a recipe app. The entities agreed so far are Recipe, Ingredient, Step, and RecipeIngredient, which holds the quantity and unit. The user then asked for field names for Recipe.",
"signature": "EuYBCkQY..."
}
]
},
{
"role": "assistant",
"content": "For Recipe, use title, description, servings, prep_minutes, and cook_minutes. Add created_at and updated_at timestamps."
},
{ "role": "user", "content": "Now do the same for Ingredient." }
]
}Este ejemplo continúa el ejemplo de solicitud, que terminó en un turno de user; el diagrama muestra el caso más simple, en el que no se realiza ningún turno mientras se escribe el resumen. Aquí el segundo mensaje de assistant es la respuesta al último turno de user resumido. Llegó mientras se escribía el resumen, por lo que no estaba entre los mensajes resumidos. Dos mensajes de assistant seguidos no son un problema aquí, porque el bloque sigue yendo primero.
La API coloca el resumen donde está el bloque y pasa cada mensaje posterior a Claude sin cambios. Sigue estas reglas:
- Coloca el bloque primero en
messages, ya sea como un mensaje deassistantindependiente o como el primer bloque de contenido del primer mensaje, ya sea este un mensaje deusero deassistant. - Elimina los mensajes resumidos. Si alguno permanece delante del bloque, la solicitud devuelve un error 400 (
compaction_block_misplaced). - Envía exactamente un bloque
compactionpor solicitud, en cada solicitud posterior.
La "threshold compaction" (compactación por umbral) funciona al revés: su bloque va después de los mensajes que resume, y la API los descarta por ti. Consulta Devolver los bloques de compactación.
En Python, usa client.beta.messages, como hacen los ejemplos de esta página. Si llamas a client.messages y serializas los bloques tú mismo, usa to_dict() o model_dump(exclude_none=True): un model_dump() simple añade citations: null y text: null al bloque, y la API lo rechaza.
Si conservas turnos después del bloque y devuelves sus bloques de pensamiento, las condiciones que mantienen válido ese pensamiento se describen en Compactación y pensamiento preservado.
Compactar de nuevo
Para compactar una conversación que ya comienza con un bloque, envía compaction de nuevo. El nuevo bloque resume el resumen anterior y todo lo que viene después. A partir de entonces, envía solo el bloque más reciente.
Compactar en un bucle
Después de cada turno, el bucle suma los tokens de entrada y de salida de la última respuesta, porque la siguiente solicitud también envía la respuesta. Cuando ese total supera un límite y aún queda otro turno por delante, envía una solicitud de compactación con el mismo modelo y la misma indicación del sistema en system, comprueba stop_reason, reemplaza su historial con el mensaje devuelto e imprime el turno antes del cual compactó. El límite de 2,500 tokens del ejemplo es deliberadamente bajo, para que una conversación corta se compacte. Establece el tuyo cerca de tu presupuesto real de entrada.
from anthropic.types.beta import BetaMessageParam
client = anthropic.Anthropic()
# Ajusta esto cerca de tu presupuesto real de entrada. Aquí es bajo para que una conversación corta se compacte.
COMPACT_AT_TOKENS = 2500
SYSTEM = "You help design a recipe app's data model. Keep answers short."
QUESTIONS = [
"What are the main entities in the data model?",
"Which fields should Recipe have?",
"Which fields should Ingredient have?",
"Which fields should RecipeIngredient have?",
"Which fields should Step have?",
"Which indexes should these tables have?",
"Which fields should be required?",
"Which fields should have default values?",
]
history: list[BetaMessageParam] = []
for turn, question in enumerate(QUESTIONS, start=1):
history.append({"role": "user", "content": question})
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=8192,
system=SYSTEM,
betas=["compact-2026-09-04"],
messages=history,
)
history.append({"role": "assistant", "content": response.content})
# La siguiente solicitud también envía esta respuesta, así que cuéntala.
conversation_tokens = response.usage.input_tokens + response.usage.output_tokens
if conversation_tokens > COMPACT_AT_TOKENS and turn < len(QUESTIONS):
summary = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=4096,
system=SYSTEM,
betas=["compact-2026-09-04"],
messages=history,
compaction={"type": "summarize"},
)
if summary.stop_reason == "compaction":
history = [{"role": "assistant", "content": summary.content}]
print(f"Compacted before turn {turn + 1}")La comprobación de stop_reason va antes de que el código busque el bloque; Manejar un resumen faltante o un error explica por qué. El historial se reemplaza, no se amplía: el mensaje devuelto reemplaza todos los mensajes que llevaba la solicitud, según las reglas de Continuar a partir del resumen. Cuando no se devuelve ningún resumen, el bucle conserva su historial y vuelve a pedirlo después del siguiente turno.
El "tool runner" (ejecutor de herramientas) del SDK en Python, TypeScript, C#, Go y Java puede enviar la solicitud de compactación por ti. Cuando decidas compactar, llama a compact_before_next_turn() en el ejecutor (compactBeforeNextTurn() en TypeScript y Java, CompactBeforeNextTurn() en C# y Go). Una vez que terminan el turno actual y sus llamadas a herramientas, el ejecutor envía la solicitud de compactación y reemplaza su historial con el mensaje devuelto. Crea el ejecutor con la beta compact-2026-09-04, porque el ejecutor no la añade. El ejecutor construye la solicitud a partir de sus propios parámetros y omite context_management. Si esos parámetros incluyen stop_sequences, un tool_choice de tipo any o tool, o un output_config.format de salida estructurada, la API rechaza la solicitud con un error 400. Solicitar un resumen explica por qué. El ejecutor se niega a compactar mientras su context_management tenga una edición de compactación, así que usa un solo tipo de compactación en cada ejecutor.
Cuándo compactar
Puedes enviar una solicitud de compactación después de cualquier turno completado, así que tu código decide cuándo hacerlo.
Para estimar qué tan grande será la siguiente solicitud, suma input_tokens y output_tokens del usage de la última respuesta, como hace el bucle. Con el "prompt caching" (almacenamiento en caché de prompts), input_tokens cuenta solo los tokens posteriores al último punto de interrupción de caché, así que suma también cache_read_input_tokens y cache_creation_input_tokens. También puedes enviar los mismos mensajes al endpoint de conteo de tokens.
Compara ese número con un límite que elijas, por debajo de la ventana de contexto del modelo.
Escribir tu propio prompt de resumen
Sin instructions, la API usa su propio prompt de resumen. Una cadena instructions no vacía (de hasta 16,384 caracteres) reemplaza ese prompt por completo. Por ejemplo:
{
"compaction": {
"type": "summarize",
"instructions": "Summarize this recipe app design conversation. Preserve every entity and field name agreed so far, and the user's latest open request. Do not call tools; respond with the summary text only."
}
}El resumidor lee toda la conversación, incluido el pensamiento anterior, con o sin instructions. En tus instructions, indica lo que el resumen debe conservar y dile al modelo que no llame a herramientas. La llamada de resumen se ejecuta bajo las mismas salvaguardas que cualquier otra solicitud.
Manejar un resumen faltante o un error
Solo se produce un resumen cuando la llamada de resumen termina normalmente con texto y sin ninguna llamada a herramienta. De lo contrario, la respuesta sigue siendo un 200 con content vacío, así que comprueba stop_reason antes de buscar el bloque. La llamada se factura de todos modos y se informa en usage.iterations, con uso cero cuando no se pudo realizar ninguna llamada. El stop_reason es aquel con el que terminó la llamada de resumen. En todos los casos puedes continuar sin un resumen y compactar más tarde.
stop_reason | Causa | Qué hacer |
|---|---|---|
"max_tokens" | El resumen quedó cortado. | Vuelve a enviar con un max_tokens mayor. |
"model_context_window_exceeded" | No había espacio para el prompt de resumen. | Vuelve a enviar con instructions más cortas o menos mensajes. |
"tool_use" | El modelo llamó a una herramienta en lugar de escribir el resumen. | Vuelve a enviar con instructions que le indiquen al modelo que no llame a herramientas. |
"refusal" | La solicitud fue rechazada. | Continúa sin un resumen. |
"end_turn" | La llamada no devolvió texto. | Continúa sin un resumen. |
La llamada de resumen está sujeta a las mismas salvaguardas que tus otras solicitudes. Después de un "refusal", stop_details identifica la categoría de política que lo motivó.
Errores
Una solicitud de compactación, o una solicitud que lleva un bloque, también puede fallar directamente. La mayoría de los errores 400 tienen un mensaje que indica qué eliminar o volver a enviar. Algunos también llevan un error.details.error_code que comienza con compaction_. Los errores de parámetros, como un campo que no se puede combinar con compaction, llevan solo el mensaje.
| Error | Causa | Qué hacer |
|---|---|---|
529 overloaded_error, error.details.error_code compaction_unavailable | Un problema transitorio del servidor al producir un bloque, o al leer uno que devolviste. | Reintenta la solicitud. |
400 compaction_block_misplaced | Quedan mensajes resumidos delante del bloque. | Elimínalos, para que el bloque vaya primero en messages. |
400 compaction_signature_invalid o compaction_content_mismatch | La signature o el content del bloque se modificó después de que la API lo devolviera. | Envía el bloque exactamente como se devolvió, incluida su signature. |
| 400 | La solicitud lleva más de un bloque compaction. | Envía exactamente uno, el más reciente. |
| 400 | El último turno de assistant termina en una llamada a herramienta que aún no tiene resultado. | Envía los resultados de herramientas de ese turno y luego compacta. |
400 compaction_nothing_to_summarize | messages no tiene contenido de user ni de assistant, por ejemplo, una lista vacía. | Envía al menos un mensaje de user o de assistant. |
400 en la solicitud de compactación, con un mensaje que dice que el parámetro compaction requires anthropic-beta: compact-2026-09-04 | La solicitud de compactación omitió el encabezado beta. | Añade el encabezado beta; consulta Solicitar un resumen. |
400 en una solicitud posterior que lleva el bloque: un error de validación que dice que compaction no es uno de los tipos de bloque de contenido esperados. El mensaje no menciona el encabezado | Esa solicitud omitió el encabezado beta. | Añade el encabezado beta a cada solicitud que lleve el bloque; consulta Solicitar un resumen. |
Error de validación 400, como messages.0.content.0.compaction.citations: Extra inputs are not permitted | Se envió de vuelta un bloque con campos que la API no había devuelto, como citations: null. | Envía el bloque exactamente como se devolvió; consulta Continuar a partir del resumen. |
Contar el uso de la compactación
La llamada de resumen se factura y está sujeta a "rate limits" (límites de velocidad) como cualquier otra solicitud, y usage.iterations la informa como la entrada compaction. Los input_tokens y output_tokens de nivel superior son cero porque no se generó ninguna respuesta. Para contar lo que consumió una conversación, suma los valores de usage.iterations, no los campos de nivel superior. Devolver un bloque en solicitudes posteriores no añade ningún costo de compactación.
Ya tienes un bucle funcional que compacta una conversación y maneja un resumen faltante. Dos páginas cambian su funcionamiento, y puedes combinarlas: Compactación que conserva los turnos recientes conserva los últimos turnos palabra por palabra, y Compactación en segundo plano permite que la conversación continúe mientras se escribe el resumen. Compactación y pensamiento preservado aplica si devuelves bloques de pensamiento y haces cualquiera de las dos cosas.
Límites e interacciones con otras funciones
- Compactación por umbral y edición de contexto. No puedes enviar
compactionycontext_managementen la misma solicitud. La compactación por umbral (compact_20260112) no puede ejecutarse en una solicitud que lleve un bloque firmado. - Almacenamiento en caché de prompts.
cache_controlen el bloque coloca un punto de interrupción después del resumen. - Mensajes del sistema a mitad de la conversación y cambios de herramientas. Los mensajes
role: "system"dentro del rango resumido también se resumen, por lo que sus instrucciones de texto dejan de aplicarse una vez que el bloque los reemplaza. Si una instrucción sigue siendo importante, vuelve a indicarla en un mensajerole: "system". Envía ese mensaje justo después de tu siguiente turno nuevo deusery déjalo en tu historial a partir de entonces. Para los cambios de herramientas, y para saber dónde va ese mensaje cuando conservas turnos después del bloque, consulta Cambiar la indicación del sistema o las herramientas. - Presupuestos de tarea. No envíes el valor
remainingde un presupuesto de tarea (output_config.task_budget.remaining) concompactionni en solicitudes que lleven el bloque. Hacerlo devuelve un error 400. - Conteo de tokens. El endpoint de conteo de tokens ignora el parámetro
compaction. - Contenido que el resumen no puede conservar. Las imágenes, los documentos, los bloques
container_uploady las URL obtenidas dentro de los mensajes resumidos desaparecen una vez que el bloque los reemplaza. Vuelve a indicar o a subir cualquier cosa que un turno posterior todavía necesite.
Compatibility
| Supported models |
|
|---|---|
| Supported platforms |
|
Was this page helpful?