Claude Platform Docs
Messages壓縮

隨需壓縮

在您的應用程式選擇的時機要求 Claude 摘要對話,然後從摘要繼續。

透過「on-demand compaction」(隨需壓縮),由您的應用程式決定何時摘要對話:您傳送一個帶有 compaction 參數的請求,Claude 會傳回摘要來取代回覆。

隨需壓縮的運作方式

壓縮請求與您的對話輪次是分開的。您將目前的對話連同 compaction 參數一起傳送,回應會包含單一 compaction 區塊。該區塊包含您可以閱讀的文字形式摘要,以及一個簽章。在後續請求中,請完全按照原樣傳送它。

從那時起,該區塊會取代它所摘要的訊息。它放在 messages 的最前面,被摘要的訊息會被移除,而您的下一個輪次接在它之後。Claude 會在那些訊息原本的位置看到摘要。

Compaction requestfour messagesuser 1asst 1user 2asst 2Responseone block, no replycompaction blockNext requestblock firstcompaction blockuser 3

請求摘要

在要求摘要的請求上,以及之後每個攜帶已簽署區塊的請求上,都要傳送 compact-2026-09-04 beta 標頭。若要檢查模型是否支援隨需壓縮,請使用 beta 標頭呼叫 Models API,並讀取每個模型的 capabilities.compaction。您無法在同一個請求中將 compactioncontext_management 結合使用。

將目前的對話連同 "compaction": {"type": "summarize"} 一起傳送。API 會對請求中的每則訊息進行一次摘要,之後不產生回覆,並單獨傳回該區塊,stop_reason"compaction"。請傳送與對話其餘部分相同的 system 提示和 tools。摘要器會讀取它們,而且如果您在使用「preserved thinking」(保留思考)的模型上保留區塊之後的輪次,只有在 systemtools 相符時,這些輪次中的思考才會保持有效。此範例中的對話沒有 system 提示或工具,因此請求兩者都不傳送:

from anthropic.types.beta import BetaMessageParam

client = anthropic.Anthropic()

history: list[BetaMessageParam] = [
    {
        "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. Add a RecipeIngredient entry that holds the quantity and unit for each ingredient in a recipe.",
    },
    {"role": "user", "content": "Good. Now suggest field names for Recipe."},
]

response = client.beta.messages.create(
    model="claude-opus-5-5",
    # max_tokens 限制整個呼叫的用量(包含任何思考內容),因此請預留數千個 token。
    max_tokens=4096,
    betas=["compact-2026-09-04"],
    messages=history,
    compaction={"type": "summarize"},
)
print(f"Stop reason: {response.stop_reason}")
Response
{
  "id": "msg_013Zva2CMHLNnXjNJJKqJ2EF",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-5-5",
  "content": [
    {
      "type": "compaction",
      "content": "Summary of the conversation: the user is designing the data model for a recipe app. The entities agreed so far are Recipe, Ingredient, Step, and RecipeIngredient, which holds the quantity and unit. The user then asked for field names for Recipe.",
      "signature": "EuYBCkQY..."
    }
  ],
  "stop_reason": "compaction",
  "usage": {
    "input_tokens": 0,
    "output_tokens": 0,
    "iterations": [{ "type": "compaction", "input_tokens": 144, "output_tokens": 276 }]
  }
}

摘要呼叫會使用請求的模型、systemtools、思考設定和 max_tokens。摘要器會讀取工具定義,但絕不會執行工具,而且回應不包含任何思考內容。max_tokens 限制的是整個呼叫,包括模型在撰寫摘要之前進行的任何思考,因此請預留數千個 token。計算壓縮用量說明此呼叫如何計費。

如果最後一個 assistant 輪次以尚未有結果的工具呼叫結束,API 會拒絕該請求。請先傳送該輪次的工具結果。此外,請省略 stop_sequences、結構化輸出的 output_config.format,以及類型為 anytooltool_choice。它們在摘要呼叫中不會有任何作用,而且 API 會拒絕它們。對話仍必須符合模型的「context window」(上下文視窗),因此請在超出之前進行壓縮,而不是之後。

