Сжатие в фоновом режиме
Запросите сводку в режиме сжатия по запросу, пока разговор продолжается с полной историей, а затем подставьте блок, когда он придёт.
«Background compaction» (фоновое сжатие), которое часто называют «async compaction» (асинхронное сжатие), меняет две вещи в цикле сжатия: запрос на сжатие выполняется, пока разговор продолжается с полной историей, а замена откладывается до получения блока. Разделы Продолжение со сводки и Обработка отсутствующей сводки или ошибки применяются без изменений.
Как работает замена, пока работа продолжается
Запрос на сжатие и возвращаемый им блок такие же, как в цикле. Ваша история растёт в промежутке между отправкой запроса и использованием его результата, и замена должна сохранить этот прирост.
- Отправьте запрос на сжатие с историей в её текущем состоянии и запишите, сколько сообщений в ней было.
- Пока этот запрос выполняется, продолжайте разговор с полной историей. Добавляйте каждый новый ход, не редактируйте ничего, что уже есть в истории, и не запускайте другой запрос на сжатие, пока этот не будет подставлен или не завершится неудачей.
- Когда придёт ответ со
stop_reason"compaction", удалите из начала истории ровно те сообщения, которые вы отправили, и поставьте на их место возвращённое сообщение. Каждый ход, добавленный после шага 1, остаётся после него. - Отправьте историю после замены в первом же запросе после получения блока, чтобы мышление, созданное во время написания сводки, оставалось действительным.
Например, если запрос на сжатие содержал сообщения с 1 по 5, а за время его выполнения в разговоре появились сообщения с 6 по 8, то после замены ваша история состоит из блока, за которым следуют сообщения с 6 по 8.
Если в ответе указан любой другой stop_reason, сводка не была создана, и это считается неудачей в смысле шага 2. Сохраните полную историю; в разделе Обработка отсутствующей сводки или ошибки перечислены причины и действия для каждой из них.
Запрос сводки в фоновом режиме
Запрос на сжатие учитывается в ваших «rate limits» (ограничениях скорости), как и любой другой запрос, и пока он выполняется, у вашего приложения одновременно открыты два запроса. Разговор продолжается с полной историей и растёт вплоть до замены, поэтому запускайте запрос на сжатие, пока в «context window» (контекстном окне) ещё есть место для ходов, которые поступят за это время.
Следующая программа — это цикл из раздела Сжатие в цикле, в котором запрос на сжатие вынесен за пределы основного хода разговора. У нее нет версии на PHP, поскольку пример основан на одновременном выполнении двух запросов. Выделенные строки показывают, чем она отличается от цикла, а в следующем списке они рассматриваются в том порядке, в котором их выполняет программа.
from concurrent.futures import Future, ThreadPoolExecutor
import anthropic
from anthropic.types.beta import BetaMessage, BetaMessageParam
client = anthropic.Anthropic()
executor = ThreadPoolExecutor(max_workers=1)
# Задайте значение, близкое к реальному бюджету входных токенов. Здесь оно занижено, чтобы короткий диалог сжимался.
COMPACT_AT_TOKENS = 2500
SYSTEM = "You help design a recipe app's data model. Keep answers short."
QUESTIONS = [
"What are the main entities in the data model?",
"Which fields should Recipe have?",
"Which fields should Ingredient have?",
"Which fields should RecipeIngredient have?",
"Which fields should Step have?",
"Which indexes should these tables have?",
"Which fields should be required?",
"Which fields should have default values?",
]
def swap_in(history: list[BetaMessageParam], summary: BetaMessage, sent: int) -> None:
if summary.stop_reason == "compaction":
# Замените ровно те сообщения, которые содержал запрос на сжатие.
# Последующие ходы остаются после блока.
history[:sent] = [{"role": "assistant", "content": summary.content}]
print(f"Swapped {sent} messages")
history: list[BetaMessageParam] = []
pending: Future[BetaMessage] | None = None
sent = 0
for turn, question in enumerate(QUESTIONS, start=1):
if pending is not None and pending.done():
swap_in(history, pending.result(), sent)
pending = None
history.append({"role": "user", "content": question})
response = client.beta.messages.create(
model="claude-opus-5-5",
max_tokens=8192,
system=SYSTEM,
betas=["compact-2026-09-04"],
messages=history,
)
history.append({"role": "assistant", "content": response.content})
# Следующий запрос тоже отправит этот ответ, поэтому учтите его.
conversation_tokens = response.usage.input_tokens + response.usage.output_tokens
if (
conversation_tokens > COMPACT_AT_TOKENS
and turn < len(QUESTIONS)
and pending is None
):
sent = len(history)
pending = executor.submit(
client.beta.messages.create,
model="claude-opus-5-5",
max_tokens=4096,
system=SYSTEM,
betas=["compact-2026-09-04"],
messages=history.copy(),
compaction={"type": "summarize"},
)
# Подставьте сводку, которая ещё формируется, прежде чем сохранять
# или продолжать диалог.
if pending is not None:
swap_in(history, pending.result(), sent)
executor.shutdown()- Решение о том, когда выполнять сжатие: проверка размера также требует, чтобы не было ожидающего запроса на сжатие.
- Запуск запроса: там, где цикл ожидает ответа на сжатие, эта версия записывает, сколько сообщений содержит история, запускает запрос на копии истории с помощью собственного инструмента параллелизма каждого языка и переходит к следующему ходу, не дожидаясь ответа.
- Проверка результата: в начале каждого хода программа проверяет, завершился ли ожидающий запрос. Если да, программа выполняет замену до отправки запроса этого хода.
- Выполнение замены: там, где цикл заменяет всю историю возвращённым сообщением, функция замены в этой версии заменяет только те сообщения, которые содержал запрос, считая от начала, и сохраняет всё, что было добавлено после.
- Завершение цикла: если запрос на сжатие всё ещё ожидает выполнения, когда цикл заканчивается, программа дожидается его и выполняет замену, чтобы сводка, которая ещё в пути, не была потеряна до того, как вы сохраните или продолжите разговор.
Проверка stop_reason не отличается от цикла: ответ без блока оставляет историю в прежнем виде. Поскольку ожидающих запросов больше нет, программа может затем запустить новый запрос на сжатие.
Сохранение действительности мышления во время создания сводки
Ходы, поступающие во время написания сводки, являются сохранёнными ходами. Если вы отправляете блоки мышления обратно модели с сохранённым мышлением, мышление в этих ходах остаётся действительным только до тех пор, пока выполняются условия, при которых сохранённое мышление остаётся действительным.
Compatibility
| Supported models |
|
|---|---|
| Supported platforms |
|
Was this page helpful?