Skip to content

最佳实践

本章节提供使用XAI-SDK开发AI应用的最佳实践和性能优化技巧。

🚀 性能优化

1. 请求优化

批量处理

当需要处理多个相似请求时,使用批量处理可以显著提高效率:

javascript
// ❌ 不推荐:逐个处理
const results = [];
for (const item of items) {
  const result = await sdk.chat(`处理:${item}`);
  results.push(result);
}

// ✅ 推荐:批量处理
const messages = items.map(item => `处理:${item}`);
const results = await sdk.batchChat(messages);

并发控制

javascript
// 控制并发数量,避免API限制
const pLimit = require('p-limit');
const limit = pLimit(5); // 最多5个并发请求

const promises = items.map(item => limit(() => sdk.chat(`处理:${item}`)));

const results = await Promise.all(promises);

2. 缓存策略

响应缓存

javascript
// 启用智能缓存
const sdk = new XAI_SDK({
  apiKey: process.env.OPENAI_API_KEY,
  provider: 'openai',
  cache: {
    enabled: true,
    ttl: 3600, // 1小时
    maxSize: 1000,
    // 自定义缓存键生成
    keyGenerator: (message, options) => {
      return `${message}-${JSON.stringify(options)}`;
    },
  },
});

本地缓存实现

javascript
class LocalCache {
  constructor(maxSize = 100) {
    this.cache = new Map();
    this.maxSize = maxSize;
  }

  get(key) {
    const item = this.cache.get(key);
    if (item && item.expires > Date.now()) {
      return item.value;
    }
    this.cache.delete(key);
    return null;
  }

  set(key, value, ttl = 3600000) {
    if (this.cache.size >= this.maxSize) {
      const firstKey = this.cache.keys().next().value;
      this.cache.delete(firstKey);
    }

    this.cache.set(key, {
      value,
      expires: Date.now() + ttl,
    });
  }
}

const cache = new LocalCache();

// 使用缓存包装SDK调用
const cachedChat = async message => {
  const cacheKey = `chat:${message}`;
  const cached = cache.get(cacheKey);

  if (cached) {
    return cached;
  }

  const result = await sdk.chat(message);
  cache.set(cacheKey, result);
  return result;
};

3. 连接管理

javascript
// 配置连接池
const sdk = new XAI_SDK({
  apiKey: process.env.OPENAI_API_KEY,
  provider: 'openai',
  pool: {
    maxConnections: 10,
    keepAlive: true,
    timeout: 30000,
    retryDelay: 1000,
  },
});

// 优雅关闭
process.on('SIGTERM', async () => {
  console.log('正在关闭SDK连接...');
  await sdk.close();
  process.exit(0);
});

🛡️ 错误处理

1. 重试机制

javascript
class RetryableSDK {
  constructor(sdk, options = {}) {
    this.sdk = sdk;
    this.maxRetries = options.maxRetries || 3;
    this.baseDelay = options.baseDelay || 1000;
    this.maxDelay = options.maxDelay || 10000;
  }

  async chatWithRetry(message, options = {}) {
    let lastError;

    for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
      try {
        return await this.sdk.chat(message, options);
      } catch (error) {
        lastError = error;

        // 不重试的错误类型
        if (this.isNonRetryableError(error)) {
          throw error;
        }

        if (attempt < this.maxRetries) {
          const delay = Math.min(
            this.baseDelay * Math.pow(2, attempt),
            this.maxDelay
          );

          console.log(
            `重试 ${attempt + 1}/${this.maxRetries},${delay}ms后重试`
          );
          await this.sleep(delay);
        }
      }
    }

    throw lastError;
  }

  isNonRetryableError(error) {
    const nonRetryableCodes = [
      'INVALID_API_KEY',
      'INSUFFICIENT_QUOTA',
      'INVALID_REQUEST',
    ];
    return nonRetryableCodes.includes(error.code);
  }

  sleep(ms) {
    return new Promise(resolve => setTimeout(resolve, ms));
  }
}

// 使用示例
const retryableSDK = new RetryableSDK(sdk, {
  maxRetries: 3,
  baseDelay: 1000,
});

try {
  const result = await retryableSDK.chatWithRetry('你好');
  console.log(result);
} catch (error) {
  console.error('最终失败:', error.message);
}

2. 错误分类处理

javascript
class ErrorHandler {
  static handle(error) {
    switch (error.code) {
      case 'RATE_LIMIT_EXCEEDED':
        return this.handleRateLimit(error);
      case 'NETWORK_ERROR':
        return this.handleNetworkError(error);
      case 'INVALID_API_KEY':
        return this.handleAuthError(error);
      case 'INSUFFICIENT_QUOTA':
        return this.handleQuotaError(error);
      default:
        return this.handleUnknownError(error);
    }
  }

