为什么需要Context压缩?
每个LLM都有上下文窗口限制——GPT-4是128K tokens,Claude是200K。听起来很多?看看实际情况:
- 一段代码+注释 ≈ 2000 tokens
- 一篇中文文章 ≈ 3000 tokens
- 一次工具调用结果 ≈ 500-5000 tokens
- 10轮对话历史 ≈ 10000-30000 tokens
如果Agent需要处理代码、搜索结果、长文档,加上几十轮对话历史,很快就会触及上下文窗口的上限。Context压缩就是解决"如何在有限空间里保留最重要信息"的技术。
💰 成本对比:
- 128K tokens全窗口:每次调用约$1.5-$3
- 压缩到20K tokens:每次调用约$0.2-$0.5
- 节省:80%成本
五种压缩策略
1. 滑动窗口(Sliding Window)
最简单的策略——只保留最近N条消息:
agent.setContextStrategy({
type: 'sliding_window',
keepRecent: 20, // 保留最近20条消息
keepFirst: 2, // 保留最开始的2条(system prompt)
// 对被移除的消息生成摘要
summarize: true,
summaryModel: 'gpt-3.5-turbo' // 用便宜模型生成摘要
});
⚠️ 注意:滑动窗口会丢失早期对话的细节。如果用户提到"还记得我们之前讨论的方案A吗?",滑动窗口可能已经丢弃了方案A的内容。
2. 摘要压缩(Summary Compression)
用LLM生成对话摘要,替代原始消息:
agent.setContextStrategy({
type: 'summary',
// 摘要生成配置
summary: {
model: 'gpt-3.5-turbo', // 用经济模型生成摘要
triggerThreshold: 0.8, // 上下文达到80%时触发压缩
// 摘要模板
template: `请将以下对话历史压缩为简洁的摘要,保留:
1. 用户的核心需求和偏好
2. 重要的决策和结论
3. 未完成的任务
4. 关键的数据点
对话历史:
{messages}
摘要:`,
maxSummaryTokens: 2000, // 摘要不超过2000 tokens
preserveRecentMessages: 10 // 摘要后的最近10条消息保持原文
}
});
3. 语义裁剪(Semantic Pruning)
根据语义重要性保留关键消息,删除冗余信息:
agent.setContextStrategy({
type: 'semantic_pruning',
// 重要性评分
importance: {
// 关键词加权
keywordWeights: {
'决定': 3, '结论': 3, '需要': 2,
'好的': 0.5, '嗯': 0.1, '是的': 0.3
},
// 自动学习用户意图
learnFromFeedback: true,
// 始终保留的类型
alwaysKeep: ['decision', 'user_requirement', 'error']
},
// 目标tokens数
targetTokens: 20000
});
4. 层级记忆(Hierarchical Memory)
将信息分为短期记忆、中期记忆、长期记忆三层:
agent.setContextStrategy({
type: 'hierarchical',
layers: {
// 短期记忆:最近5轮对话,原文保留
short_term: {
messages: 10,
format: 'original'
},
// 中期记忆:最近50轮的摘要
mid_term: {
messages: 50,
format: 'detailed_summary', // 详细摘要
maxTokens: 5000
},
// 长期记忆:所有历史的要点
long_term: {
format: 'key_points', // 关键要点
maxTokens: 2000,
persist: true // 持久化存储
}
}
});
5. Token优化(Token Optimization)
不改变内容,减少token消耗:
agent.setContextStrategy({
type: 'token_optimize',
optimizations: [
// 移除工具调用中的冗余字段
{ type: 'strip_tool_metadata' },
// 压缩重复的确认消息
{ type: 'merge_confirmations' },
// 移除错误的重试记录
{ type: 'remove_retry_errors' },
// 用缩写替代常见短语
{ type: 'abbreviation', rules: {
'在之前的对话中': '↑',
'根据您的需求': '需求:',
}},
// 移除格式化空白
{ type: 'normalize_whitespace' }
],
// 预估节省比例
estimatedSaving: '15-30%'
});
压缩策略选择指南
| 场景 | 推荐策略 | 理由 |
|---|---|---|
| 简短问答 | 滑动窗口 | 简单有效,无额外开销 |
| 长项目讨论 | 层级记忆 | 保留长期上下文 |
| 技术文档分析 | 语义裁剪 | 保留技术关键信息 |
| 日常助手 | 摘要压缩 | 平衡信息量和成本 |
| 高并发场景 | Token优化 | 零额外成本,立即生效 |
实现完整示例
import { Agent, ContextManager } from 'openclaw';
const agent = new Agent();
// 配置智能上下文管理
agent.use(new ContextManager({
// 总token预算
maxTokens: 40000,
// 预留给回复的tokens
reserveTokens: 8000,
// 可用于历史的tokens
historyBudget: 32000,
// 压缩策略组合
strategy: 'adaptive',
// 自适应规则
adaptive: {
// 上下文使用率 < 50%:不压缩
low: { threshold: 0.5, action: 'none' },
// 50%-80%:Token优化
medium: { threshold: 0.8, action: 'token_optimize' },
// 80%-95%:摘要压缩
high: { threshold: 0.95, action: 'summary' },
// > 95%:强制裁剪
critical: { threshold: 1.0, action: 'aggressive_prune' }
},
// 监控
monitor: {
onCompress: (before, after) => {
console.log(`上下文压缩: ${before} → ${after} tokens (${((1 - after/before) * 100).toFixed(0)}%节省)`);
}
}
}));
最佳实践
- ✅ 先用Token优化,再用摘要压缩——最小成本原则
- ✅ System Prompt始终保留在顶部,不被压缩
- ✅ 用经济模型(GPT-3.5)生成摘要,用强模型(GPT-4)处理任务
- ✅ 设置合理的压缩阈值,避免频繁压缩
- ✅ 保留用户的关键决策和偏好信息
- ✅ 监控压缩后的对话质量
- ✅ 提供用户"查看完整历史"的选项
💡 黄金法则:压缩的目的是降低成本和提高速度,但绝不能以牺牲关键信息为代价。宁可多花几毛钱,也不要丢掉用户的决策。
常见问题
Q: 摘要压缩会丢失信息吗?
会丢失细节,但保留核心要点。对于需要细节的历史查询,建议使用层级记忆策略。
Q: 压缩需要额外API调用吗?
摘要压缩和语义裁剪需要调用LLM生成摘要/评分,但这比直接使用大窗口便宜得多。
Q: 不同模型窗口大小不同怎么办?
设置一个统一的内部预算(如40K tokens),无论用什么模型都适用。模型切换时无需调整策略。