Сжатие и сохранённое мышление
Когда блоки мышления в ходах, сохранённых после сжатия по запросу, остаются действительными на моделях с сохранённым мышлением, и как это проверить.
Пропустите эту страницу, если только вы не отправляете «thinking blocks» (блоки мышления) обратно модели с «preserved thinking» (сохранённым мышлением) и не сохраняете ходы после блока «compaction» (сжатия). «Kept turns» (сохранённые ходы) — это ходы, следующие за блоком: недавние ходы, которые вы не включили в запрос на сжатие, как в разделе Сжатие с сохранением последних ходов, или ходы, поступившие во время написания сводки, как в разделе Сжатие в фоновом режиме.
Модели с сохранённым мышлением сверяют более ранние блоки мышления с диалогом, в котором они были созданы. Сводка заменяет часть этого диалога, но проверка принимает такую замену, если сводку написал API, поэтому мышление в сохранённых ходах может оставаться действительным.
Условия, при которых сохранённое мышление остаётся действительным
Блоки мышления в сохранённых ходах остаются действительными, пока выполняются все следующие условия:
- Запрос на сжатие выполняется на модели с сохранённым мышлением. Это условие распространяется на каждый запрос на сжатие с момента создания блока мышления, а не только на самый последний. Один из способов его выполнить — отправлять каждый запрос на сжатие той модели, которую использует диалог.
- Сохранённые ходы непосредственно следуют за суммированными сообщениями, и вы отправляете их без изменений. Отправляйте каждое сохранённое сообщение точно в том виде, в каком оно есть в вашей истории. Не пропускайте и не добавляйте сообщения между последним суммированным сообщением и первым сохранённым. Первое сохранённое сообщение также должно иметь роль, отличную от роли последнего суммированного сообщения, и оно не может быть сообщением
role: "system"в середине диалога. В противном случае API объединит его с последним суммированным сообщением. Один из способов правильно сформировать первое сохранённое сообщение — сжать ровноmessagesзапроса, который вы уже отправили. Тогда сохранённые ходы начнутся с ответа Claude на него. systemи теtools, которые не помеченыdefer_loading: true, не меняются. Они одинаковы в запросе на сжатие и в запросах, в которых было создано сохранённое мышление, и остаются такими же в последующих запросах. В разделе Изменение системной подсказки или инструментов описано, как безопасно их изменить.
Если какое-либо условие не выполняется, при сжатии ничего не завершается ошибкой, и API в любом случае принимает блок в последующих запросах. Сбой происходит при первом последующем запросе, который отправляет сохранённое мышление туда, где API применяет проверку: по умолчанию это ошибка 400, а если в запросе для thinking.block_binding.prefix_mismatch_behavior задано значение "drop_block", — отброшенные блоки мышления. В Message Batches API элемент, в котором это поле не задано, не завершается ошибкой. Там, где проверка применяется по умолчанию, API вместо этого отбрасывает блоки. В разделе Что API делает с недействительным блоком описаны оба исхода, а в разделе Когда API применяет проверку указано, какие запросы проверяются.
Повторное сжатие без нарушения более раннего мышления
Вы можете выполнить сжатие повторно и сохранить ходы: новый блок охватывает старую сводку и каждое следующее за ней сообщение в запросе на сжатие, а любые ходы, которые вы не включили в этот запрос, становятся сохранёнными ходами нового блока.
Первое из условий для сохранённого мышления учитывает каждое сжатие с момента создания блока мышления, поэтому для хода, который вы сохраняете на протяжении двух сжатий, оба сжатия должны быть выполнены на модели с сохранённым мышлением.
Сжатия, выполненные до создания блока мышления, на него не влияют. Мышление, созданное после появления блока, привязано к этому блоку и остаётся действительным при последующих сжатиях, удовлетворяющих условиям.
Изменение системной подсказки или инструментов
В последующем запросе можно использовать другой system, другие tools или другую модель, чем в запросе на сжатие, и API всё равно примет блок. Такое изменение может сделать недействительным мышление в сохранённых ходах, но других последствий у него нет.
Чтобы изменить system или tools, не делая недействительным сохранённое мышление, сначала сожмите весь диалог, чтобы не осталось сохранённых ходов. Затем измените их в следующем запросе.
Чтобы добавить инструкцию или изменить доступные инструменты, не затрагивая system или tools, добавьте изменение в messages, как описано в разделе Внесение изменений без редактирования префикса.
Системные сообщения в середине разговора внутри суммированных ходов тоже суммируются, поэтому их текстовые инструкции перестают действовать после замены. Чтобы что-то из этого оставалось в силе, повторите это в сообщении role: "system" сразу после первого нового хода user, следующего за сохранёнными ходами. Изменения инструментов внутри этих ходов переносятся автоматически, если запрос на сжатие также содержит inline-tools-2026-09-15: возвращённый блок фиксирует их итоговый эффект в своём поле tool_changes, поэтому отправляйте блок обратно без изменений. Если у блока нет поля tool_changes, повторите эти изменения инструментов тем же способом. Системное сообщение, размещённое между блоком и сохранёнными ходами, нарушает их мышление.
Проверка того, что сохранённое мышление осталось действительным
Ответ на запрос сжатия не сообщает, остаётся ли сохранённое мышление действительным. Это показывает первый запрос после замены. Чтобы проверить это в своих тестах:
- Проведите короткий диалог с включённым мышлением. Используйте модель, на которой API выполняет проверку (см. Когда API применяет проверку), и используйте её на каждом шаге, поскольку модель, которая не может прочитать блок мышления, отбрасывает его без ошибки.
- Сожмите более ранние ходы и сохраните как минимум один ход, содержащий блок мышления.
- Отправьте следующий запрос: сначала блок, затем сохранённый ход, затем новое сообщение
user, а дляthinking.block_binding.prefix_mismatch_behaviorзадайте значение"error". - Прочитайте результат. Ответ 200 с пустым массивом
input_transformationsозначает, что ни один блок мышления не провалил проверку и не был отброшен. Ошибка 400 с сообщением о том, что блок привязан к другому диалогу, означает, что такой блок есть. Сообщение начинается с пути к первому блоку, не прошедшему проверку, а в разделе Что API делает с недействительным блоком оно приведено полностью.
Для поля prefix_mismatch_behavior требуется бета-заголовок thinking-binding-controls-2026-08-01 в дополнение к бета-заголовку compact-2026-09-04. Установка этого поля также включает проверку для запроса в аккаунтах, где проверка не включена по умолчанию.
Следующая программа выполняет эти четыре шага. Она выводит, сколько блоков мышления содержит сохранённый ход и сколько записей содержит input_transformations; отсутствие записей означает, что сохранённое мышление осталось действительным:
from anthropic.types.beta import BetaMessageParam, BetaThinkingConfigParam
client = anthropic.Anthropic()
# Claude Fable 5.1 — первая модель, которая сверяет возвращённые ей блоки мышления с ходом диалога.
MODEL = "claude-fable-5-1"
BETAS = ["compact-2026-09-04", "thinking-binding-controls-2026-08-01"]
SYSTEM = "You help plan a recipe app's release. Keep answers short."
# При значении "error" блок мышления, не прошедший проверку, приводит к ошибке запроса с кодом 400.
THINKING: BetaThinkingConfigParam = {
"type": "adaptive",
"block_binding": {"prefix_mismatch_behavior": "error"},
}
# 1. Проведите короткий диалог с включённым мышлением.
history: list[BetaMessageParam] = [
{"role": "user", "content": "What are the main entities in the app's data model?"}
]
first = client.beta.messages.create(
model=MODEL,
max_tokens=8192,
system=SYSTEM,
betas=BETAS,
thinking=THINKING,
messages=history,
)
history += [
{"role": "assistant", "content": first.content},
{
"role": "user",
"content": "Testing starts on Tuesday, March 3, 2026, takes 10 weekdays, and pauses on March 9 and March 16. On which date does it end?",
},
]
second = client.beta.messages.create(
model=MODEL,
max_tokens=8192,
system=SYSTEM,
betas=BETAS,
thinking=THINKING,
messages=history,
)
history.append({"role": "assistant", "content": second.content})
thinking_blocks = sum(block.type == "thinking" for block in second.content)
print(f"Thinking blocks in the kept turn: {thinking_blocks}")
# 2. Кратко изложите первый ход. Второй ход в запрос не включается.
summary = client.beta.messages.create(
model=MODEL,
max_tokens=4096,
system=SYSTEM,
betas=BETAS,
thinking=THINKING,
messages=history[:2],
compaction={"type": "summarize"},
)
if summary.stop_reason != "compaction":
raise SystemExit(f"No summary: {summary.stop_reason}")
# 3. Поместите блок перед сохранённым ходом и задайте следующий вопрос.
history = [
{"role": "assistant", "content": summary.content},
*history[2:],
{"role": "user", "content": "Which day should the release go out?"},
]
third = client.beta.messages.create(
model=MODEL,
max_tokens=8192,
system=SYSTEM,
betas=BETAS,
thinking=THINKING,
messages=history,
)
# 4. Ответ 200 без отброшенных блоков означает, что сохранённое мышление прошло проверку.
print(f"Dropped thinking blocks: {len(third.input_transformations)}")Thinking blocks in the kept turn: 1
Dropped thinking blocks: 0В рабочей среде "drop_block" обеспечивает успешное выполнение запросов, когда какое-либо условие не выполняется, и сообщает о каждом отброшенном блоке в input_transformations с reason: "prefix_binding_mismatch". Запись, path которой указывает на сохранённый ход, означает, что мышление этого хода не осталось действительным. В разделе Что API делает с недействительным блоком описано, что именно отбрасывается и как настроить оповещения об этом.
Compatibility
| Supported models |
|
|---|---|
| Supported platforms |
|
Was this page helpful?