跳到主要内容

AI API集成与调用技巧

📖 概述

本文深入探讨AI API的集成策略和调用技巧,涵盖主流AI服务的接入方法、最佳实践、性能优化、错误处理等核心内容。通过实战案例和代码示例,帮助开发者掌握高效、稳定、安全的AI API集成技术。

🌐 主流AI API服务对比

服务提供商全景

提供商主要服务定价模式特色功能适用场景
OpenAIGPT系列、DALL-E、Whisper按Token计费强大的生成能力通用AI应用
AnthropicClaude系列按Token计费安全性、长上下文企业级应用
GoogleGemini、PaLM按请求计费多模态能力搜索、分析
MicrosoftAzure OpenAI按Token计费企业级部署企业集成
百度文心一言按调用计费中文优化中文应用
阿里云通义千问按Token计费云服务集成阿里生态
腾讯混元大模型按调用计费腾讯生态社交、游戏

API能力矩阵

功能类型OpenAIAnthropicGoogle百度阿里云腾讯
文本生成✅ GPT-4✅ Claude-3✅ Gemini✅ 文心✅ 通义✅ 混元
代码生成✅ Codex✅ Claude✅ Gemini✅ 支持✅ 支持✅ 支持
图像生成✅ DALL-E✅ Imagen✅ 支持✅ 支持✅ 支持
语音识别✅ Whisper✅ Speech✅ 支持✅ 支持✅ 支持
多模态✅ GPT-4V✅ Claude-3✅ Gemini✅ 支持✅ 支持✅ 支持
函数调用✅ 支持✅ 工具使用✅ 支持✅ 支持✅ 支持✅ 支持

🔧 统一API调用框架

抽象API客户端

const axios = require('axios');
const EventEmitter = require('events');
const crypto = require('crypto');

// API提供商配置
const API_CONFIGS = {
openai: {
baseURL: 'https://api.openai.com/v1',
headers: (apiKey) => ({
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
}),
models: {
'gpt-4': { maxTokens: 8192, costPer1K: 0.03 },
'gpt-3.5-turbo': { maxTokens: 4096, costPer1K: 0.002 },
'dall-e-3': { type: 'image', costPerImage: 0.04 }
}
},
anthropic: {
baseURL: 'https://api.anthropic.com/v1',
headers: (apiKey) => ({
'x-api-key': apiKey,
'Content-Type': 'application/json',
'anthropic-version': '2023-06-01'
}),
models: {
'claude-3-opus-20240229': { maxTokens: 200000, costPer1K: 0.015 },
'claude-3-sonnet-20240229': { maxTokens: 200000, costPer1K: 0.003 }
}
},
google: {
baseURL: 'https://generativelanguage.googleapis.com/v1beta',
headers: (apiKey) => ({
'Content-Type': 'application/json'
}),
models: {
'gemini-pro': { maxTokens: 30720, costPer1K: 0.0005 },
'gemini-pro-vision': { maxTokens: 16384, costPer1K: 0.0025 }
}
},
baidu: {
baseURL: 'https://aip.baidubce.com/rpc/2.0/ai_custom/v1',
headers: (accessToken) => ({
'Content-Type': 'application/json'
}),
models: {
'ernie-bot': { maxTokens: 2048, costPer1K: 0.008 },
'ernie-bot-turbo': { maxTokens: 2048, costPer1K: 0.003 }
}
}
};

class UniversalAIClient extends EventEmitter {
constructor(config = {}) {
super();

this.config = {
timeout: 30000,
maxRetries: 3,
retryDelay: 1000,
enableMetrics: true,
enableCache: true,
cacheExpiry: 3600000, // 1小时
rateLimits: {
openai: { rpm: 3500, tpm: 90000 },
anthropic: { rpm: 1000, tpm: 100000 },
google: { rpm: 60, tpm: 32000 }
},
...config
};

this.clients = new Map();
this.cache = new Map();
this.metrics = {
requests: 0,
successes: 0,
errors: 0,
totalCost: 0,
cacheHits: 0,
responseTime: []
};

this.rateLimiters = new Map();
this.initializeClients();
this.setupRateLimiting();
}

initializeClients() {
console.log('🔧 初始化AI客户端...');

// 清理旧告警
const originalAlerts = this.alerts.length;
this.alerts = this.alerts.filter(alert => alert.timestamp > cutoff);

const cleanedAlerts = originalAlerts - this.alerts.length;
if (cleanedAlerts > 0) {
console.log(`🧹 清理了 ${cleanedAlerts} 条历史告警`);
}
}

getActiveAlerts() {
return this.alerts.filter(alert => !alert.acknowledged);
}

getDashboardData() {
const now = Date.now();
const oneHour = 60 * 60 * 1000;
const recentRequests = this.metrics.requests.filter(
r => now - r.timestamp < oneHour
);

return {
realtime: {
activeRequests: recentRequests.length,
activeAlerts: this.getActiveAlerts().length,
avgResponseTime: this.calculateAverage(
recentRequests.map(r => r.responseTime)
),
successRate: recentRequests.length > 0 ?
(recentRequests.filter(r => r.success).length / recentRequests.length) : 1
},
trends: {
responseTime: this.metrics.responseTime.slice(-60), // 最近60个数据点
throughput: this.metrics.throughput.slice(-60),
errorRate: this.calculateErrorRateTrend()
},
providers: this.getProviderBreakdown(recentRequests)
};
}

calculateErrorRateTrend() {
const now = Date.now();
const interval = 5 * 60 * 1000; // 5分钟间隔
const points = [];

for (let i = 11; i >= 0; i--) {
const endTime = now - (i * interval);
const startTime = endTime - interval;

const requests = this.metrics.requests.filter(
r => r.timestamp >= startTime && r.timestamp < endTime
);

const errorRate = requests.length > 0 ?
requests.filter(r => !r.success).length / requests.length : 0;

points.push({
timestamp: endTime,
value: errorRate
});
}

return points;
}

stop() {
if (this.metricsTimer) {
clearInterval(this.metricsTimer);
this.metricsTimer = null;
}

console.log('📊 性能监控已停止');
}
}