當您以「streaming」(串流)方式接收回應時,區塊會完整送達。您會收到一個攜帶完整區塊的 content_block_start 事件,接著是 content_block_stop,不會有任何 content_block_delta 事件。ping 事件可能在它們之前或之間送達。

從摘要繼續

在您的歷史記錄中,將您傳送的訊息替換為傳回的 assistant 訊息。保持 compaction 區塊與 API 傳回時完全相同,包括其 signature。在您傳送壓縮請求之後進行的任何輪次,都原封不動地接在區塊之後,這正是在背景中進行壓縮所依據的基礎。在之後的每個請求中,都將區塊放在最前面傳送,並附上 beta 標頭:

{
  "model": "claude-opus-5-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. The entities agreed so far are Recipe, Ingredient, Step, and RecipeIngredient, which holds the quantity and unit. The user then asked for field names for Recipe.",
          "signature": "EuYBCkQY..."
        }
      ]
    },
    {
      "role": "assistant",
      "content": "For Recipe, use title, description, servings, prep_minutes, and cook_minutes. Add created_at and updated_at timestamps."
    },
    { "role": "user", "content": "Now do the same for Ingredient." }
  ]
}

此範例延續先前的請求範例,該範例以 user 輪次結束;圖表顯示的是較簡單的情況,即在撰寫摘要期間沒有進行任何輪次。這裡的第二則 assistant 訊息是對最後一個被摘要的 user 輪次的回覆。它是在撰寫摘要期間送達的,因此不在被摘要的訊息之中。這裡連續出現兩則 assistant 訊息沒有問題,因為區塊仍然在最前面。

API 會將摘要放在區塊所在的位置,並將之後的每則訊息原封不動地傳給 Claude。請遵循以下規則:

  • 將區塊放在 messages 的最前面,可以作為獨立的 assistant 訊息,或作為第一則訊息的第一個內容區塊,無論該訊息是 user 還是 assistant 訊息。
  • 移除被摘要的訊息。如果有任何被摘要的訊息留在區塊前面,請求會傳回 400 錯誤(compaction_block_misplaced)。
  • 每個請求恰好傳送一個 compaction 區塊,並在之後的每個請求中都這樣做。

「Threshold compaction」(閾值壓縮)的運作方式正好相反:它的區塊接在它所摘要的訊息之後,而 API 會為您捨棄那些訊息。請參閱回傳壓縮區塊

在 Python 中,請使用 client.beta.messages,如本頁範例所示。如果您呼叫 client.messages 並自行序列化區塊,請使用 to_dict()model_dump(exclude_none=True):單純的 model_dump() 會在區塊中加入 citations: nulltext: null,而 API 會拒絕它。

如果您保留區塊之後的輪次並傳回其思考區塊,讓這些思考保持有效的條件請參閱壓縮與保留思考

再次壓縮

若要壓縮已經以區塊開頭的對話,請再次傳送 compaction。新區塊會摘要舊摘要及其之後的所有內容。從那時起,只傳送最新的區塊。

在迴圈中壓縮

每個輪次之後,迴圈會將上一個回應的輸入和輸出 token 相加,因為下一個請求也會傳送該回覆。當該總數超過限制且仍有下一個輪次要進行時,它會使用相同的模型和 system 提示傳送壓縮請求、檢查 stop_reason、以傳回的訊息取代其歷史記錄,並印出它在哪個輪次之前進行了壓縮。範例中 2,500 個 token 的限制刻意設得很低,以便讓簡短的對話也會進行壓縮。請將您的限制設定在接近實際輸入預算的值。

from anthropic.types.beta import BetaMessageParam

client = anthropic.Anthropic()

# 請將此值設為接近您實際的輸入預算。此處設得較低,讓簡短的對話也會觸發壓縮。
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?",
]

history: list[BetaMessageParam] = []
for turn, question in enumerate(QUESTIONS, start=1):
    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):
        summary = client.beta.messages.create(
            model="claude-opus-5-5",
            max_tokens=4096,
            system=SYSTEM,
            betas=["compact-2026-09-04"],
            messages=history,
            compaction={"type": "summarize"},
        )
        if summary.stop_reason == "compaction":
            history = [{"role": "assistant", "content": summary.content}]
            print(f"Compacted before turn {turn + 1}")

