按令牌阈值压缩
当对话达到您设置的令牌阈值时,让 API 在普通请求中自动总结较早的上下文。
"Threshold compaction"(阈值压缩)是一种自动压缩方式:您在普通请求上设置一个令牌阈值,一旦达到该阈值,API 就会在请求进行过程中总结较早的上下文。它与按需压缩并存,按需压缩由您决定何时生成摘要(请参阅按需压缩)。要在两者之间做出选择,请参阅选择压缩方式。
压缩通过在接近 "context window"(上下文窗口)限制时自动总结较早的上下文,为长时间运行的对话和任务扩展有效上下文长度。它还能使活动上下文保持精简:随着对话增长,响应质量会下降,因此压缩会用简洁的摘要替换较早的内容。
这非常适用于:
- 基于聊天的多轮对话,您希望用户能够长时间使用同一个聊天
- 需要大量后续工作(通常是 "tool use"(工具使用))且可能超出上下文窗口的面向任务的提示
压缩的工作原理
启用压缩后,当对话达到配置的令牌阈值时,Claude 会自动总结您的对话。API 会:
- 检测输入令牌何时达到您指定的触发阈值。
- 生成当前对话的摘要。
- 创建一个包含该摘要的
compaction块。 - 使用压缩后的上下文继续生成响应。
在后续请求中,将响应追加到您的消息中。API 会自动丢弃 compaction 块之前的所有内容块,从摘要处继续对话。
基本用法
通过在 Messages API 请求的 context_management.edits 中添加 compact_20260112 策略来启用压缩。
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-5-5",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)
# 追加响应(包括任何 compaction 块)以继续对话
messages.append({"role": "assistant", "content": response.content})参数
| 参数 | 类型 | 默认值 | 描述 |
|---|---|---|---|
type | string | 必需 | 必须为 "compact_20260112" |
trigger | object | {"type": "input_tokens", "value": 150000} | 何时触发压缩。input_tokens 是唯一支持的触发类型。value 必须至少为 50,000 个令牌。 |
pause_after_compaction | boolean | false | 生成压缩摘要后是否暂停 |
instructions | string | null | 自定义摘要提示。提供时会完全替换默认提示。 |
触发配置
使用 trigger 参数配置压缩的触发时机:
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"trigger": {"type": "input_tokens", "value": 150000},
}
]
},
)自定义摘要指令
默认摘要提示因模型而异。每个默认提示都会指示 Claude 在 <summary></summary> 标签内编写摘要,其中包含在未来的上下文窗口中继续任务所需的信息。例如,某些模型使用以下提示:
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 参数提供自定义指令。自定义指令不会补充默认提示,而是完全替换它:
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"instructions": "Focus on preserving code snippets, variable names, and technical decisions.",
}
]
},
)在 Claude 5.1 及更高版本的模型上,带有自定义 instructions 的请求仅根据可见对话进行总结:较早的思考块不属于摘要器的输入。
压缩后暂停
使用 pause_after_compaction 可在生成压缩摘要后暂停 API。这样您就可以在 API 继续生成响应之前添加额外的内容块(例如保留最近的消息或特定的指令类消息)。
启用后,API 在生成压缩块后会返回一条停止原因为 compaction 的消息:
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={
"edits": [{"type": "compact_20260112", "pause_after_compaction": True}]
},
)
# 检查 compaction(压缩)是否触发了暂停
if response.stop_reason == "compaction":
# 响应仅包含 compaction 块
messages.append({"role": "assistant", "content": response.content})
# 继续该请求
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)强制执行总令牌预算
当模型处理包含多次工具使用迭代的长任务时,总令牌消耗可能会显著增长。您可以将 pause_after_compaction 与压缩计数器结合使用,以估算累计用量,并在达到预算后优雅地结束任务。
此示例仅以 SDK 语言提供:其价值在于请求周围的预算跟踪逻辑。原始请求将触发配置中的 trigger 与压缩后暂停中的 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-5-5",
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,才能使用缩短后的提示继续对话。最简单的方法是将整个响应内容追加到您的消息中:
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)
# 收到包含 compaction 块的响应后
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-5-5",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
)在 Python 中,请像本页示例那样使用 client.beta.messages。如果您调用 client.messages 并自行序列化块,普通的 model_dump() 会向 compaction 块添加 text: null 和 citations: null。API 随后会以 400 错误(Extra inputs are not permitted)拒绝该请求。请改用 to_dict() 或 model_dump(exclude_none=True)。从摘要继续针对按需压缩给出了相同的建议。
当 API 收到 compaction 块时,其之前的所有内容块都会被忽略。您可以:
- 将原始消息保留在列表中,让 API 负责移除已压缩的内容
- 手动丢弃已压缩的消息,仅包含从压缩块开始的内容
在 Claude Fable 5.1、Claude Mythos 5.1 和 Claude Opus 5.5 上,compaction 块之前的思考块不会被延续,因此摘要是模型对早期工作所掌握的全部内容。如果您编写自己的 instructions,请告诉模型摘要必须保留哪些内容;请参阅告诉模型在压缩摘要中保留什么。
流式传输
压缩块的 "streaming"(流式传输)方式与文本块不同。您会收到一个 content_block_start 事件,随后是一个包含完整摘要内容的 content_block_delta(没有中间流式传输),然后是一个 content_block_stop 事件。
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
with client.beta.messages.stream(
betas=["compact-2026-01-12"],
model="claude-opus-5-5",
max_tokens=4096,
messages=messages,
context_management={"edits": [{"type": "compact_20260112"}]},
) as stream:
for event in stream:
match event.type:
case "content_block_start":
block = event.content_block
match block.type:
case "compaction":
print("Compaction started...")
case "text":
print("Text response started...")
case "content_block_delta":
delta = event.delta
match delta.type:
case "compaction_delta":
print(f"Compaction complete: {len(delta.content or '')} chars")
case "text_delta":
print(delta.text, end="", flush=True)
# 获取最终累积的消息
message = stream.get_final_message()
messages.append({"role": "assistant", "content": message.content})提示缓存
压缩与 "prompt caching"(提示缓存)配合良好。您可以在压缩块上添加 cache_control 断点来缓存摘要内容。
{
"role": "assistant",
"content": [
{
"type": "compaction",
"content": "[summary text]",
"cache_control": { "type": "ephemeral" }
},
{
"type": "text",
"text": "Based on our conversation..."
}
]
}使用系统提示最大化缓存命中
发生压缩时,摘要会成为需要写入缓存的新内容。如果没有额外的缓存断点,这也会使任何已缓存的 "system prompt"(系统提示)失效,需要将其与压缩摘要一起重新缓存。
为了最大化缓存命中率,请在系统提示的末尾添加一个 cache_control 断点。这样可以使系统提示与对话分开缓存,因此在发生压缩时:
- 系统提示缓存保持有效,并从缓存中读取
- 只有压缩摘要需要作为新的缓存条目写入
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
response = client.beta.messages.create(
betas=["compact-2026-01-12"],
model="claude-opus-5-5",
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"}]},
)这样可以在整个对话的多次压缩事件中保持长系统提示的缓存。
了解用量
压缩需要一个额外的采样步骤,这会计入 "rate limit"(速率限制)和计费。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 迭代完全一致,因为只有一个非压缩迭代。最后一次迭代的令牌计数反映了压缩后的有效上下文大小。
与其他功能结合使用
服务器工具
使用服务器工具(例如网页搜索)时,会在每次采样迭代开始时检查压缩触发条件。根据您的触发阈值和生成的输出量,单个请求中可能会发生多次压缩。
令牌计数
令牌计数端点(/v1/messages/count_tokens)会应用提示中已有的 compaction 块,但不会触发新的压缩。使用它来检查之前压缩后的有效令牌数:
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "Hello, Claude"}]
count_response = client.beta.messages.count_tokens(
betas=["compact-2026-01-12"],
model="claude-opus-5-5",
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-5-5",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"trigger": {"type": "input_tokens", "value": 100000},
}
]
},
)
# 追加响应(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"))
# 根据对话需要持续调用 chat()在 Claude Fable 5.1 和 Claude Opus 5.5 上,请从您在压缩块之后重新插入的任何助手轮次中移除 thinking 和 redacted_thinking 块,或者在使用 thinking-binding-controls-2026-08-01 beta 标头的同时发送 thinking.block_binding.prefix_mismatch_behavior: "drop_block"。这些块是在完整历史记录存在时生成的,因此它们不再能通过对话检查。在强制执行该检查的情况下,继续请求会以 400 错误被拒绝。保留的文本块和工具块可以保持原样。让 API 总结所有内容而不重新插入较早的轮次,即可避免此问题。
以下示例使用 pause_after_compaction 逐字保留上一轮交流和当前用户消息(共三条消息),而不是对它们进行总结:
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-5-5",
max_tokens=4096,
messages=messages,
context_management={
"edits": [
{
"type": "compact_20260112",
"trigger": {"type": "input_tokens", "value": 100000},
"pause_after_compaction": True,
}
]
},
)
# 检查是否发生了 compaction(压缩)并已暂停
if response.stop_reason == "compaction":
# 从响应中获取 compaction 块
compaction_block = response.content[0]
# 保留之前的对话轮次 + 当前用户消息(共 3 条消息)
# 方法是将它们放在 compaction 块之后
preserved_messages = messages[-3:] if len(messages) >= 3 else messages
# 构建新的消息列表:compaction + 保留的消息
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-5-5",
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"))
# 根据对话需要持续调用 chat()当前限制
-
使用相同模型进行总结: 请求中指定的模型将用于总结。目前无法选择使用其他(例如更便宜的)模型来生成摘要。
-
定义了工具时压缩可能失败: 当您的请求包含
tools时,模型偶尔会在内部总结步骤中调用工具,而不是编写摘要。发生这种情况时,响应会包含一个content: null的compaction块。为防止这种情况,请将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.
后续步骤
使用上下文编辑在对话增长时自动管理对话上下文。
了解上下文窗口大小和管理策略。
探索一个实际实现,它使用后台线程和提示缓存,通过即时会话记忆压缩来管理长时间运行的对话。
Compatibility
| Supported models |
|
|---|---|
| Supported platforms |
|
Was this page helpful?