// 使用示例
const monitor = new APIPerformanceMonitor({
metricsInterval: 30000, // 30秒
alertThresholds: {
responseTime: 3000,
errorRate: 0.05,
costPerHour: 5
}
});

// 监听事件
monitor.on('alert', (alert) => {
console.log(`🚨 收到告警: ${alert.type}`);
// 这里可以发送通知
});

monitor.on('metricsCollected', (metrics) => {
// 可以将指标发送到监控系统
console.log(`📊 指标已收集: ${metrics.totalRequests} 请求`);
});

// 集成到AI客户端
class MonitoredAIClient extends UniversalAIClient {
constructor(config = {}) {
super(config);
this.monitor = new APIPerformanceMonitor(config.monitoring || {});
this.setupMonitoring();
}

setupMonitoring() {
// 监听API调用事件
this.on('apiCall', (data) => {
this.monitor.recordRequest({
...data,
success: true
});
});

this.on('apiError', (data) => {
this.monitor.recordRequest({
...data,
success: false
});
});
}

async generateReport(timeRange = '24h') {
return this.monitor.generateReport(timeRange);
}

getDashboard() {
return this.monitor.getDashboardData();
}

cleanup() {
super.cleanup();
this.monitor.stop();
}
}

module.exports = { APIPerformanceMonitor, MonitoredAIClient };

🔄 错误处理与重试策略

智能重试管理器

class SmartRetryManager {
constructor(options = {}) {
this.options = {
maxRetries: 3,
baseDelay: 1000,
maxDelay: 30000,
backoffMultiplier: 2,
jitterRange: 0.1,
retryableErrors: [
'ECONNRESET',
'ETIMEDOUT',
'ENOTFOUND',
'rate_limit_exceeded',
'server_error',
'service_unavailable'
],
circuitBreakerThreshold: 5,
circuitBreakerTimeout: 60000,
...options
};

this.circuitBreakers = new Map();
this.retryStats = new Map();
}

async executeWithRetry(operation, context = {}) {
const {
provider = 'default',
operationId = 'unknown',
maxRetries = this.options.maxRetries
} = context;

// 检查熔断器状态
if (this.isCircuitOpen(provider)) {
throw new Error(`${provider} 服务熔断中,请稍后重试`);
}

let lastError;

for (let attempt = 0; attempt <= maxRetries; attempt++) {
try {
console.log(`🔄 执行操作 ${operationId} (尝试 ${attempt + 1}/${maxRetries + 1})`);

const result = await operation();

// 成功时重置熔断器
this.recordSuccess(provider);

if (attempt > 0) {
console.log(`✅ 操作在第 ${attempt + 1} 次尝试后成功`);
}

return result;

} catch (error) {
lastError = error;

console.log(`❌ 操作失败 (尝试 ${attempt + 1}): ${error.message}`);

// 记录失败
this.recordFailure(provider, error);

// 检查是否应该重试
if (attempt === maxRetries || !this.shouldRetry(error)) {
console.log(`🛑 不再重试: ${this.getRetryReason(error, attempt, maxRetries)}`);
break;
}

// 计算延迟时间
const delay = this.calculateDelay(attempt);
console.log(`⏳ 等待 ${delay}ms 后重试...`);

await this.sleep(delay);
}
}

throw lastError;
}

shouldRetry(error) {
// 检查错误类型是否可重试
const errorMessage = error.message.toLowerCase();
const isRetryable = this.options.retryableErrors.some(retryableError =>
errorMessage.includes(retryableError.toLowerCase())
);

// 检查HTTP状态码
if (error.response) {
const status = error.response.status;

// 4xx错误通常不应重试(除了429)
if (status >= 400 && status < 500 && status !== 429) {
return false;
}

// 5xx错误应该重试
if (status >= 500) {
return true;
}
}

return isRetryable;
}

getRetryReason(error, attempt, maxRetries) {
if (attempt >= maxRetries) {
return '已达最大重试次数';
}

if (!this.shouldRetry(error)) {
return '错误类型不可重试';
}

return '未知原因';
}

calculateDelay(attempt) {
// 指数退避算法
let delay = this.options.baseDelay * Math.pow(this.options.backoffMultiplier, attempt);

// 添加抖动
const jitter = delay * this.options.jitterRange * (Math.random() * 2 - 1);
delay += jitter;

// 限制最大延迟
return Math.min(delay, this.options.maxDelay);
}

recordSuccess(provider) {
// 重置熔断器
if (this.circuitBreakers.has(provider)) {
const breaker = this.circuitBreakers.get(provider);
breaker.failures = 0;
breaker.state = 'closed';
breaker.nextAttempt = null;
}

// 更新统计
if (!this.retryStats.has(provider)) {
this.retryStats.set(provider, {
successes: 0,
failures: 0,
totalRetries: 0
});
}

this.retryStats.get(provider).successes++;
}

recordFailure(provider, error) {
// 更新熔断器
if (!this.circuitBreakers.has(provider)) {
this.circuitBreakers.set(provider, {
failures: 0,
state: 'closed', // closed, open, half-open
nextAttempt: null
});
}

const breaker = this.circuitBreakers.get(provider);
breaker.failures++;

// 检查是否需要打开熔断器
if (breaker.failures >= this.options.circuitBreakerThreshold) {
breaker.state = 'open';
breaker.nextAttempt = Date.now() + this.options.circuitBreakerTimeout;

console.log(`🔥 ${provider} 熔断器已打开,${this.options.circuitBreakerTimeout / 1000}秒后尝试恢复`);
}

// 更新统计
if (!this.retryStats.has(provider)) {
this.retryStats.set(provider, {
successes: 0,
failures: 0,
totalRetries: 0
});
}

this.retryStats.get(provider).failures++;
}

isCircuitOpen(provider) {
const breaker = this.circuitBreakers.get(provider);
if (!breaker) return false;

if (breaker.state === 'closed') {
return false;
}

if (breaker.state === 'open') {
if (Date.now() >= breaker.nextAttempt) {
// 转换到半开状态
breaker.state = 'half-open';
console.log(`🔄 ${provider} 熔断器转为半开状态`);
return false;
}
return true;
}

// half-open状态允许一次尝试
return false;
}

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

getStats() {
const stats = {
circuitBreakers: {},
retryStats: {}
};

this.circuitBreakers.forEach((breaker, provider) => {
stats.circuitBreakers[provider] = {
state: breaker.state,
failures: breaker.failures,
nextAttempt: breaker.nextAttempt
};
});

this.retryStats.forEach((stat, provider) => {
stats.retryStats[provider] = { ...stat };
});

return stats;
}

reset(provider = null) {
if (provider) {
this.circuitBreakers.delete(provider);
this.retryStats.delete(provider);
console.log(`🔄 ${provider} 重试状态已重置`);
} else {
this.circuitBreakers.clear();
this.retryStats.clear();
console.log('🔄 所有重试状态已重置');
}
}
}