stop_reason 的檢查發生在程式碼尋找區塊之前;處理缺少摘要或錯誤的情況說明了原因。歷史記錄是被取代,而不是被附加:傳回的訊息會依照從摘要繼續中的規則,取代請求所攜帶的每則訊息。當沒有傳回摘要時,迴圈會保留其歷史記錄,並在下一個輪次之後再次請求。

Python、TypeScript、C#、Go 和 Java 中的 SDK 「tool runner」(工具執行器)可以為您傳送壓縮請求。當您決定壓縮時,請在執行器上呼叫 compact_before_next_turn()(在 TypeScript 和 Java 中為 compactBeforeNextTurn(),在 C# 和 Go 中為 CompactBeforeNextTurn())。當目前的輪次及其工具呼叫完成後,執行器會傳送壓縮請求,並以傳回的訊息取代其歷史記錄。請使用 compact-2026-09-04 beta 建立執行器,因為執行器不會自動加入它。執行器會根據自己的參數建立請求,並省略 context_management。如果這些參數包含 stop_sequences、類型為 anytooltool_choice,或結構化輸出的 output_config.format,API 會以 400 錯誤拒絕該請求。請求摘要說明了原因。當執行器的 context_management 含有壓縮編輯時,執行器會拒絕進行壓縮,因此請在一個執行器上只使用一種壓縮方式。

何時壓縮

您可以在任何已完成的輪次之後傳送壓縮請求,因此由您的程式碼決定時機。

若要估計下一個請求的大小,請如迴圈所做的那樣,將上一個回應 usage 中的 input_tokensoutput_tokens 相加。使用「prompt caching」(提示快取)時,input_tokens 只計算最後一個快取中斷點之後的 token,因此也要加上 cache_read_input_tokenscache_creation_input_tokens。您也可以將相同的訊息傳送到「token counting」(token 計數)端點。

將該數字與您選擇的限制進行比較,該限制應低於模型的上下文視窗

撰寫您自己的摘要提示

若未提供 instructions,API 會使用自己的摘要提示。非空白的 instructions 字串(最多 16,384 個字元)會完全取代該提示。例如:

{
  "compaction": {
    "type": "summarize",
    "instructions": "Summarize this recipe app design conversation. Preserve every entity and field name agreed so far, and the user's latest open request. Do not call tools; respond with the summary text only."
  }
}

無論是否提供 instructions,摘要器都會讀取整個對話,包括先前的思考。在您的 instructions 中,請說明摘要必須保留哪些內容,並告訴模型不要呼叫工具。摘要呼叫與任何其他請求一樣,在相同的安全防護措施下執行。

處理缺少摘要或錯誤的情況

只有當摘要呼叫以文字正常結束且沒有工具呼叫時,才會產生摘要。否則,回應仍然是 200,但 content 為空,因此請在尋找區塊之前先檢查 stop_reason。該呼叫仍會計費並在 usage.iterations 中回報,若無法進行呼叫,則用量為零。stop_reason 是摘要呼叫結束時的原因。在所有情況下,您都可以在沒有摘要的情況下繼續,並稍後再壓縮。

stop_reason原因處理方式
"max_tokens"摘要被截斷。使用更大的 max_tokens 重新傳送。
"model_context_window_exceeded"沒有空間容納摘要提示。使用較短的 instructions 或較少的訊息重新傳送。
"tool_use"模型呼叫了工具,而不是撰寫摘要。使用告訴模型不要呼叫工具的 instructions 重新傳送。
"refusal"請求遭到拒絕。在沒有摘要的情況下繼續。
"end_turn"呼叫沒有傳回任何文字。在沒有摘要的情況下繼續。

摘要呼叫與您的其他請求受到相同的安全防護措施約束。在 "refusal" 之後,stop_details 會指出其背後的政策類別。

錯誤

