---
title: Сохранённые размышления
url: https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking
description: Сохранённые размышления позволяют модели использовать блок размышлений из предыдущего хода, только если его создала эта модель или одна из фиксированного набора других моделей и ничего перед этим блоком не изменилось.
---

«Preserved thinking» (сохранённые размышления) — это свойство новых моделей Claude, которое защищает от «distillation» (дистилляции). Оно определяет, может ли модель использовать «thinking block» (блок размышлений), который вы отправляете обратно из предыдущего хода. Начиная с Claude Fable 5.1, когда блок `thinking` или `redacted_thinking` возвращается в запросе, API проверяет `signature` блока на два условия:

* **Модель может прочитать блок.** Каждая модель читает собственные блоки размышлений и блоки фиксированного набора других моделей. Claude Fable 5.1 читает блоки от Claude Opus 5 и, в Claude API, от Claude Opus 5.5; ни Claude Opus 5, ни Claude Opus 5.5 не читают блоки от Claude Fable 5.1. Если текущая модель не может прочитать блок, API удаляет его из этого запроса без ошибки. См. [Переключение моделей посреди разговора](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#switching-models).
* **Ничего перед блоком размышлений не изменилось.** Системная подсказка верхнего уровня `system`, `tools` и `messages` перед блоком составляют его «prefix» (префикс). Если префикс отличается от того, что вы отправили, когда блок был создан, этот блок и все последующие блоки размышлений становятся недействительными, и API либо отклоняет запрос с ошибкой 400, либо удаляет недействительные блоки — в зависимости от вашего выбора. См. [Сохранение префикса неизменным](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#prefix-check).

Блоки размышлений от Claude Sonnet 5.5 и Claude Haiku 5.5 также привязаны к аккаунту, который их создал. О том, где API применяет это правило, см. [Блоки размышлений остаются в аккаунте, который их создал](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#account-bound-thinking).

Проверка модели применяется ко всем аккаунтам. Проверку префикса API применяет по умолчанию для аккаунтов, созданных 31 августа 2026 года, 00:00 UTC, или позже. Для более старых аккаунтов проверка префикса применяется только к запросам, в которых задан `thinking.block_binding.prefix_mismatch_behavior`. **Сделайте свою интеграцию работающей только на добавление (append-only) независимо от возраста аккаунта**, чтобы один и тот же код работал на любом аккаунте, включая новые аккаунты, для которых проверка применяется по умолчанию.

## Кому нужно что-то менять

Для вас ничего не меняется, если ваши запросы формирует Claude Code, claude.ai, Claude Managed Agents или Claude Agent SDK, либо если ваш код сохраняет `system` и `tools` неизменными в течение сеанса и только добавляет сообщения в `messages`. Claude Mythos 5.1 и модели до Claude Fable 5.1 не выполняют проверку префикса. Если вы никогда не отправляете блоки размышлений обратно, проверке префикса нечего отклонять, а модель не получает никаких своих предыдущих рассуждений.

Проверьте свою интеграцию, если между двумя запросами в одном разговоре она делает что-либо из перечисленного ниже. Каждый пункт ведёт к описанию того, что делать вместо этого:

* [Перестраивает системную подсказку `system`](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#new-instructions): дату, флаг режима, заново прочитанные инструкции проекта или плагин либо сервер MCP, который подключается после первого хода
* [Заново формирует контекст в первом сообщении пользователя](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#changing-context)
* [Очищает или сокращает старые результаты инструментов либо перекодирует старые изображения](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#server-side-trimming)
* [Суммирует или удаляет старые ходы на стороне клиента](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#custom-compaction-on-the-client) и сохраняет недавние ходы вместе с их размышлениями
* [Добавляет, удаляет или редактирует записи в `tools`](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#tool-changes)
* [Добавляет напоминание в ход пользователя](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#per-turn-reminders), а позже удаляет или переписывает его
* [Удаляет некоторые блоки `thinking` и сохраняет более поздние](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#append-assistant-turns-exactly-as-returned) или удаляет их, а [позже возвращает обратно](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#prefix-check)
* [Восстанавливает сохранённый сеанс из шаблонов](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#faq) вместо воспроизведения того, что было отправлено

На более старом аккаунте ни одно из этих действий не вызывает ошибку, если в запросе не задан `prefix_mismatch_behavior`, поэтому запуск без ошибок с вашим собственным ключом не показывает, затронут ли ваш код. Если люди используют ваш инструмент со своими ключами API, то пользователи новых аккаунтов получат ошибку 400 раньше вас. Чтобы увидеть то, что видят они, не меняя поведения своих запросов, отправляйте бета-заголовок `thinking-binding-controls-2026-08-01`. На более старом аккаунте каждый ответ тогда помечает блоки, не прошедшие проверку, а модель по-прежнему их читает (см. [Задание поведения при несоответствии и чтение `input_transformations`](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#preserved-thinking-controls)).

Также проверьте свою интеграцию, если она отправляет блоки размышлений Claude Sonnet 5.5 или Claude Haiku 5.5 от одного аккаунта в запросе, сделанном другим аккаунтом. См. [Блоки размышлений остаются в аккаунте, который их создал](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#account-bound-thinking).

## Переключение моделей посреди разговора

Claude Fable 5.1 и Claude Mythos 5.1 читают блоки размышлений, созданные друг другом и более ранними моделями Claude. Никакая другая модель не читает блоки размышлений от Claude Fable 5.1 или Claude Mythos 5.1.

Claude Opus 5.5 читает блоки размышлений от Claude Opus 5, от более ранних моделей Opus, Sonnet и Haiku, а в Claude API и Google Cloud — от Claude Sonnet 5.5 и Claude Haiku 5.5, но не от моделей Claude Fable или Claude Mythos. В Claude API Claude Fable 5.1 и Claude Mythos 5.1 читают блоки размышлений от Claude Opus 5.5; никакая другая модель этого не делает. Поэтому разговор, который переходит с Claude Opus 5 на Claude Opus 5.5, сохраняет свои рассуждения, как и разговор, который переходит с Claude Opus 5.5 на Claude Fable 5.1 или Claude Mythos 5.1 в Claude API. Разговор, который переходит с Claude Fable 5.1 или Claude Mythos 5.1 на Claude Opus 5.5 либо с Claude Opus 5.5 на любую модель, кроме этих двух, выполняет ходы после переключения без рассуждений предыдущей модели. Блоки удаляются, а не отклоняются, как описано далее в этом разделе.

Claude Sonnet 5.5 читает блоки размышлений от Claude Sonnet 5, Claude Opus 4.8, Claude Haiku 4.5 и более ранних моделей, а в Claude API и Google Cloud — от Claude Haiku 5.5, но не от Claude Opus 5, Claude Opus 5.5 или любой модели Claude Fable или Claude Mythos. В Claude API и Google Cloud Claude Opus 5.5 читает блоки размышлений от Claude Sonnet 5.5; никакая другая модель этого не делает. Поэтому разговор, который переходит с Claude Sonnet 5 на Claude Sonnet 5.5, сохраняет свои рассуждения, как и разговор, который переходит с Claude Sonnet 5.5 на Claude Opus 5.5 в Claude API и Google Cloud. Разговор, который переходит на Claude Sonnet 5.5 с Claude Opus 5, Claude Opus 5.5 или модели Claude Fable или Claude Mythos, выполняет ходы после переключения без рассуждений предыдущей модели. То же относится к любому другому переходу с Claude Sonnet 5.5, например к [резервному переключению на стороне сервера](https://platform.claude.com/docs/ru/build-with-claude/refusals-and-fallback#server-side-fallback) на Claude Sonnet 5.

Claude Haiku 5.5 читает блоки размышлений от Claude Sonnet 5, Claude Opus 4.8, Claude Haiku 4.5 и более ранних моделей, но не от Claude Opus 5, Claude Opus 5.5, Claude Sonnet 5.5 или любой модели Claude Fable или Claude Mythos. В Claude API и Google Cloud Claude Opus 5.5 и Claude Sonnet 5.5 читают блоки размышлений от Claude Haiku 5.5; никакая другая модель этого не делает. Поэтому разговор, который переходит с Claude Haiku 4.5 на Claude Haiku 5.5, сохраняет свои рассуждения, как и разговор, который переходит с Claude Haiku 5.5 на Claude Opus 5.5 или Claude Sonnet 5.5 в Claude API и Google Cloud. Разговор, который переходит на Claude Haiku 5.5 с Claude Opus 5, Claude Opus 5.5, Claude Sonnet 5.5 или модели Claude Fable или Claude Mythos, выполняет ходы после переключения без рассуждений предыдущей модели, как и при любом другом переходе с Claude Haiku 5.5.

* **Разговор, который переходит на Claude Fable 5.1 с более ранней модели или с Claude Opus 5.5 в Claude API, сохраняет свои рассуждения.** Блоки размышлений более ранней модели остаются читаемыми, поэтому модель размышляет как обычно с первого хода после переключения.
* **Разговор, который переходит с Claude Fable 5.1 на любую модель, кроме Claude Mythos 5.1, теряет рассуждения Claude Fable 5.1 для этого запроса.** Это происходит, когда маршрутизатор отправляет ход более дешёвой модели, после [резервного переключения при отказе классификатора](https://platform.claude.com/docs/ru/build-with-claude/refusals-and-fallback) или во время [резервного переключения на стороне сервера](https://platform.claude.com/docs/ru/build-with-claude/refusals-and-fallback#server-side-fallback). API удаляет нечитаемые блоки до того, как подсказка достигнет модели. Они не тарифицируются и не учитываются в `input_tokens`.

Продолжайте отправлять полную историю в каждом запросе, включая блоки размышлений, и позвольте API удалять то, что текущая модель не может прочитать. API никогда не редактирует ваш массив `messages`, поэтому удалённые блоки остаются в вашей истории. Когда та же история снова отправляется в Claude Fable 5.1, её блоки снова становятся читаемыми вместе с размышлениями более ранней модели. Рассуждения теряются навсегда, только если ваш клиент сам удаляет блоки, например обвязка (harness), которая вырезает размышления при переключении модели или восстанавливает историю из того, что использовала каждая модель.

<Frame>
  ![Анимация: при переключении на Claude Opus размышления Claude Fable 5.1 пропускаются для этого хода; при обратном переключении всё снова читается](https://platform.claude.com/docs/images/preserved-thinking-model-switch.svg)
</Frame>

С [бета-заголовком](https://platform.claude.com/docs/ru/api/beta-headers) `thinking-binding-controls-2026-08-01` ответ перечисляет каждый удалённый блок в массиве верхнего уровня `input_transformations` с `reason: "model_binding_mismatch"`:

```json
{
  "input_transformations": [
    {
      "type": "thinking_dropped",
      "path": "messages.3.content.0",
      "reason": "model_binding_mismatch"
    }
  ]
}
```

Без заголовка удаление происходит незаметно. Эта запись не означает ошибку в вашей интеграции, и `prefix_mismatch_behavior` на неё не влияет: блок, который текущая модель не может прочитать, всегда удаляется.

## Блоки размышлений остаются в аккаунте, который их создал

Блоки размышлений, которые создаёт Claude Sonnet 5.5 или Claude Haiku 5.5, работают только в аккаунте, который их создал, или в связанном с ним аккаунте. Когда другой аккаунт отправляет один из таких блоков, API удаляет блок до того, как его увидит модель, и запрос выполняется успешно. Модель отвечает без рассуждений из удалённых блоков. Блоки от более ранних моделей это не затрагивает.

В Claude API и Google Cloud с [бета-заголовком](https://platform.claude.com/docs/ru/api/beta-headers) `thinking-binding-controls-2026-08-01` ответ перечисляет каждый удалённый блок в `input_transformations` как запись `thinking_dropped` с `reason: "organization_binding_mismatch"`. Без заголовка удаление происходит незаметно.

## Сохранение префикса неизменным

В Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 и Claude Haiku 5.5 блок размышлений остаётся действительным, только пока всё, что вы отправили перед ним, остаётся неизменным в последующих запросах. Проверяемый префикс состоит из трёх частей:

* Системная подсказка верхнего уровня `system`
* Набор `tools`
* Каждое `message` перед блоком

Примечание: при серверном [сжатии (compaction)](https://platform.claude.com/docs/ru/build-with-claude/compaction) проверяемый префикс начинается с самого последнего блока сжатия.

Параметры запроса за пределами этих трёх полей, такие как `effort`, `max_tokens`, `output_config`, `tool_choice` и `metadata`, не входят в проверку префикса, как и маркеры `cache_control`. Полный список приведён в разделе [Что считается редактированием](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#what-counts-as-an-edit).

Более ранние блоки размышлений не входят в префикс, но каждый блок размышлений записывает, какой блок размышлений шёл перед ним, в том числе между ходами. Вы можете удалять блоки размышлений с начала истории (начиная с самых старых), с конца или все сразу. Ошибку вызывает разрыв: сохраняемые блоки размышлений должны образовывать непрерывную часть исходной последовательности, поэтому удаление блока из середины делает недействительными блоки размышлений после него. Удалив блок, больше не добавляйте его. Если вернуть его обратно, блоки размышлений, созданные в его отсутствие, станут недействительными.

Сохраняйте `system` и `tools` неизменными в течение сеанса и рассматривайте `messages` как массив только для добавления. Та же дисциплина сохраняет префикс стабильным для [кэширования подсказок](https://platform.claude.com/docs/ru/build-with-claude/prompt-caching): правки, которые делают размышления недействительными, — это те же правки, которые перезапускают кэш.

### Что API делает с недействительным блоком

Вы выбираете это с помощью `thinking.block_binding.prefix_mismatch_behavior`:

* **`"error"` (по умолчанию):** API отклоняет запрос с ошибкой 400 `invalid_request_error`, в которой указан первый не прошедший проверку блок.
* **`"drop_block"`:** API отбрасывает каждый не прошедший проверку блок и все блоки размышлений после него, и запрос выполняется успешно. Отброшенные блоки не тарифицируются. Модель отвечает на этом ходе без использования рассуждений из отброшенных блоков, а кэш подсказок перезапускается с места правки. Ответ перечисляет каждый отброшенный блок в `input_transformations` (в событии `message_start` при «streaming» (потоковой передаче)) с `reason: "prefix_binding_mismatch"`.

<Warning>
  `"drop_block"` позволяет запросам выполняться успешно, но не исправляет правку, вызвавшую несовпадение, и имеет свою цену. Отбрасывание блоков может значительно увеличить количество генерируемых выходных токенов, особенно при более высоких уровнях усилий или когда блоки отбрасываются на каждом ходу. Подробнее см. [Стоимость `"drop_block"` в выходных токенах](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#drop-block-cost). Отброшенные блоки не тарифицируются, но Claude воссоздаёт рассуждения, которые больше не может прочитать, поэтому генерирует больше выходных токенов. Качество вывода также может измениться в задачах, где более поздние ходы опираются на более ранние рассуждения. Используйте `"drop_block"` как временную меру, пока исправляете правку, но не как долгосрочную настройку.
</Warning>

Подсчитывайте ответы в каждом сеансе, у которых в `input_transformations` есть запись `prefix_binding_mismatch`, настройте по ним оповещения и замените каждую правку соответствующим шаблоном из раздела [Внесение изменений без редактирования префикса](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#replace-prefix-edits). В Message Batches API элемент, в котором поле не задано, не завершается ошибкой. Там, где API применяет проверку по умолчанию, он вместо этого отбрасывает не прошедшие проверку блоки. Явно задайте там `"error"`, если хотите, чтобы элементы пакета завершались ошибкой.

И поле, и массив `input_transformations` требуют [бета-заголовка](https://platform.claude.com/docs/ru/api/beta-headers) `thinking-binding-controls-2026-08-01`. В разделе [Задание поведения при несоответствии и чтение `input_transformations`](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#preserved-thinking-controls) показан запрос в каждом SDK.

Сообщение об ошибке 400 начинается так:

```text wrap
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".
```

Если запрос не отправил бета-заголовок, сообщение продолжается так:

```text wrap
That setting requires the `thinking-binding-controls-2026-08-01` value in the `anthropic-beta` header.
```

Обычно оно заканчивается предложением, называющим, что изменилось, например, что системная подсказка `system` или список `tools` отличается от того, что было при создании блока. В разделе [Устранение неполадок размышлений](https://platform.claude.com/docs/ru/build-with-claude/thinking-troubleshooting#error-thinking-block-signature) описано, что может называть это предложение.

Подделанная или нерасшифровываемая подпись — это другой тип сбоя. В этом случае всегда возвращается 400 (``Invalid `signature` in `thinking` block`` без предложения о разговоре), и `prefix_mismatch_behavior` к нему не применяется.

#### Стоимость `"drop_block"` в выходных токенах

В тестировании Anthropic на многоходовом бенчмарке по программированию отбрасывание блоков размышлений один раз за сеанс увеличило количество выходных токенов на 2,5% при низком уровне усилий, на 3,9% при среднем, на 4,5% при высоком и на 20,1% при максимальном. Отбрасывание их на каждом ходу после первого увеличило количество выходных токенов на 4,6% при низком уровне усилий, на 9,7% при среднем, на 10,3% при высоком и на 67,1% при максимальном. Эти цифры — оценки с большой погрешностью, и влияние на вашу рабочую нагрузку зависит от вашей обвязки.

Когда Claude больше не может прочитать рассуждения из более ранних ходов, он воссоздаёт эти рассуждения, поэтому запросы, в которых отбрасываются блоки размышлений, генерируют больше выходных токенов и могут отвечать дольше. Отбрасывание на каждом ходу обходится дороже, чем эпизодическое, а насколько дороже — зависит от вашей обвязки: как часто она редактирует префикс и насколько каждый ход опирается на более ранние рассуждения.

Прежде чем полагаться на `"drop_block"`, проведите оценки на вашей собственной рабочей нагрузке, чтобы измерить прирост. Если он небольшой, `"drop_block"` может обеспечивать успешное выполнение запросов, пока вы исправляете правку. В любом случае исправление правки с помощью шаблона из раздела [Внесение изменений без редактирования префикса](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#replace-prefix-edits) — лучшее долгосрочное решение.

#### Обработка ошибки в коде

Это ошибка 400 `invalid_request_error`, показанная ранее в этом разделе. Не отправляйте повторно то же тело запроса: оно каждый раз будет завершаться ошибкой одинаково. Повторите попытку один раз с бета-заголовком и `prefix_mismatch_behavior: "drop_block"` в качестве временной меры ([`"drop_block"` может увеличить количество выходных токенов](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#drop-block-cost)) и сохраните этот выбор вместе с сеансом, чтобы каждый последующий запрос тоже его отправлял, в том числе после перезапуска. В Claude Sonnet 5.5 и Claude Haiku 5.5 `block_binding` работает только с `thinking: {"type": "adaptive"}`. При `between_tools` в Claude Sonnet 5.5 или `thinking: {"type": "disabled"}` в Claude Haiku 5.5 сохраняйте историю только для добавления или вырезайте блоки размышлений начиная с отредактированного хода. Если вы не можете отправить бета-заголовок, один раз удалите из истории все блоки `thinking` и `redacted_thinking`, больше не возвращайте их и продолжайте. Затем исправьте правку, вызвавшую несовпадение.

### Задание поведения при несоответствии и чтение `input_transformations`

[Бета-заголовок](https://platform.claude.com/docs/ru/api/beta-headers) `thinking-binding-controls-2026-08-01` добавляет:

* Массив верхнего уровня `input_transformations` в каждом ответе
* Объект `block_binding` в конфигурации `thinking`, единственное поле которого — `prefix_mismatch_behavior`

`block_binding` принимается вместе с `thinking.type: "adaptive"` и `thinking.type: "enabled"`. В Claude Sonnet 5.5 и Claude Haiku 5.5 `block_binding` работает только с `thinking: {"type": "adaptive"}`. Отправка его вместе с `between_tools` в Claude Sonnet 5.5 или с `thinking: {"type": "disabled"}` в Claude Haiku 5.5 возвращает ошибку 400. Отправка его без бета-заголовка возвращает ошибку 400, сообщение которой заканчивается на `block_binding: Extra inputs are not permitted`. Модели, которые не выполняют проверку префикса, принимают этот объект и сообщают только об удалениях по проверке модели, поэтому одно тело запроса работает для разных моделей. В справочнике API проверка префикса называется проверкой разговора.

Следующий запрос выбирает удаление вместо отклонения. На первом ходе воспроизводить нечего, поэтому `input_transformations` возвращается пустым:

<CodeGroup>
  ```bash cURL
  curl https://api.anthropic.com/v1/messages \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -H "content-type: application/json" \
    -d '{
      "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?"
        }
      ]
    }'
  ```

  ```bash CLI
  ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
    --format yaml <<'YAML'
  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?
  YAML
  ```

  ```python Python
  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 [])}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const response = await 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 (const block of response.content) {
    if (block.type === "text") {
      console.log(block.text);
    }
  }
  console.log(`Input transformations: ${response.input_transformations?.length ?? 0}`);
  ```

  ```csharp C#
  AnthropicClient client = new();

  var response = await client.Beta.Messages.Create(
      new()
      {
          Model = Model.ClaudeFable5_1,
          MaxTokens = 16000,
          Thinking = new BetaThinkingConfigAdaptive
          {
              BlockBinding = new()
              {
                  PrefixMismatchBehavior = BetaThinkingPrefixMismatchBehavior.DropBlock,
              },
          },
          Messages =
          [
              new()
              {
                  Role = Role.User,
                  Content = "What is the greatest common divisor of 1071 and 462?",
              },
          ],
          Betas = [AnthropicBeta.ThinkingBindingControls2026_08_01],
      }
  );

  foreach (var block in response.Content)
  {
      if (block.TryPickText(out var textBlock))
      {
          Console.WriteLine(textBlock.Text);
      }
  }

  Console.WriteLine($"Input transformations: {response.InputTransformations?.Count ?? 0}");
  ```

  ```go Go
  client := anthropic.NewClient()

  response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
  	Model:     anthropic.ModelClaudeFable5_1,
  	MaxTokens: 16000,
  	Thinking: anthropic.BetaThinkingConfigParamUnion{
  		OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{
  			BlockBinding: anthropic.BetaThinkingBlockBindingParam{
  				PrefixMismatchBehavior: anthropic.BetaThinkingPrefixMismatchBehaviorDropBlock,
  			},
  		},
  	},
  	Messages: []anthropic.BetaMessageParam{
  		anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock("What is the greatest common divisor of 1071 and 462?")),
  	},
  	Betas: []anthropic.AnthropicBeta{anthropic.AnthropicBetaThinkingBindingControls2026_08_01},
  })
  if err != nil {
  	log.Fatal(err)
  }

  for _, block := range response.Content {
  	if textBlock, ok := block.AsAny().(anthropic.BetaTextBlock); ok {
  		fmt.Println(textBlock.Text)
  	}
  }
  fmt.Printf("Input transformations: %d\n", len(response.InputTransformations))
  ```

  ```java Java
  import com.anthropic.models.beta.AnthropicBeta;
  import com.anthropic.models.beta.messages.BetaMessage;
  import com.anthropic.models.beta.messages.BetaThinkingBlockBinding;
  import com.anthropic.models.beta.messages.BetaThinkingConfigAdaptive;
  import com.anthropic.models.beta.messages.BetaThinkingPrefixMismatchBehavior;
  import com.anthropic.models.beta.messages.MessageCreateParams;
  import com.anthropic.models.messages.Model;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      MessageCreateParams params = MessageCreateParams.builder()
          .model(Model.CLAUDE_FABLE_5_1)
          .maxTokens(16000L)
          .addBeta(AnthropicBeta.THINKING_BINDING_CONTROLS_2026_08_01)
          .thinking(BetaThinkingConfigAdaptive.builder()
              .blockBinding(BetaThinkingBlockBinding.builder()
                  .prefixMismatchBehavior(BetaThinkingPrefixMismatchBehavior.DROP_BLOCK)
                  .build())
              .build())
          .addUserMessage("What is the greatest common divisor of 1071 and 462?")
          .build();

      BetaMessage response = client.beta().messages().create(params);

      response.content().stream()
          .flatMap(block -> block.text().stream())
          .forEach(textBlock -> IO.println(textBlock.text()));
      IO.println("Input transformations: "
          + response.inputTransformations().map(List::size).orElse(0));
  }
  ```

  ```php PHP
  use Anthropic\Beta\AnthropicBeta;
  use Anthropic\Beta\Messages\BetaThinkingBlockBinding;
  use Anthropic\Beta\Messages\BetaThinkingConfigAdaptive;
  use Anthropic\Beta\Messages\BetaThinkingPrefixMismatchBehavior;
  use Anthropic\Client;

  $client = new Client();

  $response = $client->beta->messages->create(
      model: 'claude-fable-5-1',
      maxTokens: 16000,
      thinking: BetaThinkingConfigAdaptive::with(
          blockBinding: BetaThinkingBlockBinding::with(
              prefixMismatchBehavior: BetaThinkingPrefixMismatchBehavior::DROP_BLOCK,
          ),
      ),
      messages: [
          ['role' => 'user', 'content' => 'What is the greatest common divisor of 1071 and 462?'],
      ],
      betas: [AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
  );

  foreach ($response->content as $block) {
      if ($block->type === 'text') {
          echo $block->text, PHP_EOL;
      }
  }

  echo 'Input transformations: ', count($response->inputTransformations ?? []), PHP_EOL;
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  response = client.beta.messages.create(
    model: "claude-fable-5-1",
    max_tokens: 16_000,
    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: [Anthropic::AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01]
  )

  response.content.each do |block|
    puts block.text if block.type == :text
  end

  puts "Input transformations: #{response.input_transformations&.length || 0}"
  ```
</CodeGroup>

```text Output wrap
The greatest common divisor of 1071 and 462 is 21.
Input transformations: 0
```

С бета-заголовком каждый ответ от модели, поддерживающей размышления, содержит `input_transformations`. Каждая запись указывает один блок размышлений по его `path` (например, `messages.1.content.0`) и содержит `reason`. Существует два типа записей:

* **`thinking_dropped`:** API удаляет блок до того, как модель его прочитает, и блок не тарифицируется. `reason` — это `prefix_binding_mismatch` или `model_binding_mismatch` (см. [Переключение моделей посреди разговора](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#switching-models)). `reason` также может быть `organization_binding_mismatch`, что означает, что блок пришёл из другого аккаунта (см. [Блоки размышлений остаются в аккаунте, который их создал](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#account-bound-thinking)).
* **`thinking_mismatch_allowed`:** блок не проходит проверку префикса, но API не применяет эту проверку для данного запроса, поэтому блок попадает к модели без изменений и тарифицируется. `reason` всегда `prefix_binding_mismatch`. Эта запись появляется только в запросах, для которых API не применяет проверку по умолчанию, например в запросах от более старого аккаунта (см. [Когда API применяет проверку](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#enforcement)). Задание `prefix_mismatch_behavior` в любое значение включает применение проверки для запроса, поэтому запрос, в котором оно задано, никогда не получает эту запись.

Массив пуст, если ни один блок не был удалён и ни один не провалил проверку префикса. Игнорируйте записи, `type` или `reason` которых вам незнакомы, потому что последующие проверки добавляют новые значения.

При [потоковой передаче](https://platform.claude.com/docs/ru/build-with-claude/streaming) массив приходит в объекте `message` в событии `message_start`. После резервного переключения на стороне сервера посреди потока финальное событие `message_delta` снова содержит его с записями обслуживающей модели. В [пакете сообщений](https://platform.claude.com/docs/ru/build-with-claude/batch-processing) элемент, блок которого не проходит проверку префикса при явно заданном `"error"`, получает статус `errored`. Элемент, в котором поле не задано, не завершается ошибкой. Там, где API применяет проверку по умолчанию, он вместо этого удаляет не прошедшие проверку блоки. Эндпоинт [подсчёта токенов](https://platform.claude.com/docs/ru/build-with-claude/token-counting) выполняет ту же проверку префикса и возвращает ту же ошибку 400.

### Когда API применяет проверку

API применяет проверку префикса в Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 и Claude Haiku 5.5 для новых аккаунтов.

* **Аккаунты, созданные 31 августа 2026 года, 00:00 UTC, или позже:** API проверяет запросы к Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 и Claude Haiku 5.5 и применяет `"error"`, если вы не задали `"drop_block"`. Одно и то же определение нового аккаунта действует для Claude API и облачных платформ.
* **Более старые аккаунты:** API применяет проверку только к запросам, в которых задан `prefix_mismatch_behavior`. Задание этого поля включает проверку для запроса, поэтому вы можете увидеть то, что видит новый аккаунт, не создавая его. В запросах, где поле не задано, API всё равно выполняет проверку, но пропускает не прошедшие её блоки к модели. С бета-заголовком ответ перечисляет каждый такой блок в `input_transformations` как `thinking_mismatch_allowed`, поэтому вы можете находить правки префикса, не меняя того, что получает модель.

Чтобы узнать, к какой группе относится ваш аккаунт, возьмите разговор с Claude Fable 5.1, содержащий блок размышлений, измените что-нибудь перед этим блоком и отправьте его в Claude Fable 5.1 без бета-заголовка и без поля `block_binding`. Ответ 400, в котором упоминается заголовок, означает, что для вашего аккаунта проверка применяется по умолчанию. Ответ 200 означает, что не применяется. Для подтверждения отправьте тот же запрос ещё раз с бета-заголовком, по-прежнему без `block_binding`: ответ перечислит каждый блок размышлений после вашей правки в `input_transformations` как `thinking_mismatch_allowed`.

### Что считается редактированием

Каждая строка сравнивает два последовательных запроса:

| Изменение между запросами                                                                                                                                                   | Последующие блоки размышлений                                                                                                                                                                                                                                                                                                                                                          |
| --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Добавление сообщений в конец                                                                                                                                                | Действительны                                                                                                                                                                                                                                                                                                                                                                          |
| Добавление инструмента с `defer_loading: true`, на который ещё ничто не ссылалось                                                                                           | Действительны                                                                                                                                                                                                                                                                                                                                                                          |
| Удаление блоков `thinking` с начала истории, с конца или всех сразу                                                                                                         | Действительны (модель теряет эти рассуждения)                                                                                                                                                                                                                                                                                                                                          |
| Изменение любого параметра запроса вне `system`, `tools` и `messages` (`effort`, `max_tokens`, `output_config`, `tool_choice`, `metadata`, `thinking.display` и т. д.)      | Действительны                                                                                                                                                                                                                                                                                                                                                                          |
| Добавление, перемещение или удаление маркеров `cache_control`                                                                                                               | Действительны                                                                                                                                                                                                                                                                                                                                                                          |
| Ротируемый подписанный URL, возвращающий те же байты                                                                                                                        | Действительны                                                                                                                                                                                                                                                                                                                                                                          |
| Серверное сжатие или редактирование контекста удаляет или заменяет содержимое                                                                                               | Действительны (проверка сравнивает то, что отправили вы, а не отредактированную сервером копию)                                                                                                                                                                                                                                                                                        |
| Очищенное [системное сообщение с областью действия хода](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#per-turn-reminders), оставленное на месте | Действительны                                                                                                                                                                                                                                                                                                                                                                          |
| Редактирование, изменение порядка или удаление любого более раннего сообщения `user`, `assistant` или `system`                                                              | Недействительны, за исключением случая, когда подписанный блок из [сжатия по запросу](https://platform.claude.com/docs/ru/build-with-claude/compaction-on-demand) заменяет резюмируемые им сообщения при соблюдении [условий для сохранённых размышлений](https://platform.claude.com/docs/ru/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid) |
| Повторное формирование контекста, помещённого в первое сообщение пользователя, с изменённым значением                                                                       | Недействительны все блоки размышлений                                                                                                                                                                                                                                                                                                                                                  |
| Очистка или сокращение более раннего `tool_result`, перекодирование более раннего изображения или изменение входных данных более раннего `tool_use`                         | Недействительны все последующие блоки размышлений                                                                                                                                                                                                                                                                                                                                      |
| Добавление текстового блока в более ранний ход пользователя или удаление блока, добавленного в прошлый раз                                                                  | Недействительны                                                                                                                                                                                                                                                                                                                                                                        |
| Изменение строки или блоков `system` верхнего уровня                                                                                                                        | Недействительны                                                                                                                                                                                                                                                                                                                                                                        |
| Добавление, удаление, переименование или редактирование инструмента в `tools`                                                                                               | Недействительны                                                                                                                                                                                                                                                                                                                                                                        |
| Удаление блока `thinking` из середины истории с сохранением более поздних                                                                                                   | Недействительны все последующие блоки размышлений                                                                                                                                                                                                                                                                                                                                      |
| Возврат блока `thinking`, удалённого в более раннем запросе                                                                                                                 | Недействительны блоки размышлений, созданные, пока его не было                                                                                                                                                                                                                                                                                                                         |
| URL изображения или документа, возвращающий другие байты при следующем запросе                                                                                              | Недействительны                                                                                                                                                                                                                                                                                                                                                                        |
| То же сообщение с областью действия хода, удалённое или переформулированное в более позднем запросе                                                                         | Недействительны                                                                                                                                                                                                                                                                                                                                                                        |

### Проверка того, редактирует ли ваш код префикс

<Tip>
  **Автоматизируйте эту проверку с помощью навыка Claude API.** В последней версии [Claude Code](https://code.claude.com/docs/en/overview) откройте репозиторий, который формирует ваши запросы, и запустите встроенный [навык Claude API](https://platform.claude.com/docs/ru/agents-and-tools/agent-skills/claude-api-skill#checking-an-integration-for-preserved-thinking):

  Позвольте Claude Code проверить ваш код за вас

  ```text
  /claude-api preserved-thinking-migration
  ```

  Навык записывает несколько ваших собственных многоходовых сеансов и сравнивает последовательные запросы, чтобы найти места, где ваш код редактирует префикс. Затем он воспроизводит сеансы с `"drop_block"` и подсчитывает блоки размышлений, которые удаляет API. После этого он исправляет по одной причине за раз и повторяет измерение после каждого исправления.
</Tip>

Сначала сравните то, что вы отправляете. Запишите тела запросов, которые ваша интеграция отправляет за несколько обычных ходов, включая сжатие или изменение инструментов. Для каждой пары последовательных запросов сравните `system`, `tools` и общие для них `messages`. Они должны быть идентичны вплоть до вновь добавленных ходов.

Затем подтвердите результат через API. Добавьте бета-заголовок `thinking-binding-controls-2026-08-01`, задайте `prefix_mismatch_behavior` значение `"drop_block"` и проведите обычный многоходовый сеанс через свою интеграцию на claude-fable-5-1. Следующий пример выполняет два хода так, как это должна делать ваша интеграция: `messages` только растёт, каждый ход ассистента отправляется обратно точно в том виде, в каком его вернул API, включая блоки `thinking`, а `block_binding` задаётся в каждом запросе. После каждого хода он выводит количество блоков `thinking` в ответе и количество удалённых блоков:

<CodeGroup>
  ```bash cURL
  # Подсчитывает блоки размышлений в ответе и блоки, отброшенные API
  COUNTS='"thinking blocks: \([.content[] | select(.type == "thinking")] | length), " +
    "dropped: \(.input_transformations | length)"'

  FIRST=$(curl -s https://api.anthropic.com/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -d '{
      "model": "claude-fable-5-1",
      "max_tokens": 16000,
      "thinking": {
        "type": "adaptive",
        "block_binding": { "prefix_mismatch_behavior": "drop_block" }
      },
      "messages": [
        {
          "role": "user",
          "content": "How many positive integers below 500 have exactly 6 positive divisors?"
        }
      ]
    }')
  echo "$FIRST" | jq -r "$COUNTS"

  # Ход 2: ход ассистента передаётся обратно точно в полученном виде, затем следующее сообщение пользователя
  MESSAGES=$(jq -n --argjson first "$FIRST" '[
    {
      role: "user",
      content: "How many positive integers below 500 have exactly 6 positive divisors?"
    },
    { role: "assistant", content: $first.content },
    { role: "user", content: "How many of those are odd?" }
  ]')

  jq -n --argjson messages "$MESSAGES" '{
    model: "claude-fable-5-1",
    max_tokens: 16000,
    thinking: {
      type: "adaptive",
      block_binding: { prefix_mismatch_behavior: "drop_block" }
    },
    messages: $messages
  }' | curl -s https://api.anthropic.com/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -d @- | jq -r "$COUNTS"
  ```

  ```bash CLI
  # Подсчитывает блоки размышлений в ответе и блоки, отброшенные API
  COUNTS='"thinking blocks: \([.content[] | select(.type == "thinking")] | length), " +
    "dropped: \(.input_transformations | length)"'

  FIRST=$(ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
    --format json <<'YAML'
  model: claude-fable-5-1
  max_tokens: 16000
  thinking:
    type: adaptive
    block_binding:
      prefix_mismatch_behavior: drop_block
  messages:
    - role: user
      content: How many positive integers below 500 have exactly 6 positive divisors?
  YAML
  )
  echo "$FIRST" | jq -r "$COUNTS"

  # Ход 2: ход ассистента передаётся обратно точно в том виде, в каком был получен, затем следующее сообщение пользователя
  ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
    --format json <<YAML | jq -r "$COUNTS"
  model: claude-fable-5-1
  max_tokens: 16000
  thinking:
    type: adaptive
    block_binding:
      prefix_mismatch_behavior: drop_block
  messages:
    - role: user
      content: How many positive integers below 500 have exactly 6 positive divisors?
    - role: assistant
      content: $(echo "$FIRST" | jq -c .content)
    - role: user
      content: How many of those are odd?
  YAML
  ```

  ```python Python
  client = anthropic.Anthropic()

  user_turns = [
      "How many positive integers below 500 have exactly 6 positive divisors?",
      "How many of those are odd?",
  ]

  # messages растёт от хода к ходу: каждый ход ассистента возвращается ровно в том виде, в каком был получен
  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}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const userTurns = [
    "How many positive integers below 500 have exactly 6 positive divisors?",
    "How many of those are odd?"
  ];

  // messages растёт от хода к ходу: каждый ход assistant возвращается ровно в том виде, в каком получен
  const messages: Anthropic.Beta.BetaMessageParam[] = [];
  for (const userTurn of userTurns) {
    messages.push({ role: "user", content: userTurn });
    const response = await client.beta.messages.create({
      model: "claude-fable-5-1",
      max_tokens: 16000,
      thinking: {
        type: "adaptive",
        block_binding: { prefix_mismatch_behavior: "drop_block" }
      },
      messages,
      betas: ["thinking-binding-controls-2026-08-01"]
    });
    messages.push({ role: "assistant", content: response.content });
    const thinkingBlocks = response.content.filter((block) => block.type === "thinking");
    const dropped = response.input_transformations ?? [];
    console.log(`thinking blocks: ${thinkingBlocks.length}, dropped: ${dropped.length}`);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  string[] userTurns =
  [
      "How many positive integers below 500 have exactly 6 positive divisors?",
      "How many of those are odd?",
  ];

  // messages растёт от хода к ходу: каждый ход ассистента возвращается ровно в том виде, в каком был получен
  List<BetaMessageParam> messages = [];
  foreach (var userTurn in userTurns)
  {
      messages.Add(new() { Role = Role.User, Content = userTurn });
      var response = await client.Beta.Messages.Create(
          new()
          {
              Model = Model.ClaudeFable5_1,
              MaxTokens = 16000,
              Thinking = new BetaThinkingConfigAdaptive
              {
                  BlockBinding = new()
                  {
                      PrefixMismatchBehavior = BetaThinkingPrefixMismatchBehavior.DropBlock,
                  },
              },
              Messages = messages,
              Betas = [AnthropicBeta.ThinkingBindingControls2026_08_01],
          }
      );
      messages.Add(new()
      {
          Role = Role.Assistant,
          Content = response.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList(),
      });
      var thinkingBlocks = response.Content.Count(block => block.TryPickThinking(out _));
      var dropped = response.InputTransformations?.Count ?? 0;
      Console.WriteLine($"thinking blocks: {thinkingBlocks}, dropped: {dropped}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  userTurns := []string{
  	"How many positive integers below 500 have exactly 6 positive divisors?",
  	"How many of those are odd?",
  }

  // messages растёт от хода к ходу: каждый ход assistant возвращается ровно в том виде, в каком получен
  messages := []anthropic.BetaMessageParam{}
  for _, userTurn := range userTurns {
  	messages = append(messages, anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock(userTurn)))
  	response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
  		Model:     anthropic.ModelClaudeFable5_1,
  		MaxTokens: 16000,
  		Thinking: anthropic.BetaThinkingConfigParamUnion{
  			OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{
  				BlockBinding: anthropic.BetaThinkingBlockBindingParam{
  					PrefixMismatchBehavior: anthropic.BetaThinkingPrefixMismatchBehaviorDropBlock,
  				},
  			},
  		},
  		Messages: messages,
  		Betas:    []anthropic.AnthropicBeta{anthropic.AnthropicBetaThinkingBindingControls2026_08_01},
  	})
  	if err != nil {
  		log.Fatal(err)
  	}
  	messages = append(messages, response.ToParam())
  	thinkingBlocks := 0
  	for _, block := range response.Content {
  		if block.Type == "thinking" {
  			thinkingBlocks++
  		}
  	}
  	fmt.Printf("thinking blocks: %d, dropped: %d\n", thinkingBlocks, len(response.InputTransformations))
  }
  ```

  ```java Java
  import com.anthropic.models.beta.AnthropicBeta;
  import com.anthropic.models.beta.messages.BetaContentBlock;
  import com.anthropic.models.beta.messages.BetaMessage;
  import com.anthropic.models.beta.messages.BetaThinkingBlockBinding;
  import com.anthropic.models.beta.messages.BetaThinkingConfigAdaptive;
  import com.anthropic.models.beta.messages.BetaThinkingPrefixMismatchBehavior;
  import com.anthropic.models.beta.messages.MessageCreateParams;
  import com.anthropic.models.messages.Model;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      List<String> userTurns = List.of(
          "How many positive integers below 500 have exactly 6 positive divisors?",
          "How many of those are odd?");

      // Список сообщений в builder растёт от хода к ходу: каждый ход ассистента возвращается ровно в том виде, в каком был получен
      MessageCreateParams.Builder conversation = MessageCreateParams.builder()
          .model(Model.CLAUDE_FABLE_5_1)
          .maxTokens(16000L)
          .thinking(BetaThinkingConfigAdaptive.builder()
              .blockBinding(BetaThinkingBlockBinding.builder()
                  .prefixMismatchBehavior(BetaThinkingPrefixMismatchBehavior.DROP_BLOCK)
                  .build())
              .build())
          .addBeta(AnthropicBeta.THINKING_BINDING_CONTROLS_2026_08_01);

      for (String userTurn : userTurns) {
          conversation.addUserMessage(userTurn);
          BetaMessage response = client.beta().messages().create(conversation.build());
          conversation.addMessage(response);
          long thinkingBlocks = response.content().stream()
              .filter(BetaContentBlock::isThinking)
              .count();
          int dropped = response.inputTransformations().map(List::size).orElse(0);
          IO.println("thinking blocks: " + thinkingBlocks + ", dropped: " + dropped);
      }
  }
  ```

  ```php PHP
  use Anthropic\Beta\AnthropicBeta;
  use Anthropic\Beta\Messages\BetaThinkingBlockBinding;
  use Anthropic\Beta\Messages\BetaThinkingConfigAdaptive;
  use Anthropic\Beta\Messages\BetaThinkingPrefixMismatchBehavior;
  use Anthropic\Client;

  $client = new Client();

  $userTurns = [
      'How many positive integers below 500 have exactly 6 positive divisors?',
      'How many of those are odd?',
  ];

  // $messages растёт от хода к ходу: каждый ход ассистента возвращается ровно в том виде, в каком получен
  $messages = [];
  foreach ($userTurns as $userTurn) {
      $messages[] = ['role' => 'user', 'content' => $userTurn];
      $response = $client->beta->messages->create(
          model: 'claude-fable-5-1',
          maxTokens: 16000,
          thinking: BetaThinkingConfigAdaptive::with(
              blockBinding: BetaThinkingBlockBinding::with(
                  prefixMismatchBehavior: BetaThinkingPrefixMismatchBehavior::DROP_BLOCK,
              ),
          ),
          messages: $messages,
          betas: [AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
      );
      $messages[] = ['role' => 'assistant', 'content' => $response->content];
      $thinkingBlocks = array_filter($response->content, fn ($block) => $block->type === 'thinking');
      $dropped = $response->inputTransformations ?? [];
      echo 'thinking blocks: ', count($thinkingBlocks), ', dropped: ', count($dropped), PHP_EOL;
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  user_turns = [
    "How many positive integers below 500 have exactly 6 positive divisors?",
    "How many of those are odd?"
  ]

  # messages растёт от хода к ходу: каждый ход assistant возвращается ровно в том виде, в каком был получен
  messages = []
  user_turns.each do |user_turn|
    messages << {role: "user", content: user_turn}
    response = client.beta.messages.create(
      model: "claude-fable-5-1",
      max_tokens: 16_000,
      thinking: {
        type: "adaptive",
        block_binding: {prefix_mismatch_behavior: "drop_block"}
      },
      messages: messages,
      betas: [Anthropic::AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01]
    )
    messages << {role: "assistant", content: response.content}
    thinking_blocks = response.content.count { |block| block.type == :thinking }
    dropped = (response.input_transformations || []).length
    puts "thinking blocks: #{thinking_blocks}, dropped: #{dropped}"
  end
  ```
</CodeGroup>

```text Output wrap
thinking blocks: 1, dropped: 0
thinking blocks: 1, dropped: 0
```

Ни один ход не удаляет блок, потому что ничего ранее не изменилось. Убедитесь, что первый ответ содержит блок `thinking`. При адаптивных размышлениях некоторые ответы их не содержат. Если ни один ответ в сеансе не содержит такого блока, проверять нечего и количество удалённых блоков будет 0, что бы вы ни меняли, поэтому запустите пример ещё раз.

Записывайте `input_transformations` в журнал на каждом ходе своей интеграции. Когда API удаляет блок, запись выглядит так:

```json
{
  "input_transformations": [
    {
      "type": "thinking_dropped",
      "path": "messages.1.content.0",
      "reason": "prefix_binding_mismatch"
    }
  ]
}
```

* **Пусто на каждом ходе сеанса, содержащего блоки `thinking`:** ваша интеграция сохраняет префикс нетронутым.
* **`reason: "prefix_binding_mismatch"`:** что-то перед блоком по адресу `path` изменилось с предыдущего запроса. Сравните `system`, `tools` и `messages` вплоть до этого хода, чтобы найти изменение, или отправьте запрос повторно с `"error"`: ошибка 400 обычно заканчивается предложением, указывающим, что изменилось. Затем найдите соответствующую замену в разделе [Внесение изменений без редактирования префикса](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#replace-prefix-edits).
* **`reason: "model_binding_mismatch"`:** разговор перешёл на модель, которая не может читать блоки более ранней модели. Это не правка префикса. См. [Переключение моделей посреди разговора](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#switching-models).
* **`reason: "organization_binding_mismatch"`:** блок пришёл из другого аккаунта. См. [Блоки размышлений остаются в аккаунте, который их создал](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#account-bound-thinking).

Чтобы намеренно вызвать сбой, отправьте третий ход из предыдущего примера и добавьте системную подсказку `system` только в этот запрос, чтобы он отличался от первых двух запросов, в которых её не было. С `"drop_block"` количество удалённых блоков больше не равно 0: ответ содержит по одной записи для каждого блока размышлений в истории, каждую с `reason: "prefix_binding_mismatch"`. С `"error"` запрос возвращает ошибку 400, описанную в разделе [Что API делает с недействительным блоком](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#mismatch-behavior), и её последнее предложение указывает на системную подсказку `system`. На вкладках cURL и CLI удалите фильтр `jq`, чтобы увидеть тело ошибки. Если количество по-прежнему равно 0, проверять было нечего: убедитесь, что используется модель claude-fable-5-1, что в запросе задан `block_binding`, что отправленная история содержит блоки `thinking` и что в первых двух запросах не было системной подсказки `system`.

Два простых хода редко выявляют проблему. Проведите сеанс через каждый из следующих сценариев с заданным `"error"`, чтобы регрессия приводила к сбою в вашем CI:

* Первое сжатие или обрезка на стороне клиента
* Инструмент, плагин или сервер MCP, который подключается после первого хода
* Смена режима или инструкций
* Длинный цикл инструментов, если вы добавляете напоминания или сокращаете старые результаты инструментов
* Переключение на другую модель и обратно
* Сохранение, перезапуск и возобновление в более позднюю дату

На более старом аккаунте вы также можете наблюдать за рабочим трафиком, не включая применение проверки: отправляйте бета-заголовок, не указывайте `block_binding` и записывайте `input_transformations` в журнал. Отправка одного только заголовка не меняет того, что получает модель. Каждый блок размышлений, идущий после отредактированного вами содержимого, не проходит проверку и получает собственную запись `thinking_mismatch_allowed` с теми же полями `path` и `reason`, что и у записи `thinking_dropped`. Блоки перед правкой по-прежнему проходят проверку. Правка в `system` или `tools` находится перед каждым блоком, поэтому из-за неё проверку не проходит каждый блок размышлений в запросе. Одна запись выглядит так:

```json
{
  "input_transformations": [
    {
      "type": "thinking_mismatch_allowed",
      "path": "messages.1.content.0",
      "reason": "prefix_binding_mismatch"
    }
  ]
}
```

Запускайте следующий пример с [более старого аккаунта](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#enforcement), потому что новый аккаунт отклонит его третий запрос с ошибкой 400. Пример отправляет заголовок без `block_binding` и продолжает предыдущий сеанс третьим запросом, который добавляет системную подсказку, намеренно изменяя префикс. После каждого хода он выводит количество блоков `thinking` и помеченных блоков:

<CodeGroup>
  ```bash cURL
  # Подсчитывает блоки размышлений в ответе и блоки, не прошедшие проверку префикса
  COUNTS='"thinking blocks: \([.content[] | select(.type == "thinking")] | length), " +
    "flagged: \([.input_transformations[] |
      select(.type == "thinking_mismatch_allowed")] | length)"'

  FIRST=$(curl -s https://api.anthropic.com/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -d '{
      "model": "claude-fable-5-1",
      "max_tokens": 16000,
      "thinking": { "type": "adaptive" },
      "messages": [
        {
          "role": "user",
          "content": "How many positive integers below 500 have exactly 6 positive divisors?"
        }
      ]
    }')
  echo "$FIRST" | jq -r "$COUNTS"

  # Ход 2: ход ассистента возвращается ровно в том виде, в каком получен, затем следующее сообщение пользователя
  MESSAGES=$(jq -n --argjson first "$FIRST" '[
    {
      role: "user",
      content: "How many positive integers below 500 have exactly 6 positive divisors?"
    },
    { role: "assistant", content: $first.content },
    { role: "user", content: "How many of those are odd?" }
  ]')

  SECOND=$(jq -n --argjson messages "$MESSAGES" '{
    model: "claude-fable-5-1",
    max_tokens: 16000,
    thinking: { type: "adaptive" },
    messages: $messages
  }' | curl -s https://api.anthropic.com/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -d @-)
  echo "$SECOND" | jq -r "$COUNTS"

  # Ход 3: только этот запрос добавляет системную подсказку, намеренно изменяя префикс
  jq -n --argjson messages "$MESSAGES" --argjson second "$SECOND" '{
    model: "claude-fable-5-1",
    max_tokens: 16000,
    thinking: { type: "adaptive" },
    system: "Answer briefly.",
    messages: ($messages + [
      { role: "assistant", content: $second.content },
      { role: "user", content: "And how many of the odd ones are below 100?" }
    ])
  }' | curl -s https://api.anthropic.com/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -d @- | jq -r "$COUNTS"
  ```

  ```bash CLI
  # Подсчитывает блоки размышлений в ответе и блоки, не прошедшие проверку префикса
  COUNTS='"thinking blocks: \([.content[] | select(.type == "thinking")] | length), " +
    "flagged: \([.input_transformations[] |
      select(.type == "thinking_mismatch_allowed")] | length)"'

  FIRST=$(ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
    --format json <<'YAML'
  model: claude-fable-5-1
  max_tokens: 16000
  thinking:
    type: adaptive
  messages:
    - role: user
      content: How many positive integers below 500 have exactly 6 positive divisors?
  YAML
  )
  echo "$FIRST" | jq -r "$COUNTS"

  # Ход 2: ход ассистента возвращается ровно в том виде, в каком получен, затем следующее сообщение пользователя
  SECOND=$(ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
    --format json <<YAML
  model: claude-fable-5-1
  max_tokens: 16000
  thinking:
    type: adaptive
  messages:
    - role: user
      content: How many positive integers below 500 have exactly 6 positive divisors?
    - role: assistant
      content: $(echo "$FIRST" | jq -c .content)
    - role: user
      content: How many of those are odd?
  YAML
  )
  echo "$SECOND" | jq -r "$COUNTS"

  # Ход 3: только этот запрос добавляет системную подсказку, намеренно изменяя префикс
  ant beta:messages create --beta thinking-binding-controls-2026-08-01 \
    --format json <<YAML | jq -r "$COUNTS"
  model: claude-fable-5-1
  max_tokens: 16000
  thinking:
    type: adaptive
  system: Answer briefly.
  messages:
    - role: user
      content: How many positive integers below 500 have exactly 6 positive divisors?
    - role: assistant
      content: $(echo "$FIRST" | jq -c .content)
    - role: user
      content: How many of those are odd?
    - role: assistant
      content: $(echo "$SECOND" | jq -c .content)
    - role: user
      content: And how many of the odd ones are below 100?
  YAML
  ```

  ```python Python
  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 растёт от хода к ходу: каждый ход ассистента возвращается ровно в том виде, в каком был получен
  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"},
          # Только последний запрос добавляет системную подсказку, что намеренно меняет префикс
          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}")
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  const userTurns = [
    "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 растёт от хода к ходу: каждый ход ассистента возвращается ровно в том виде, в каком получен
  const messages: Anthropic.Beta.BetaMessageParam[] = [];
  for (const [turnIndex, userTurn] of userTurns.entries()) {
    messages.push({ role: "user", content: userTurn });
    const response = await client.beta.messages.create({
      model: "claude-fable-5-1",
      max_tokens: 16000,
      thinking: { type: "adaptive" },
      // Только последний запрос добавляет системную подсказку, намеренно меняя префикс
      system: turnIndex === userTurns.length - 1 ? "Answer briefly." : undefined,
      messages,
      betas: ["thinking-binding-controls-2026-08-01"]
    });
    messages.push({ role: "assistant", content: response.content });
    const thinkingBlocks = response.content.filter((block) => block.type === "thinking");
    const flagged = (response.input_transformations ?? []).filter(
      (transformation) => transformation.type === "thinking_mismatch_allowed"
    );
    console.log(`thinking blocks: ${thinkingBlocks.length}, flagged: ${flagged.length}`);
  }
  ```

  ```csharp C#
  AnthropicClient client = new();

  string[] userTurns =
  [
      "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 растёт от хода к ходу: каждый ход ассистента возвращается ровно в том виде, в каком был получен
  List<BetaMessageParam> messages = [];
  for (var turnIndex = 0; turnIndex < userTurns.Length; turnIndex++)
  {
      messages.Add(new() { Role = Role.User, Content = userTurns[turnIndex] });
      var response = await client.Beta.Messages.Create(
          new()
          {
              Model = Model.ClaudeFable5_1,
              MaxTokens = 16000,
              Thinking = new BetaThinkingConfigAdaptive(),
              // Только последний запрос добавляет системную подсказку, что намеренно меняет префикс
              System = turnIndex == userTurns.Length - 1 ? new("Answer briefly.") : null,
              Messages = messages,
              Betas = [AnthropicBeta.ThinkingBindingControls2026_08_01],
          }
      );
      messages.Add(new()
      {
          Role = Role.Assistant,
          Content = response.Content.Select(block => new BetaContentBlockParam(block.Json)).ToList(),
      });
      var thinkingBlocks = response.Content.Count(block => block.TryPickThinking(out _));
      var flagged = response.InputTransformations?.Count(transformation =>
          transformation.TryPickThinkingMismatchAllowed(out _)
      ) ?? 0;
      Console.WriteLine($"thinking blocks: {thinkingBlocks}, flagged: {flagged}");
  }
  ```

  ```go Go
  client := anthropic.NewClient()

  userTurns := []string{
  	"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 растёт от хода к ходу: каждый ход ассистента возвращается ровно в том виде, в каком получен
  messages := []anthropic.BetaMessageParam{}
  for i, userTurn := range userTurns {
  	messages = append(messages, anthropic.NewBetaUserMessage(anthropic.NewBetaTextBlock(userTurn)))
  	// Только последний запрос добавляет системную подсказку, намеренно меняя префикс
  	var system []anthropic.BetaTextBlockParam
  	if i == len(userTurns)-1 {
  		system = []anthropic.BetaTextBlockParam{{Text: "Answer briefly."}}
  	}
  	response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
  		Model:     anthropic.ModelClaudeFable5_1,
  		MaxTokens: 16000,
  		Thinking: anthropic.BetaThinkingConfigParamUnion{
  			OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{},
  		},
  		System:   system,
  		Messages: messages,
  		Betas:    []anthropic.AnthropicBeta{anthropic.AnthropicBetaThinkingBindingControls2026_08_01},
  	})
  	if err != nil {
  		log.Fatal(err)
  	}
  	messages = append(messages, response.ToParam())
  	thinkingBlocks := 0
  	for _, block := range response.Content {
  		if block.Type == "thinking" {
  			thinkingBlocks++
  		}
  	}
  	flagged := 0
  	for _, transformation := range response.InputTransformations {
  		if transformation.Type == "thinking_mismatch_allowed" {
  			flagged++
  		}
  	}
  	fmt.Printf("thinking blocks: %d, flagged: %d\n", thinkingBlocks, flagged)
  }
  ```

  ```java Java
  import com.anthropic.models.beta.AnthropicBeta;
  import com.anthropic.models.beta.messages.BetaContentBlock;
  import com.anthropic.models.beta.messages.BetaInputTransformation;
  import com.anthropic.models.beta.messages.BetaMessage;
  import com.anthropic.models.beta.messages.BetaThinkingConfigAdaptive;
  import com.anthropic.models.beta.messages.MessageCreateParams;
  import com.anthropic.models.messages.Model;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      List<String> userTurns = List.of(
          "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?");

      // Список сообщений в builder растёт от хода к ходу: каждый ход ассистента возвращается ровно в том виде, в каком был получен
      MessageCreateParams.Builder conversation = MessageCreateParams.builder()
          .model(Model.CLAUDE_FABLE_5_1)
          .maxTokens(16000L)
          .thinking(BetaThinkingConfigAdaptive.builder().build())
          .addBeta(AnthropicBeta.THINKING_BINDING_CONTROLS_2026_08_01);

      for (int turnIndex = 0; turnIndex < userTurns.size(); turnIndex++) {
          if (turnIndex == userTurns.size() - 1) {
              // Только последний запрос добавляет системную подсказку, что намеренно меняет префикс
              conversation.system("Answer briefly.");
          }
          conversation.addUserMessage(userTurns.get(turnIndex));
          BetaMessage response = client.beta().messages().create(conversation.build());
          conversation.addMessage(response);
          long thinkingBlocks = response.content().stream()
              .filter(BetaContentBlock::isThinking)
              .count();
          long flagged = response.inputTransformations().stream()
              .flatMap(List::stream)
              .filter(BetaInputTransformation::isThinkingMismatchAllowed)
              .count();
          IO.println("thinking blocks: " + thinkingBlocks + ", flagged: " + flagged);
      }
  }
  ```

  ```php PHP
  use Anthropic\Beta\AnthropicBeta;
  use Anthropic\Beta\Messages\BetaThinkingConfigAdaptive;
  use Anthropic\Beta\Messages\BetaThinkingMismatchAllowedInputTransformation;
  use Anthropic\Client;

  $client = new Client();

  $userTurns = [
      '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 растёт от хода к ходу: каждый ход ассистента возвращается ровно в том виде, в каком получен
  $messages = [];
  foreach ($userTurns as $turnIndex => $userTurn) {
      $messages[] = ['role' => 'user', 'content' => $userTurn];
      $response = $client->beta->messages->create(
          model: 'claude-fable-5-1',
          maxTokens: 16000,
          thinking: BetaThinkingConfigAdaptive::with(),
          // Только последний запрос добавляет системную подсказку, намеренно меняя префикс
          system: $turnIndex === array_key_last($userTurns) ? 'Answer briefly.' : null,
          messages: $messages,
          betas: [AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
      );
      $messages[] = ['role' => 'assistant', 'content' => $response->content];
      $thinkingBlocks = array_filter($response->content, fn ($block) => $block->type === 'thinking');
      $flagged = array_filter(
          $response->inputTransformations ?? [],
          fn ($transformation) => $transformation instanceof BetaThinkingMismatchAllowedInputTransformation,
      );
      echo 'thinking blocks: ', count($thinkingBlocks), ', flagged: ', count($flagged), PHP_EOL;
  }
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  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 растёт от хода к ходу: каждый ход ассистента возвращается ровно в том виде, в каком был получен
  messages = []
  user_turns.each_with_index do |user_turn, turn_index|
    messages << {role: "user", content: user_turn}
    # Только последний запрос добавляет системную подсказку, что намеренно меняет префикс
    system_param = (turn_index == user_turns.length - 1) ? {system_: "Answer briefly."} : {}
    response = client.beta.messages.create(
      model: "claude-fable-5-1",
      max_tokens: 16_000,
      thinking: {type: "adaptive"},
      messages: messages,
      betas: [Anthropic::AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
      **system_param
    )
    messages << {role: "assistant", content: response.content}
    thinking_blocks = response.content.count { |block| block.type == :thinking }
    flagged = (response.input_transformations || []).count do |transformation|
      transformation.type == :thinking_mismatch_allowed
    end
    puts "thinking blocks: #{thinking_blocks}, flagged: #{flagged}"
  end
  ```
</CodeGroup>

```text Output wrap
thinking blocks: 1, flagged: 0
thinking blocks: 1, flagged: 0
thinking blocks: 1, flagged: 2
```

Третий ответ помечает каждый блок размышлений из предыдущих ходов, по одному на ход в этом запуске, потому что новая системная подсказка находится перед всеми ними. Модель всё равно их прочитала.

Обрабатывайте эти записи так же, как удаления `prefix_binding_mismatch`. Правка находится перед первым указанным блоком: сравните `system`, `tools` и `messages` вплоть до `path` этого блока с предыдущим запросом, чтобы найти её, а затем замените её соответствующим шаблоном из раздела [Внесение изменений без редактирования префикса](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#replace-prefix-edits). На новом аккаунте или в любом запросе, где задан `prefix_mismatch_behavior`, API вместо этого отклоняет запрос или удаляет не прошедшие проверку блоки. Записи — это нижняя граница того, что удалило бы применение проверки: с `"drop_block"` не прошедший проверку блок также уносит с собой остальные блоки размышлений этого хода, а удаление одного блока может привести к тому, что следующий тоже не пройдёт проверку. Когда API только фиксирует результат проверки, он оценивает каждый блок отдельно и указывает блок, только если именно этот блок не прошёл проверку.

## Внесение изменений без редактирования префикса

Для каждой распространённой правки префикса есть замена, которая даёт модели ту же информацию и оставляет более ранние байты неизменными, поэтому последующие размышления остаются действительными. Найдите правку, которую ваш код делает сейчас, в первом столбце:

| Вместо                                                                                                                           | Используйте                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      | Бета-заголовок                                                                                                                                                                                                                                                     |
| -------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Перестроения системной подсказки верхнего уровня `system`                                                                        | [Системное сообщение посреди разговора](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#new-instructions)                                                                                                                                                                                                                                                                                                                                                               | Нет                                                                                                                                                                                                                                                                |
| Повторного формирования контекста в первом сообщении пользователя (окружение, дата, память, инструкции проекта) в каждом запросе | Сформируйте его один раз и отправляйте повторно без изменений. Когда что-то меняется, [поместите новую версию в самый новый ход](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#changing-context)                                                                                                                                                                                                                                                                      | Нет                                                                                                                                                                                                                                                                |
| Очистки или сокращения старого содержимого `tool_result` либо перекодирования старых изображений на месте                        | Сокращайте результат инструмента или уменьшайте изображение до первой отправки, а не после. Чтобы позже очистить старые результаты, [обрезайте контекст на сервере](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#server-side-trimming) с помощью `clear_tool_uses_20250919`                                                                                                                                                                                          | `context-management-2025-06-27`                                                                                                                                                                                                                                    |
| Вставки напоминания и его удаления в следующем запросе                                                                           | [Системное сообщение с областью действия хода](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#per-turn-reminders) (`clear_at: "next_user_message"`)                                                                                                                                                                                                                                                                                                                    | `mid-conversation-system-clear-at-2026-08-21`                                                                                                                                                                                                                      |
| Добавления или удаления записей в `tools`                                                                                        | [Блоки `tool_addition` и `tool_removal`](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#tool-changes)                                                                                                                                                                                                                                                                                                                                                                  | `inline-tools-2026-09-15` (добавьте `mcp-client-2026-09-15`, если инструмент поступает с сервера MCP, подключённого через коннектор MCP) или более старый `mid-conversation-tool-changes-2026-07-01`, который работает в Claude API, Amazon Bedrock и Google Cloud |
| Изменения `output_config.effort` верхнего уровня (перезапускает кэш, не влияет на размышления)                                   | [`output_config` на уровне сообщения](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#effort-changes)                                                                                                                                                                                                                                                                                                                                                                   | `mid-conversation-output-config-2026-07-01`                                                                                                                                                                                                                        |
| Удаления или суммирования старых ходов на стороне клиента                                                                        | [Сжатие по запросу](https://platform.claude.com/docs/ru/build-with-claude/compaction-on-demand), чтобы сохранить недавние ходы с их размышлениями, другое серверное [сжатие или редактирование контекста](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#server-side-trimming) либо [сжатие на стороне клиента](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#custom-compaction-on-the-client), которое не сохраняет устаревшие размышления | `compact-2026-09-04`                                                                                                                                                                                                                                               |
| URL изображения или документа, байты которого меняются между запросами                                                           | [`file_id` из Files API](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#files-by-id) или base64                                                                                                                                                                                                                                                                                                                                                                        | Нет                                                                                                                                                                                                                                                                |

Все эти варианты предполагают, что вы [отправляете ходы ассистента обратно точно в том виде, в каком они были возвращены](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#append-assistant-turns-exactly-as-returned). Системные сообщения посреди разговора, системные сообщения с областью действия хода и изменения инструментов доступны не во всех моделях: на странице [Системные сообщения и изменения инструментов в середине разговора](https://platform.claude.com/docs/ru/build-with-claude/mid-conversation-system-messages) перечислены модели, которые их принимают. Если ваш код обслуживает несколько моделей, продолжайте редактировать системную подсказку верхнего уровня `system` для моделей, которые их не принимают.

Чтобы использовать несколько бета-функций в одном запросе в Claude API, объедините их названия в одном заголовке `anthropic-beta`:

```text wrap
anthropic-beta: thinking-binding-controls-2026-08-01,mid-conversation-system-clear-at-2026-08-21,inline-tools-2026-09-15
```

Другие платформы, предлагающие эти бета-функции, используют те же названия. О том, как отправлять их там, см. [Бета-функции на других платформах](https://platform.claude.com/docs/ru/api/beta-headers#beta-features-on-other-platforms).

### Отправка ходов ассистента обратно точно в том виде, в каком они были возвращены

Сохраняйте массив `content` из каждого ответа и отправляйте его обратно без изменений в качестве хода ассистента: все типы блоков в порядке получения, включая блоки `thinking`, поле `thinking` которых пусто. Сериализатор, который отбрасывает неизвестные типы блоков, отбрасывает пустые поля или переупорядочивает блоки, редактирует префикс для каждого последующего хода.

В Claude Fable 5.1, Claude Opus 5.5, Claude Sonnet 5.5 и Claude Haiku 5.5 поле `thinking` по умолчанию пусто, а рассуждения несёт `signature`, поэтому сериализатор, пропускающий пустые блоки, удаляет размышления. Если он удаляет их все, ничего не завершается ошибкой, а модель теряет свои предыдущие рассуждения на каждом ходе. Если вы сами разбираете поток, сохраняйте блок, даже если текст размышлений не приходит: он открывается, получает свою `signature` в событии `signature_delta` и закрывается. Блок, отправленный обратно с пустой `signature`, не проходит проверку.

### Добавление инструкций с помощью системного сообщения посреди разговора

Некоторые обвязки перестраивают системную подсказку `system` верхнего уровня при каждом запросе, чтобы передать текущее время, бюджет токенов, флаг режима или недавно обнаруженный контекст проекта. Это делает недействительными все блоки размышлений в разговоре. Вместо этого зафиксируйте `system` в начале сеанса. Когда что-то меняется, добавьте [сообщение `role: "system"`](https://platform.claude.com/docs/ru/build-with-claude/mid-conversation-system-messages) в то место `messages`, где изменение вступает в силу:

```json
{
  "role": "system",
  "content": "The user switched the workspace to read-only mode. Do not write files until told otherwise."
}
```

Модель воспринимает это сообщение с полномочиями системной подсказки, а всё, что перед ним, остаётся неизменным. В цикле инструментов размещайте сообщение после пользовательского сообщения с `tool_result`, но никогда между `tool_use` ассистента и соответствующим `tool_result` (см. [Ограничения](https://platform.claude.com/docs/ru/build-with-claude/mid-conversation-system-messages#limitations)). После отправки сообщение становится частью префикса для последующих размышлений: оставляйте его на месте в последующих запросах.

### Размещение изменяющегося контекста в самом новом ходе

Некоторые обвязки помещают блок окружения в первое сообщение пользователя (рабочий каталог, ветка, дата, память, инструкции проекта) и формируют его заново при каждом запросе. Когда любое значение меняется, меняется `messages[0]`, и все блоки размышлений в разговоре становятся недействительными. Сформируйте этот блок один раз и отправляйте его повторно в исходном виде. Когда значение меняется, сообщите об этом в самом новом ходе: добавьте текстовый блок в сообщение пользователя, которое вы собираетесь отправить, или добавьте [системное сообщение посреди разговора](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#new-instructions), если изменение исходит от вас как оператора.

```json
{
  "role": "user",
  "content": [
    {
      "type": "text",
      "text": "Environment update: the current branch is now release-2."
    },
    { "type": "text", "text": "Run the tests again." }
  ]
}
```

После отправки этот текстовый блок становится частью префикса для последующих размышлений: оставляйте его на месте в последующих запросах.

### Отправляйте напоминания на каждый ход как системные сообщения с областью действия на ход

Распространённая правка префикса — напоминание на каждом ходе: строка вроде «request independent reads together» или «you haven't updated the user in a while», которую ваш код добавляет после каждой партии результатов инструментов. Чтобы напоминания не накапливались, отправляйте каждое из них как [системное сообщение посреди разговора](https://platform.claude.com/docs/ru/build-with-claude/mid-conversation-system-messages) с `clear_at: "next_user_message"`, размещённое после пользовательского сообщения с `tool_result`. Для `clear_at` требуется бета-заголовок `mid-conversation-system-clear-at-2026-08-21`. Следующий массив `messages` — это запрос после двух вызовов инструментов и их результатов. `messages[3]` — напоминание из предыдущего запроса, оставленное на месте, а `messages[6]` — копия для этого запроса:

```json
[
  { "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."
  }
]
```

Сообщение пользователя, содержащее только блоки `tool_result`, считается «следующим сообщением пользователя», поэтому `messages[3]` уже очищено. Оно ничего не добавляет к тому, что видит модель, и не расходует входные токены, но поскольку оно всё ещё находится в массиве, размышления в `messages[4]` остаются действительными. `messages[6]` — это копия, которую модель видит на этом ходе. В последующих запросах оставляйте оба сообщения на своих местах и добавляйте новую копию после следующего сообщения с `tool_result`.

### Добавление или удаление инструментов с помощью `tool_addition` и `tool_removal`

Если изменить массив `tools` в середине сеанса, сохранённые блоки размышлений становятся недействительными. Оставьте массив в том виде, в каком вы отправили его впервые. Чтобы изменить набор инструментов, доступных модели, добавьте сообщение `role: "system"` с блоками `tool_addition` или `tool_removal`. Это [изменения инструментов в середине разговора](https://platform.claude.com/docs/ru/build-with-claude/mid-conversation-system-messages#mid-conversation-tool-changes), и для них нужен бета-заголовок `inline-tools-2026-09-15`, доступный в Claude API. Более старый заголовок `mid-conversation-tool-changes-2026-07-01` по-прежнему работает для изменений, которые указывают инструмент по ссылке, в Claude API, Amazon Bedrock и Google Cloud.

Эти блоки можно использовать двумя способами:

* **Объявите все инструменты заранее.** Поместите все инструменты, которые могут понадобиться в сеансе, в `tools` в первом запросе, указав `defer_loading: true` для тех, которые модель пока не должна видеть. Затем включайте и выключайте инструменты с помощью блоков `tool_addition` и `tool_removal`, которые их называют.
* **Начните со снимка и добавляйте инструменты по ходу работы.** Поместите известные вам инструменты в `tools` в первом запросе. Когда появляется новый инструмент, определите его внутри блока `tool_addition` вместо редактирования `tools`.

В любом случае `tools` никогда не меняется, поэтому более ранние размышления остаются действительными, а кэш подсказок по-прежнему срабатывает, за одним исключением, описанным далее в этом разделе.

Например, чтобы отозвать опасный инструмент после смены режима:

```json
{
  "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." }
  ]
}
```

Чтобы включить инструмент, объявленный с `defer_loading: true`, добавьте блок `tool_addition`, который его называет:

```json
{
  "role": "system",
  "content": [
    { "type": "tool_addition", "tool": { "type": "tool_reference", "name": "deploy" } },
    { "type": "text", "text": "Authentication succeeded. Deployment is now available." }
  ]
}
```

Иногда вы не можете объявить инструмент заранее, потому что ещё не знаете его схему: это инструмент, который ваше приложение обнаруживает во время выполнения, или MCP-сервер, подключающийся после первого хода. Определите его внутри блока `tool_addition`, не трогая `tools`. С `inline-tools-2026-09-15` поле `tool` блока может иметь вид `{"type": "tool_definition", "definition": {...}}` и содержать ту же запись, которую вы поместили бы в `tools`:

```json
{
  "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"]
          }
        }
      }
    }
  ]
}
```

Новый инструмент поступает в `messages`, `tools` никогда не меняется, и более ранние размышления остаются действительными. Оставьте в `tools` хотя бы один инструмент без `defer_loading: true`: если все инструменты там отложены, первый инструмент, определённый таким способом, обойдётся в один полный промах кэша подсказок.

Если API подключается к MCP-серверу за вас через [MCP connector](https://platform.claude.com/docs/ru/agents-and-tools/mcp-connector), также отправляйте `mcp-client-2026-09-15`. Он охватывает всё, что делает `mcp-client-2025-11-20`, поэтому отправляйте его вместо последнего. Тогда `definition` блока может быть `mcp_toolset` для сервера, указанного в `mcp_servers`. Когда API нужно получить список инструментов сервера, ответ начинается с блока `mcp_tool_listing` для этого сервера. Отправьте его обратно без изменений вместе с остальной частью хода ассистента и продолжайте отправлять `mcp-client-2026-09-15` в каждом последующем запросе, который его содержит. Блок привязывает набор инструментов к этому списку, поэтому API больше не обращается за ним к серверу. Эти функции MCP connector доступны в Claude API.

Имея только более старый заголовок, вы всё равно можете добавить инструмент, о котором узнали посреди сеанса, в `tools` с `defer_loading: true`, а затем предложить его с помощью блока `tool_addition`. Это безопасно, потому что проверка префикса игнорирует отложенный инструмент, пока на него не сошлётся блок `tool_addition`. Добавление инструмента без `defer_loading: true` изменяет префикс и делает недействительными более ранние размышления.

Сообщения `role: "system"`, содержащие эти блоки, становятся частью префикса для последующих размышлений. Оставляйте их на месте в последующих запросах.

### Изменение уровня усилий с помощью `output_config` для отдельного сообщения

Изменение `output_config.effort` верхнего уровня между запросами не делает размышления недействительными, потому что уровень усилий не входит в префикс. Однако изменение уровня усилий верхнего уровня перезапускает кэш подсказок. Если модель и платформа поддерживают [уровень усилий для отдельного сообщения](https://platform.claude.com/docs/ru/build-with-claude/effort#change-effort-mid-conversation-beta), используйте его вместо этого: добавьте в конец сообщение `role: "system"` с пустым `content` и новым уровнем. Для этого нужен бета-заголовок `mid-conversation-output-config-2026-07-01`. На Claude Haiku 5.5 уровень усилий для отдельного сообщения доступен в Claude API и Google Cloud и требует адаптивных размышлений.

```json
{ "role": "system", "content": [], "output_config": { "effort": "low" } }
```

Момент вступления нового уровня в силу зависит от того, где вы разместите сообщение. Непосредственно после сообщения `user` с новыми входными данными он начинает действовать с ответа Claude на это сообщение. В любом другом месте, например после сообщения `assistant` или после сообщения `user`, содержащего только блоки `tool_result`, он начинает действовать со следующего сообщения `user` с новыми входными данными, поэтому уже идущий цикл инструментов сохраняет текущий уровень до этого момента. После отправки сообщение становится частью `messages` и, следовательно, частью префикса для последующих размышлений: оставляйте его на месте в последующих запросах и добавляйте ещё одно, чтобы снова изменить уровень усилий.

### Обрезка контекста на сервере

Ещё одна распространённая правка префикса — обрезка на стороне клиента: отбрасывание или суммирование самых старых ходов с дословным сохранением недавних. Блоки размышлений сохранённых ходов были созданы, когда удалённая история ещё была на месте, поэтому они не проходят проверку. Серверные аналоги не считаются правками, потому что проверка сравнивает разговор в том виде, в каком вы его отправили:

* [Сжатие по запросу](https://platform.claude.com/docs/ru/build-with-claude/compaction-on-demand) (бета) возвращает сводку в отдельном запросе, который можно [выполнять в фоновом режиме](https://platform.claude.com/docs/ru/build-with-claude/compaction-background). Полученный блок вы отправляете вместо сообщений, которые он обобщает. Проверка принимает такую замену, поэтому сохранённые ходы могут остаться действительными вместе со своими размышлениями при соблюдении [условий для сохранённых размышлений](https://platform.claude.com/docs/ru/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid). В разделе [Запрос сводки](https://platform.claude.com/docs/ru/build-with-claude/compaction-on-demand#request-a-summary) показан сам запрос и указан нужный для него бета-заголовок.
* [Сжатие при достижении порога токенов](https://platform.claude.com/docs/ru/build-with-claude/compaction-threshold) обобщает более старые ходы в блок сжатия, когда контекст приближается к заданному вами порогу. Проверяемый префикс начинается заново с этого блока. [Параметр `instructions`](https://platform.claude.com/docs/ru/build-with-claude/compaction-threshold#custom-summarization-instructions) принимает вашу собственную подсказку для составления сводки, например «сохрани каждый тикер, размер позиции и заявленное допущение».
* [Редактирование контекста](https://platform.claude.com/docs/ru/build-with-claude/context-editing) очищает старые результаты инструментов или старые блоки размышлений по правилу, начиная с самых старых. Для этого используются стратегии `clear_tool_uses_20250919` и `clear_thinking_20251015`.

### Сжатие на стороне клиента

Сжимать контекст на клиенте по-прежнему можно. Если вы пишете сводку сами, не отправляйте обратно блоки размышлений, созданные до переписывания. Если сводку пишет API с помощью сжатия по запросу, в разделе [Условия, при которых сохранённые размышления остаются действительными](https://platform.claude.com/docs/ru/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid) перечислено, когда сохранённые размышления остаются действительными.

#### Простое сжатие (рекомендуется)

Когда разговор становится слишком длинным, обобщите весь сеанс в одно сообщение пользователя и отправьте только это сообщение плюс следующую инструкцию. Ничего из более раннего не воспроизводится, поэтому не остаётся размышлений, которые могли бы не пройти проверку, и модель рассуждает заново на основе сводки.

<Frame>
  ![«Simple compaction» (простое сжатие): запрос 4 отправляет полную историю с размышлениями в каждом ходе ассистента; запрос 5 отправляет одно сообщение пользователя, содержащее сводку ходов 1–4 плюс следующую инструкцию, поэтому более ранние размышления не отправляются и ничего не проверяется](https://platform.claude.com/docs/images/preserved-thinking-simple-compaction.svg)
</Frame>

```json
[
  {
    "role": "user",
    "content": "<summary of the session so far>\n\n<the next instruction>"
  }
]
```

Модели Claude обучены на долгосрочных задачах с этой схемой, и для большинства рабочих нагрузок она работает хорошо.

#### Сжатие с сохранением хвоста

Сжатие с сохранением хвоста обобщает более старые ходы и сохраняет самые последние ходы дословно, поэтому модель по-прежнему видит последние несколько обменов слово в слово. Если вы пишете сводку сами, это нарушает правило: сохранённые ходы ассистента по-прежнему содержат блоки размышлений, созданные, когда перед ними шли исходные ходы, а не сводка. Эти блоки не проходят проверку.

Чтобы сохранить эти размышления, поручите API написать сводку с помощью сжатия по запросу. В разделе [Сжатие с сохранением последних ходов](https://platform.claude.com/docs/ru/build-with-claude/compaction-keep-recent-turns) показано, как это сделать, а в разделе [Условия, при которых сохранённые размышления остаются действительными](https://platform.claude.com/docs/ru/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid) перечислено, когда сохранённые размышления остаются действительными.

Остальная часть этого раздела посвящена сводке, которую вы пишете сами.

<Frame>
  ![«Keep-tail compaction» (сжатие с сохранением хвоста): история заменяется сводкой ходов 1 и 2, за которой дословно следуют ходы 3–5; размышления в ходах ассистента 3 и 4 были созданы после исходных ходов, а не после сводки, поэтому они не проходят проверку; тот же запрос, отправленный с prefix\_mismatch\_behavior drop\_block, выполняется успешно, API отбрасывает эти два блока и перечисляет их в input\_transformations](https://platform.claude.com/docs/images/preserved-thinking-keep-tail-compaction.svg)
</Frame>

Решение: сохраните ходы в точности такими, какие они есть, и отправьте `prefix_mismatch_behavior: "drop_block"`. API отбрасывает устаревшие блоки размышлений, модель читает блоки `text` и `tool_use` сохранённых ходов, и запрос выполняется успешно.

Передайте сжатую историю как `messages` и задайте `block_binding` в конфигурации `thinking`. В следующем примере `compacted_messages` — это массив, созданный вашим шагом сжатия: сообщение со сводкой, за которым следуют сохранённые ходы в точности в том виде, в каком их вернул API, включая блоки `thinking`:

<CodeGroup>
  ```bash cURL
  curl https://api.anthropic.com/v1/messages \
    -H "content-type: application/json" \
    -H "x-api-key: $ANTHROPIC_API_KEY" \
    -H "anthropic-version: 2023-06-01" \
    -H "anthropic-beta: thinking-binding-controls-2026-08-01" \
    -d "{
      \"model\": \"claude-fable-5-1\",
      \"max_tokens\": 16000,
      \"thinking\": {
        \"type\": \"adaptive\",
        \"block_binding\": { \"prefix_mismatch_behavior\": \"drop_block\" }
      },
      \"messages\": $COMPACTED_MESSAGES
    }"
  ```

  ```bash CLI
  ant beta:messages create --beta thinking-binding-controls-2026-08-01 <<YAML
  model: claude-fable-5-1
  max_tokens: 16000
  thinking:
    type: adaptive
    block_binding:
      prefix_mismatch_behavior: drop_block
  messages: $COMPACTED_MESSAGES
  YAML
  ```

  ```python Python
  client = anthropic.Anthropic()

  # compacted_messages: сначала сообщение-сводка, затем сохранённые ходы в том виде, в каком они возвращены
  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)
  ```

  ```typescript TypeScript
  const client = new Anthropic();

  // compactedMessages: сначала сообщение-сводка, затем сохранённые ходы в том виде, в каком они возвращены
  const response = await client.beta.messages.create({
    model: "claude-fable-5-1",
    max_tokens: 16000,
    thinking: {
      type: "adaptive",
      block_binding: { prefix_mismatch_behavior: "drop_block" }
    },
    messages: compactedMessages,
    betas: ["thinking-binding-controls-2026-08-01"]
  });

  console.log(response.input_transformations);
  ```

  ```csharp C#
  AnthropicClient client = new();

  // compactedMessages: сначала сообщение-сводка, затем сохранённые ходы в возвращённом виде
  var response = await client.Beta.Messages.Create(
      new()
      {
          Model = Model.ClaudeFable5_1,
          MaxTokens = 16000,
          Thinking = new BetaThinkingConfigAdaptive
          {
              BlockBinding = new()
              {
                  PrefixMismatchBehavior = BetaThinkingPrefixMismatchBehavior.DropBlock,
              },
          },
          Messages = compactedMessages,
          Betas = [AnthropicBeta.ThinkingBindingControls2026_08_01],
      }
  );

  Console.WriteLine(response.InputTransformations?.Count ?? 0);
  ```

  ```go Go
  client := anthropic.NewClient()

  // compactedMessages: сначала сообщение-сводка, затем сохранённые ходы в возвращённом виде
  response, err := client.Beta.Messages.New(context.TODO(), anthropic.BetaMessageNewParams{
  	Model:     anthropic.ModelClaudeFable5_1,
  	MaxTokens: 16000,
  	Thinking: anthropic.BetaThinkingConfigParamUnion{
  		OfAdaptive: &anthropic.BetaThinkingConfigAdaptiveParam{
  			BlockBinding: anthropic.BetaThinkingBlockBindingParam{
  				PrefixMismatchBehavior: anthropic.BetaThinkingPrefixMismatchBehaviorDropBlock,
  			},
  		},
  	},
  	Messages: compactedMessages,
  	Betas:    []anthropic.AnthropicBeta{anthropic.AnthropicBetaThinkingBindingControls2026_08_01},
  })
  if err != nil {
  	log.Fatal(err)
  }

  fmt.Println(len(response.InputTransformations))
  ```

  ```java Java
  import com.anthropic.models.beta.AnthropicBeta;
  import com.anthropic.models.beta.messages.BetaMessage;
  import com.anthropic.models.beta.messages.BetaThinkingBlockBinding;
  import com.anthropic.models.beta.messages.BetaThinkingConfigAdaptive;
  import com.anthropic.models.beta.messages.BetaThinkingPrefixMismatchBehavior;
  import com.anthropic.models.beta.messages.MessageCreateParams;
  import com.anthropic.models.messages.Model;

  void main() {
      AnthropicClient client = AnthropicOkHttpClient.fromEnv();

      // compactedMessages: сначала сообщение-сводка, затем сохранённые ходы в возвращённом виде
      MessageCreateParams params = MessageCreateParams.builder()
          .model(Model.CLAUDE_FABLE_5_1)
          .maxTokens(16000L)
          .thinking(BetaThinkingConfigAdaptive.builder()
              .blockBinding(BetaThinkingBlockBinding.builder()
                  .prefixMismatchBehavior(BetaThinkingPrefixMismatchBehavior.DROP_BLOCK)
                  .build())
              .build())
          .messages(compactedMessages)
          .addBeta(AnthropicBeta.THINKING_BINDING_CONTROLS_2026_08_01)
          .build();

      BetaMessage response = client.beta().messages().create(params);

      IO.println(response.inputTransformations());
  }
  ```

  ```php PHP
  use Anthropic\Beta\AnthropicBeta;
  use Anthropic\Beta\Messages\BetaThinkingBlockBinding;
  use Anthropic\Beta\Messages\BetaThinkingConfigAdaptive;
  use Anthropic\Beta\Messages\BetaThinkingPrefixMismatchBehavior;
  use Anthropic\Client;

  $client = new Client();

  // $compactedMessages: сообщение-сводка, затем сохранённые ходы в возвращённом виде
  $response = $client->beta->messages->create(
      model: 'claude-fable-5-1',
      maxTokens: 16000,
      thinking: BetaThinkingConfigAdaptive::with(
          blockBinding: BetaThinkingBlockBinding::with(
              prefixMismatchBehavior: BetaThinkingPrefixMismatchBehavior::DROP_BLOCK,
          ),
      ),
      messages: $compactedMessages,
      betas: [AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01],
  );

  var_dump($response->inputTransformations);
  ```

  ```ruby Ruby
  client = Anthropic::Client.new

  # compacted_messages: сначала сообщение-сводка, затем сохранённые ходы в том виде, в каком они возвращены
  response = client.beta.messages.create(
    model: "claude-fable-5-1",
    max_tokens: 16_000,
    thinking: {
      type: "adaptive",
      block_binding: {prefix_mismatch_behavior: "drop_block"}
    },
    messages: compacted_messages,
    betas: [Anthropic::AnthropicBeta::THINKING_BINDING_CONTROLS_2026_08_01]
  )

  puts response.input_transformations
  ```
</CodeGroup>

Ответ, как обычно, содержит новый ход ассистента, а также по одной записи `input_transformations` на каждый отброшенный блок. Для истории на диаграмме это размышления в ходах ассистента 3 и 4:

```json
{
  "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"
    }
  ]
}
```

Продолжайте отправлять `"drop_block"` в последующих запросах, пока эти два хода остаются в истории. Размышления, которые модель создаёт начиная с этого запроса, следуют за сводкой и остаются действительными. Если вы не хотите зависеть от бета-заголовка, альтернатива — самостоятельно удалить блоки `thinking` и `redacted_thinking` из сохранённых ходов ассистента при построении сжатой истории.

#### Фоновое (асинхронное) сжатие

Фоновое сжатие строит сводку вне критического пути, пока разговор продолжается, а затем подставляет её через несколько запросов. Чтобы сохранить размышления, созданные за это время, поручите API написать сводку с помощью сжатия по запросу. Порядок действий описан в разделе [Сжатие в фоновом режиме](https://platform.claude.com/docs/ru/build-with-claude/compaction-background). Эти размышления остаются действительными при тех же [условиях для сохранённых размышлений](https://platform.claude.com/docs/ru/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid), что и сохранённые недавние ходы.

Сводка, которую вы строите сами, нарушает правило так же, как сжатие с сохранением хвоста, но с задержкой. Каждый ход ассистента, созданный во время построения сводки, содержит размышления, предшествующие замене. Все эти размышления перестают проходить проверку в момент подстановки сводки. Если вы используете такую сводку, обращайтесь с заменой как со сжатием с сохранением хвоста и отправляйте `"drop_block"` начиная с замены. Другой вариант — выполнять сжатие синхронно.

#### Шаблоны, которые не работают с сохранёнными размышлениями

* **Вырезание ходов из середины.** Удаление отдельных ходов делает недействительными все блоки размышлений после них, и никакая схема сжатия этого не избегает. Если вы вырезали ход, чтобы изменить инструкцию, вместо этого добавьте [системное сообщение в середине разговора](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#new-instructions). Чтобы выборочно удалить старые результаты инструментов или старые размышления, используйте серверное [редактирование контекста](https://platform.claude.com/docs/ru/build-with-claude/context-editing).
* **Сжатие посреди раунда инструментов.** Не выполняйте сжатие между `tool_use` хода ассистента и отвечающим на него `tool_result`. Отправьте этот ход ассистента обратно с нетронутыми размышлениями, чтобы модель завершила раунд со своими рассуждениями. См. [Сохранение блоков размышлений](https://platform.claude.com/docs/ru/build-with-claude/thinking#preserving-thinking-blocks).

### Ссылайтесь на файлы по ID, а не по URL с изменяющимся содержимым

Для блока `image` или `document` с источником `url` проверка охватывает загруженные байты, а не строку URL. URL с изменяющимся содержимым делает недействительными последующие размышления. Примеры — эндпоинт «последний скриншот» или документ, который кто-то редактирует между ходами. Ротируемый подписанный URL для того же файла к такому результату не приводит. Содержимое, на которое вы ссылаетесь в нескольких ходах, загрузите один раз с помощью [Files API](https://platform.claude.com/docs/ru/build-with-claude/files) и используйте `file_id`, либо отправляйте его в base64.

### Библиотеки, прокси и шлюзы

Библиотека, прокси или шлюз находится между чужой историей и API. Поэтому их собственные переписывания считаются правками, а их пользователи не могут эти правки увидеть или исправить.

* **Пропускайте то, что вы не распознаёте.** Передавайте значения `anthropic-beta` и `thinking.block_binding` вызывающей стороны без изменений и возвращайте ей `input_transformations`. Схема параметров, отклоняющая неизвестные ключи, не позволяет вашим пользователям выбрать `"drop_block"`.
* **Оставляйте сообщение `role: "system"` там, где его разместила вызывающая сторона.** Перемещение его в поле верхнего уровня `system` изменяет `system` в этом запросе и делает недействительными все блоки размышлений в разговоре.
* **Чтобы отключить использование инструментов для запроса, отправьте `tool_choice: {"type": "none"}`.** Не удаляйте `tools`.
* **Не скрывайте ошибку 400.** Ваш код может перехватывать её, удалять размышления и повторять запрос от имени вызывающей стороны. В этом случае записывайте это в журнал: история вызывающей стороны всё равно изменена, и модель теряет свои прежние рассуждения в каждом последующем запросе.

## Часто задаваемые вопросы

<AccordionGroup>
  <Accordion title="Нужна ли мне новая учётная запись, чтобы протестировать сохранённые размышления?">
    Нет. Отправьте бета-заголовок `thinking-binding-controls-2026-08-01` и задайте `thinking.block_binding.prefix_mismatch_behavior`. Задание этого поля включает принудительную проверку для данного запроса независимо от возраста учётной записи. `"error"` отклоняет изменённую историю с той же ошибкой 400, которую получает новая учётная запись, а `"drop_block"` пропускает запрос и перечисляет отброшенное в `input_transformations`. Чтобы найти изменения префикса в более старой учётной записи без принудительной проверки, отправьте заголовок и оставьте поле незаданным: блоки, не прошедшие проверку, всё равно доходят до модели, а `input_transformations` перечисляет их как `thinking_mismatch_allowed`. См. [Проверка того, редактирует ли ваш код префикс](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#how-to-tell-whether-your-integration-is-impacted).
  </Accordion>

  <Accordion title="Если что-либо перед блоком размышлений меняется, даже одно описание инструмента, становится ли разговор непригодным?">
    Нет. Проверку не проходят размышления, уже находящиеся в истории после изменённого места, и вы сами выбираете, что с ними происходит. С `prefix_mismatch_behavior: "drop_block"` API отбрасывает эти блоки, и запрос выполняется успешно: модель отвечает на этом ходе без этих рассуждений, а кэш подсказок начинается заново с места изменения. Со значением по умолчанию `"error"` API отклоняет запрос с ошибкой 400, пока вы не отмените изменение или не отправите запрос повторно с `"drop_block"`. См. [Что API делает с недействительным блоком](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#mismatch-behavior). В разделе [Что считается редактированием](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#what-counts-as-an-edit) перечислено, какие изменения имеют значение.
  </Accordion>

  <Accordion title="Делает ли изменение уровня усилий или других настроек размышлений между запросами более ранние размышления недействительными?">
    Нет. `output_config.effort`, `max_tokens` и конфигурация `thinking` не входят в проверяемый префикс, который охватывает только `system`, `tools` и `messages`. Изменение уровня усилий верхнего уровня делает недействительной большую часть кэша подсказок. Если модель и платформа поддерживают [уровень усилий для отдельного сообщения](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#effort-changes), изменение уровня усилий для отдельного сообщения сохраняет кэш подсказок и используется как новый уровень усилий до следующего изменения.
  </Accordion>

  <Accordion title="Мой список инструментов меняется посреди сеанса. Как избежать того, чтобы разговор стал недействительным?">
    Не изменяйте `tools`. Объявите полный набор в начале сеанса, пометьте ещё недоступные инструменты с помощью `defer_loading: true` и предлагайте или отзывайте их с помощью блоков `tool_addition` и `tool_removal`. Если схема инструмента становится известна только посреди сеанса, определите его внутри блока `tool_addition` (`inline-tools-2026-09-15`, плюс `mcp-client-2026-09-15` для сервера, к которому обращается коннектор MCP в API) и оставьте `tools` без изменений. Сообщения `role: "system"`, содержащие эти блоки, становятся частью префикса для последующих размышлений, поэтому впоследствии не перемещайте, не переформулируйте и не удаляйте их. См. [Добавление или удаление инструментов с помощью `tool_addition` и `tool_removal`](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#tool-changes).
  </Accordion>

  <Accordion title="Я выполняю сжатие, обобщая более старые ходы и сохраняя последние ходы дословно. Это по-прежнему работает?">
    Да, если сводку пишет API. [Сжатие по запросу](https://platform.claude.com/docs/ru/build-with-claude/compaction-on-demand) (бета-заголовок `compact-2026-09-04`) обобщает более старые ходы в подписанный блок, который вы отправляете вместо них. Последние ходы сохраняют свои размышления при соблюдении [условий для сохранённых размышлений](https://platform.claude.com/docs/ru/build-with-claude/compaction-thinking-blocks#conditions-for-kept-thinking-to-stay-valid).

    Если вы пишете сводку сами, размышления сохранённых ходов не проходят проверку, потому что эти блоки были созданы на основе истории, которую вы заменили. Удалите блоки `thinking` и `redacted_thinking` из переносимых ходов и сохраните их блоки `text` и `tool_use` либо отправьте `prefix_mismatch_behavior: "drop_block"` и позвольте API отбросить их. Простое сжатие не оставляет размышлений, которые могли бы не пройти проверку, и является рекомендуемым подходом: одно сообщение со сводкой плюс следующий ход пользователя, без воспроизведения более ранних ходов. Серверное [сжатие](https://platform.claude.com/docs/ru/build-with-claude/compaction) и [редактирование контекста](https://platform.claude.com/docs/ru/build-with-claude/context-editing) не считаются изменениями. См. [Сжатие на стороне клиента](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#custom-compaction-on-the-client).
  </Accordion>

  <Accordion title="Как обрабатывать файлы инструкций, такие как AGENTS.md или CLAUDE.md, которые меняются посреди сеанса?">
    Загрузите их один раз в начале сеанса и оставьте системную подсказку `system` верхнего уровня и `tools` неизменными. Когда файл меняется, добавьте новую версию в этом месте `messages` вместо изменения оригинала. Используйте [системное сообщение посреди разговора](https://platform.claude.com/docs/ru/build-with-claude/mid-conversation-system-messages) для инструкций, исходящих от вас как от оператора. Для текста файлов, который вы считаете недоверенным и который не должен обладать полномочиями системной подсказки, поместите содержимое в следующий ход `user`. См. [Добавление инструкций с помощью системного сообщения посреди разговора](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#new-instructions) и [Ограничения](https://platform.claude.com/docs/ru/build-with-claude/mid-conversation-system-messages#limitations).
  </Accordion>

  <Accordion title="Могу ли я возобновить сохранённый сеанс позже, после перезапуска или на следующий день?">
    Да. Возобновлённый сеанс — это обычный последующий запрос: `system`, `tools` и более ранние `messages` должны иметь то же содержимое, что и в последней отправке. Форматирование JSON и порядок ключей не имеют значения; значения — имеют. Сохраняйте в точности то, что вы отправили и получили, и воспроизводите это: сформированную системную подсказку, определения инструментов и каждый ход ассистента в том виде, в каком он был возвращён. Не формируйте их заново из входных данных, которые могли с тех пор измениться, таких как дата, обновлённый файл инструкций или новая версия инструмента. Всё новое помещается в добавленное в конец сообщение. См. [Отправка ходов ассистента обратно точно в том виде, в каком они были возвращены](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#append-assistant-turns-exactly-as-returned).
  </Accordion>

  <Accordion title="Сохранённый сеанс теперь завершается ошибкой при каждом запросе. Как снова заставить его работать?">
    В сохранённой истории есть изменение, поэтому её воспроизведение не может быть успешным. Отправляйте этот сеанс с `prefix_mismatch_behavior: "drop_block"` с этого момента или один раз удалите его блоки `thinking` и `redacted_thinking` и продолжайте. В Claude Sonnet 5.5 и Claude Haiku 5.5 `block_binding` работает только с `thinking: {"type": "adaptive"}`. С `between_tools` в Claude Sonnet 5.5 или с `thinking: {"type": "disabled"}` в Claude Haiku 5.5 сохраняйте историю только с добавлением в конец или удалите блоки размышлений начиная с изменённого хода. Размышления, которые модель создаёт с этого момента, остаются действительными, пока ничего перед ними снова не изменится. Затем найдите изменение, чтобы новые сеансы с ним не сталкивались. См. [Обработка ошибки в коде](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#handle-the-error-in-code).
  </Accordion>

  <Accordion title="Моя обвязка может направить ход модели, отличной от Claude. Делают ли такие ходы более ранние размышления Claude недействительными?">
    Нет, при условии что они добавляются после существующей истории и ничего более раннего не меняется: сообщение ассистента без блоков размышлений — такое же добавленное в конец сообщение, как и любое другое. Отправляйте вывод другой модели как содержимое `text` и `tool_use`.
  </Accordion>

  <Accordion title="Могу ли я перенести рассуждения одного разговора в новый разговор?">
    Не в другой разговор. Блок размышлений можно использовать, только когда он следует за теми же самыми `system`, `tools` и `messages`, на основе которых он был создан. Ветвь, которая воспроизводит эту историю без изменений до точки разветвления, сохраняет свои размышления. Разговор, начинающийся с чего-либо другого, не может их использовать, поэтому начинайте такой разговор со сводки состояния задачи, как при [простом сжатии](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#custom-compaction-on-the-client): цель, принятые решения, файлы и результаты на данный момент и следующий шаг. Блоки размышлений Claude Sonnet 5.5 и Claude Haiku 5.5 также нельзя повторно использовать из другого аккаунта (см. [Блоки размышлений остаются в аккаунте, который их создал](https://platform.claude.com/docs/ru/build-with-claude/preserved-thinking#account-bound-thinking)).
  </Accordion>
</AccordionGroup>

## Следующие шаги

<CardGroup cols={2}>
  <Card title="Устранение неполадок размышлений" icon="hammer" href="https://platform.claude.com/docs/ru/build-with-claude/thinking-troubleshooting">
    Диагностируйте и исправляйте наиболее распространённые сбои размышлений: ошибки конфигурации 400, пустые или отсутствующие блоки размышлений, остановки max\_tokens и промахи кэша.
  </Card>

  <Card title="Системные сообщения и изменения инструментов в середине разговора" icon="messages" href="https://platform.claude.com/docs/ru/build-with-claude/mid-conversation-system-messages">
    Изменяйте системные инструкции или доступность инструментов в середине разговора, не делая недействительным кэшированный префикс, который был перед ними.
  </Card>

  <Card title="Компактификация" icon="stack" href="https://platform.claude.com/docs/ru/build-with-claude/compaction">
    Серверная компактификация контекста для управления длинными разговорами, которые приближаются к пределам контекстного окна.
  </Card>

  <Card title="Кэширование подсказок" icon="database" href="https://platform.claude.com/docs/ru/build-with-claude/prompt-caching">
    Кэшируйте префиксы подсказок с помощью `cache_control`, чтобы сократить затраты и задержку, используя автоматическое кэширование или явные точки прерывания с TTL в 5 минут или 1 час.
  </Card>
</CardGroup>
