Блог • AI / API
Новые возможности Claude API 2026: что такое Conversation Compaction? Как AI Agent сохраняет длинный контекст и сжатое состояние в JSON?
Чем дольше крутится Agent, тем длиннее массив Messages. Результаты инструментов, блоки размышлений, ходы user — всё это забивает окно контекста. В 2026 Messages API сделала из этого официальную возможность: Conversation Compaction.
Compaction — это не написать резюме на клиенте и вклеить обратно. API выдаёт блок type: "compaction" в JSON. Следующий запрос должен положить этот блок как есть обратно в messages, чтобы session продолжилась со сжатого состояния.
В этой статье:
- Какая beta у пороговой компрессии и какая у сентябрьского сжатия по запросу
- Как выглядит
messagesдо и после сжатия - Какие поля нужно записать: без них session не восстановить
- Как JSON переставляется при фоновом сжатии и когда оставляют последние ходы
- Как в JSONNote сверить позицию и поля блока
Запомните это: На диск пишется не «весь диалог», а последний блок compaction плюс ходы после блока, которые ещё не съели. В блоке content, signature, encrypted_content — контракт, не комментарий. Ниже: два вида сжатия → как выглядит блок → список записи → правила перестановки.
Какой отрезок сжимает Compaction
Официальная позиция ясна: серверное сжатие — рекомендуемый способ для длинных диалогов и Agent-workflow, без своего кода резюме на клиенте. Когда окно забито старым содержимым, качество ответа падает; сжатие меняет более раннее на резюме, чтобы полезный контекст ещё мог идти вперёд. Описание:
Когда пороговая компрессия включена, API делает четыре шага: входные token доходят до порога; пишет резюме; пишет блок compaction; продолжает ответ уже по сжатому контексту. В следующий раз вы дописываете весь ответ assistant в messages, и API выбрасывает содержимое перед этим блоком, чтобы продолжить с резюме.
Это lossy. Конкретные параметры инструментов, исходные фразы, ранний thinking пословно не останутся. Останутся цели, решения и факты, которые ещё пригодятся. Это не то же самое, что «положить весь массив messages в базу». Как растёт контекст в стеке Agent — в
Два пути: пороговая компрессия и сжатие по запросу
В 2026 две beta. Не мешайте их в одном запросе. В документации прямо: параметр compaction нельзя слать вместе с context_management.
| Путь | Beta-заголовок | Что писать в JSON | Где появляется блок |
|---|---|---|---|
| Пороговая компрессия | compact-2026-01-12 |
context_management.edits: добавить compact_20260112 |
В начале обычного ответа; дальше может идти text |
| Сжатие по запросу | compact-2026-09-04 |
На верхнем уровне compaction: {"type":"summarize"} |
Отдельный ответ, stop_reason равен compaction, без обычного ответа |
Порог срабатывания пороговой компрессии по умолчанию input_tokens150000, минимум 50000. Опция pause_after_compaction: резюме написали и сразу стоп, чтобы вы вставили последние ходы или инструктивные сообщения после блока и только потом продолжили генерацию. Свой instructions целиком заменяет подсказку резюме по умолчанию, максимум 16384 символа.
Сжатие по запросу — главный пункт сентябрьской линии. Вы решаете, когда сжимать; запрос резюме можно гонять в фоне, диалог идёт по полной истории; можно оставить последние ходы текстом после резюме. Подписанный блок должен стоять в самом начале messages, уже резюмированные сообщения нужно убрать перед блоком, иначе 400, имя ошибки compaction_block_misplaced. У Bedrock и Google Cloud этого пути по запросу нет.
Messages JSON до и после сжатия
Сначала до сжатия: обычные ходы user / assistant.
{
"model": "claude-opus-5",
"max_tokens": 4096,
"messages": [
{
"role": "user",
"content": "I am building a recipe app. Help me name the main entities in the data model."
},
{
"role": "assistant",
"content": "Start with Recipe, Ingredient, and Step."
},
{
"role": "user",
"content": "Good. Now suggest field names for Recipe."
}
],
"compaction": { "type": "summarize" }
}
В ответе только один подписанный блок compaction, stop_reason равен compaction. Дальше в каждом запросе этот блок должен быть самым первым; после него — только ходы, которые это резюме не съело.
{
"model": "claude-opus-5",
"max_tokens": 2048,
"messages": [
{
"role": "assistant",
"content": [
{
"type": "compaction",
"content": "Summary of the conversation: the user is designing the data model for a recipe app...",
"signature": "EuYBCkQY..."
}
]
},
{
"role": "assistant",
"content": "For Recipe, use title, description, servings..."
},
{
"role": "user",
"content": "Now do the same for Ingredient."
}
]
}
Блок пороговой компрессии больше «зажат в ответ»: массив content у assistant сначала compaction, потом text. При нескольких сжатиях считается последний блок: он представляет конечное состояние текущего промпта. Увидев этот блок, API игнорирует блоки содержимого перед ним. Можно вернуть всё целиком или самим выбросить старые сообщения и слать только от этого блока дальше.
| Поле | Что это | Можно ли менять |
|---|---|---|
type |
Фиксированно compaction |
Нельзя |
content |
Текст резюме; при сбое — null |
Нельзя менять текст; пустая строка незаконна |
signature |
Подпись, которую возвращает сжатие по запросу | Вернуть как есть |
encrypted_content |
Непрозрачные метаданные; тип SDK требует verbatim round-trip | Если есть — храните как есть, не парсите |
cache_control |
Необязательно, отдельная cache-точка для резюме | Добавляете сами, это не выданное поле |
SDK описывает encrypted_content как «непрозрачные метаданные после прежнего сжатия, их нужно вернуть verbatim». Клиент не разбирает его и не показывает как текст резюме. Когда content у сбойного блока равен null, сервер считает это no-op; блок всё ещё можно вернуть, но валидным резюме он не станет.
Поля, которые нужно записать, чтобы восстановить session
Как только Agent перезапустится, messages в памяти пропадут. Восстанавливать нужно не «всю переписку до сжатия», а состояние, из которого после сжатия ещё можно продолжать запросы.
-
1
Последний блок compaction
Весь JSON блока, включая
content,signature,encrypted_content. Если блоков несколько, нужен только последний: следующее сжатие съест и старое резюме, и содержимое после него. -
2
messages после блока
Ходы user / assistant, которые это резюме не покрыло, в исходном порядке. Ходы, наросшие во время фонового сжатия, тоже здесь.
-
3
Тогдашние system и tools
При сжатии по запросу запрос резюме должен нести тот же набор
systemиtools, что и остальная часть диалога. На моделях с сохранением thinking то, останутся ли thinking ходов после блока валидными, зависит от того, менялись ли эти два пункта и примыкает ли хвост к уже резюмированным сообщениям. -
4
Какую beta вы ведёте
Пороговая компрессия дальше несёт
compact-2026-01-12. Блок сжатия по запросу в каждом следующем запросе требуетcompact-2026-09-04. Не тот заголовок — блок могут не узнать.
{
"beta": "compact-2026-09-04",
"model": "claude-opus-5",
"system": "You are a coding agent.",
"tools": [],
"compaction_block": {
"type": "compaction",
"content": "Summary of the conversation: ...",
"signature": "EuYBCkQY...",
"encrypted_content": "..."
},
"tail": [
{
"role": "assistant",
"content": "For Recipe, use title, description..."
},
{
"role": "user",
"content": "Now do the same for Ingredient."
}
]
}
Когда собираете запрос заново: в messages[0] кладёте assistant с этим блоком (или блок в первый content первого сообщения), затем склеиваете tail. Старые сообщения user до сжатия снова перед блок не засовывайте.
Это не тот слой, что оценка прав. Там решают, может ли Tool Call бежать; здесь — осталось ли состояние после того, как окно съели. Про права:
Как Claude Managed Agents автоматически решает Tool Call. Как Agent сотрудничают в длинном потоке:
Как Claude участвует в workflow ИИ-R&D.
Как переставлять при фоновом сжатии и keep-tail
Запрос сжатия по запросу резюмирует только те сообщения, которые получил. Поэтому можно отдать на сжатие только старые ходы, последние ходы оставить текстом локально, а после вставить блок перед этими ходами. В документации это keep-tail.
Фоновое сжатие (async) идёт дальше: пока резюме ещё пишется, диалог продолжает полную историю. Когда вернётся, нельзя заменить всю историю одним блоком: с головы снимают «те сообщения, что тогда ушли на сжатие», кладут вернувшееся сообщение assistant, а ходы, наросшие сзади, оставляют как есть.
if response.stop_reason == "compaction":
compaction_message = {
"role": "assistant",
"content": response.content,
}
history = [compaction_message] + history[sent_count:]
# sent_count = number of messages sent in the compaction request
Пока ждёте, не правьте сообщения, уже лежащие в истории. Перестановка должна случиться на первом запросе после прихода блока, чтобы thinking, рождённый во время резюме, ещё был валиден. Нет блока — держите полную историю и повторите позже.
Если у пороговой компрессии включён pause_after_compaction, в ответе часто только этот блок, stop_reason тоже compaction. Текст, который нужно оставить, стыкуете после блока и шлёте следующий запрос. Важно: на Claude Fable 5.1, если старые ходы assistant снова вставляете после блока, уберите из них thinking / redacted_thinking либо несите thinking-binding-controls-2026-08-01 и задайте prefix_mismatch_behavior: "drop_block", иначе возможен 400. Эти блоки размышлений писались против полной истории и не сходятся со сжатым диалогом.
Как это складывается с prompt cache
Сжатие и prompt caching можно использовать вместе. На блок compaction можно добавить cache_control: {"type":"ephemeral"}, чтобы резюме отдельно попало в кэш. Ещё одна точка разрыва в конце system prompt: когда случится сжатие, кэш system prompt ещё попадёт, переписать нужно только отрезок резюме.
При биллинге не смотрите только верхний usage. Token итераций сжатия могут быть в usage.iterations. На стороне записи по-прежнему важны только блок и хвост; usage не контракт для восстановления session.
Сверить блок и историю в JSONNote
Объём JSON до и после сжатия сильно расходится, поля глазами не просканировать. При отладке сверяйте позиции, не стиль.
-
1
Сначала отформатировать записанный файл
Бросьте session JSON в Форматирование JSON, убедитесь, что
compaction_block.typeравенcompaction, аsignatureна месте. -
2
Потом проверить форму блока
Через JSON Schema напишите минимальный schema: enum у
typeтолькоcompaction;contentдопускает string или null;signature/encrypted_contentесли есть — как string. Пустую строку запретить. -
3
Сравнить messages до и после сжатия
Через JSON Diff смотрите, каких ходов не стало в голове очереди и что появилось после блока. После сжатия по запросу перед блоком не должно снова быть уже резюмированных сообщений user.
-
4
При разборе маскировать подпись
Текст резюме можно показать человеку. Подпись и непрозрачные поля перед Hash-шаринг сначала замаскируйте. Ими продолжают session — не рассылайте как обычный текст.
FAQ
Conversation Compaction удаляет весь диалог?
Нет. API заменяет уже сжатые старые сообщения резюме. Резюме лежит в блоке содержимого, у которого type — compaction. Этот блок нужно вернуть как есть, чтобы session продолжилась с резюме.
Какой минимальный JSON нужен, чтобы восстановить session?
Как минимум последний блок compaction (с content, signature, encrypted_content), все messages после блока, плюс тогдашние system и tools. Без подписи или непрозрачного поля следующий запрос не продолжится.
Чем пороговая компрессия отличается от сентябрьского сжатия по запросу?
Пороговая компрессия идёт через compact-2026-01-12 и срабатывает по token в обычном запросе. Сжатие по запросу идёт через compact-2026-09-04: отдельно шлёте compaction: {type: summarize}, получаете подписанный блок, его нужно поставить в самое начало messages.
Можно ли заменить блок compaction своим текстом резюме?
Не как тот же контракт. Платформа узнаёт блок, который сама выдала. Написанный вами текст user — просто другое сообщение, без signature, и API из-за него не выбросит старое содержимое перед блоком.
Можно ли править content блока compaction и отправлять обратно?
Не правьте. Документация требует вернуть как есть. Пустая строка в content незаконна; content равный null значит, что сжатие не удалось, сервер считает это no-op. Правка signature или encrypted_content сломает следующие запросы или потеряет резюме.
Итог
Conversation Compaction сворачивает «окно вот-вот лопнет» в JSON, который можно вернуть. Пороговая компрессия случается сама в обычном запросе; сентябрьское сжатие по запросу даёт вам решать, когда сжимать, можно ли в фоне и оставлять ли последние ходы текстом.
Восстановление session держится на последнем блоке compaction плюс tail после него, не на полном тексте до сжатия. content, signature, encrypted_content храните как есть и шлите как есть. Если блок стоит не там, API не сделает вид, что та история у вас ещё с собой.
Читайте блок и tail как два контракта. Для длинной задачи под присмотром человека в instructions резюме запишите сущности, которые нельзя потерять, и открытые вопросы; для Agent, которому нужно меньше прерываний, меняйте блок фоновым сжатием по запросу, а не оставляйте в памяти только свою записку.
Разобрать блок compaction и tail