  static handleRateLimit(error) {
    const retryAfter = error.retryAfter || 60;
    console.warn(`请求频率限制,${retryAfter}秒后重试`);
    return { shouldRetry: true, delay: retryAfter * 1000 };
  }

  static handleNetworkError(error) {
    console.warn('网络错误,将重试');
    return { shouldRetry: true, delay: 2000 };
  }

  static handleAuthError(error) {
    console.error('API密钥无效,请检查配置');
    return { shouldRetry: false };
  }

  static handleQuotaError(error) {
    console.error('配额不足,请检查账户余额');
    return { shouldRetry: false };
  }

  static handleUnknownError(error) {
    console.error('未知错误:', error.message);
    return { shouldRetry: false };
  }
}

// 使用错误处理器
const chatWithErrorHandling = async message => {
  try {
    return await sdk.chat(message);
  } catch (error) {
    const handling = ErrorHandler.handle(error);

    if (handling.shouldRetry) {
      await new Promise(resolve => setTimeout(resolve, handling.delay));
      return chatWithErrorHandling(message); // 递归重试
    }

    throw error;
  }
};

🔒 安全最佳实践

1. API密钥管理

javascript
// ✅ 推荐:使用环境变量
const sdk = new XAI_SDK({
  apiKey: process.env.OPENAI_API_KEY,
  provider: 'openai',
});

// ❌ 不推荐:硬编码API密钥
const sdk = new XAI_SDK({
  apiKey: 'sk-xxxxxxxxxxxxxxxx', // 永远不要这样做!
  provider: 'openai',
});

// 密钥验证
if (!process.env.OPENAI_API_KEY) {
  throw new Error('OPENAI_API_KEY环境变量未设置');
}

2. 输入验证和清理

