03 - 压缩与裁剪
本篇回答:已经在上下文里的东西怎么砍掉。两种砍法的语义完全不同,代价也完全不同。
本篇会用到的词:
| 词 | 意思 |
|---|---|
| 压缩(compaction) | 把旧内容总结成一段摘要,用摘要替换原文。语义保留,细节丢失 |
| 裁剪(context editing) | 直接删掉特定内容块,替换成一句占位文本。不做总结,删了就是删了 |
| compaction 块 | 压缩产生的一个内容块,装着摘要。它必须被回传,否则压缩状态丢失 |
| 采样迭代 | 一次 API 调用内部可能发生多次模型采样。压缩就是一次额外的采样迭代 |
| 占位文本 | 裁剪后留在原位的一句说明,告诉模型"这里原本有内容,已被移除" |
一、两种砍法
二、服务端压缩
2.1 机制
const response = await client.beta.messages.create({
betas: ["compact-2026-01-12"],
model: "claude-opus-5",
max_tokens: 16000,
messages,
context_management: {
edits: [{ type: "compact_20260112" }],
},
});
// ⚠️ 必须追加完整的 response.content,不能只取里面的文本块。
// 压缩产生的 compaction 块就在 content 里,API 靠它在下一次请求时
// 丢弃摘要之前的全部内容。只 append 文本 = 压缩状态静默丢失,
// 表现是"开了压缩但上下文还在无限增长",且不报任何错。
messages.push({ role: "assistant", content: response.content });
流程是四步:检测到输入 token 达到阈值 → 生成摘要 → 产生一个 compaction 块 → 带着压缩后的上下文继续这次回答。后续请求里,API 自动丢弃 compaction 块之前的所有内 容块。
2.2 全部参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
type | string | 必填 | 必须是 "compact_20260112" |
trigger | object | {"type": "input_tokens", "value": 150000} | 何时触发。input_tokens 是唯一支持的类型,value 最低 50,000 |
pause_after_compaction | boolean | false | 生成摘要后是否暂停,交回控制权 |
instructions | string | null | 自定义总结提示词。提供时完全替换默认提示词,不是追加 |
2.3 三个坑
instructions 一段明确禁止调工具的提示词。注意 instructions 是完全替换默认提示词的,所以自定义的那段里必须同时写清"要在摘要里保留什么",否则会连默认提示词里的那些要求一起丢掉。第③个坑的量级值得单独看一眼。官方文档给的示例响应: