目录
-
- 摘要
- [1. 引言 - Token 限制的挑战](#1. 引言 - Token 限制的挑战)
-
- [1.1 什么是 Token?](#1.1 什么是 Token?)
- [1.2 Token 限制带来的挑战](#1.2 Token 限制带来的挑战)
- [1.3 优化目标](#1.3 优化目标)
- [2. Token 计算原理](#2. Token 计算原理)
-
- [2.1 Token 计算规则](#2.1 Token 计算规则)
- [2.2 Token 计算工具](#2.2 Token 计算工具)
- [2.3 各模型上下文限制](#2.3 各模型上下文限制)
- [3. 上下文压缩技术](#3. 上下文压缩技术)
-
- [3.1 压缩策略概览](#3.1 压缩策略概览)
- [3.2 摘要压缩](#3.2 摘要压缩)
- [3.3 选择性加载](#3.3 选择性加载)
- [3.4 滑动窗口](#3.4 滑动窗口)
- [3.5 语义去重](#3.5 语义去重)
- [4. OpenClaw 上下文管理](#4. OpenClaw 上下文管理)
-
- [4.1 OpenClaw 上下文结构](#4.1 OpenClaw 上下文结构)
- [4.2 Token 分配策略](#4.2 Token 分配策略)
- [4.3 动态上下文加载](#4.3 动态上下文加载)
- [5. 实战优化案例](#5. 实战优化案例)
-
- [5.1 案例一:长对话压缩](#5.1 案例一:长对话压缩)
- [5.2 案例二:记忆精简](#5.2 案例二:记忆精简)
- [5.3 案例三:技能按需加载](#5.3 案例三:技能按需加载)
- [6. 成本优化策略](#6. 成本优化策略)
-
- [6.1 成本计算](#6.1 成本计算)
- [6.2 成本优化技巧](#6.2 成本优化技巧)
- [6.3 成本监控](#6.3 成本监控)
- [7. 高级优化技巧](#7. 高级优化技巧)
-
- [7.1 分层上下文](#7.1 分层上下文)
- [7.2 智能预测加载](#7.2 智能预测加载)
- [7.3 渐进式加载](#7.3 渐进式加载)
- [8. 常见问题与解决](#8. 常见问题与解决)
- [9. 总结](#9. 总结)
-
- [9.1 核心要点](#9.1 核心要点)
- [9.2 优化清单](#9.2 优化清单)
- 参考资料
摘要
本文深入探讨 OpenClaw 框架中的上下文管理与 Token 优化策略。从上下文窗口限制、Token 计算原理、压缩技术到智能裁剪策略,全面解析如何在有限 Token 预算下最大化上下文利用率。通过实际案例演示长对话压缩、记忆精简、动态上下文加载等优化技巧,帮助开发者构建高效、低成本的 AI 应用。💰
1. 引言 - Token 限制的挑战
1.1 什么是 Token?
| 概念 | 说明 | 示例 |
|---|---|---|
| Token | AI 模型的基本处理单位 | "Hello" ≈ 1 token |
| 上下文窗口 | 模型一次能处理的最大 Token 数 | GPT-4: 128K tokens |
| Token 成本 | API 调用的计费单位 | $0.01/1K tokens |
1.2 Token 限制带来的挑战
长对话
Token 超限
截断历史
丢失上下文
AI 回复质量下降
大量记忆
加载慢
成本增加
响应延迟
1.3 优化目标
| 目标 | 说明 | 指标 |
|---|---|---|
| 控制成本 | 减少 Token 消耗 | 成本降低 30%+ |
| 保持质量 | 不影响回复质量 | 质量评分 > 90% |
| 提升速度 | 减少响应延迟 | 响应时间 < 3s |
| 保留关键 | 保留核心上下文 | 关键信息保留率 > 95% |
2. Token 计算原理
2.1 Token 计算规则
| 内容类型 | Token 估算 | 示例 |
|---|---|---|
| 英文单词 | 1 token/词 | "Hello world" = 2 tokens |
| 中文汉字 | 1-2 tokens/字 | "你好世界" ≈ 4-6 tokens |
| 代码 | 1 token/3-4字符 | def hello(): ≈ 3 tokens |
| 空格/标点 | 0.5-1 token | "Hello, world!" ≈ 4 tokens |
2.2 Token 计算工具
python
import tiktoken
def count_tokens(text, model="gpt-4"):
"""计算文本的 Token 数量"""
encoding = tiktoken.encoding_for_model(model)
return len(encoding.encode(text))
# 示例
text = "你好,这是一段测试文本"
token_count = count_tokens(text)
print(f"Token 数量: {token_count}")
2.3 各模型上下文限制
| 模型 | 上下文窗口 | 输入限制 | 输出限制 |
|---|---|---|---|
| GPT-4 Turbo | 128K | 128K | 4K |
| GPT-4 | 8K/32K | 8K/32K | 4K |
| GPT-3.5 Turbo | 16K | 16K | 4K |
| Claude 3 | 200K | 200K | 4K |
| 国产模型 | 4K-32K | 不等 | 不等 |
3. 上下文压缩技术
3.1 压缩策略概览
压缩策略
摘要压缩
提取关键信息
选择性加载
按需加载记忆
滑动窗口
保留最近N轮
语义去重
合并相似内容
减少 Token
3.2 摘要压缩
原理:将长文本压缩为简短摘要
python
def summarize_conversation(messages, max_tokens=500):
"""将对话历史压缩为摘要"""
# 提取关键信息
key_points = []
for msg in messages:
if is_important(msg):
key_points.append(extract_key_point(msg))
# 生成摘要
summary = generate_summary(key_points, max_tokens)
return summary
效果对比:
| 原始内容 | 压缩后 | 压缩率 |
|---|---|---|
| 10轮对话(5000 tokens) | 摘要(500 tokens) | 90% |
| 项目历史(3000 tokens) | 关键点(300 tokens) | 90% |
3.3 选择性加载
原理:只加载当前需要的记忆
偏好相关
项目相关
历史问题
通用问题
用户提问
分析问题类型
问题类型
加载用户偏好
加载项目上下文
加载问题记录
最小上下文
组合上下文
发送给模型
3.4 滑动窗口
原理:只保留最近 N 轮对话
python
def sliding_window(messages, window_size=10):
"""滑动窗口保留最近N轮对话"""
if len(messages) <= window_size:
return messages
# 保留系统消息
system_messages = [m for m in messages if m['role'] == 'system']
# 保留最近N轮对话
recent_messages = messages[-(window_size * 2):]
return system_messages + recent_messages
窗口大小建议:
| 场景 | 窗口大小 | 说明 |
|---|---|---|
| 简单问答 | 5轮 | 足够理解上下文 |
| 复杂任务 | 10轮 | 保留更多历史 |
| 长对话 | 20轮 | 需要更多上下文 |
3.5 语义去重
原理:合并语义相似的内容
python
def semantic_deduplicate(contents, threshold=0.9):
"""语义去重"""
unique = []
for content in contents:
is_duplicate = False
for existing in unique:
similarity = calculate_similarity(content, existing)
if similarity > threshold:
is_duplicate = True
break
if not is_duplicate:
unique.append(content)
return unique
4. OpenClaw 上下文管理
4.1 OpenClaw 上下文结构
OpenClaw 上下文组成
├── 系统提示词 (System Prompt)
│ ├── 角色定义
│ ├── 能力说明
│ └── 工具描述
├── 记忆内容 (Memory)
│ ├── MEMORY.md
│ └── 每日日志
├── 对话历史 (Conversation)
│ ├── 用户消息
│ └── AI 回复
└── 技能内容 (Skills)
├── SKILL.md
└── 参考文档
4.2 Token 分配策略
40% 20% 20% 10% 10% Token 分配比例 系统提示词 记忆内容 对话历史 技能内容 输出预留
4.3 动态上下文加载
python
class ContextManager:
def __init__(self, max_tokens=8000):
self.max_tokens = max_tokens
self.reserved_for_output = 1000
def build_context(self, user_message):
"""构建优化的上下文"""
available = self.max_tokens - self.reserved_for_output
context = []
# 1. 必须包含系统提示词
system_prompt = self.get_system_prompt()
context.append(system_prompt)
available -= count_tokens(system_prompt)
# 2. 选择性加载记忆
memory = self.load_relevant_memory(user_message, available * 0.3)
context.extend(memory)
available -= count_tokens(memory)
# 3. 加载相关技能
skills = self.load_relevant_skills(user_message, available * 0.3)
context.extend(skills)
available -= count_tokens(skills)
# 4. 剩余空间给对话历史
history = self.load_conversation_history(available)
context.extend(history)
return context
5. 实战优化案例
5.1 案例一:长对话压缩
场景:用户进行了 50 轮对话,Token 即将超限
优化前:
总 Token: 15000
- 系统提示词: 2000
- 对话历史: 12000
- 输出预留: 1000
优化后:
总 Token: 6000
- 系统提示词: 2000
- 对话摘要: 1000
- 最近10轮: 2000
- 输出预留: 1000
压缩代码:
python
def compress_long_conversation(messages, keep_recent=10):
"""压缩长对话"""
if len(messages) <= keep_recent * 2:
return messages
# 分离旧消息和最近消息
old_messages = messages[:-keep_recent * 2]
recent_messages = messages[-keep_recent * 2:]
# 生成旧消息摘要
summary = generate_summary(old_messages)
# 组合返回
return [
{"role": "system", "content": f"[历史摘要]\n{summary}"},
*recent_messages
]
5.2 案例二:记忆精简
场景:MEMORY.md 内容过多,影响加载速度
优化前:
markdown
# MEMORY.md (8000 tokens)
## 用户信息
(详细记录)
## 所有历史任务
(100+ 条任务记录)
## 所有决策记录
(50+ 条决策)
优化后:
markdown
# MEMORY.md (1500 tokens)
## 用户信息
- 姓名:张龙生
- 昵称:老大
## 当前项目
- 目标:100篇文章
- 进度:45%
## 用户偏好
- 表达风格:简洁
## 近期决策(最近10条)
- ...
## 归档索引
- 历史任务:见 archive/2026-Q1/
- 历史决策:见 archive/2026-Q1/
5.3 案例三:技能按需加载
场景:用户有多个技能,但每次只需要一个
优化策略:
python
def load_skill_on_demand(user_message, skills):
"""按需加载技能"""
# 分析用户意图
intent = analyze_intent(user_message)
# 匹配相关技能
relevant_skills = []
for skill in skills:
if is_relevant(intent, skill):
relevant_skills.append(skill)
# 只加载最相关的技能
if relevant_skills:
top_skill = rank_skills(relevant_skills)[0]
return load_skill(top_skill)
return None
6. 成本优化策略
6.1 成本计算
python
def calculate_cost(tokens, model="gpt-4"):
"""计算 API 调用成本"""
pricing = {
"gpt-4": {"input": 0.03, "output": 0.06}, # per 1K tokens
"gpt-3.5-turbo": {"input": 0.0015, "output": 0.002},
"claude-3": {"input": 0.015, "output": 0.075}
}
input_tokens = tokens['input']
output_tokens = tokens['output']
cost = (
input_tokens / 1000 * pricing[model]['input'] +
output_tokens / 1000 * pricing[model]['output']
)
return cost
6.2 成本优化技巧
| 技巧 | 说明 | 节省 |
|---|---|---|
| 使用更便宜的模型 | 简单任务用 GPT-3.5 | 95% |
| 压缩上下文 | 摘要替代完整历史 | 50-80% |
| 缓存结果 | 相同问题缓存回复 | 30-50% |
| 批量处理 | 合并多个请求 | 20-30% |
6.3 成本监控
python
class CostMonitor:
def __init__(self):
self.total_tokens = 0
self.total_cost = 0
self.requests = []
def log_request(self, input_tokens, output_tokens, model):
"""记录请求"""
cost = calculate_cost(
{'input': input_tokens, 'output': output_tokens},
model
)
self.total_tokens += input_tokens + output_tokens
self.total_cost += cost
self.requests.append({
'timestamp': datetime.now(),
'tokens': input_tokens + output_tokens,
'cost': cost
})
def get_report(self):
"""生成成本报告"""
return {
'total_tokens': self.total_tokens,
'total_cost': self.total_cost,
'avg_tokens_per_request': self.total_tokens / len(self.requests),
'avg_cost_per_request': self.total_cost / len(self.requests)
}
7. 高级优化技巧
7.1 分层上下文
分层上下文
核心层 - 始终加载
重要层 - 按需加载
扩展层 - 可选加载
系统提示词
用户核心信息
项目上下文
用户偏好
历史记录
详细文档
7.2 智能预测加载
python
def predict_needed_context(user_message, history):
"""预测需要的上下文"""
# 分析用户消息
entities = extract_entities(user_message)
intent = classify_intent(user_message)
# 预测相关上下文
predicted_context = []
# 如果提到项目,加载项目上下文
if 'project' in entities or '项目' in user_message:
predicted_context.append(load_project_context())
# 如果是问题,加载相关解决方案
if intent == 'question':
predicted_context.append(load_solutions(user_message))
return predicted_context
7.3 渐进式加载
python
def progressive_loading(user_message, max_tokens):
"""渐进式加载上下文"""
context = []
current_tokens = 0
# 优先级队列
priorities = [
(load_system_prompt, 1), # 最高优先级
(load_user_info, 2),
(load_project_context, 3),
(load_recent_history, 4),
(load_relevant_skills, 5),
(load_archived_memory, 6) # 最低优先级
]
for loader, priority in sorted(priorities, key=lambda x: x[1]):
content = loader()
content_tokens = count_tokens(content)
if current_tokens + content_tokens <= max_tokens:
context.append(content)
current_tokens += content_tokens
else:
break
return context
8. 常见问题与解决
Q1:压缩后信息丢失怎么办?
解决方案:
- 使用摘要而非直接删除
- 保留关键信息标记
- 建立信息索引便于检索
Q2:如何平衡质量和成本?
解决方案:
- 核心任务用高质量模型
- 简单任务用便宜模型
- 动态选择模型
Q3:上下文窗口太小怎么办?
解决方案:
- 使用支持更大窗口的模型
- 实现分块处理
- 使用 RAG 检索增强
9. 总结
9.1 核心要点
| 要点 | 说明 |
|---|---|
| 理解限制 | 了解模型的 Token 限制 |
| 压缩优先 | 优先使用压缩技术 |
| 按需加载 | 只加载必要的上下文 |
| 监控成本 | 持续监控 Token 消耗 |
9.2 优化清单
- 实现对话历史压缩
- 精简 MEMORY.md 内容
- 按需加载技能
- 监控 Token 消耗
- 选择合适的模型