// 使用示例
const retryManager = new SmartRetryManager({
maxRetries: 3,
baseDelay: 1000,
circuitBreakerThreshold: 3
});

// 集成到AI客户端
class ResilientAIClient extends MonitoredAIClient {
constructor(config = {}) {
super(config);
this.retryManager = new SmartRetryManager(config.retry || {});
}

async callAPI(provider, endpoint, data, options = {}) {
return this.retryManager.executeWithRetry(
() => super.callAPI(provider, endpoint, data, options),
{
provider,
operationId: `${provider}:${endpoint}`,
maxRetries: options.maxRetries
}
);
}

getRetryStats() {
return this.retryManager.getStats();
}

resetRetryState(provider = null) {
this.retryManager.reset(provider);
}
}

module.exports = { SmartRetryManager, ResilientAIClient };

🎯 学习检验

理论理解检验

  1. API对比分析:能否分析不同AI服务的特点和适用场景?
  2. 集成策略:能否设计统一的API调用框架?
  3. 安全管理:能否理解API密钥的安全管理策略?
  4. 性能优化:能否掌握缓存、重试、监控等优化技术?

实践能力检验

  1. 客户端开发:能否开发统一的AI API客户端?
  2. 错误处理:能否实现智能的重试和熔断机制?
  3. 性能监控:能否构建完整的API性能监控系统?
  4. 安全实践:能否实现安全的密钥管理和配置加密?

🚀 实践项目建议

基础实战项目

  1. 多模型对话系统:集成多个AI服务的对话应用
  2. API性能测试工具:AI API的性能测试和对比工具
  3. 智能重试代理:带有智能重试的API代理服务
  4. 成本监控仪表板:AI API使用成本的监控面板

高级综合项目

  1. 企业AI网关:企业级的AI API统一网关
  2. 多云AI平台:支持多个云服务商的AI平台
  3. AI服务编排器:复杂AI工作流的编排和执行引擎
  4. 智能负载均衡器:AI服务的智能负载均衡和故障转移

📚 延伸阅读

技术文档

  1. "API Integration Best Practices" - API集成最佳实践
  2. "Microservices Patterns" - 微服务架构模式
  3. "Building Resilient Systems" - 构建弹性系统
  4. "API Security Guide" - API安全指南

开源项目

  1. LangChain - AI应用开发框架
  2. LiteLLM - 统一LLM API接口
  3. OpenAI Node.js - OpenAI官方Node.js库
  4. Anthropic SDK - Anthropic官方SDK

💡 学习提示:AI API集成需要考虑多个维度:功能对比、性能优化、成本控制、安全管理等。建议从简单的单一API集成开始,逐步构建统一的调用框架。重视错误处理和监控告警,关注API的使用成本和性能指标。实践中要注意不同服务商的API差异,合理设计抽象层来屏蔽这些差异。

  // 初始化各个提供商的客户端
Object.keys(API_CONFIGS).forEach(provider => {
const config = API_CONFIGS[provider];
const apiKey = this.getApiKey(provider);

if (apiKey) {
this.clients.set(provider, {
config,
apiKey,
httpClient: axios.create({
baseURL: config.baseURL,
timeout: this.config.timeout,
headers: config.headers(apiKey)
})
});

console.log(`[成功] ${provider} 客户端初始化成功`);
} else {
console.log(`[警告] ${provider} API密钥未配置`);
}
});
}

getApiKey(provider) {
const keyMap = {
openai: process.env.OPENAI_API_KEY,
anthropic: process.env.ANTHROPIC_API_KEY,
google: process.env.GOOGLE_AI_API_KEY,
baidu: process.env.BAIDU_API_KEY
};

return keyMap[provider];
}

setupRateLimiting() {
// 简单的令牌桶算法实现
Object.entries(this.config.rateLimits).forEach(([provider, limits]) => {
this.rateLimiters.set(provider, {
rpm: {
tokens: limits.rpm,
maxTokens: limits.rpm,
refillRate: limits.rpm / 60, // 每秒补充的令牌数
lastRefill: Date.now()
},
tpm: {
tokens: limits.tpm,
maxTokens: limits.tpm,
refillRate: limits.tpm / 60,
lastRefill: Date.now()
}
});
});

// 定期补充令牌
setInterval(() => {
this.refillTokens();
}, 1000);
}

refillTokens() {
const now = Date.now();

this.rateLimiters.forEach((limiter, provider) => {
['rpm', 'tpm'].forEach(type => {
const bucket = limiter[type];
const timePassed = (now - bucket.lastRefill) / 1000;
const tokensToAdd = timePassed * bucket.refillRate;

bucket.tokens = Math.min(bucket.maxTokens, bucket.tokens + tokensToAdd);
bucket.lastRefill = now;
});
});
}

async checkRateLimit(provider, estimatedTokens = 1) {
const limiter = this.rateLimiters.get(provider);
if (!limiter) return true;

// 检查RPM限制
if (limiter.rpm.tokens < 1) {
throw new Error(`${provider} RPM限制已达到,请稍后重试`);
}

// 检查TPM限制
if (limiter.tpm.tokens < estimatedTokens) {
throw new Error(`${provider} TPM限制已达到,请稍后重试`);
}

// 消耗令牌
limiter.rpm.tokens -= 1;
limiter.tpm.tokens -= estimatedTokens;

return true;
}

