Was this page helpful?
Эта функция соответствует требованиям Zero Data Retention (ZDR) (нулевого хранения данных). Если у вашей организации действует соглашение ZDR, данные, отправленные через эту функцию, не сохраняются после возврата ответа API.
Серверное сжатие контекста — рекомендуемая стратегия управления контекстом в длительных разговорах и агентных рабочих процессах. Оно автоматически управляет контекстом с минимальными усилиями по интеграции.
«Compaction» (сжатие контекста) увеличивает эффективную длину контекста для длительных разговоров и задач, автоматически суммируя более старый контекст при приближении к пределу контекстного окна. Речь идёт не только о том, чтобы оставаться в пределах лимита токенов. По мере удлинения разговоров моделям становится сложнее удерживать фокус на всей истории. Сжатие контекста сохраняет активный контекст сфокусированным и производительным, заменяя устаревшее содержимое краткими сводками.
Подробнее о том, почему длинные контексты деградируют и как помогает сжатие контекста, см. в статье Effective context engineering.
Это идеально подходит для:
Сжатие контекста находится в бета-версии. Включите бета-заголовок compact-2026-01-12 в ваши запросы к API, чтобы использовать эту функцию.
Сжатие контекста поддерживается в следующих моделях:
claude-fable-5)claude-mythos-5)Когда сжатие контекста включено, Claude автоматически суммирует ваш разговор при приближении к настроенному порогу токенов. API выполняет следующее:
compaction, содержащий сводку.При последующих запросах добавьте ответ к вашим сообщениям. API автоматически отбрасывает все блоки сообщений, предшествующие блоку compaction, продолжая разговор со сводки.
Включите сжатие контекста, добавив стратегию compact_20260112 в context_management.edits в вашем запросе к Messages API.
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
type | string | Обязательный | Должен быть "compact_20260112" |
trigger | object | 150 000 токенов | Когда запускать сжатие контекста. Должно быть не менее 50 000 токенов. |
pause_after_compaction | boolean | false | Приостанавливать ли выполнение после генерации сводки сжатия |
instructions | string | null | Пользовательская подсказка для суммирования. Полностью заменяет подсказку по умолчанию, если указана. |
Настройте момент срабатывания сжатия контекста с помощью параметра trigger:
По умолчанию сжатие контекста использует следующую подсказку для суммирования:
You have written a partial transcript for the initial task above. Please write a summary of the transcript. The purpose of this summary is to provide continuity so you can continue to make progress towards solving the task in a future context, where the raw history above may not be accessible and will be replaced with this summary. Write down anything that would be helpful, including the state, next steps, learnings etc. You must wrap your summary in a <summary></summary> block.Вы можете предоставить пользовательские инструкции через параметр instructions, чтобы полностью заменить эту подсказку. Пользовательские инструкции не дополняют подсказку по умолчанию, а полностью её заменяют:
Используйте pause_after_compaction, чтобы приостановить API после генерации сводки сжатия. Это позволяет вам добавить дополнительные блоки содержимого (например, сохранить недавние сообщения или конкретные сообщения с инструкциями) до того, как API продолжит формирование ответа.
Когда этот параметр включён, API возвращает сообщение с причиной остановки compaction после генерации блока сжатия:
Когда модель работает над длительными задачами с множеством итераций использования инструментов, общее потребление токенов может значительно возрасти. Вы можете объединить pause_after_compaction со счётчиком сжатий, чтобы оценивать совокупное использование и корректно завершать задачу при достижении бюджета:
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
TRIGGER_THRESHOLD = 100_000
TOTAL_TOKEN_BUDGET = 3_000_000
n_compactions = 0
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"trigger": {"type": "input_tokens", "value": TRIGGER_THRESHOLD},
"pause_after_compaction": True,
}
]
},
)
if response.stop_reason == "compaction":
n_compactions += 1
messages.append({"role": "assistant", "content": response.content})
# Оценить общее число использованных токенов; при превышении бюджета предложить завершение
if n_compactions * TRIGGER_THRESHOLD >= TOTAL_TOKEN_BUDGET:
messages.append(
{
"role": "user",
"content": "Please wrap up your current work and summarize the final state.",
}
)Когда срабатывает сжатие контекста, API возвращает блок compaction в начале ответа ассистента.
Длительный разговор может привести к нескольким сжатиям. Последний блок сжатия отражает итоговое состояние подсказки, заменяя предшествующее ему содержимое сгенерированной сводкой.
{
"content": [
{
"type": "compaction",
"content": "Summary of the conversation: The user requested help building a web scraper..."
},
{
"type": "text",
"text": "Based on our conversation so far..."
}
]
}Вы должны передавать блок compaction обратно в API при последующих запросах, чтобы продолжить разговор с укороченной подсказкой. Самый простой подход — добавить всё содержимое ответа к вашим сообщениям:
Когда API получает блок compaction, все блоки содержимого перед ним игнорируются. Вы можете либо:
При потоковой передаче ответов с включённым сжатием контекста вы получите событие content_block_start, когда начнётся сжатие. Блок сжатия передаётся потоком иначе, чем текстовые блоки. Вы получите событие content_block_start, за которым последует одно событие content_block_delta с полным содержимым сводки (без промежуточной потоковой передачи), а затем событие content_block_stop.
Сжатие контекста хорошо работает с кэшированием подсказок. Вы можете добавить точку останова cache_control на блоки сжатия, чтобы кэшировать суммированное содержимое. Исходное сжатое содержимое игнорируется.
{
"role": "assistant",
"content": [
{
"type": "compaction",
"content": "[summary text]",
"cache_control": { "type": "ephemeral" }
},
{
"type": "text",
"text": "Based on our conversation..."
}
]
}Когда происходит сжатие контекста, сводка становится новым содержимым, которое необходимо записать в кэш. Без дополнительных точек останова кэша это также сделало бы недействительной любую кэшированную системную подсказку, требуя её повторного кэширования вместе со сводкой сжатия.
Чтобы максимизировать частоту попаданий в кэш, добавьте точку останова cache_control в конце вашей системной подсказки. Это сохраняет системную подсказку в кэше отдельно от разговора, поэтому при сжатии контекста:
Этот подход особенно полезен для длинных системных подсказок, поскольку они остаются кэшированными даже при нескольких событиях сжатия контекста на протяжении разговора.
Сжатие контекста требует дополнительного шага сэмплирования, который учитывается в ограничениях скорости и тарификации. API возвращает подробную информацию об использовании в ответе:
{
"usage": {
"input_tokens": 23000,
"output_tokens": 1000,
"iterations": [
{
"type": "compaction",
"input_tokens": 180000,
"output_tokens": 3500
},
{
"type": "message",
"input_tokens": 23000,
"output_tokens": 1000
}
]
}
}Массив iterations показывает использование для каждой итерации сэмплирования. Когда происходит сжатие контекста, вы увидите итерацию compaction, за которой следует основная итерация message. Верхнеуровневые input_tokens и output_tokens в этом примере точно совпадают с итерацией message, поскольку есть только одна итерация, не связанная со сжатием. Количество токенов последней итерации отражает эффективный размер контекста после сжатия.
Верхнеуровневые input_tokens и output_tokens не включают использование итерации сжатия. Они отражают сумму всех итераций, не связанных со сжатием. Чтобы рассчитать общее количество токенов, потреблённых и тарифицированных для запроса, просуммируйте все записи в массиве usage.iterations.
Если вы ранее полагались на usage.input_tokens и usage.output_tokens для отслеживания затрат или аудита, вам потребуется обновить логику отслеживания, чтобы агрегировать данные по usage.iterations при включённом сжатии контекста. Массив iterations заполняется только тогда, когда новое сжатие запускается во время запроса. Повторное применение предыдущего блока compaction не влечёт дополнительных затрат на сжатие, и верхнеуровневые поля использования остаются точными в этом случае.
При использовании серверных инструментов (например, веб-поиска) триггер сжатия контекста проверяется в начале каждой итерации сэмплирования. Сжатие может происходить несколько раз в рамках одного запроса в зависимости от вашего порога срабатывания и объёма сгенерированного вывода.
Эндпоинт подсчёта токенов (/v1/messages/count_tokens) применяет существующие блоки compaction в вашей подсказке, но не запускает новые сжатия. Используйте его, чтобы проверить эффективное количество токенов после предыдущих сжатий:
Вот полный пример длительного разговора со сжатием контекста:
Вот пример, использующий pause_after_compaction для сохранения предыдущего обмена репликами и текущего сообщения пользователя (всего три сообщения) дословно вместо их суммирования:
Та же модель для суммирования: Модель, указанная в вашем запросе, используется для суммирования. Нет возможности использовать другую (например, более дешёвую) модель для сводки.
Сжатие контекста может завершиться неудачей при определённых инструментах: Когда ваш запрос включает tools, модель иногда вызывает инструмент во время внутреннего шага суммирования вместо написания сводки. Когда это происходит, ответ содержит блок compaction с content: null. Чтобы предотвратить это, задайте в instructions подсказку, которая явно указывает модели не вызывать инструменты, например:
Summarize the transcript inside <summary></summary> tags. Include relevant information in the summary for continuing the task in the next context window. Do not call any tools while writing this summary; respond with text only.Изучите практическую реализацию, которая управляет длительными разговорами с мгновенным сжатием памяти сессии, используя фоновую многопоточность и кэширование подсказок.
Узнайте о размерах контекстного окна и стратегиях управления.
Изучите другие стратегии управления контекстом разговора, такие как очистка результатов инструментов и очистка блоков мышления.
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Help me build a website"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)
# Добавьте ответ (включая блок уплотнения, если он есть), чтобы продолжить разговор
messages.append({"role": "assistant", "content": response.content})client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"trigger": {"type": "input_tokens", "value": 150000},
}
]
},
)client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"instructions": "Focus on preserving code snippets, variable names, and technical decisions.",
}
]
},
)client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
max_tokens=4096,
messages=messages,
context_management={
"edits": [{"type": "compact_20260112", "pause_after_compaction": True}]
},
)
# Проверяем, вызвало ли уплотнение паузу
if response.stop_reason == "compaction":
# Ответ содержит только блок уплотнения
messages.append({"role": "assistant", "content": response.content})
# Продолжаем запрос
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)
# После получения ответа с блоком уплотнения
messages.append({"role": "assistant", "content": response.content})
# Продолжите разговор
messages.append({"role": "user", "content": "Now add error handling"})
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
with client.beta.messages.stream(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
) as stream:
for event in stream:
if event.type == "content_block_start":
if event.content_block.type == "compaction":
print("Compaction started...")
elif event.content_block.type == "text":
print("Text response started...")
elif event.type == "content_block_delta":
if event.delta.type == "compaction_delta":
print(f"Compaction complete: {len(event.delta.content or '')} chars")
elif event.delta.type == "text_delta":
print(event.delta.text, end="", flush=True)
# Получить итоговое накопленное сообщение
message = stream.get_final_message()
messages.append({"role": "assistant", "content": message.content})client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
max_tokens=4096,
system=[
{
"type": "text",
"text": "You are a helpful coding assistant...",
"cache_control": {
"type": "ephemeral"
}, # Cache the system prompt separately
}
],
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
count_response = client.beta.messages.count_tokens(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)
print(f"Current tokens: {count_response.input_tokens}")
print(f"Original tokens: {count_response.context_management.original_input_tokens}")client = anthropic.Anthropic()
messages: list[dict] = []
def chat(user_message: str) -> str:
messages.append({"role": "user", "content": user_message})
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"trigger": {"type": "input_tokens", "value": 100000},
}
]
},
)
# Добавляем ответ (блоки уплотнения включаются автоматически)
messages.append({"role": "assistant", "content": response.content})
# Возвращаем текстовое содержимое
return next(block.text for block in response.content if block.type == "text")
# Запускаем длинный диалог
print(chat("Help me build a Python web scraper"))
print(chat("Add support for JavaScript-rendered pages"))
print(chat("Now add rate limiting and error handling"))
# ... продолжайте столько, сколько потребуетсяfrom typing import Any
client = anthropic.Anthropic()
messages: list[dict[str, Any]] = []
def chat(user_message: str) -> str:
messages.append({"role": "user", "content": user_message})
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"trigger": {"type": "input_tokens", "value": 100000},
"pause_after_compaction": True,
}
]
},
)
# Проверяем, произошло ли уплотнение и была ли приостановка
if response.stop_reason == "compaction":
# Получаем блок уплотнения из ответа
compaction_block = response.content[0]
# Сохраняем предыдущий обмен + текущее сообщение пользователя (3 сообщения),
# включив их после блока уплотнения
preserved_messages = messages[-3:] if len(messages) >= 3 else messages
# Формируем новый список сообщений: уплотнение + сохранённые сообщения
new_assistant_content = [compaction_block]
messages_after_compaction = [
{"role": "assistant", "content": new_assistant_content}
] + preserved_messages
# Продолжаем запрос с уплотнённым контекстом + сохранёнными сообщениями
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-4-8",
max_tokens=4096,
messages=messages_after_compaction,
context_management={"edits": [{"type": "compact_20260112"}]},
)
# Обновляем наш список сообщений с учётом уплотнения
messages.clear()
messages.extend(messages_after_compaction)
# Добавляем финальный ответ
messages.append({"role": "assistant", "content": response.content})
# Возвращаем текстовое содержимое
return next(block.text for block in response.content if block.type == "text")
# Запускаем длинный диалог
print(chat("Help me build a Python web scraper"))
print(chat("Add support for JavaScript-rendered pages"))
print(chat("Now add rate limiting and error handling"))
# ... продолжаем столько, сколько потребуется