壓縮請求或攜帶區塊的請求也可能直接失敗。大多數 400 錯誤都附有訊息,說明要移除或重新傳送什麼。有些錯誤還會攜帶以 compaction_ 開頭的 error.details.error_code。參數錯誤(例如無法與 compaction 結合使用的欄位)只會攜帶訊息。

錯誤原因處理方式
529 overloaded_errorerror.details.error_codecompaction_unavailable在產生區塊時,或在讀取您傳回的區塊時,發生暫時性的伺服器問題。重試請求。
400 compaction_block_misplaced被摘要的訊息留在區塊前面。移除它們,讓區塊位於 messages 的最前面。
400 compaction_signature_invalidcompaction_content_mismatch區塊的 signaturecontent 在 API 傳回後遭到變更。完全按照傳回的樣子傳送區塊,包括其 signature
400請求攜帶了多個 compaction 區塊。恰好傳送一個,也就是最新的那個。
400最後一個 assistant 輪次以尚未有結果的工具呼叫結束。傳送該輪次的工具結果,然後再壓縮。
400 compaction_nothing_to_summarizemessages 沒有任何 userassistant 內容,例如空清單。至少傳送一則 userassistant 訊息。
壓縮請求上的 400,訊息指出 compaction 參數 requires anthropic-beta: compact-2026-09-04壓縮請求遺漏了 beta 標頭。加入 beta 標頭;請參閱請求摘要
之後攜帶區塊的請求上的 400:驗證錯誤指出 compaction 不是預期的內容區塊類型之一。訊息中不會提及標頭該請求遺漏了 beta 標頭。在每個攜帶區塊的請求中加入 beta 標頭;請參閱請求摘要
400 驗證錯誤,例如 messages.0.content.0.compaction.citations: Extra inputs are not permitted傳回的區塊帶有 API 未傳回的欄位,例如 citations: null完全按照傳回的樣子傳送區塊;請參閱從摘要繼續

計算壓縮用量

摘要呼叫與任何其他請求一樣會計費並受到「rate limit」(速率限制),而 usage.iterations 會將其回報為 compaction 項目。頂層的 input_tokensoutput_tokens 為零,因為沒有產生回覆。若要計算對話消耗的用量,請加總 usage.iterations 中的數值,而不是頂層欄位。在之後的請求中傳回區塊不會增加壓縮成本。

您現在有一個可以壓縮對話並處理缺少摘要情況的可運作迴圈。有兩個頁面會改變它的運作方式,而且您可以將它們結合使用:保留最近輪次的壓縮會逐字保留最後幾個輪次,而在背景中進行壓縮讓對話在撰寫摘要期間繼續進行。如果您傳回思考區塊並採用其中任一種方式,則適用壓縮與保留思考

限制以及與其他功能的互動

  • 閾值壓縮與「context editing」(上下文編輯)。 您無法在同一個請求中傳送 compactioncontext_management。閾值壓縮(compact_20260112)無法在攜帶已簽署區塊的請求上執行。
  • 提示快取。 區塊上的 cache_control 會在摘要之後放置一個中斷點。
  • 對話中途的系統訊息與工具變更。 被摘要範圍內的 role: "system" 訊息也會被摘要,因此一旦區塊取代它們,其文字指示就不再適用。如果某項指示仍然重要,請在 role: "system" 訊息中再次說明。在您下一個新的 user 輪次之後立即傳送該訊息,並從此將其保留在您的歷史記錄中。關於工具變更,以及當您保留區塊之後的輪次時該訊息應放在何處,請參閱變更系統提示或工具
  • 任務預算。 請勿在帶有 compaction 的請求或攜帶區塊的請求上傳送「task budget」(任務預算)remaining 值(output_config.task_budget.remaining)。這樣做會傳回 400 錯誤。
  • Token 計數。 token 計數端點會忽略 compaction 參數。
  • 摘要無法攜帶的內容。 被摘要訊息中的圖片、文件、container_upload 區塊和擷取的 URL,一旦被區塊取代就會消失。請重新說明或重新上傳之後輪次仍需要的任何內容。

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?