async callAPI(provider, endpoint, data, options = {}) {
const startTime = Date.now();
this.metrics.requests++;

try {
const client = this.clients.get(provider);
if (!client) {
throw new Error(`未找到 ${provider} 客户端`);
}

// 检查缓存
const cacheKey = this.generateCacheKey(provider, endpoint, data);
if (this.config.enableCache && this.cache.has(cacheKey)) {
const cached = this.cache.get(cacheKey);
if (Date.now() - cached.timestamp < this.config.cacheExpiry) {
this.metrics.cacheHits++;
return { ...cached.data, fromCache: true };
} else {
this.cache.delete(cacheKey);
}
}

// 估算Token数量
const estimatedTokens = this.estimateTokens(data);

// 检查速率限制
await this.checkRateLimit(provider, estimatedTokens);

console.log(`\n🚀 调用 ${provider} API: ${endpoint}`);
console.log(`估算Token数: ${estimatedTokens}`);

// 发送请求
const response = await this.makeRequest(client, endpoint, data, options);

// 缓存结果
if (this.config.enableCache && !options.noCache) {
this.cache.set(cacheKey, {
data: response.data,
timestamp: Date.now()
});
}

// 更新指标
this.metrics.successes++;
const responseTime = Date.now() - startTime;
this.metrics.responseTime.push(responseTime);

// 计算成本
const cost = this.calculateCost(provider, response.data);
this.metrics.totalCost += cost;

console.log(`✅ API调用成功 - 响应时间: ${responseTime}ms, 成本: $${cost.toFixed(4)}`);

this.emit('apiCall', {
provider,
endpoint,
success: true,
responseTime,
cost,
tokens: response.data.usage
});

return {
...response.data,
provider,
responseTime,
cost,
fromCache: false
};

} catch (error) {
this.metrics.errors++;

console.error(`${provider} API调用失败:`, error.message);

this.emit('apiError', {
provider,
endpoint,
error: error.message,
responseTime: Date.now() - startTime
});

// 重试逻辑
if (options.retry !== false && this.shouldRetry(error)) {
return this.retryRequest(provider, endpoint, data, options);
}

throw error;
}
}

async makeRequest(client, endpoint, data, options) {
const { method = 'POST', params = {} } = options;

const requestConfig = {
method,
url: endpoint,
data: method === 'GET' ? undefined : data,
params: method === 'GET' ? { ...data, ...params } : params
};

return await client.httpClient.request(requestConfig);
}

shouldRetry(error) {
// 可重试的错误类型
const retryableErrors = [
'ECONNRESET',
'ETIMEDOUT',
'ENOTFOUND',
'rate_limit_exceeded',
'server_error'
];

return retryableErrors.some(errorType =>
error.message.toLowerCase().includes(errorType.toLowerCase())
) || (error.response && error.response.status >= 500);
}

async retryRequest(provider, endpoint, data, options, attempt = 1) {
if (attempt > this.config.maxRetries) {
throw new Error(`${provider} API重试次数已达上限`);
}

const delay = this.config.retryDelay * Math.pow(2, attempt - 1); // 指数退避
console.log(`🔄 第${attempt}次重试 ${provider} API,${delay}ms后执行...`);

await new Promise(resolve => setTimeout(resolve, delay));

try {
return await this.callAPI(provider, endpoint, data, {
...options,
retry: false // 避免无限重试
});
} catch (error) {
return this.retryRequest(provider, endpoint, data, options, attempt + 1);
}
}

estimateTokens(data) {
// 简单的Token估算(实际应用中可以使用更精确的方法)
let text = '';

if (typeof data === 'string') {
text = data;
} else if (data.messages) {
text = data.messages.map(m => m.content).join(' ');
} else if (data.prompt) {
text = data.prompt;
}

// 粗略估算:1个Token约等于4个字符
return Math.ceil(text.length / 4);
}

calculateCost(provider, response) {
const config = API_CONFIGS[provider];
if (!config || !response.usage) return 0;

const usage = response.usage;
let cost = 0;

// 根据不同提供商计算成本
if (usage.prompt_tokens && usage.completion_tokens) {
const model = response.model || Object.keys(config.models)[0];
const modelConfig = config.models[model];

if (modelConfig && modelConfig.costPer1K) {
cost = ((usage.prompt_tokens + usage.completion_tokens) / 1000) * modelConfig.costPer1K;
}
}

return cost;
}

generateCacheKey(provider, endpoint, data) {
const keyData = {
provider,
endpoint,
data: typeof data === 'object' ? JSON.stringify(data) : data
};

return crypto.createHash('md5').update(JSON.stringify(keyData)).digest('hex');
}

// 统一的文本生成接口
async generateText(prompt, options = {}) {
const {
provider = 'openai',
model = 'gpt-3.5-turbo',
maxTokens = 1000,
temperature = 0.7,
stream = false
} = options;

switch (provider) {
case 'openai':
return this.callOpenAI(prompt, { model, maxTokens, temperature, stream });
case 'anthropic':
return this.callAnthropic(prompt, { model, maxTokens, temperature });
case 'google':
return this.callGoogle(prompt, { model, maxTokens, temperature });
case 'baidu':
return this.callBaidu(prompt, { model, maxTokens, temperature });
default:
throw new Error(`不支持的提供商: ${provider}`);
}
}

async callOpenAI(prompt, options) {
const { model, maxTokens, temperature, stream } = options;

const data = {
model,
messages: [{ role: 'user', content: prompt }],
max_tokens: maxTokens,
temperature,
stream
};

return this.callAPI('openai', '/chat/completions', data);
}

async callAnthropic(prompt, options) {
const { model, maxTokens, temperature } = options;

const data = {
model,
max_tokens: maxTokens,
temperature,
messages: [{ role: 'user', content: prompt }]
};

return this.callAPI('anthropic', '/messages', data);
}

async callGoogle(prompt, options) {
const { model, maxTokens, temperature } = options;

const data = {
contents: [{
parts: [{ text: prompt }]
}],
generationConfig: {
temperature,
maxOutputTokens: maxTokens
}
};

return this.callAPI('google', `/models/${model}:generateContent`, data, {
params: { key: this.getApiKey('google') }
});
}

async callBaidu(prompt, options) {
const { model, maxTokens, temperature } = options;

// 百度需要先获取access_token
const accessToken = await this.getBaiduAccessToken();

const data = {
messages: [{ role: 'user', content: prompt }],
max_output_tokens: maxTokens,
temperature
};

return this.callAPI('baidu', `/wenxinworkshop/chat/${model}`, data, {
params: { access_token: accessToken }
});
}

