Claude Platform Docs
Messages壓縮

在背景中進行壓縮

在對話以完整歷史記錄繼續進行的同時,請求隨需壓縮摘要,並在區塊送達時將其替換進去。

「Background compaction」(背景壓縮),通常稱為「async compaction」(非同步壓縮),會改變壓縮迴圈中的兩件事:壓縮請求會在對話以完整歷史記錄繼續進行的同時執行,而替換則會等到區塊送達後才進行。從摘要繼續處理缺少摘要或錯誤的情況的內容維持不變地適用。

工作持續進行時的替換方式

壓縮請求及其傳回的區塊與迴圈中的相同。您的歷史記錄會在送出請求與使用其結果之間持續增長,而替換必須保留這些增長的部分。

  1. 以目前的歷史記錄送出壓縮請求,並記錄其中包含多少則訊息。
  2. 在該請求執行期間,以完整歷史記錄讓對話繼續進行。附加每個新輪次,不要編輯歷史記錄中已有的任何內容,並且在此請求被替換進去或失敗之前,不要啟動另一個壓縮請求。
  3. 當回應送達且 stop_reason"compaction" 時,從歷史記錄的開頭精確移除您所送出的那些訊息,並將傳回的訊息放在它們的位置。自步驟 1 以來附加的每個輪次都保留在其後方。
  4. 在區塊送達後的第一個請求中送出替換後的歷史記錄,如此一來,在撰寫摘要期間產生的思考內容才能保持有效。

例如,如果壓縮請求包含訊息 1 到 5,而對話在其執行期間新增了訊息 6 到 8,則替換後您的歷史記錄會是該區塊,後面接著訊息 6 到 8。

Request sentmessages 1–512345While it runs6–8 arrive12345678compaction request: 1–5After the swapblock, then 6–8compaction block678

如果回應具有任何其他 stop_reason,表示未產生摘要,這在步驟 2 中視為失敗。請保留完整歷史記錄;處理缺少摘要或錯誤的情況列出了各種原因以及每種情況的處理方式。

在背景中請求摘要

壓縮請求與其他任何請求一樣,會計入您的「rate limit」(速率限制),而在其執行期間,您的應用程式會同時有兩個開啟中的請求。在替換之前,對話會以完整歷史記錄持續增長,因此請在「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
  • Fable 5 and 5.1
  • Mythos 5, 5.1, and Preview
  • Opus 4.6, 4.7, 4.8, 5, and 5.5
  • Sonnet 4.6 and 5
Supported platforms
  • Claude APIBeta
  • Claude Platform on AWSBeta
  • Google CloudBeta
  • Microsoft FoundryBeta

Was this page helpful?