javascript
class InputValidator {
  static sanitize(input) {
    if (typeof input !== 'string') {
      throw new Error('输入必须是字符串');
    }

    // 移除潜在的恶意内容
    return input
      .trim()
      .slice(0, 4000) // 限制长度
      .replace(/[<>"'&]/g, ''); // 移除HTML特殊字符
  }

  static validateMessage(message) {
    if (!message || message.length === 0) {
      throw new Error('消息不能为空');
    }

    if (message.length > 4000) {
      throw new Error('消息长度不能超过4000字符');
    }

    // 检查敏感内容
    const sensitivePatterns = [
      /password/i,
      /api[_-]?key/i,
      /secret/i,
      /token/i,
    ];

    for (const pattern of sensitivePatterns) {
      if (pattern.test(message)) {
        console.warn('检测到可能的敏感信息');
        break;
      }
    }

    return true;
  }
}

// 安全的聊天函数
const secureChat = async rawMessage => {
  try {
    InputValidator.validateMessage(rawMessage);
    const sanitizedMessage = InputValidator.sanitize(rawMessage);
    return await sdk.chat(sanitizedMessage);
  } catch (error) {
    console.error('输入验证失败:', error.message);
    throw error;
  }
};

3. 访问控制

javascript
class AccessControl {
  constructor() {
    this.rateLimits = new Map();
    this.maxRequestsPerMinute = 60;
  }

  checkRateLimit(userId) {
    const now = Date.now();
    const userRequests = this.rateLimits.get(userId) || [];

    // 清理过期的请求记录
    const validRequests = userRequests.filter(
      timestamp => now - timestamp < 60000
    );

    if (validRequests.length >= this.maxRequestsPerMinute) {
      throw new Error('请求频率过高,请稍后重试');
    }

    validRequests.push(now);
    this.rateLimits.set(userId, validRequests);

    return true;
  }

  async authorizedChat(userId, message) {
    this.checkRateLimit(userId);
    return await secureChat(message);
  }
}

const accessControl = new AccessControl();

// 使用访问控制
app.post('/chat', async (req, res) => {
  try {
    const { userId, message } = req.body;
    const result = await accessControl.authorizedChat(userId, message);
    res.json({ success: true, result });
  } catch (error) {
    res.status(429).json({ success: false, error: error.message });
  }
});

📊 监控和日志

1. 性能监控

javascript
class PerformanceMonitor {
  constructor() {
    this.metrics = {
      totalRequests: 0,
      successfulRequests: 0,
      failedRequests: 0,
      totalResponseTime: 0,
      averageResponseTime: 0,
    };
  }

  async monitoredChat(message) {
    const startTime = Date.now();
    this.metrics.totalRequests++;

    try {
      const result = await sdk.chat(message);
      this.metrics.successfulRequests++;

      const responseTime = Date.now() - startTime;
      this.metrics.totalResponseTime += responseTime;
      this.metrics.averageResponseTime =
        this.metrics.totalResponseTime / this.metrics.successfulRequests;

      console.log(`请求成功,耗时: ${responseTime}ms`);
      return result;
    } catch (error) {
      this.metrics.failedRequests++;
      console.error(`请求失败,耗时: ${Date.now() - startTime}ms`);
      throw error;
    }
  }

  getStats() {
    return {
      ...this.metrics,
      successRate: this.metrics.successfulRequests / this.metrics.totalRequests,
      errorRate: this.metrics.failedRequests / this.metrics.totalRequests,
    };
  }

  logStats() {
    const stats = this.getStats();
    console.log('性能统计:', {
      总请求数: stats.totalRequests,
      成功率: `${(stats.successRate * 100).toFixed(2)}%`,
      平均响应时间: `${stats.averageResponseTime.toFixed(2)}ms`,
    });
  }
}

const monitor = new PerformanceMonitor();

// 定期输出统计信息
setInterval(() => {
  monitor.logStats();
}, 60000); // 每分钟输出一次

2. 结构化日志

javascript
const winston = require('winston');

const logger = winston.createLogger({
  level: 'info',
  format: winston.format.combine(
    winston.format.timestamp(),
    winston.format.errors({ stack: true }),
    winston.format.json()
  ),
  transports: [
    new winston.transports.File({ filename: 'error.log', level: 'error' }),
    new winston.transports.File({ filename: 'combined.log' }),
    new winston.transports.Console({
      format: winston.format.simple(),
    }),
  ],
});

class LoggingSDK {
  constructor(sdk) {
    this.sdk = sdk;
  }

  async chat(message, options = {}) {
    const requestId = this.generateRequestId();
    const startTime = Date.now();

    logger.info('开始处理请求', {
      requestId,
      message: message.substring(0, 100), // 只记录前100个字符
      options,
    });

    try {
      const result = await this.sdk.chat(message, options);
      const duration = Date.now() - startTime;

      logger.info('请求处理成功', {
        requestId,
        duration,
        responseLength: result.length,
      });

      return result;
    } catch (error) {
      const duration = Date.now() - startTime;

      logger.error('请求处理失败', {
        requestId,
        duration,
        error: error.message,
        stack: error.stack,
      });

      throw error;
    }
  }

  generateRequestId() {
    return Math.random().toString(36).substring(2, 15);
  }
}

const loggingSDK = new LoggingSDK(sdk);

🧪 测试策略

1. 单元测试

javascript
const { jest } = require('@jest/globals');

// 模拟SDK
const mockSDK = {
  chat: jest.fn(),
};

describe('ChatService', () => {
  beforeEach(() => {
    mockSDK.chat.mockClear();
  });

  test('应该正确处理正常响应', async () => {
    mockSDK.chat.mockResolvedValue('测试响应');

    const service = new ChatService(mockSDK);
    const result = await service.processMessage('测试消息');

    expect(result).toBe('测试响应');
    expect(mockSDK.chat).toHaveBeenCalledWith('测试消息');
  });

  test('应该正确处理错误', async () => {
    const error = new Error('API错误');
    mockSDK.chat.mockRejectedValue(error);

    const service = new ChatService(mockSDK);

    await expect(service.processMessage('测试消息')).rejects.toThrow('API错误');
  });
});

2. 集成测试

javascript
describe('SDK集成测试', () => {
  let sdk;

  beforeAll(() => {
    sdk = new XAI_SDK({
      apiKey: process.env.TEST_API_KEY,
      provider: 'openai',
    });
  });

  afterAll(async () => {
    await sdk.close();
  });

  test('应该能够进行基础对话', async () => {
    const response = await sdk.chat('你好');
    expect(response).toBeTruthy();
    expect(typeof response).toBe('string');
  }, 10000); // 10秒超时

  test('应该能够处理流式响应', async () => {
    const chunks = [];
    const stream = sdk.streamChat('计数到5');

    for await (const chunk of stream) {
      chunks.push(chunk);
    }

    expect(chunks.length).toBeGreaterThan(0);
  }, 15000);
});

🚀 部署最佳实践

1. 环境配置

javascript
// config/production.js
module.exports = {
  sdk: {
    apiKey: process.env.OPENAI_API_KEY,
    provider: 'openai',
    model: 'gpt-3.5-turbo',
    timeout: 30000,
    retries: 3,
    cache: {
      enabled: true,
      ttl: 3600,
      maxSize: 1000,
    },
    pool: {
      maxConnections: 20,
      keepAlive: true,
    },
  },
  logging: {
    level: 'info',
    format: 'json',
  },
  monitoring: {
    enabled: true,
    interval: 60000,
  },
};

// config/development.js
module.exports = {
  sdk: {
    apiKey: process.env.OPENAI_API_KEY,
    provider: 'openai',
    model: 'gpt-3.5-turbo',
    timeout: 10000,
    debug: true,
  },
  logging: {
    level: 'debug',
    format: 'simple',
  },
};

2. 健康检查

javascript
class HealthChecker {
  constructor(sdk) {
    this.sdk = sdk;
  }

  async checkHealth() {
    const checks = {
      sdk: await this.checkSDK(),
      memory: this.checkMemory(),
      uptime: process.uptime(),
    };

    const isHealthy = Object.values(checks).every(check =>
      typeof check === 'object' ? check.status === 'ok' : check
    );

    return {
      status: isHealthy ? 'healthy' : 'unhealthy',
      checks,
      timestamp: new Date().toISOString(),
    };
  }

  async checkSDK() {
    try {
      const startTime = Date.now();
      await this.sdk.chat('健康检查');
      const responseTime = Date.now() - startTime;

      return {
        status: 'ok',
        responseTime,
      };
    } catch (error) {
      return {
        status: 'error',
        error: error.message,
      };
    }
  }

  checkMemory() {
    const usage = process.memoryUsage();
    const totalMB = Math.round(usage.heapTotal / 1024 / 1024);
    const usedMB = Math.round(usage.heapUsed / 1024 / 1024);

    return {
      status: usedMB < 500 ? 'ok' : 'warning', // 500MB阈值
      totalMB,
      usedMB,
      usage: `${usedMB}/${totalMB}MB`,
    };
  }
}

// Express健康检查端点
app.get('/health', async (req, res) => {
  const healthChecker = new HealthChecker(sdk);
  const health = await healthChecker.checkHealth();

  const statusCode = health.status === 'healthy' ? 200 : 503;
  res.status(statusCode).json(health);
});

🔧 故障排除

常见问题和解决方案

1. API密钥问题

bash
# 错误:INVALID_API_KEY
# 解决方案:
# 1. 检查环境变量
echo $OPENAI_API_KEY

# 2. 验证密钥格式
# OpenAI密钥格式:sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# 3. 检查密钥权限和配额

2. 网络连接问题

javascript
// 配置代理
const sdk = new XAI_SDK({
  apiKey: process.env.OPENAI_API_KEY,
  provider: 'openai',
  proxy: {
    host: 'proxy.company.com',
    port: 8080,
    auth: {
      username: 'user',
      password: 'pass',
    },
  },
});

// 配置超时
const sdk = new XAI_SDK({
  apiKey: process.env.OPENAI_API_KEY,
  provider: 'openai',
  timeout: 60000, // 60秒
  retries: 5,
});

3. 内存泄漏问题

javascript
// 定期清理缓存
setInterval(() => {
  sdk.clearCache();
  if (global.gc) {
    global.gc();
  }
}, 300000); // 每5分钟清理一次

// 监控内存使用
setInterval(() => {
  const usage = process.memoryUsage();
  console.log('内存使用:', {
    rss: Math.round(usage.rss / 1024 / 1024) + 'MB',
    heapTotal: Math.round(usage.heapTotal / 1024 / 1024) + 'MB',
    heapUsed: Math.round(usage.heapUsed / 1024 / 1024) + 'MB',
  });
}, 60000); // 每分钟检查一次

📈 性能基准

推荐配置

场景并发数超时时间缓存TTL重试次数
开发环境1-510s1h2
测试环境5-1030s30m3
生产环境10-5060s1h5
高并发50-10030s2h3

性能优化检查清单

  • [ ] 启用响应缓存
  • [ ] 配置合适的连接池大小
  • [ ] 实现请求重试机制
  • [ ] 使用批量处理
  • [ ] 监控内存使用
  • [ ] 设置合理的超时时间
  • [ ] 实现优雅关闭
  • [ ] 配置日志记录
  • [ ] 添加健康检查
  • [ ] 实现错误处理

🤝 社区贡献

贡献指南

  1. 报告问题

    • 使用GitHub Issues报告bug
    • 提供详细的复现步骤
    • 包含环境信息和错误日志
  2. 提交代码

    • Fork项目并创建特性分支
    • 遵循代码规范
    • 添加测试用例
    • 更新文档
  3. 改进文档

    • 修正错误和不准确的信息
    • 添加使用示例
    • 翻译文档

开发环境设置

bash
# 克隆项目
git clone https://github.com/xai-sdk/xai-sdk.git
cd xai-sdk

# 安装依赖
npm install

# 运行测试
npm test

# 构建项目
npm run build

# 启动开发服务器
npm run dev

通过遵循这些最佳实践,您可以构建出高性能、可靠且安全的AI应用。如果您有任何问题或建议,欢迎参与社区讨论!

Released under the MIT License.