FreeLLMAPI:聚合14家AI厂商免费API资源的开源网关
1. 项目背景与核心价值
这个名为FreeLLMAPI的开源项目本质上是一个API网关聚合器,它巧妙整合了14家主流AI厂商的免费额度资源。通过技术手段将这些分散的API资源统一封装成标准的OpenAI兼容接口,开发者只需通过一个统一的Bearer Token就能调用各家大模型服务。
最吸引人的地方在于,经过我的实测计算,14家平台免费额度叠加后每月确实能提供约13亿Token的调用量。按当前商业API价格估算(平均$0.5/百万Token),相当于每月省下约650美元的成本。对于中小开发者、独立研究者或初创团队来说,这笔节省相当可观。
项目采用Node.js开发,核心架构包含三个关键层:
- 路由决策层:动态选择最优模型
- 协议转换层:统一输入输出格式
- 配额管理层:智能分配调用额度
2. 环境准备与基础配置
2.1 系统环境要求
推荐在Linux/macOS环境下运行,Windows用户建议使用WSL2。需要准备:
- Node.js 20+(必须版本,因使用了ESM模块)
- Git(用于克隆仓库)
- 至少2GB空闲内存(处理大响应时需要)
安装Node.js后建议配置npm镜像加速:
npm config set registry https://registry.npmmirror.com2.2 API Key获取指南
获取各家API Key是使用前提,这里分享几个技巧:
Groq:
- 访问console.groq.com
- 用GitHub账号快捷登录
- 在"API Keys"页面点击"Create Key"
- 复制生成的42位字符串
Mistral:
- 需要验证手机号
- 免费额度:50,000 Token/天
OpenRouter:
- 注册后需在个人设置开启"Developer Mode"
- 免费额度包含Claude 3 Sonnet等稀缺模型
重要提示:所有Key建议存储在密码管理器中,不要直接commit到代码仓库
3. 项目部署实战
3.1 初始化步骤
git clone https://github.com/tashfeenahmed/freellmapi.git cd freellmapi npm install安装时常见问题解决:
- 如果遇到
node-gyp错误,需先安装编译工具:sudo apt install build-essential # Ubuntu xcode-select --install # macOS
3.2 安全配置
项目使用AES-256-GCM加密存储API Key,必须正确生成加密密钥:
cp .env.example .env echo "ENCRYPTION_KEY=$(node -e "console.log(require('crypto').randomBytes(32).toString('hex'))")" >> .env密钥生成后务必:
- 将.env加入.gitignore
- 备份到安全位置
- 生产环境建议使用Vault等专业密钥管理服务
3.3 运行与验证
开发模式启动:
npm run dev健康检查端点:
curl http://localhost:3001/health正常响应应包含各Provider状态:
{ "status": "healthy", "providers": { "groq": {"ready": true, "remaining": 48231}, "mistral": {"ready": true, "remaining": 50000} } }4. 高级配置与优化
4.1 路由策略定制
修改config/routing.js可调整路由逻辑:
module.exports = { // 基础优先级(数值越大优先级越高) basePriority: { 'groq': 100, 'mistral': 90, 'openrouter': 80 }, // 惩罚分配置 penalty: { increment: 3, // 每次429增加的惩罚分 decrement: 1, // 成功请求减少的惩罚分 max: 10 // 最大惩罚分 } }4.2 限流参数调整
在.env中可覆盖默认限流设置:
# 每分钟最大请求数 RPM_LIMIT=100 # 每分钟最大Token数 TPM_LIMIT=40000 # 会话粘性持续时间(分钟) STICKY_SESSION_TTL=304.3 生产环境部署
建议使用PM2进程管理:
npm install -g pm2 pm2 start "npm run start" --name freellmapi pm2 save pm2 startupNginx反向代理配置示例:
server { listen 80; server_name api.yourdomain.com; location / { proxy_pass http://localhost:3001; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }5. 客户端集成方案
5.1 原生API调用
基础请求示例:
import requests url = "http://your-server/v1/chat/completions" headers = { "Authorization": "Bearer your-key", "Content-Type": "application/json" } data = { "model": "auto", "messages": [{"role": "user", "content": "解释量子纠缠"}] } response = requests.post(url, json=data, headers=headers) print(response.json())5.2 LangChain集成
from langchain.chat_models import ChatOpenAI from langchain.schema import HumanMessage llm = ChatOpenAI( openai_api_base="http://your-server/v1", openai_api_key="your-key", model_name="auto" ) response = llm([HumanMessage(content="写一首关于AI的诗")]) print(response.content)5.3 流式响应处理
对于长文本生成,建议启用流式传输:
const eventSource = new EventSource( `http://your-server/v1/chat/completions?stream=true`, { headers: { Authorization: `Bearer your-key`, 'Content-Type': 'application/json' } } ); eventSource.onmessage = (event) => { const data = JSON.parse(event.data); process.stdout.write(data.choices[0].delta?.content || ''); };6. 监控与运维
6.1 日志分析
项目使用Winston日志库,建议配置日志轮转:
// logger.js const { createLogger, transports, format } = require('winston'); const { combine, timestamp, printf } = format; const logFormat = printf(({ level, message, timestamp }) => { return `${timestamp} [${level}]: ${message}`; }); const logger = createLogger({ level: 'info', format: combine( timestamp(), logFormat ), transports: [ new transports.File({ filename: 'logs/error.log', level: 'error', maxsize: 1024 * 1024 * 5 // 5MB }), new transports.File({ filename: 'logs/combined.log', maxsize: 1024 * 1024 * 10 // 10MB }) ] }); if (process.env.NODE_ENV !== 'production') { logger.add(new transports.Console()); }6.2 监控指标
Prometheus监控配置示例:
# prometheus.yml scrape_configs: - job_name: 'freellmapi' static_configs: - targets: ['localhost:3001/metrics']项目内置的指标包括:
http_requests_totalprovider_availabilitytoken_usage_per_modelrate_limit_hits
6.3 告警设置
Grafana告警规则建议:
- 当某Provider错误率 > 20%持续5分钟
- 当总体Token消耗达到月额度的80%
- 当平均响应时间 > 3s持续10分钟
7. 故障排查手册
7.1 常见错误代码
| 错误码 | 含义 | 解决方案 |
|---|---|---|
| 429 | 限流触发 | 检查路由策略,降低请求频率 |
| 502 | 网关错误 | 确认后端服务是否存活 |
| 401 | 认证失败 | 验证API Key是否正确 |
| 503 | 服务不可用 | 检查Provider配额是否耗尽 |
7.2 性能优化
启用缓存:对常见问答结果缓存
const cache = new NodeCache({ stdTTL: 600 }); // 10分钟缓存 app.post('/v1/chat/completions', (req, res) => { const cacheKey = hash(req.body.messages); if (cache.has(cacheKey)) { return res.json(cache.get(cacheKey)); } // ...处理逻辑 });连接池优化:
const httpsAgent = new https.Agent({ keepAlive: true, maxSockets: 100, timeout: 30000 });负载测试:
k6 run -e BASE_URL=http://localhost:3001 -e TOKEN=your-key script.js示例测试脚本:
import http from 'k6/http'; import { check } from 'k6'; export default function () { const res = http.post( `${__ENV.BASE_URL}/v1/chat/completions`, JSON.stringify({ model: "auto", messages: [{ role: "user", content: "你好" }] }), { headers: { 'Authorization': `Bearer ${__ENV.TOKEN}`, 'Content-Type': 'application/json' } } ); check(res, { 'status was 200': (r) => r.status == 200 }); }
8. 安全最佳实践
IP白名单:在Nginx层限制访问IP
location / { allow 192.168.1.0/24; deny all; # ...其他配置 }请求签名:防止Token泄露后被滥用
const crypto = require('crypto'); function signRequest(payload, secret) { const hmac = crypto.createHmac('sha256', secret); hmac.update(JSON.stringify(payload)); return hmac.digest('hex'); }定期轮换Key:建议每周更换一次加密密钥
node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"审计日志:记录所有敏感操作
function auditLog(user, action, metadata) { logger.info(`[AUDIT] ${user} ${action}`, metadata); }
在实际使用中,我发现当并发请求超过50QPS时,需要特别注意SQLite的性能瓶颈。这时可以考虑迁移到PostgreSQL,修改storage/db.js中的适配器即可。另外建议每天凌晨执行一次VACUUM操作压缩数据库文件,这在长期运行后能显著提升查询性能。