# 错误修复:LLM summarization aborted 错误与重试机制
**修复时间**:2025-12-04
**错误级别**:High
## 问题详情
### 错误信息
```
[2025-12-04T08:12:24.543Z] [ERROR] LLM summarization failed {"error":"aborted"}
```
### 错误类型
- 类型:网络/API 调用错误
- 状态:请求被中止
- 影响功能:web_search、fetch_and_summarize、batch_fetch 工具的 LLM 总结功能
## 解决方案
### 根本原因
"aborted" 错误通常由以下原因导致:
1. **请求超时**:默认 60 秒超时对大内容处理不够
2. **网络不稳定**:间歇性网络连接问题
3. **API 服务器问题**:LLM 服务临时不可用或负载过高
4. **并发限制**:超过 API 的并发请求限制
5. **大内容处理**:处理大量网页内容时响应时间过长
### 修改文件
- `src/services/summarizer.ts`:实现智能重试机制和错误分类处理
- `src/utils/config.ts`:添加超时和重试配置支持
- `src/types/index.ts`:更新类型定义
- `.env.example`:添加新的配置选项示例
### 代码变更
#### 1. 重试机制实现
```typescript
// 修改前:简单的错误处理
try {
const response = await axios.post(/* ... */);
// 处理响应
} catch (error) {
if (axios.isAxiosError(error)) {
const message = error.response?.data?.error?.message || error.message;
throw new Error(`LLM summarization failed: ${message}`);
}
throw error;
}
// 修改后:智能重试机制
async summarize(request: SummaryRequest): Promise<SummaryResponse> {
const maxRetries = this.config.maxRetries || 2;
for (let attempt = 1; attempt <= maxRetries + 1; attempt++) {
try {
// API 调用
return result;
} catch (error) {
// 错误分类处理
if (shouldRetry(error) && attempt <= maxRetries) {
await this.sleep(attempt * 2000); // 指数退避
continue;
}
throw error;
}
}
}
```
#### 2. 智能错误分类
```typescript
// 对于某些错误,不应该重试
if (statusCode === 401 || statusCode === 403) {
// 认证错误,重试无意义
throw new Error(`LLM summarization failed: Authentication error (${statusCode})`);
}
// 对于 aborted 错误或网络错误,重试
if (error.code === 'ECONNABORTED' || error.code === 'ECONNRESET' ||
error.message.includes('aborted') || error.message.includes('timeout')) {
// 实施重试逻辑
}
```
#### 3. 配置化超时和重试
```typescript
export interface SummarizerConfig {
apiKey: string;
baseUrl: string;
model: string;
maxTokens: number;
timeout?: number; // 新增:超时时间配置
maxRetries?: number; // 新增:重试次数配置
}
```
## 技术特性
### 1. 指数退避重试
- 第一次重试:等待 2 秒
- 第二次重试:等待 4 秒
- 可配置最大重试次数(默认 2 次)
### 2. 智能错误分类
- **可重试错误**:网络超时、连接中断、aborted 错误
- **不可重试错误**:认证失败 (401/403)、请求格式错误 (400)
- **服务器错误**:5xx 错误会重试
### 3. 增强的超时配置
- 默认超时:120 秒(从 60 秒增加)
- 可通过 `SUMMARY_TIMEOUT` 环境变量配置
- 支持不同场景下的灵活超时设置
### 4. 详细的日志记录
```typescript
logger.info('Starting LLM summarization', {
contentLength: content.length,
model: this.config.model,
maxRetries,
});
logger.warn('LLM summarization attempt failed', {
attempt,
totalAttempts: maxRetries + 1,
statusCode,
errorMessage,
errorType: error.code,
});
```
## 配置选项
### 新增环境变量
```env
# LLM 总结服务配置
SUMMARY_TIMEOUT=120000 # 超时时间(毫秒),默认 120 秒
SUMMARY_MAX_RETRIES=2 # 最大重试次数,默认 2 次
```
### 使用建议
- **稳定网络环境**:保持默认配置(120秒超时,2次重试)
- **不稳定网络**:增加超时时间到 180-240 秒
- **高性能要求**:减少重试次数到 1 次,增加超时到 60 秒
## 验证结果
- [x] 代码检查通过(`npm run typecheck`)
- [x] 重试机制测试成功
- [x] 错误分类处理正确
- [x] 超时配置生效
- [x] 日志记录详细准确
## 最佳实践
### 1. 监控重试情况
```bash
# 查看重试日志
grep "Retrying LLM summarization" /path/to/logfile
```
### 2. 性能优化
- 根据网络状况调整超时时间
- 监控重试频率,过高重试可能表明网络或 API 问题
- 定期检查 API key 和配额使用情况
### 3. 错误处理
```typescript
try {
const result = await summarizer.summarize(content);
} catch (error) {
if (error.message.includes('Authentication error')) {
// 处理认证问题
} else if (error.message.includes('Bad request')) {
// 处理请求格式问题
} else {
// 处理其他错误(可能是网络问题)
}
}
```
## 注意事项
- 重试机制会增加总响应时间,需在性能和可靠性间平衡
- 某些 API 可能对重试频率有限制,需遵守服务提供商的规则
- 大量并发请求时,建议实施请求限流机制
- 定期监控重试成功率,优化配置参数