async getBaiduAccessToken() {
// 实现百度access_token获取逻辑
const clientId = process.env.BAIDU_CLIENT_ID;
const clientSecret = process.env.BAIDU_CLIENT_SECRET;

if (!clientId || !clientSecret) {
throw new Error('百度API凭证未配置');
}

// 这里应该实现实际的token获取逻辑
return 'mock_access_token';
}

// 批量处理
async batchProcess(requests, options = {}) {
const {
concurrency = 3,
delayBetweenBatches = 1000,
failFast = false
} = options;

console.log(`\n📦 开始批量处理 ${requests.length} 个请求`);
console.log(`并发数: ${concurrency}`);

const results = [];
const errors = [];

for (let i = 0; i < requests.length; i += concurrency) {
const batch = requests.slice(i, i + concurrency);

console.log(`\n处理批次 ${Math.floor(i / concurrency) + 1}/${Math.ceil(requests.length / concurrency)}`);

const batchPromises = batch.map(async (request, index) => {
try {
const result = await this.generateText(request.prompt, request.options);
return { index: i + index, success: true, result };
} catch (error) {
const errorResult = { index: i + index, success: false, error: error.message };

if (failFast) {
throw error;
}

return errorResult;
}
});

try {
const batchResults = await Promise.all(batchPromises);

batchResults.forEach(result => {
if (result.success) {
results.push(result);
} else {
errors.push(result);
}
});

console.log(`批次完成: 成功 ${batchResults.filter(r => r.success).length}, 失败 ${batchResults.filter(r => !r.success).length}`);

// 批次间延迟
if (i + concurrency < requests.length) {
await new Promise(resolve => setTimeout(resolve, delayBetweenBatches));
}

} catch (error) {
if (failFast) {
throw error;
}

console.error(`批次处理失败:`, error.message);
}
}

console.log(`\n✅ 批量处理完成`);
console.log(`总成功: ${results.length}`);
console.log(`总失败: ${errors.length}`);

return {
total: requests.length,
successes: results.length,
errors: errors.length,
results,
errorDetails: errors
};
}

// 获取指标统计
getMetrics() {
const avgResponseTime = this.metrics.responseTime.length > 0 ?
this.metrics.responseTime.reduce((a, b) => a + b, 0) / this.metrics.responseTime.length : 0;

return {
...this.metrics,
avgResponseTime: Math.round(avgResponseTime),
successRate: this.metrics.requests > 0 ?
(this.metrics.successes / this.metrics.requests * 100).toFixed(2) + '%' : '0%',
cacheHitRate: this.metrics.requests > 0 ?
(this.metrics.cacheHits / this.metrics.requests * 100).toFixed(2) + '%' : '0%',
availableProviders: Array.from(this.clients.keys()),
cacheSize: this.cache.size
};
}

// 健康检查
async healthCheck() {
console.log('\n执行健康检查...');

const results = {};

for (const [provider] of this.clients) {
try {
const startTime = Date.now();

await this.generateText('Hello', {
provider,
maxTokens: 10,
noCache: true
});

results[provider] = {
status: 'healthy',
responseTime: Date.now() - startTime
};

console.log(`[健康] ${provider}`);

} catch (error) {
results[provider] = {
status: 'unhealthy',
error: error.message
};

console.log(`[不健康] ${provider}: ${error.message}`);
}
}

return results;
}

// 清理资源
cleanup() {
this.cache.clear();
this.metrics.responseTime = [];
console.log('资源清理完成');
}
}

// 使用示例
const aiClient = new UniversalAIClient({
enableCache: true,
enableMetrics: true,
timeout: 30000
});

// 监听事件
aiClient.on('apiCall', (data) => {
console.log(`API调用: ${data.provider} - ${data.responseTime}ms - $${data.cost.toFixed(4)}`);
});

aiClient.on('apiError', (data) => {
console.log(`API错误: ${data.provider} - ${data.error}`);
});

// 文本生成演示已移除

// 健康检查演示
async function healthCheckDemo() {
const healthStatus = await aiClient.healthCheck();

console.log('\n健康检查结果:');
Object.entries(healthStatus).forEach(([provider, status]) => {
console.log(`${provider}: ${status.status}`);
if (status.responseTime) {
console.log(` 响应时间: ${status.responseTime}ms`);
}
});
}

// 运行演示
if (require.main === module) {
(async () => {
await textGenerationDemo();
await healthCheckDemo();

// 清理资源
aiClient.cleanup();
})().catch(console.error);
}

module.exports = { UniversalAIClient, API_CONFIGS };

🔐 API密钥管理与安全

安全配置管理器

const crypto = require('crypto');
const fs = require('fs');
const path = require('path');

