⚡ 为什么需要性能优化?
凌晨3点27分,我盯着终端里那个冷启动需要9.8秒的Agent,突然意识到一个问题:时间就是Token,Token就是钱。
就像王家卫电影里说的:"有些Agent,还没开始工作,就已经老了。" 但经过优化,我们可以让冷启动时间从9.8秒降到1.9秒,性能提升5.1倍。
5.1x
性能提升倍数
9.8s → 1.9s
冷启动时间优化
🎯 优化策略一:模型选择
1. 根据任务选择模型
不是所有任务都需要GPT-4。就像你不会用火箭发动机去骑自行车。
💡 模型选择原则
- 简单任务(分类、提取):使用 GPT-3.5 或 Claude Instant,成本降低80%
- 中等任务(翻译、总结):使用 GPT-4-turbo 或 Claude 2.1
- 复杂任务(推理、创作):使用 GPT-4o 或 Claude 3 Opus
// 动态选择模型
const selectModel = (taskComplexity) => {
switch(taskComplexity) {
case 'simple':
return 'gpt-3.5-turbo';
case 'medium':
return 'gpt-4-turbo';
case 'complex':
return 'gpt-4o';
default:
return 'gpt-4-turbo';
}
};
const selectModel = (taskComplexity) => {
switch(taskComplexity) {
case 'simple':
return 'gpt-3.5-turbo';
case 'medium':
return 'gpt-4-turbo';
case 'complex':
return 'gpt-4o';
default:
return 'gpt-4-turbo';
}
};
2. 使用本地模型
对于高频简单任务,使用本地模型可以大幅降低成本:
# 安装 Ollama(本地模型运行器)
curl -fsSL https://ollama.com/install.sh | sh
# 下载模型
ollama pull llama3.2:3b
# 在 OpenClaw 中配置
openclaw config set model.local.endpoint http://localhost:11434
openclaw config set model.local.model llama3.2:3b
curl -fsSL https://ollama.com/install.sh | sh
# 下载模型
ollama pull llama3.2:3b
# 在 OpenClaw 中配置
openclaw config set model.local.endpoint http://localhost:11434
openclaw config set model.local.model llama3.2:3b
📦 优化策略二:缓存策略
1. 响应缓存
相同的输入应该得到相同的输出,那为什么还要重新计算?
const { Skill } = require('@openclaw/core');
const { LRUCache } = require('lru-cache');
class CachedSkill extends Skill {
constructor() {
super();
this.cache = new LRUCache({
max: 100,
ttl: 1000 * 60 * 5 // 5分钟
});
}
async execute(options) {
const cacheKey = JSON.stringify(options);
// 检查缓存
if (this.cache.has(cacheKey)) {
this.logger.info('从缓存返回结果');
return this.cache.get(cacheKey);
}
// 执行计算
const result = await this.compute(options);
// 存入缓存
this.cache.set(cacheKey, result);
return result;
}
}
const { LRUCache } = require('lru-cache');
class CachedSkill extends Skill {
constructor() {
super();
this.cache = new LRUCache({
max: 100,
ttl: 1000 * 60 * 5 // 5分钟
});
}
async execute(options) {
const cacheKey = JSON.stringify(options);
// 检查缓存
if (this.cache.has(cacheKey)) {
this.logger.info('从缓存返回结果');
return this.cache.get(cacheKey);
}
// 执行计算
const result = await this.compute(options);
// 存入缓存
this.cache.set(cacheKey, result);
return result;
}
}
2. 语义缓存(Semantic Cache)
即使输入不完全相同,但语义相似的问题也应该命中缓存:
const { SemanticCache } = require('@openclaw/cache');
class SmartSkill extends Skill {
async init() {
this.semCache = new SemanticCache({
similarityThreshold: 0.95,
maxEntries: 1000
});
}
async execute(options) {
const cached = await this.semCache.find(options.input);
if (cached) {
return cached;
}
const result = await this.process(options);
await this.semCache.add(options.input, result);
return result;
}
}
class SmartSkill extends Skill {
async init() {
this.semCache = new SemanticCache({
similarityThreshold: 0.95,
maxEntries: 1000
});
}
async execute(options) {
const cached = await this.semCache.find(options.input);
if (cached) {
return cached;
}
const result = await this.process(options);
await this.semCache.add(options.input, result);
return result;
}
}
🔄 优化策略三:并发控制
1. 批量处理
当你需要调用100次API时,不要一个一个调,要批量调:
class BatchProcessor {
async processBatch(items, batchSize = 10) {
const results = [];
for (let i = 0; i < items.length; i += batchSize) {
const batch = items.slice(i, i + batchSize);
const batchResults = await Promise.all(
batch.map(item => this.processItem(item))
);
results.push(...batchResults);
}
return results;
}
}
async processBatch(items, batchSize = 10) {
const results = [];
for (let i = 0; i < items.length; i += batchSize) {
const batch = items.slice(i, i + batchSize);
const batchResults = await Promise.all(
batch.map(item => this.processItem(item))
);
results.push(...batchResults);
}
return results;
}
}
2. 并发限制
无限制的并发会导致资源耗尽,要控制并发数:
const { pLimit } = require('p-limit');
class ConcurrentProcessor {
async processWithConcurrency(items, concurrency = 5) {
const limit = pLimit(concurrency);
const tasks = items.map(item =>
limit(() => this.processItem(item))
);
return await Promise.all(tasks);
}
}
class ConcurrentProcessor {
async processWithConcurrency(items, concurrency = 5) {
const limit = pLimit(concurrency);
const tasks = items.map(item =>
limit(() => this.processItem(item))
);
return await Promise.all(tasks);
}
}
💰 优化策略四:Token优化
1. 提示词压缩
冗长的提示词浪费Token,要学会精简:
✅ 提示词优化技巧
- 删除冗余词汇("请"、"谢谢"等礼貌用语)
- 使用简洁的指令格式
- 避免重复说明
- 使用占位符代替重复内容
// 优化前
const prompt1 = `
请你帮我分析一下这段文本的情感。
我会提供一段文本,然后你需要判断它是正面、负面还是中性。
请仔细分析,然后给出你的判断。
谢谢!
`;
// 优化后
const prompt2 = `分析情感: {text}\n输出: 正面/负面/中性`;
// Token 减少: ~100 → ~20 (减少80%)
const prompt1 = `
请你帮我分析一下这段文本的情感。
我会提供一段文本,然后你需要判断它是正面、负面还是中性。
请仔细分析,然后给出你的判断。
谢谢!
`;
// 优化后
const prompt2 = `分析情感: {text}\n输出: 正面/负面/中性`;
// Token 减少: ~100 → ~20 (减少80%)
2. 上下文管理
上下文窗口有限,要学会管理:
class ContextManager {
constructor(maxTokens = 4096) {
this.maxTokens = maxTokens;
this.messages = [];
}
addMessage(message) {
this.messages.push(message);
this.trimIfNeeded();
}
trimIfNeeded() {
const totalTokens = this.countTokens(this.messages);
while (totalTokens > this.maxTokens && this.messages.length > 1) {
// 删除最旧的消息(保留系统消息)
if (this.messages[1].role !== 'system') {
this.messages.shift();
}
}
}
}
constructor(maxTokens = 4096) {
this.maxTokens = maxTokens;
this.messages = [];
}
addMessage(message) {
this.messages.push(message);
this.trimIfNeeded();
}
trimIfNeeded() {
const totalTokens = this.countTokens(this.messages);
while (totalTokens > this.maxTokens && this.messages.length > 1) {
// 删除最旧的消息(保留系统消息)
if (this.messages[1].role !== 'system') {
this.messages.shift();
}
}
}
}
📊 性能监控
优化不是一次性的,需要持续监控:
const { Skill } = require('@openclaw/core');
class MonitoredSkill extends Skill {
async init() {
this.metrics = {
requests: 0,
totalTime: 0,
totalTokens: 0,
errors: 0
};
}
async execute(options) {
const startTime = Date.now();
try {
const result = await super.execute(options);
// 记录指标
this.metrics.requests++;
this.metrics.totalTime += Date.now() - startTime;
this.metrics.totalTokens += result.tokens || 0;
return result;
} catch (error) {
this.metrics.errors++;
throw error;
}
}
getStats() {
return {
avgResponseTime: this.metrics.totalTime / this.metrics.requests,
avgTokensPerRequest: this.metrics.totalTokens / this.metrics.requests,
errorRate: this.metrics.errors / this.metrics.requests
};
}
}
class MonitoredSkill extends Skill {
async init() {
this.metrics = {
requests: 0,
totalTime: 0,
totalTokens: 0,
errors: 0
};
}
async execute(options) {
const startTime = Date.now();
try {
const result = await super.execute(options);
// 记录指标
this.metrics.requests++;
this.metrics.totalTime += Date.now() - startTime;
this.metrics.totalTokens += result.tokens || 0;
return result;
} catch (error) {
this.metrics.errors++;
throw error;
}
}
getStats() {
return {
avgResponseTime: this.metrics.totalTime / this.metrics.requests,
avgTokensPerRequest: this.metrics.totalTokens / this.metrics.requests,
errorRate: this.metrics.errors / this.metrics.requests
};
}
}
🎯 实战案例:优化前后对比
案例:文档处理技能
| 指标 | 优化前 | 优化后 | 提升 |
|---|---|---|---|
| 冷启动时间 | 9.8s | 1.9s | 5.1x |
| 平均响应时间 | 3.2s | 0.8s | 4x |
| Token消耗(每次) | 2,500 | 800 | -68% |
| 并发处理能力 | 5 req/s | 25 req/s | 5x |