class SecureConfigManager {
constructor(options = {}) {
this.options = {
encryptionKey: process.env.CONFIG_ENCRYPTION_KEY || this.generateKey(),
configPath: options.configPath || './config/secure.json',
backupPath: options.backupPath || './config/backup',
rotationInterval: options.rotationInterval || 30 * 24 * 60 * 60 * 1000, // 30天
...options
};

this.algorithm = 'aes-256-gcm';
this.configs = new Map();
this.loadConfigs();
this.setupRotation();
}

generateKey() {
return crypto.randomBytes(32).toString('hex');
}

encrypt(text) {
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipher(this.algorithm, this.options.encryptionKey);
cipher.setAAD(Buffer.from('config-data'));

let encrypted = cipher.update(text, 'utf8', 'hex');
encrypted += cipher.final('hex');

const authTag = cipher.getAuthTag();

return {
encrypted,
iv: iv.toString('hex'),
authTag: authTag.toString('hex')
};
}

decrypt(encryptedData) {
const decipher = crypto.createDecipher(this.algorithm, this.options.encryptionKey);
decipher.setAAD(Buffer.from('config-data'));
decipher.setAuthTag(Buffer.from(encryptedData.authTag, 'hex'));

let decrypted = decipher.update(encryptedData.encrypted, 'hex', 'utf8');
decrypted += decipher.final('utf8');

return decrypted;
}

setApiKey(provider, apiKey, metadata = {}) {
console.log(`🔐 设置 ${provider} API密钥`);

const config = {
apiKey,
provider,
createdAt: new Date().toISOString(),
lastUsed: null,
usageCount: 0,
metadata: {
environment: process.env.NODE_ENV || 'development',
...metadata
}
};

this.configs.set(provider, config);
this.saveConfigs();

console.log(`${provider} API密钥已安全存储`);
}

getApiKey(provider) {
const config = this.configs.get(provider);
if (!config) {
throw new Error(`未找到 ${provider} 的API密钥`);
}

// 更新使用统计
config.lastUsed = new Date().toISOString();
config.usageCount++;

return config.apiKey;
}

rotateApiKey(provider, newApiKey) {
console.log(`🔄 轮换 ${provider} API密钥`);

const oldConfig = this.configs.get(provider);
if (oldConfig) {
// 备份旧密钥
this.backupConfig(provider, oldConfig);
}

this.setApiKey(provider, newApiKey, {
rotatedFrom: oldConfig?.apiKey?.substring(0, 8) + '...',
rotatedAt: new Date().toISOString()
});

console.log(`${provider} API密钥轮换完成`);
}

validateApiKey(provider, apiKey) {
// API密钥格式验证
const patterns = {
openai: /^sk-[a-zA-Z0-9]{48}$/,
anthropic: /^sk-ant-[a-zA-Z0-9\-_]{95}$/,
google: /^[a-zA-Z0-9\-_]{39}$/,
baidu: /^[a-zA-Z0-9]{24}$/
};

const pattern = patterns[provider];
if (pattern && !pattern.test(apiKey)) {
throw new Error(`${provider} API密钥格式无效`);
}

return true;
}

async testApiKey(provider, apiKey) {
console.log(`🧪 测试 ${provider} API密钥`);

try {
// 这里应该实现实际的API测试逻辑
const testClient = new UniversalAIClient();

// 临时设置密钥进行测试
const originalKey = process.env[`${provider.toUpperCase()}_API_KEY`];
process.env[`${provider.toUpperCase()}_API_KEY`] = apiKey;

await testClient.generateText('Hello', {
provider,
maxTokens: 5
});

// 恢复原密钥
if (originalKey) {
process.env[`${provider.toUpperCase()}_API_KEY`] = originalKey;
}

console.log(`${provider} API密钥测试通过`);
return true;

} catch (error) {
console.error(`${provider} API密钥测试失败:`, error.message);
return false;
}
}

loadConfigs() {
try {
if (fs.existsSync(this.options.configPath)) {
const encryptedData = JSON.parse(fs.readFileSync(this.options.configPath, 'utf8'));
const decryptedData = this.decrypt(encryptedData);
const configs = JSON.parse(decryptedData);

Object.entries(configs).forEach(([provider, config]) => {
this.configs.set(provider, config);
});

console.log(`📖 已加载 ${this.configs.size} 个API配置`);
}
} catch (error) {
console.error('配置加载失败:', error.message);
}
}

saveConfigs() {
try {
const configsObj = Object.fromEntries(this.configs);
const configData = JSON.stringify(configsObj, null, 2);
const encryptedData = this.encrypt(configData);

// 确保目录存在
const configDir = path.dirname(this.options.configPath);
if (!fs.existsSync(configDir)) {
fs.mkdirSync(configDir, { recursive: true });
}

fs.writeFileSync(this.options.configPath, JSON.stringify(encryptedData, null, 2));
console.log('💾 配置已安全保存');

} catch (error) {
console.error('配置保存失败:', error.message);
}
}

backupConfig(provider, config) {
try {
const backupDir = this.options.backupPath;
if (!fs.existsSync(backupDir)) {
fs.mkdirSync(backupDir, { recursive: true });
}

const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const backupFile = path.join(backupDir, `${provider}_${timestamp}.json`);

const encryptedConfig = this.encrypt(JSON.stringify(config, null, 2));
fs.writeFileSync(backupFile, JSON.stringify(encryptedConfig, null, 2));

console.log(`📦 ${provider} 配置已备份到: ${backupFile}`);

} catch (error) {
console.error('配置备份失败:', error.message);
}
}

setupRotation() {
// 定期检查密钥是否需要轮换
setInterval(() => {
this.checkRotationNeeded();
}, 24 * 60 * 60 * 1000); // 每天检查一次
}

checkRotationNeeded() {
const now = Date.now();

this.configs.forEach((config, provider) => {
const createdAt = new Date(config.createdAt).getTime();
const age = now - createdAt;

if (age > this.options.rotationInterval) {
console.log(`⚠️ ${provider} API密钥需要轮换 (已使用 ${Math.floor(age / (24 * 60 * 60 * 1000))} 天)`);

// 这里可以发送通知或自动轮换
this.emit('rotationNeeded', { provider, age });
}
});
}

getUsageStats() {
const stats = {};

this.configs.forEach((config, provider) => {
stats[provider] = {
usageCount: config.usageCount,
lastUsed: config.lastUsed,
createdAt: config.createdAt,
age: Date.now() - new Date(config.createdAt).getTime()
};
});

return stats;
}

exportConfigs(outputPath, includeKeys = false) {
const exportData = {
timestamp: new Date().toISOString(),
configs: {}
};

this.configs.forEach((config, provider) => {
exportData.configs[provider] = {
provider: config.provider,
createdAt: config.createdAt,
lastUsed: config.lastUsed,
usageCount: config.usageCount,
metadata: config.metadata
};

if (includeKeys) {
exportData.configs[provider].apiKey = config.apiKey;
}
});

if (includeKeys) {
// 如果包含密钥,需要加密
const encryptedData = this.encrypt(JSON.stringify(exportData, null, 2));
fs.writeFileSync(outputPath, JSON.stringify(encryptedData, null, 2));
} else {
fs.writeFileSync(outputPath, JSON.stringify(exportData, null, 2));
}

console.log(`📤 配置已导出到: ${outputPath}`);
}

cleanup() {
this.configs.clear();
console.log('🧹 配置管理器已清理');
}
}

// 使用示例
const configManager = new SecureConfigManager({
configPath: './config/api_keys.json',
rotationInterval: 30 * 24 * 60 * 60 * 1000 // 30天
});

// 设置API密钥
async function setupApiKeys() {
console.log('🔐 API密钥管理演示\n');

try {
// 设置各个提供商的API密钥
const apiKeys = {
openai: process.env.OPENAI_API_KEY,
anthropic: process.env.ANTHROPIC_API_KEY,
google: process.env.GOOGLE_AI_API_KEY
};

for (const [provider, apiKey] of Object.entries(apiKeys)) {
if (apiKey) {
// 验证密钥格式
try {
configManager.validateApiKey(provider, apiKey);
console.log(`${provider} 密钥格式验证通过`);
} catch (error) {
console.log(`⚠️ ${provider} 密钥格式验证失败: ${error.message}`);
continue;
}

// 测试密钥有效性
const isValid = await configManager.testApiKey(provider, apiKey);
if (isValid) {
configManager.setApiKey(provider, apiKey, {
environment: 'production',
description: `${provider} API密钥`
});
}
}
}

// 显示使用统计
const stats = configManager.getUsageStats();
console.log('\n📊 API密钥使用统计:');
Object.entries(stats).forEach(([provider, stat]) => {
console.log(`${provider}:`);
console.log(` 使用次数: ${stat.usageCount}`);
console.log(` 最后使用: ${stat.lastUsed || '未使用'}`);
console.log(` 创建时间: ${stat.createdAt}`);
});

// 导出配置(不包含密钥)
configManager.exportConfigs('./config/api_stats.json', false);

} catch (error) {
console.error('API密钥设置失败:', error.message);
}
}

module.exports = { SecureConfigManager };

📈 性能监控与优化

API性能监控器

const EventEmitter = require('events');
const fs = require('fs');

class APIPerformanceMonitor extends EventEmitter {
constructor(options = {}) {
super();

this.options = {
metricsInterval: 60000, // 1分钟
alertThresholds: {
responseTime: 5000, // 5秒
errorRate: 0.1, // 10%
costPerHour: 10 // $10/小时
},
retentionPeriod: 7 * 24 * 60 * 60 * 1000, // 7天
...options
};

this.metrics = {
requests: [],
errors: [],
costs: [],
responseTime: [],
throughput: []
};

this.alerts = [];
this.startMonitoring();
}

startMonitoring() {
console.log('📊 启动API性能监控...');

// 定期收集指标
this.metricsTimer = setInterval(() => {
this.collectMetrics();
this.checkAlerts();
this.cleanupOldData();
}, this.options.metricsInterval);

console.log(`✅ 性能监控已启动,间隔: ${this.options.metricsInterval / 1000}`);
}

recordRequest(data) {
const record = {
timestamp: Date.now(),
provider: data.provider,
endpoint: data.endpoint,
responseTime: data.responseTime,
success: data.success,
cost: data.cost || 0,
tokens: data.tokens || 0,
error: data.error || null
};

this.metrics.requests.push(record);

if (!data.success) {
this.metrics.errors.push(record);
}

if (data.cost > 0) {
this.metrics.costs.push(record);
}

this.metrics.responseTime.push({
timestamp: record.timestamp,
value: data.responseTime,
provider: data.provider
});

// 触发实时事件
this.emit('requestRecorded', record);
}

collectMetrics() {
const now = Date.now();
const oneHour = 60 * 60 * 1000;
const recentRequests = this.metrics.requests.filter(
r => now - r.timestamp < oneHour
);

if (recentRequests.length === 0) return;

const metrics = {
timestamp: now,
totalRequests: recentRequests.length,
successfulRequests: recentRequests.filter(r => r.success).length,
failedRequests: recentRequests.filter(r => !r.success).length,
avgResponseTime: this.calculateAverage(
recentRequests.map(r => r.responseTime)
),
totalCost: recentRequests.reduce((sum, r) => sum + r.cost, 0),
totalTokens: recentRequests.reduce((sum, r) => sum + r.tokens, 0),
errorRate: recentRequests.filter(r => !r.success).length / recentRequests.length,
throughput: recentRequests.length / (oneHour / 1000), // 请求/秒
providerBreakdown: this.getProviderBreakdown(recentRequests)
};

this.metrics.throughput.push({
timestamp: now,
value: metrics.throughput
});

this.emit('metricsCollected', metrics);

console.log(`\n📊 性能指标 (过去1小时):`);
console.log(`总请求: ${metrics.totalRequests}`);
console.log(`成功率: ${((1 - metrics.errorRate) * 100).toFixed(2)}%`);
console.log(`平均响应时间: ${metrics.avgResponseTime.toFixed(0)}ms`);
console.log(`总成本: $${metrics.totalCost.toFixed(4)}`);
console.log(`吞吐量: ${metrics.throughput.toFixed(2)} 请求/秒`);

return metrics;
}

checkAlerts() {
const now = Date.now();
const oneHour = 60 * 60 * 1000;
const recentRequests = this.metrics.requests.filter(
r => now - r.timestamp < oneHour
);

if (recentRequests.length === 0) return;

const currentMetrics = {
avgResponseTime: this.calculateAverage(
recentRequests.map(r => r.responseTime)
),
errorRate: recentRequests.filter(r => !r.success).length / recentRequests.length,
costPerHour: recentRequests.reduce((sum, r) => sum + r.cost, 0)
};

// 检查响应时间告警
if (currentMetrics.avgResponseTime > this.options.alertThresholds.responseTime) {
this.triggerAlert('HIGH_RESPONSE_TIME', {
current: currentMetrics.avgResponseTime,
threshold: this.options.alertThresholds.responseTime,
message: `平均响应时间过高: ${currentMetrics.avgResponseTime.toFixed(0)}ms`
});
}

// 检查错误率告警
if (currentMetrics.errorRate > this.options.alertThresholds.errorRate) {
this.triggerAlert('HIGH_ERROR_RATE', {
current: currentMetrics.errorRate,
threshold: this.options.alertThresholds.errorRate,
message: `错误率过高: ${(currentMetrics.errorRate * 100).toFixed(2)}%`
});
}

// 检查成本告警
if (currentMetrics.costPerHour > this.options.alertThresholds.costPerHour) {
this.triggerAlert('HIGH_COST', {
current: currentMetrics.costPerHour,
threshold: this.options.alertThresholds.costPerHour,
message: `每小时成本过高: $${currentMetrics.costPerHour.toFixed(4)}`
});
}
}

triggerAlert(type, data) {
const alert = {
id: crypto.randomUUID(),
type,
timestamp: Date.now(),
data,
acknowledged: false
};

this.alerts.push(alert);

console.log(`\n🚨 告警触发: ${type}`);
console.log(`详情: ${data.message}`);
console.log(`当前值: ${data.current}`);
console.log(`阈值: ${data.threshold}`);

this.emit('alert', alert);

// 可以在这里添加邮件、短信等通知逻辑
this.sendNotification(alert);
}

sendNotification(alert) {
// 这里可以集成邮件、Slack、钉钉等通知服务
console.log(`📧 发送告警通知: ${alert.type}`);
}

acknowledgeAlert(alertId) {
const alert = this.alerts.find(a => a.id === alertId);
if (alert) {
alert.acknowledged = true;
alert.acknowledgedAt = Date.now();
console.log(`✅ 告警已确认: ${alert.type}`);
}
}

getProviderBreakdown(requests) {
const breakdown = {};

requests.forEach(request => {
if (!breakdown[request.provider]) {
breakdown[request.provider] = {
requests: 0,
successes: 0,
errors: 0,
totalCost: 0,
avgResponseTime: 0,
responseTimes: []
};
}

const provider = breakdown[request.provider];
provider.requests++;

if (request.success) {
provider.successes++;
} else {
provider.errors++;
}

provider.totalCost += request.cost;
provider.responseTimes.push(request.responseTime);
});

// 计算平均响应时间
Object.values(breakdown).forEach(provider => {
provider.avgResponseTime = this.calculateAverage(provider.responseTimes);
provider.successRate = provider.successes / provider.requests;
delete provider.responseTimes; // 清理临时数据
});

return breakdown;
}

calculateAverage(numbers) {
if (numbers.length === 0) return 0;
return numbers.reduce((sum, num) => sum + num, 0) / numbers.length;
}

calculatePercentile(numbers, percentile) {
if (numbers.length === 0) return 0;

const sorted = numbers.slice().sort((a, b) => a - b);
const index = Math.ceil((percentile / 100) * sorted.length) - 1;
return sorted[index];
}

generateReport(timeRange = '1h') {
const now = Date.now();
const ranges = {
'1h': 60 * 60 * 1000,
'24h': 24 * 60 * 60 * 1000,
'7d': 7 * 24 * 60 * 60 * 1000
};

const range = ranges[timeRange] || ranges['1h'];
const requests = this.metrics.requests.filter(
r => now - r.timestamp < range
);

if (requests.length === 0) {
return { error: '指定时间范围内无数据' };
}

const responseTimes = requests.map(r => r.responseTime);
const costs = requests.map(r => r.cost);

const report = {
timeRange,
generatedAt: new Date().toISOString(),
summary: {
totalRequests: requests.length,
successfulRequests: requests.filter(r => r.success).length,
failedRequests: requests.filter(r => !r.success).length,
successRate: (requests.filter(r => r.success).length / requests.length * 100).toFixed(2) + '%',
totalCost: costs.reduce((sum, cost) => sum + cost, 0),
avgCostPerRequest: this.calculateAverage(costs)
},
performance: {
avgResponseTime: this.calculateAverage(responseTimes),
p50ResponseTime: this.calculatePercentile(responseTimes, 50),
p95ResponseTime: this.calculatePercentile(responseTimes, 95),
p99ResponseTime: this.calculatePercentile(responseTimes, 99),
maxResponseTime: Math.max(...responseTimes),
minResponseTime: Math.min(...responseTimes)
},
providers: this.getProviderBreakdown(requests),
errors: this.getErrorBreakdown(requests.filter(r => !r.success)),
alerts: this.alerts.filter(a => now - a.timestamp < range)
};

return report;
}

getErrorBreakdown(errorRequests) {
const breakdown = {};

errorRequests.forEach(request => {
const errorType = request.error || 'Unknown Error';

if (!breakdown[errorType]) {
breakdown[errorType] = {
count: 0,
providers: {},
firstOccurrence: request.timestamp,
lastOccurrence: request.timestamp
};
}

breakdown[errorType].count++;
breakdown[errorType].lastOccurrence = Math.max(
breakdown[errorType].lastOccurrence,
request.timestamp
);

if (!breakdown[errorType].providers[request.provider]) {
breakdown[errorType].providers[request.provider] = 0;
}
breakdown[errorType].providers[request.provider]++;
});

return breakdown;
}

exportReport(timeRange = '24h', format = 'json') {
const report = this.generateReport(timeRange);
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
const filename = `api_performance_report_${timeRange}_${timestamp}.${format}`;

if (format === 'json') {
fs.writeFileSync(filename, JSON.stringify(report, null, 2));
} else if (format === 'csv') {
// 实现CSV导出逻辑
const csv = this.convertToCSV(report);
fs.writeFileSync(filename, csv);
}

console.log(`📊 性能报告已导出: ${filename}`);
return filename;
}

convertToCSV(report) {
// 简单的CSV转换实现
const lines = [];
lines.push('Metric,Value');
lines.push(`Total Requests,${report.summary.totalRequests}`);
lines.push(`Success Rate,${report.summary.successRate}`);
lines.push(`Total Cost,$${report.summary.totalCost.toFixed(4)}`);
lines.push(`Avg Response Time,${report.performance.avgResponseTime.toFixed(0)}ms`);

return lines.join('\n');
}

cleanupOldData() {
const cutoff = Date.now() - this.options.retentionPeriod;

['requests', 'errors', 'costs', 'responseTime', 'throughput'].forEach(metric => {
const originalLength = this.metrics[metric].length;
this.metrics[metric] = this.metrics[metric].filter(
item => item.timestamp > cutoff
);

const cleaned = originalLength - this.metrics[metric].length;
if (cleaned > 0) {
console.log(`🧹 清理了 ${cleaned}${metric} 历史数据`);
}
});

//